From ea135812b12f577f08184c4277ef8ea30ae2fe8a Mon Sep 17 00:00:00 2001 From: Asturur Date: Tue, 4 Jul 2017 00:47:01 +0200 Subject: [PATCH] packaged beta 3 --- CHANGELOG.md | 101 +++ HEADER.js | 2 +- README.md | 2 +- dist/fabric.js | 2026 ++++++++++++++++++++---------------------------- dist/fabric.min.js | 18 +- dist/fabric.min.js.gz | Bin 74377 -> 75119 bytes dist/fabric.require.js | 958 ++++++++++++----------- package.json | 2 +- 8 files changed, 1480 insertions(+), 1629 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2253a6787..03839aa05 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,104 @@ +**Version 2.0.0** + +- incompat: New filter system with WEBGL. +- incompat: New Text/IText/Textbox code. Multibyte compatible, more accurate. +- incompat: RequestAnimationFrame is used for the automatic render calls. +- incompat: Named setter/getter are optional now. +- incompat: Removed PathGroup class +- incompat: Paths cannot be restored anymore from strings [#3713](https://github.com/kangax/fabric.js/pull/3713) +- incompat: bumped node version to 4+ and jsdom to 9. [#3717](https://github.com/kangax/fabric.js/pull/3717) +- incompat: removed the es5 / JSON shim support [#3722](https://github.com/kangax/fabric.js/pull/3722) +- fix/incompat: IText setSelectionStyles does not change anymore style if no selection is present [#3765](https://github.com/kangax/fabric.js/pull/3765) +- skipOffscreen default to true +- Text.setSelectionStyle does not change anything if there is no selection [#3765](https://github.com/kangax/fabric.js/pull/3765) +- Switch to canvas-prebuilt as dependency. Added parameter to choose the canvas package [#3757](https://github.com/kangax/fabric.js/pull/3757) +- improvement: renderControls can now be called on its own. Added parameter styleOverride to allow for overriding current properties [#3887](https://github.com/kangax/fabric.js/pull/3887) +- removed hasMoved and saveCoords from Group class [#3910](https://github.com/kangax/fabric.js/pull/3910) +- forced all fromObject and fromElement to be async, normalized api. [#3996](https://github.com/kangax/fabric.js/pull/3996) +- improvement: added support for request animation frame in mouse events [#3997](https://github.com/kangax/fabric.js/pull/3997) +- added dblclick support for all objects [#3998](https://github.com/kangax/fabric.js/pull/3997) +- textbox scale as a normal object [#4052](https://github.com/kangax/fabric.js/pull/4052) +- Removed image meetOrSlice, alignX, alignY, introduced cropX, cropY [#4055](https://github.com/kangax/fabric.js/pull/4055) +- Added Text.cleanStyle, Text.removeStyle [#4060](https://github.com/kangax/fabric.js/pull/4060) +- change: lockRotation will not hide the mtr control anymore. introduced notAllowedCursor for canvas. [#4064](https://github.com/kangax/fabric.js/pull/4064) +- improvement: added 2 percentage values to fabric.util.animate. [#4068](https://github.com/kangax/fabric.js/pull/4068) + +**Version 1.7.15** + +- Improvement: Made iText keymap public. [#4053](https://github.com/kangax/fabric.js/pull/4053) +- Improvement: Fix a bug in updateCacheCanvas that was returning always true [#4051](https://github.com/kangax/fabric.js/pull/4051) + +**Version 1.7.14** + +- Improvement: Avoid cache canvas to resize each mouse move step. [#4037](https://github.com/kangax/fabric.js/pull/4037) +- Improvement: Make cache canvas limited in size. [#4035](https://github.com/kangax/fabric.js/pull/4035) +- Fix: Make groups and statefull cache work. [#4032](https://github.com/kangax/fabric.js/pull/4032) +- Add: Marked the hiddentextarea from itext so that custom projects can recognize it. [#4022](https://github.com/kangax/fabric.js/pull/4022) + +**Version 1.7.13** + +- Fix: Try to minimize delay in loadFroJson [#4007](https://github.com/kangax/fabric.js/pull/4007) +- Fix: allow fabric.Color to parse rgba(x,y,z,.a) without leading 0 [#4006](https://github.com/kangax/fabric.js/pull/4006) +- Allow path to execute Object.initialize, make extensions easier [#4005](https://github.com/kangax/fabric.js/pull/4005) +- Fix: properly set options from path fromDatalessObjects [#3995](https://github.com/kangax/fabric.js/pull/3995) +- Check for slice before action.slice. Avoid conflicts with heavy customized code. [#3992](https://github.com/kangax/fabric.js/pull/3992) + + +**Version 1.7.12** + +- Fix: removed possible memleaks from window resize event. [#3984](https://github.com/kangax/fabric.js/pull/3984) +- Fix: restored default cursor to noTarget only. unselectable objects get the standard hovercursor. [#3953](https://github.com/kangax/fabric.js/pull/3953) +- Cache fixes: fix uncached pathGroup, removed cache creation at initialize time [#3982](https://github.com/kangax/fabric.js/pull/3982) +- Improvement: nextTarget to mouseOut and prevTarget to mouseOver [#3900](https://github.com/kangax/fabric.js/pull/3900) +- Improvement: add isClick boolean to left mouse up [#3898](https://github.com/kangax/fabric.js/pull/3898) +- Fix: can start selection on top of non selectable object [#3892](https://github.com/kangax/fabric.js/pull/3892) +- Improvement: better management of right/middle click [#3888](https://github.com/kangax/fabric.js/pull/3888) +- Fix: subTargetCheck on activeObject/activeGroup was firing too many events [#3909](https://github.com/kangax/fabric.js/pull/3909) +- Fix: After addWithUpdate or removeWithUpdate object coords must be updated. [#3911](https://github.com/kangax/fabric.js/pull/3911) + + +**Version 1.7.11** + +- Hotfix: restore path-groups ability to render [#3877](https://github.com/kangax/fabric.js/pull/3877) + +**Version 1.7.10** + +- Fix: correct svg export for radial gradients [#3807](https://github.com/kangax/fabric.js/pull/3807) +- Fix: Update fireout events to export the event object [#3853](https://github.com/kangax/fabric.js/pull/3853) +- Fix: Improve callSuper to avoid infinite loops (not all of them) [#3844](https://github.com/kangax/fabric.js/pull/3844) +- Fix: avoid selectionBackgroundColor leak on toDataUrl [#3862](https://github.com/kangax/fabric.js/pull/3862) +- Fix: toDatelessObject for Group [#3863](https://github.com/kangax/fabric.js/pull/3863) +- Improvement: better caching logic for groups [#3864](https://github.com/kangax/fabric.js/pull/3864) +- Fix: correct svg gradient export for radial in polygons [#3866](https://github.com/kangax/fabric.js/pull/3866) +- Fix: First draw could be empty for some objects [#3870](https://github.com/kangax/fabric.js/pull/3870) +- Fix: Always send event data to object:selected [#3871](https://github.com/kangax/fabric.js/pull/3871) +- Improvement: reduce angle calculation error [#3872](https://github.com/kangax/fabric.js/pull/3872) + +**Version 1.7.9** + +- Fix: Avoid textarea wrapping from chome v57+ [#3804](https://github.com/kangax/fabric.js/pull/3804) +- Fix: double click needed to move cursor when enterEditing is called programatically [#3804](https://github.com/kangax/fabric.js/pull/3804) +- Fix: Style regression when inputing new style objects [#3804](https://github.com/kangax/fabric.js/pull/3804) +- Add: try to support crossOrigin for svg image tags [#3804](https://github.com/kangax/fabric.js/pull/3804) + +**Version 1.7.8** + +- Fix: Fix dirty flag propagation [#3782](https://github.com/kangax/fabric.js/pull/3782) +- Fix: Path parsing error in bounding boxes of curves [#3774](https://github.com/kangax/fabric.js/pull/3774) +- Add: Middle click mouse management on canvas [#3764](https://github.com/kangax/fabric.js/pull/3764) +- Add: Add parameter to detect and skip offscreen drawing [#3758](https://github.com/kangax/fabric.js/pull/3758) +- Fix: textarea loosing focus after a drag and exit from canvas [#3759](https://github.com/kangax/fabric.js/pull/3759) + +**Version 1.7.7** + +- Fix for opacity parsing in svg with nested opacities [#3747](https://github.com/kangax/fabric.js/pull/3747) +- Fix text initialization and boundingrect [#3745](https://github.com/kangax/fabric.js/pull/3745) +- Fix line bounding box [#3742](https://github.com/kangax/fabric.js/pull/3742) +- Improvement: do not pollute style object while typing if not necessary [#3743](https://github.com/kangax/fabric.js/pull/3743) +- fix for broken prototype chain when restoring a dataless object on fill an stroke [#3735](https://github.com/kangax/fabric.js/pull/3735) +- fix for deselected event not fired on mouse actions [#3716](https://github.com/kangax/fabric.js/pull/3716) +- fix for blurriness introduced on 1.7.3 [#3721](https://github.com/kangax/fabric.js/pull/3721) + **Version 1.7.6** - Fix: make the cacheCanvas created on the fly if not available [#3705](https://github.com/kangax/fabric.js/pull/3705) diff --git a/HEADER.js b/HEADER.js index 8e88638aa..464f2d90c 100644 --- a/HEADER.js +++ b/HEADER.js @@ -1,6 +1,6 @@ /*! Fabric.js Copyright 2008-2015, Printio (Juriy Zaytsev, Maxim Chernyak) */ -var fabric = fabric || { version: '2.0.0-beta2' }; +var fabric = fabric || { version: '2.0.0-beta3' }; if (typeof exports !== 'undefined') { exports.fabric = fabric; } diff --git a/README.md b/README.md index 5d4fea502..fe672fd54 100644 --- a/README.md +++ b/README.md @@ -43,7 +43,7 @@ Fabric.js allows you to easily create simple shapes like rectangles, circles, tr ### Goals -- Unit tested (4000+ assertion, 800+ tests at the moment, 75%+ coverage) +- Unit tested (4400+ assertion, 940+ tests at the moment, 75%+ coverage) - Modular (~60 small ["classes", modules, mixins](http://fabricjs.com/docs/)) - Cross-browser - [Fast](https://github.com/kangax/fabric.js/wiki/Focus-on-speed) diff --git a/dist/fabric.js b/dist/fabric.js index 0179fca94..0c42b3ce7 100644 --- a/dist/fabric.js +++ b/dist/fabric.js @@ -1,7 +1,7 @@ -/* build: `node build.js modules=ALL exclude=json,gestures minifier=uglifyjs` */ +/* build: `node build.js modules=ALL exclude=json,gestures,accessors minifier=uglifyjs` */ /*! Fabric.js Copyright 2008-2015, Printio (Juriy Zaytsev, Maxim Chernyak) */ -var fabric = fabric || { version: '2.0.0-beta2' }; +var fabric = fabric || { version: '2.0.0-beta3' }; if (typeof exports !== 'undefined') { exports.fabric = fabric; } @@ -62,7 +62,32 @@ fabric.DPI = 96; fabric.reNum = '(?:[-+]?(?:\\d+|\\d*\\.\\d+)(?:e[-+]?\\d+)?)'; fabric.fontPaths = { }; fabric.iMatrix = [1, 0, 0, 1, 0, 0]; -fabric.canvasModule = 'canvas-prebuilt'; +fabric.canvasModule = 'canvas'; + +/** + * Pixel limit for cache canvases. 1Mpx , 4Mpx should be fine. + * @since 1.7.14 + * @type Number + * @default + */ +fabric.perfLimitSizeTotal = 2097152; + +/** + * Pixel limit for cache canvases width or height. IE fixes the maximum at 5000 + * @since 1.7.14 + * @type Number + * @default + */ +fabric.maxCacheSideLimit = 4096; + +/** + * Lowest pixel limit for cache canvases, set at 256PX + * @since 1.7.14 + * @type Number + * @default + */ +fabric.minCacheSideLimit = 256; + /** * Cache Object for widths of chars in text rendering. */ @@ -823,8 +848,7 @@ fabric.CommonMethods = { var enlivenedObjects = [], numLoadedObjects = 0, - numTotalObjects = objects.length, - forceAsync = true; + numTotalObjects = objects.length; if (!numTotalObjects) { callback && callback(enlivenedObjects); @@ -842,7 +866,7 @@ fabric.CommonMethods = { error || (enlivenedObjects[index] = obj); reviver && reviver(o, obj, error); onLoaded(); - }, forceAsync); + }); }); }, @@ -1003,37 +1027,6 @@ fabric.CommonMethods = { }, /** - * Creates accessors (getXXX, setXXX) for a "class", based on "stateProperties" array - * @static - * @memberOf fabric.util - * @param {Object} klass "Class" to create accessors for - */ - createAccessors: function(klass) { - var proto = klass.prototype, i, propName, - capitalizedPropName, setterName, getterName; - - for (i = proto.stateProperties.length; i--; ) { - - propName = proto.stateProperties[i]; - capitalizedPropName = propName.charAt(0).toUpperCase() + propName.slice(1); - setterName = 'set' + capitalizedPropName; - getterName = 'get' + capitalizedPropName; - - // using `new Function` for better introspection - if (!proto[getterName]) { - proto[getterName] = (function(property) { - return new Function('return this.get("' + property + '")'); - })(propName); - } - if (!proto[setterName]) { - proto[setterName] = (function(property) { - return new Function('value', 'return this.set("' + property + '", value)'); - })(propName); - } - } - }, - - /** * @static * @memberOf fabric.util * @param {fabric.Object} receiver Object implementing `clipTo` method @@ -1202,6 +1195,33 @@ fabric.CommonMethods = { else if (fabric.charWidthsCache[fontFamily]) { delete fabric.charWidthsCache[fontFamily]; } + }, + + /** + * Clear char widths cache for a font family. + * @memberOf fabric.util + * @param {Number} ar aspect ratio + * @param {Number} maximumArea Maximum area you want to achieve + * @param {Number} maximumSide biggest side allowed + * @return {Object.x} Limited dimensions by X + * @return {Object.y} Limited dimensions by Y + */ + limitDimsByArea: function(ar, maximumArea) { + var roughWidth = Math.sqrt(maximumArea * ar), + perfLimitSizeY = Math.floor(maximumArea / roughWidth); + return { x: Math.floor(roughWidth), y: perfLimitSizeY }; + }, + + capValue: function(min, value, max) { + return Math.max(min, Math.min(value, max)); + }, + + findScaleToFit: function(source, destination) { + return Math.min(destination.width / source.width, destination.height / source.height); + }, + + findScaleToCover: function(source, destination) { + return Math.max(destination.width / source.width, destination.height / source.height); } }; @@ -2563,6 +2583,10 @@ if (typeof console !== 'undefined') { (function() { + function noop() { + return false; + } + /** * Changes value from one to another within certain period of time, invoking callbacks as value is being changed. * @memberOf fabric.util @@ -2583,8 +2607,9 @@ if (typeof console !== 'undefined') { var start = timestamp || +new Date(), duration = options.duration || 500, finish = start + duration, time, - onChange = options.onChange || function() { }, - abort = options.abort || function() { return false; }, + onChange = options.onChange || noop, + abort = options.abort || noop, + onComplete = options.onComplete || noop, easing = options.easing || function(t, b, c, d) {return -c * Math.cos(t / d * (Math.PI / 2)) + c + b;}, startValue = 'startValue' in options ? options.startValue : 0, endValue = 'endValue' in options ? options.endValue : 100, @@ -2593,13 +2618,16 @@ if (typeof console !== 'undefined') { options.onStart && options.onStart(); (function tick(ticktime) { - time = ticktime || +new Date(); - var currentTime = time > finish ? duration : (time - start); if (abort()) { - options.onComplete && options.onComplete(); + onComplete(endValue, 1, 1); return; } - onChange(easing(currentTime, startValue, byValue, duration)); + time = ticktime || +new Date(); + var currentTime = time > finish ? duration : (time - start), + timePerc = currentTime / duration, + current = easing(currentTime, startValue, byValue, duration), + valuePerc = Math.abs((current - startValue) / byValue); + onChange(current, valuePerc, timePerc); if (time > finish) { options.onComplete && options.onComplete(); return; @@ -3732,9 +3760,9 @@ if (typeof console !== 'undefined') { fabric.gradientDefs[svgUid] = fabric.getGradientDefs(doc); fabric.cssRules[svgUid] = fabric.getCSSRules(doc); // Precedence of rules: style > class > attribute - fabric.parseElements(elements, function(instances) { + fabric.parseElements(elements, function(instances, elements) { if (callback) { - callback(instances, options); + callback(instances, options, elements, descendants); } }, clone(options), reviver, parsingOptions); }; @@ -4039,8 +4067,8 @@ if (typeof console !== 'undefined') { callback && callback(null); } - fabric.parseSVGDocument(xml.documentElement, function (results, _options) { - callback && callback(results, _options); + fabric.parseSVGDocument(xml.documentElement, function (results, _options, elements, allElements) { + callback && callback(results, _options, elements, allElements); }, reviver, options); } }, @@ -4070,8 +4098,8 @@ if (typeof console !== 'undefined') { doc.loadXML(string.replace(//i, '')); } - fabric.parseSVGDocument(doc.documentElement, function (results, _options) { - callback(results, _options); + fabric.parseSVGDocument(doc.documentElement, function (results, _options, elements, allElements) { + callback(results, _options, elements, allElements); }, reviver, options); } }); @@ -4122,18 +4150,7 @@ fabric.ElementsParser.prototype.createObject = function(el, index) { }; fabric.ElementsParser.prototype._createObject = function(klass, el, index) { - if (klass.async) { - klass.fromElement(el, this.createCallback(index, el), this.options); - } - else { - var obj = klass.fromElement(el, this.options); - this.resolveGradient(obj, 'fill'); - this.resolveGradient(obj, 'stroke'); - obj._removeTransformMatrix(); - this.reviver && this.reviver(el, obj); - this.instances[index] = obj; - this.checkIfDone(); - } + klass.fromElement(el, this.createCallback(index, el), this.options); }; fabric.ElementsParser.prototype.createCallback = function(index, el) { @@ -4142,6 +4159,9 @@ fabric.ElementsParser.prototype.createCallback = function(index, el) { _this.resolveGradient(obj, 'fill'); _this.resolveGradient(obj, 'stroke'); obj._removeTransformMatrix(); + if (obj instanceof fabric.Image) { + obj.parsePreserveAspectRatioAttribute(el); + } _this.reviver && _this.reviver(el, obj); _this.instances[index] = obj; _this.checkIfDone(); @@ -4167,7 +4187,7 @@ fabric.ElementsParser.prototype.checkIfDone = function() { // eslint-disable-next-line no-eq-null, eqeqeq return el != null; }); - this.callback(this.instances); + this.callback(this.instances, this.elements); } }; @@ -4967,7 +4987,7 @@ fabric.ElementsParser.prototype.checkIfDone = function() { * @memberOf fabric.Color */ // eslint-disable-next-line max-len - fabric.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*)?\)$/; + fabric.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*)?\)$/; /** * Regex matching color in HSL or HSLA formats (ex: hsl(200, 80%, 10%), hsla(300, 50%, 80%, 0.5), hsla( 300 , 50% , 80% , 0.5 )) @@ -6046,7 +6066,7 @@ fabric.ElementsParser.prototype.checkIfDone = function() { */ initialize: function(el, options) { options || (options = { }); - + this.renderAndResetBound = this.renderAndReset.bind(this); this._initStatic(el, options); }, @@ -6672,14 +6692,14 @@ fabric.ElementsParser.prototype.checkIfDone = function() { * @chainable true */ setViewportTransform: function (vpt) { - var activeGroup = this._activeGroup, object, ingoreVpt = false, skipAbsolute = true; + var activeGroup = this._activeGroup, object, ignoreVpt = false, skipAbsolute = true; this.viewportTransform = vpt; for (var i = 0, len = this._objects.length; i < len; i++) { object = this._objects[i]; - object.group || object.setCoords(ingoreVpt, skipAbsolute); + object.group || object.setCoords(ignoreVpt, skipAbsolute); } if (activeGroup) { - activeGroup.setCoords(ingoreVpt, skipAbsolute); + activeGroup.setCoords(ignoreVpt, skipAbsolute); } this.calcViewportBoundaries(); this.renderAll(); @@ -6825,6 +6845,31 @@ fabric.ElementsParser.prototype.checkIfDone = function() { }, /** + * Function created to be instance bound at initialization + * used in requestAnimationFrame rendering + * @return {fabric.Canvas} instance + * @chainable + */ + renderAndReset: function() { + this.renderAll(); + this.isRendering = false; + }, + + /** + * Append a renderAll request to next animation frame. + * a boolean flag will avoid appending more. + * @return {fabric.Canvas} instance + * @chainable + */ + requestRenderAll: function () { + if (!this.isRendering) { + this.isRendering = true; + fabric.util.requestAnimFrame(this.renderAndResetBound); + } + return this; + }, + + /** * Calculate the position of the 4 corner of canvas with current viewportTransform. * helps to determinate when an object is in the current rendering viewport using * object absolute coordinates ( aCoords ) @@ -6832,7 +6877,7 @@ fabric.ElementsParser.prototype.checkIfDone = function() { * @chainable */ calcViewportBoundaries: function() { - var points = { }, width = this.getWidth(), height = this.getHeight(), + var points = { }, width = this.width, height = this.height, iVpt = invertTransform(this.viewportTransform); points.tl = transformPoint({ x: 0, y: 0 }, iVpt); points.br = transformPoint({ x: width, y: height }, iVpt); @@ -6939,8 +6984,8 @@ fabric.ElementsParser.prototype.checkIfDone = function() { */ getCenter: function () { return { - top: this.getHeight() / 2, - left: this.getWidth() / 2 + top: this.height / 2, + left: this.width / 2 }; }, @@ -7430,7 +7475,8 @@ fabric.ElementsParser.prototype.checkIfDone = function() { removeFromArray(this._objects, object); this._objects.unshift(object); } - return this.renderAll && this.renderAll(); + this.renderAll && this.renderAll(); + return this; }, /** @@ -7458,7 +7504,8 @@ fabric.ElementsParser.prototype.checkIfDone = function() { removeFromArray(this._objects, object); this._objects.push(object); } - return this.renderAll && this.renderAll(); + this.renderAll && this.renderAll(); + return this; }, /** @@ -8017,7 +8064,7 @@ fabric.BaseBrush = fabric.util.createClass(/** @lends fabric.BaseBrush.prototype // rendered inconsistently across browsers // Firefox 4, for example, renders a dot, // whereas Chrome 10 renders nothing - this.canvas.renderAll(); + this.canvas.requestRenderAll(); return; } @@ -8028,7 +8075,7 @@ fabric.BaseBrush = fabric.util.createClass(/** @lends fabric.BaseBrush.prototype this.canvas.clearContext(this.canvas.contextTop); this._resetShadow(); - this.canvas.renderAll(); + this.canvas.requestRenderAll(); // fire event 'path' created this.canvas.fire('path:created', { path: path }); @@ -8131,7 +8178,7 @@ fabric.CircleBrush = fabric.util.createClass(fabric.BaseBrush, /** @lends fabric this.canvas.clearContext(this.canvas.contextTop); this._resetShadow(); this.canvas.renderOnAddRemove = originalRenderOnAddRemove; - this.canvas.renderAll(); + this.canvas.requestRenderAll(); }, /** @@ -8280,7 +8327,7 @@ fabric.SprayBrush = fabric.util.createClass( fabric.BaseBrush, /** @lends fabric this.canvas.clearContext(this.canvas.contextTop); this._resetShadow(); this.canvas.renderOnAddRemove = originalRenderOnAddRemove; - this.canvas.renderAll(); + this.canvas.requestRenderAll(); }, /** @@ -8461,6 +8508,7 @@ fabric.PatternBrush = fabric.util.createClass(fabric.PencilBrush, /** @lends fab * @fires mouse:up * @fires mouse:over * @fires mouse:out + * @fires mouse:doubleclick * */ fabric.Canvas = fabric.util.createClass(fabric.StaticCanvas, /** @lends fabric.Canvas.prototype */ { @@ -8473,7 +8521,7 @@ fabric.PatternBrush = fabric.util.createClass(fabric.PencilBrush, /** @lends fab */ initialize: function(el, options) { options || (options = { }); - + this.renderAndResetBound = this.renderAndReset.bind(this); this._initStatic(el, options); this._initInteractive(); this._createCacheCanvas(); @@ -8638,6 +8686,14 @@ fabric.PatternBrush = fabric.util.createClass(fabric.PencilBrush, /** @lends fab rotationCursor: 'crosshair', /** + * Cursor value used for disabled elements ( corners with disabled action ) + * @type String + * @since 2.0.0 + * @default + */ + notAllowedCursor: 'not-allowed', + + /** * Default element class that's given to wrapper (div) element of canvas * @type String * @default @@ -9705,7 +9761,13 @@ fabric.PatternBrush = fabric.util.createClass(fabric.PencilBrush, /** @lends fab _createUpperCanvas: function () { var lowerCanvasClass = this.lowerCanvasEl.className.replace(/\s*lower-canvas\s*/, ''); - this.upperCanvasEl = this._createCanvasElement(); + // there is no need to create a new upperCanvas element if we have already one. + if (this.upperCanvasEl) { + this.upperCanvasEl.className = ''; + } + else { + this.upperCanvasEl = this._createCanvasElement(); + } fabric.util.addClass(this.upperCanvasEl, 'upper-canvas ' + lowerCanvasClass); this.wrapperEl.appendChild(this.upperCanvasEl); @@ -9733,8 +9795,8 @@ fabric.PatternBrush = fabric.util.createClass(fabric.PencilBrush, /** @lends fab 'class': this.containerClass }); fabric.util.setStyle(this.wrapperEl, { - width: this.getWidth() + 'px', - height: this.getHeight() + 'px', + width: this.width + 'px', + height: this.height + 'px', position: 'relative' }); fabric.util.makeElementUnselectable(this.wrapperEl); @@ -9745,8 +9807,8 @@ fabric.PatternBrush = fabric.util.createClass(fabric.PencilBrush, /** @lends fab * @param {HTMLElement} element canvas element to apply styles on */ _applyCanvasStyle: function (element) { - var width = this.getWidth() || element.width, - height = this.getHeight() || element.height; + var width = this.width || element.width, + height = this.height || element.height; fabric.util.setStyle(element, { position: 'absolute', @@ -9818,7 +9880,7 @@ fabric.PatternBrush = fabric.util.createClass(fabric.PencilBrush, /** @lends fab this._setActiveObject(object); this.fire('object:selected', { target: object, e: e }); object.fire('selected', { e: e }); - this.renderAll(); + this.requestRenderAll(); return this; }, @@ -10124,15 +10186,6 @@ fabric.PatternBrush = fabric.util.createClass(fabric.PencilBrush, /** @lends fab /** @ignore */ fabric.Canvas.prototype._setCursorFromEvent = function() { }; } - - /** - * @ignore - * @class fabric.Element - * @alias fabric.Canvas - * @deprecated Use {@link fabric.Canvas} instead. - * @constructor - */ - fabric.Element = fabric.Canvas; })(); @@ -10178,13 +10231,17 @@ fabric.PatternBrush = fabric.util.createClass(fabric.PencilBrush, /** @lends fab * @private */ _initEventListeners: function () { - + // in case we initialized the class twice. This should not happen normally + // but in some kind of applications where the canvas element may be changed + // this is a workaround to having double listeners. + this.removeListeners(); this._bindEvents(); addListener(fabric.window, 'resize', this._onResize); // mouse events addListener(this.upperCanvasEl, 'mousedown', this._onMouseDown); + addListener(this.upperCanvasEl, 'dblclick', this._onDoubleClick); addListener(this.upperCanvasEl, 'mousemove', this._onMouseMove); addListener(this.upperCanvasEl, 'mouseout', this._onMouseOut); addListener(this.upperCanvasEl, 'mouseenter', this._onMouseEnter); @@ -10208,6 +10265,10 @@ fabric.PatternBrush = fabric.util.createClass(fabric.PencilBrush, /** @lends fab * @private */ _bindEvents: function() { + if (this.eventsBinded) { + // for any reason we pass here twice we do not want to bind events twice. + return; + } this._onMouseDown = this._onMouseDown.bind(this); this._onMouseMove = this._onMouseMove.bind(this); this._onMouseUp = this._onMouseUp.bind(this); @@ -10221,6 +10282,8 @@ fabric.PatternBrush = fabric.util.createClass(fabric.PencilBrush, /** @lends fab 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.eventsBinded = true; }, /** @@ -10235,7 +10298,7 @@ fabric.PatternBrush = fabric.util.createClass(fabric.PencilBrush, /** @lends fab removeListener(this.upperCanvasEl, 'mouseenter', this._onMouseEnter); removeListener(this.upperCanvasEl, 'wheel', this._onMouseWheel); removeListener(this.upperCanvasEl, 'contextmenu', this._onContextMenu); - + removeListener(this.upperCanvasEl, 'doubleclick', this._onDoubleClick); removeListener(this.upperCanvasEl, 'touchstart', this._onMouseDown); removeListener(this.upperCanvasEl, 'touchmove', this._onMouseMove); @@ -10346,9 +10409,17 @@ fabric.PatternBrush = fabric.util.createClass(fabric.PencilBrush, /** @lends fab * @private * @param {Event} e Event object fired on mousedown */ + _onDoubleClick: function (e) { + var target; + this._handleEvent(e, 'dblclick', target); + }, + + /** + * @private + * @param {Event} e Event object fired on mousedown + */ _onMouseDown: function (e) { this.__onMouseDown(e); - addListener(fabric.document, 'touchend', this._onMouseUp, { passive: false }); addListener(fabric.document, 'touchmove', this._onMouseMove, { passive: false }); @@ -10474,7 +10545,7 @@ fabric.PatternBrush = fabric.util.createClass(fabric.PencilBrush, /** @lends fab isClick = (!groupSelector || (groupSelector.left === 0 && groupSelector.top === 0)); if (transform) { - this._finalizeCurrentTransform(); + this._finalizeCurrentTransform(e); searchTarget = !transform.actionPerformed; } @@ -10498,7 +10569,7 @@ fabric.PatternBrush = fabric.util.createClass(fabric.PencilBrush, /** @lends fab this._setCursorFromEvent(e, target); this._handleEvent(e, 'up', target ? target : null, LEFT_CLICK, isClick); target && (target.__corner = 0); - shouldRender && this.renderAll(); + shouldRender && this.requestRenderAll(); }, /** @@ -10529,8 +10600,9 @@ fabric.PatternBrush = fabric.util.createClass(fabric.PencilBrush, /** @lends fab /** * @private + * @param {Event} e send the mouse event that generate the finalize down, so it can be used in the event */ - _finalizeCurrentTransform: function() { + _finalizeCurrentTransform: function(e) { var transform = this._currentTransform, target = transform.target; @@ -10543,8 +10615,8 @@ fabric.PatternBrush = fabric.util.createClass(fabric.PencilBrush, /** @lends fab this._restoreOriginXY(target); if (transform.actionPerformed || (this.stateful && target.hasStateChanged())) { - this.fire('object:modified', { target: target }); - target.fire('modified'); + this.fire('object:modified', { target: target, e: e }); + target.fire('modified', { e: e }); } }, @@ -10577,7 +10649,7 @@ fabric.PatternBrush = fabric.util.createClass(fabric.PencilBrush, /** @lends fab */ _onMouseDownInDrawingMode: function(e) { this._isCurrentlyDrawing = true; - this.discardActiveObject(e).renderAll(); + this.discardActiveObject(e).requestRenderAll(); if (this.clipTo) { fabric.util.clipContext(this, this.contextTop); } @@ -10689,7 +10761,7 @@ fabric.PatternBrush = fabric.util.createClass(fabric.PencilBrush, /** @lends fab } this._handleEvent(e, 'down', target ? target : null); // we must renderAll so that we update the visuals - shouldRender && this.renderAll(); + shouldRender && this.requestRenderAll(); }, /** @@ -10811,7 +10883,7 @@ fabric.PatternBrush = fabric.util.createClass(fabric.PencilBrush, /** @lends fab this._beforeScaleTransform(e, transform); this._performTransformAction(e, transform, pointer); - transform.actionPerformed && this.renderAll(); + transform.actionPerformed && this.requestRenderAll(); }, /** @@ -10887,7 +10959,7 @@ fabric.PatternBrush = fabric.util.createClass(fabric.PencilBrush, /** @lends fab * @return {Boolean} true if the scaling occurred */ _onScale: function(e, transform, x, y) { - if ((e[this.uniScaleKey] || this.uniScaleTransform) && !transform.target.get('lockUniScaling')) { + if (this._isUniscalePossible(e, transform.target)) { transform.currentAction = 'scale'; return this._scaleObject(x, y); } @@ -10903,13 +10975,23 @@ fabric.PatternBrush = fabric.util.createClass(fabric.PencilBrush, /** @lends fab }, /** + * @private + * @param {Event} e Event object + * @param {fabric.Object} target current target + * @return {Boolean} true if unproportional scaling is possible + */ + _isUniscalePossible: function(e, target) { + return (e[this.uniScaleKey] || this.uniScaleTransform) && !target.get('lockUniScaling'); + }, + + /** * Sets the cursor depending on where the canvas is being hovered. * Note: very buggy in Opera * @param {Event} e Event object * @param {Object} target Object that the mouse is hovering, if so. */ _setCursorFromEvent: function (e, target) { - if (!target || !target.selectable) { + if (!target) { this.setCursor(this.defaultCursor); return false; } @@ -10925,26 +11007,41 @@ fabric.PatternBrush = fabric.util.createClass(fabric.PencilBrush, /** @lends fab this.setCursor(hoverCursor); } else { - this._setCornerCursor(corner, target, e); + this.setCursor(this.getCornerCursor(corner, target, e)); } - //actually unclear why it should return something - //is never evaluated - return true; }, /** * @private */ - _setCornerCursor: function(corner, target, e) { - if (corner in cursorOffset) { - this.setCursor(this._getRotatedCornerCursor(corner, target, e)); + getCornerCursor: function(corner, target, e) { + if (this.actionIsDisabled(corner, target, e)) { + return this.notAllowedCursor; + } + else if (corner in cursorOffset) { + return this._getRotatedCornerCursor(corner, target, e); } else if (corner === 'mtr' && target.hasRotatingPoint) { - this.setCursor(this.rotationCursor); + return this.rotationCursor; } else { - this.setCursor(this.defaultCursor); - return false; + return this.defaultCursor; + } + }, + + actionIsDisabled: function(corner, target, e) { + if (corner === 'mt' || corner === 'mb') { + return e[this.altActionKey] ? target.lockSkewingX : target.lockScalingY; + } + else if (corner === 'ml' || corner === 'mr') { + return e[this.altActionKey] ? target.lockSkewingY : target.lockScalingX; + } + else if (corner === 'mtr') { + return target.lockRotation; + } + else { + return this._isUniscalePossible(e, target) ? + target.lockScalingX && target.lockScalingY : target.lockScalingX || target.lockScalingY; } }, @@ -10952,7 +11049,7 @@ fabric.PatternBrush = fabric.util.createClass(fabric.PencilBrush, /** @lends fab * @private */ _getRotatedCornerCursor: function(corner, target, e) { - var n = Math.round((target.getAngle() % 360) / 45); + var n = Math.round((target.angle % 360) / 45); if (n < 0) { n += 8; // full circle ahead @@ -11096,7 +11193,7 @@ fabric.PatternBrush = fabric.util.createClass(fabric.PencilBrush, /** @lends fab group.addWithUpdate(); this.setActiveGroup(group, e); this.fire('selection:created', { target: group, e: e }); - this.renderAll(); + this.requestRenderAll(); } }, @@ -11220,10 +11317,10 @@ fabric.PatternBrush = fabric.util.createClass(fabric.PencilBrush, /** @lends fab */ __toDataURLWithMultiplier: function(format, quality, cropping, multiplier) { - var origWidth = this.getWidth(), - origHeight = this.getHeight(), - scaledWidth = (cropping.width || this.getWidth()) * multiplier, - scaledHeight = (cropping.height || this.getHeight()) * multiplier, + var origWidth = this.width, + origHeight = this.height, + scaledWidth = (cropping.width || this.width) * multiplier, + scaledHeight = (cropping.height || this.height) * multiplier, zoom = this.getZoom(), newZoom = zoom * multiplier, vp = this.viewportTransform, @@ -11339,11 +11436,19 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, /** @lends fabric.Stati ? JSON.parse(json) : fabric.util.object.clone(json); - this.clear(); + var _this = this, + renderOnAddRemove = this.renderOnAddRemove; + this.renderOnAddRemove = false; - var _this = this; - this._enlivenObjects(serialized.objects, function () { + this._enlivenObjects(serialized.objects, function (enlivenedObjects) { + _this.clear(); _this._setBgOverlay(serialized, function () { + enlivenedObjects.forEach(function(obj, index) { + // we splice the array just in case some custom classes restored from JSON + // will add more object to canvas at canvas init. + _this.insertAt(obj, index); + }); + _this.renderOnAddRemove = renderOnAddRemove; // remove parts i cannot set as options delete serialized.objects; delete serialized.backgroundImage; @@ -11355,6 +11460,7 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, /** @lends fabric.Stati // create the Object instance. Here the Canvas is // already an instance and we are just loading things over it _this._setOptions(serialized); + _this.renderAll(); callback && callback(); }); }, reviver); @@ -11367,13 +11473,12 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, /** @lends fabric.Stati * @param {Function} callback Invoked after all background and overlay images/patterns loaded */ _setBgOverlay: function(serialized, callback) { - var _this = this, - loaded = { - backgroundColor: false, - overlayColor: false, - backgroundImage: false, - overlayImage: false - }; + var loaded = { + backgroundColor: false, + overlayColor: false, + backgroundImage: false, + overlayImage: false + }; if (!serialized.backgroundImage && !serialized.overlayImage && !serialized.background && !serialized.overlay) { callback && callback(); @@ -11382,7 +11487,6 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, /** @lends fabric.Stati var cbIfLoaded = function () { if (loaded.backgroundImage && loaded.overlayImage && loaded.backgroundColor && loaded.overlayColor) { - _this.renderAll(); callback && callback(); } }; @@ -11431,25 +11535,13 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, /** @lends fabric.Stati * @param {Function} [reviver] */ _enlivenObjects: function (objects, callback, reviver) { - var _this = this; - if (!objects || objects.length === 0) { - callback && callback(); + callback && callback([]); return; } - var renderOnAddRemove = this.renderOnAddRemove; - this.renderOnAddRemove = false; - fabric.util.enlivenObjects(objects, function(enlivenedObjects) { - enlivenedObjects.forEach(function(obj, index) { - // we splice the array just in case some custom classes restored from JSON - // will add more object to canvas at canvas init. - _this.insertAt(obj, index); - }); - - _this.renderOnAddRemove = renderOnAddRemove; - callback && callback(); + callback && callback(enlivenedObjects); }, null, reviver); }, @@ -11499,8 +11591,8 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, /** @lends fabric.Stati cloneWithoutData: function(callback) { var el = fabric.document.createElement('canvas'); - el.width = this.getWidth(); - el.height = this.getHeight(); + el.width = this.width; + el.height = this.height; var clone = new fabric.Canvas(el); clone.clipTo = this.clipTo; @@ -11530,7 +11622,8 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, /** @lends fabric.Stati capitalize = fabric.util.string.capitalize, degreesToRadians = fabric.util.degreesToRadians, supportsLineDash = fabric.StaticCanvas.supports('setLineDash'), - objectCaching = !fabric.isLikelyNode; + objectCaching = !fabric.isLikelyNode, + ALIASING_LIMIT = 2; if (fabric.Object) { return; @@ -11558,399 +11651,146 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, /** @lends fabric.Stati * @fires mouseover * @fires mouseout * @fires mousewheel + * @fires mousedblclick */ fabric.Object = fabric.util.createClass(fabric.CommonMethods, /** @lends fabric.Object.prototype */ { /** - * Retrieves object's {@link fabric.Object#clipTo|clipping function} - * @method getClipTo - * @memberOf fabric.Object.prototype - * @return {Function} + * Type of an object (rect, circle, path, etc.). + * Note that this property is meant to be read-only and not meant to be modified. + * If you modify, certain parts of Fabric (such as JSON loading) won't work correctly. + * @type String + * @default */ + type: 'object', /** - * Sets object's {@link fabric.Object#clipTo|clipping function} - * @method setClipTo - * @memberOf fabric.Object.prototype - * @param {Function} clipTo Clipping function - * @return {fabric.Object} thisArg - * @chainable + * Horizontal origin of transformation of an object (one of "left", "right", "center") + * See http://jsfiddle.net/1ow02gea/244/ on how originX/originY affect objects in groups + * @type String + * @default */ + originX: 'left', /** - * Retrieves object's {@link fabric.Object#transformMatrix|transformMatrix} - * @method getTransformMatrix - * @memberOf fabric.Object.prototype - * @return {Array} transformMatrix + * Vertical origin of transformation of an object (one of "top", "bottom", "center") + * See http://jsfiddle.net/1ow02gea/244/ on how originX/originY affect objects in groups + * @type String + * @default */ + originY: 'top', /** - * Sets object's {@link fabric.Object#transformMatrix|transformMatrix} - * @method setTransformMatrix - * @memberOf fabric.Object.prototype - * @param {Array} transformMatrix - * @return {fabric.Object} thisArg - * @chainable + * Top position of an object. Note that by default it's relative to object top. You can change this by setting originY={top/center/bottom} + * @type Number + * @default */ + top: 0, /** - * Retrieves object's {@link fabric.Object#visible|visible} state - * @method getVisible - * @memberOf fabric.Object.prototype - * @return {Boolean} True if visible + * Left position of an object. Note that by default it's relative to object left. You can change this by setting originX={left/center/right} + * @type Number + * @default */ + left: 0, /** - * Sets object's {@link fabric.Object#visible|visible} state - * @method setVisible - * @memberOf fabric.Object.prototype - * @param {Boolean} value visible value - * @return {fabric.Object} thisArg - * @chainable + * Object width + * @type Number + * @default */ + width: 0, /** - * Retrieves object's {@link fabric.Object#shadow|shadow} - * @method getShadow - * @memberOf fabric.Object.prototype - * @return {Object} Shadow instance + * Object height + * @type Number + * @default */ + height: 0, /** - * Retrieves object's {@link fabric.Object#stroke|stroke} - * @method getStroke - * @memberOf fabric.Object.prototype - * @return {String} stroke value + * Object scale factor (horizontal) + * @type Number + * @default */ + scaleX: 1, /** - * Sets object's {@link fabric.Object#stroke|stroke} - * @method setStroke - * @memberOf fabric.Object.prototype - * @param {String} value stroke value - * @return {fabric.Object} thisArg - * @chainable + * Object scale factor (vertical) + * @type Number + * @default */ + scaleY: 1, /** - * Retrieves object's {@link fabric.Object#strokeWidth|strokeWidth} - * @method getStrokeWidth - * @memberOf fabric.Object.prototype - * @return {Number} strokeWidth value + * When true, an object is rendered as flipped horizontally + * @type Boolean + * @default */ + flipX: false, /** - * Sets object's {@link fabric.Object#strokeWidth|strokeWidth} - * @method setStrokeWidth - * @memberOf fabric.Object.prototype - * @param {Number} value strokeWidth value - * @return {fabric.Object} thisArg - * @chainable + * When true, an object is rendered as flipped vertically + * @type Boolean + * @default */ + flipY: false, /** - * Retrieves object's {@link fabric.Object#originX|originX} - * @method getOriginX - * @memberOf fabric.Object.prototype - * @return {String} originX value + * Opacity of an object + * @type Number + * @default */ + opacity: 1, /** - * Sets object's {@link fabric.Object#originX|originX} - * @method setOriginX - * @memberOf fabric.Object.prototype - * @param {String} value originX value - * @return {fabric.Object} thisArg - * @chainable + * Angle of rotation of an object (in degrees) + * @type Number + * @default */ + angle: 0, /** - * Retrieves object's {@link fabric.Object#originY|originY} - * @method getOriginY - * @memberOf fabric.Object.prototype - * @return {String} originY value + * Angle of skew on x axes of an object (in degrees) + * @type Number + * @default */ + skewX: 0, /** - * Sets object's {@link fabric.Object#originY|originY} - * @method setOriginY - * @memberOf fabric.Object.prototype - * @param {String} value originY value - * @return {fabric.Object} thisArg - * @chainable + * Angle of skew on y axes of an object (in degrees) + * @type Number + * @default */ + skewY: 0, /** - * Retrieves object's {@link fabric.Object#fill|fill} - * @method getFill - * @memberOf fabric.Object.prototype - * @return {String} Fill value + * Size of object's controlling corners (in pixels) + * @type Number + * @default */ + cornerSize: 13, /** - * Sets object's {@link fabric.Object#fill|fill} - * @method setFill - * @memberOf fabric.Object.prototype - * @param {String} value Fill value - * @return {fabric.Object} thisArg - * @chainable + * When true, object's controlling corners are rendered as transparent inside (i.e. stroke instead of fill) + * @type Boolean + * @default */ + transparentCorners: true, /** - * Retrieves object's {@link fabric.Object#opacity|opacity} - * @method getOpacity - * @memberOf fabric.Object.prototype - * @return {Number} Opacity value (0-1) + * Default cursor value used when hovering over this object on canvas + * @type String + * @default */ + hoverCursor: null, /** - * Sets object's {@link fabric.Object#opacity|opacity} - * @method setOpacity - * @memberOf fabric.Object.prototype - * @param {Number} value Opacity value (0-1) - * @return {fabric.Object} thisArg - * @chainable + * Default cursor value used when moving this object on canvas + * @type String + * @default */ - - /** - * Retrieves object's {@link fabric.Object#angle|angle} (in degrees) - * @method getAngle - * @memberOf fabric.Object.prototype - * @return {Number} - */ - - /** - * Retrieves object's {@link fabric.Object#top|top position} - * @method getTop - * @memberOf fabric.Object.prototype - * @return {Number} Top value (in pixels) - */ - - /** - * Sets object's {@link fabric.Object#top|top position} - * @method setTop - * @memberOf fabric.Object.prototype - * @param {Number} value Top value (in pixels) - * @return {fabric.Object} thisArg - * @chainable - */ - - /** - * Retrieves object's {@link fabric.Object#left|left position} - * @method getLeft - * @memberOf fabric.Object.prototype - * @return {Number} Left value (in pixels) - */ - - /** - * Sets object's {@link fabric.Object#left|left position} - * @method setLeft - * @memberOf fabric.Object.prototype - * @param {Number} value Left value (in pixels) - * @return {fabric.Object} thisArg - * @chainable - */ - - /** - * Retrieves object's {@link fabric.Object#scaleX|scaleX} value - * @method getScaleX - * @memberOf fabric.Object.prototype - * @return {Number} scaleX value - */ - - /** - * Sets object's {@link fabric.Object#scaleX|scaleX} value - * @method setScaleX - * @memberOf fabric.Object.prototype - * @param {Number} value scaleX value - * @return {fabric.Object} thisArg - * @chainable - */ - - /** - * Retrieves object's {@link fabric.Object#scaleY|scaleY} value - * @method getScaleY - * @memberOf fabric.Object.prototype - * @return {Number} scaleY value - */ - - /** - * Sets object's {@link fabric.Object#scaleY|scaleY} value - * @method setScaleY - * @memberOf fabric.Object.prototype - * @param {Number} value scaleY value - * @return {fabric.Object} thisArg - * @chainable - */ - - /** - * Retrieves object's {@link fabric.Object#flipX|flipX} value - * @method getFlipX - * @memberOf fabric.Object.prototype - * @return {Boolean} flipX value - */ - - /** - * Sets object's {@link fabric.Object#flipX|flipX} value - * @method setFlipX - * @memberOf fabric.Object.prototype - * @param {Boolean} value flipX value - * @return {fabric.Object} thisArg - * @chainable - */ - - /** - * Retrieves object's {@link fabric.Object#flipY|flipY} value - * @method getFlipY - * @memberOf fabric.Object.prototype - * @return {Boolean} flipY value - */ - - /** - * Sets object's {@link fabric.Object#flipY|flipY} value - * @method setFlipY - * @memberOf fabric.Object.prototype - * @param {Boolean} value flipY value - * @return {fabric.Object} thisArg - * @chainable - */ - - /** - * Type of an object (rect, circle, path, etc.). - * Note that this property is meant to be read-only and not meant to be modified. - * If you modify, certain parts of Fabric (such as JSON loading) won't work correctly. - * @type String - * @default - */ - type: 'object', - - /** - * Horizontal origin of transformation of an object (one of "left", "right", "center") - * See http://jsfiddle.net/1ow02gea/244/ on how originX/originY affect objects in groups - * @type String - * @default - */ - originX: 'left', - - /** - * Vertical origin of transformation of an object (one of "top", "bottom", "center") - * See http://jsfiddle.net/1ow02gea/244/ on how originX/originY affect objects in groups - * @type String - * @default - */ - originY: 'top', - - /** - * Top position of an object. Note that by default it's relative to object top. You can change this by setting originY={top/center/bottom} - * @type Number - * @default - */ - top: 0, - - /** - * Left position of an object. Note that by default it's relative to object left. You can change this by setting originX={left/center/right} - * @type Number - * @default - */ - left: 0, - - /** - * Object width - * @type Number - * @default - */ - width: 0, - - /** - * Object height - * @type Number - * @default - */ - height: 0, - - /** - * Object scale factor (horizontal) - * @type Number - * @default - */ - scaleX: 1, - - /** - * Object scale factor (vertical) - * @type Number - * @default - */ - scaleY: 1, - - /** - * When true, an object is rendered as flipped horizontally - * @type Boolean - * @default - */ - flipX: false, - - /** - * When true, an object is rendered as flipped vertically - * @type Boolean - * @default - */ - flipY: false, - - /** - * Opacity of an object - * @type Number - * @default - */ - opacity: 1, - - /** - * Angle of rotation of an object (in degrees) - * @type Number - * @default - */ - angle: 0, - - /** - * Angle of skew on x axes of an object (in degrees) - * @type Number - * @default - */ - skewX: 0, - - /** - * Angle of skew on y axes of an object (in degrees) - * @type Number - * @default - */ - skewY: 0, - - /** - * Size of object's controlling corners (in pixels) - * @type Number - * @default - */ - cornerSize: 13, - - /** - * When true, object's controlling corners are rendered as transparent inside (i.e. stroke instead of fill) - * @type Boolean - * @default - */ - transparentCorners: true, - - /** - * Default cursor value used when hovering over this object on canvas - * @type String - * @default - */ - hoverCursor: null, - - /** - * Default cursor value used when moving this object on canvas - * @type String - * @default - */ - moveCursor: null, + moveCursor: null, /** * Padding between object and its controlling borders (in pixels) @@ -12318,16 +12158,6 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, /** @lends fabric.Stati dirty: true, /** - * When set to `true`, force the object to have its own cache, even if it is inside a group - * it may be needed when your object behave in a particular way on the cache and always needs - * its own isolated canvas to render correctly. - * since 1.7.5 - * @type Boolean - * @default false - */ - needsItsOwnCache: false, - - /** * List of properties to consider when checking if state * of an object is changed (fabric.Object#hasStateChanged) * as well as for history (undo/redo) purposes @@ -12336,8 +12166,8 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, /** @lends fabric.Stati stateProperties: ( 'top left width height scaleX scaleY flipX flipY originX originY transformMatrix ' + 'stroke strokeWidth strokeDashArray strokeLineCap strokeLineJoin strokeMiterLimit ' + - 'angle opacity fill fillRule globalCompositeOperation shadow clipTo visible backgroundColor ' + - 'skewX skewY' + 'angle opacity fill globalCompositeOperation shadow clipTo visible backgroundColor ' + + 'skewX skewY fillRule' ).split(' '), /** @@ -12345,8 +12175,8 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, /** @lends fabric.Stati * @type Array */ cacheProperties: ( - 'fill stroke strokeWidth strokeDashArray width height stroke strokeWidth strokeDashArray' + - ' strokeLineCap strokeLineJoin strokeMiterLimit fillRule backgroundColor' + 'fill stroke strokeWidth strokeDashArray width height' + + ' strokeLineCap strokeLineJoin strokeMiterLimit backgroundColor' ).split(' '), /** @@ -12358,9 +12188,6 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, /** @lends fabric.Stati if (options) { this.setOptions(options); } - if (this.objectCaching) { - this._createCacheCanvas(); - } }, /** @@ -12375,6 +12202,46 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, /** @lends fabric.Stati }, /** + * Limit the cache dimensions so that X * Y do not cross fabric.perfLimitSizeTotal + * and each side do not cross fabric.cacheSideLimit + * those numbers are configurable so that you can get as much detail as you want + * making bargain with performances. + * @param {Object} dims + * @param {Object} dims.width width of canvas + * @param {Object} dims.height height of canvas + * @param {Object} dims.zoomX zoomX zoom value to unscale the canvas before drawing cache + * @param {Object} dims.zoomY zoomY zoom value to unscale the canvas before drawing cache + * @return {Object}.width width of canvas + * @return {Object}.height height of canvas + * @return {Object}.zoomX zoomX zoom value to unscale the canvas before drawing cache + * @return {Object}.zoomY zoomY zoom value to unscale the canvas before drawing cache + */ + _limitCacheSize: function(dims) { + var perfLimitSizeTotal = fabric.perfLimitSizeTotal, + maximumSide = fabric.cacheSideLimit, + width = dims.width, height = dims.height, + ar = width / height, limitedDims = fabric.util.limitDimsByArea(ar, perfLimitSizeTotal, maximumSide), + capValue = fabric.util.capValue, max = fabric.maxCacheSideLimit, min = fabric.minCacheSideLimit, + x = capValue(min, limitedDims.x, max), + y = capValue(min, limitedDims.y, max); + if (width > x) { + dims.zoomX /= width / x; + dims.width = x; + } + else if (width < min) { + dims.width = min; + } + if (height > y) { + dims.zoomY /= height / y; + dims.height = y; + } + else if (height < min) { + dims.height = min; + } + return dims; + }, + + /** * Return the dimension and the zoom level needed to create a cache canvas * big enough to host the object to be cached. * @private @@ -12393,8 +12260,8 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, /** @lends fabric.Stati width = dim.x * zoomX, height = dim.y * zoomY; return { - width: width + 2, - height: height + 2, + width: width + ALIASING_LIMIT, + height: height + ALIASING_LIMIT, zoomX: zoomX, zoomY: zoomY }; @@ -12409,21 +12276,45 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, /** @lends fabric.Stati _updateCacheCanvas: function() { if (this.noScaleCache && this.canvas && this.canvas._currentTransform) { var action = this.canvas._currentTransform.action; - if (action.slice(0, 5) === 'scale') { + if (action.slice && action.slice(0, 5) === 'scale') { return false; } } - var dims = this._getCacheCanvasDimensions(), + var dims = this._limitCacheSize(this._getCacheCanvasDimensions()), + minCacheSize = fabric.minCacheSideLimit, width = dims.width, height = dims.height, - zoomX = dims.zoomX, zoomY = dims.zoomY; - - if (width !== this.cacheWidth || height !== this.cacheHeight) { - this._cacheCanvas.width = Math.ceil(width); - this._cacheCanvas.height = Math.ceil(height); - this._cacheContext.translate(width / 2, height / 2); - this._cacheContext.scale(zoomX, zoomY); + zoomX = dims.zoomX, zoomY = dims.zoomY, + dimensionsChanged = width !== this.cacheWidth || height !== this.cacheHeight, + zoomChanged = this.zoomX !== zoomX || this.zoomY !== zoomY, + shouldRedraw = dimensionsChanged || zoomChanged, + additionalWidth = 0, additionalHeight = 0, shouldResizeCanvas = false; + if (dimensionsChanged) { + var canvasWidth = this._cacheCanvas.width, + canvasHeight = this._cacheCanvas.height, + sizeGrowing = width > canvasWidth || height > canvasHeight, + sizeShrinking = (width < canvasWidth * 0.9 || height < canvasHeight * 0.9) && + canvasWidth > minCacheSize && canvasHeight > minCacheSize; + shouldResizeCanvas = sizeGrowing || sizeShrinking; + if (sizeGrowing) { + additionalWidth = (width * 0.1) & ~1; + additionalHeight = (height * 0.1) & ~1; + } + } + if (shouldRedraw) { + if (shouldResizeCanvas) { + this._cacheCanvas.width = Math.max(Math.ceil(width) + additionalWidth, minCacheSize); + this._cacheCanvas.height = Math.max(Math.ceil(height) + additionalHeight, minCacheSize); + this.cacheTranslationX = (width + additionalWidth) / 2; + this.cacheTranslationY = (height + additionalHeight) / 2; + } + else { + this._cacheContext.setTransform(1, 0, 0, 1, 0, 0); + this._cacheContext.clearRect(0, 0, this._cacheCanvas.width, this._cacheCanvas.height); + } this.cacheWidth = width; this.cacheHeight = height; + this._cacheContext.translate(this.cacheTranslationX, this.cacheTranslationY); + this._cacheContext.scale(zoomX, zoomY); this.zoomX = zoomX; this.zoomY = zoomY; return true; @@ -12489,7 +12380,7 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, /** @lends fabric.Stati strokeMiterLimit: toFixed(this.strokeMiterLimit, NUM_FRACTION_DIGITS), scaleX: toFixed(this.scaleX, NUM_FRACTION_DIGITS), scaleY: toFixed(this.scaleY, NUM_FRACTION_DIGITS), - angle: toFixed(this.getAngle(), NUM_FRACTION_DIGITS), + angle: toFixed(this.angle, NUM_FRACTION_DIGITS), flipX: this.flipX, flipY: this.flipY, opacity: toFixed(this.opacity, NUM_FRACTION_DIGITS), @@ -12616,7 +12507,7 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, /** @lends fabric.Stati this.dirty = true; } - if (this.group && this.stateProperties.indexOf(key) > -1) { + if (this.group && this.stateProperties.indexOf(key) > -1 && this.group.isOnACache()) { this.group.set('dirty', true); } @@ -12641,7 +12532,7 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, /** @lends fabric.Stati * Retrieves viewportTransform from Object's canvas if possible * @method getViewportTransform * @memberOf fabric.Object.prototype - * @return {Boolean} flipY value // TODO + * @return {Boolean} */ getViewportTransform: function() { if (this.canvas && this.canvas.viewportTransform) { @@ -12650,20 +12541,29 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, /** @lends fabric.Stati return fabric.iMatrix.concat(); }, + /* + * @private + * return if the object would be visible in rendering + * @memberOf fabric.Object.prototype + * @return {Boolean} + */ + isNotVisible: function() { + return this.opacity === 0 || (this.width === 0 && this.height === 0) || !this.visible; + }, + /** * Renders an object on a specified context * @param {CanvasRenderingContext2D} ctx Context to render on */ render: function(ctx) { // do not render if width/height are zeros or object is not visible - if ((this.width === 0 && this.height === 0) || !this.visible) { + if (this.isNotVisible()) { return; } if (this.canvas && this.canvas.skipOffscreen && !this.group && !this.isOnScreen()) { return; } ctx.save(); - //setup fill rule for current object this._setupCompositeOperation(ctx); this.drawSelectionBackground(ctx); this.transform(ctx); @@ -12685,6 +12585,7 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, /** @lends fabric.Stati this.drawCacheOnCanvas(ctx); } else { + this.dirty = false; this.drawObject(ctx); if (this.objectCaching && this.statefullCache) { this.saveState({ propertySet: 'cacheProperties' }); @@ -12695,7 +12596,19 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, /** @lends fabric.Stati }, /** - * Decide if the object should cache or not. + * When set to `true`, force the object to have its own cache, even if it is inside a group + * it may be needed when your object behave in a particular way on the cache and always needs + * its own isolated canvas to render correctly. + * Created to be overridden + * since 1.7.12 + * @returns false + */ + needsItsOwnCache: function() { + return false; + }, + + /** + * Decide if the object should cache or not. Create its own cache level * objectCaching is a global flag, wins over everything * needsItsOwnCache should be used when the object drawing method requires * a cache step. None of the fabric classes requires it. @@ -12703,8 +12616,9 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, /** @lends fabric.Stati * @return {Boolean} */ shouldCache: function() { - return this.objectCaching && - (!this.group || this.needsItsOwnCache || !this.group.isCaching()); + this.ownCaching = this.objectCaching && + (!this.group || this.needsItsOwnCache() || !this.group.isOnACache()); + return this.ownCaching; }, /** @@ -12713,7 +12627,7 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, /** @lends fabric.Stati * @return {Boolean} */ willDrawShadow: function() { - return !!this.shadow; + return !!this.shadow && (this.shadow.offsetX !== 0 || this.shadow.offsetY !== 0); }, /** @@ -12733,7 +12647,7 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, /** @lends fabric.Stati */ drawCacheOnCanvas: function(ctx) { ctx.scale(1 / this.zoomX, 1 / this.zoomY); - ctx.drawImage(this._cacheCanvas, -this.cacheWidth / 2, -this.cacheHeight / 2); + ctx.drawImage(this._cacheCanvas, -this.cacheTranslationX, -this.cacheTranslationY); }, /** @@ -12742,13 +12656,16 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, /** @lends fabric.Stati * on parent canvas. */ isCacheDirty: function(skipCanvas) { - if (!skipCanvas && this._updateCacheCanvas()) { + if (this.isNotVisible()) { + return false; + } + if (this._cacheCanvas && !skipCanvas && this._updateCacheCanvas()) { // in this case the context is already cleared. return true; } else { if (this.dirty || (this.statefullCache && this.hasStateChanged('cacheProperties'))) { - if (!skipCanvas) { + if (this._cacheCanvas && !skipCanvas) { var width = this.cacheWidth / this.zoomX; var height = this.cacheHeight / this.zoomY; this._cacheContext.clearRect(-width / 2, -height / 2, width, height); @@ -12846,8 +12763,10 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, /** @lends fabric.Stati _renderControls: function(ctx, styleOverride) { var vpt = this.getViewportTransform(), matrix = this.calcTransformMatrix(), - options; + options, drawBorders, drawControls; styleOverride = styleOverride || { }; + drawBorders = typeof styleOverride.hasBorders !== 'undefined' ? styleOverride.hasBorders : this.hasBorders; + drawControls = typeof styleOverride.hasControls !== 'undefined' ? styleOverride.hasControls : this.hasControls; matrix = fabric.util.multiplyTransformMatrices(vpt, matrix); options = fabric.util.qrDecompose(matrix); ctx.save(); @@ -12858,13 +12777,13 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, /** @lends fabric.Stati } if (this.group && this.group === this.canvas.getActiveGroup()) { ctx.rotate(degreesToRadians(options.angle)); - (this.hasBorders || styleOverride.hasBorders) && this.drawBordersInGroup(ctx, options, styleOverride); + drawBorders && this.drawBordersInGroup(ctx, options, styleOverride); } else { ctx.rotate(degreesToRadians(this.angle)); - (this.hasBorders || styleOverride.hasBorders) && this.drawBorders(ctx, styleOverride); + drawBorders && this.drawBorders(ctx, styleOverride); } - (this.hasControls || styleOverride.hasControls) && this.drawControls(ctx, styleOverride); + drawControls && this.drawControls(ctx, styleOverride); ctx.restore(); }, @@ -12993,17 +12912,18 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, /** @lends fabric.Stati }, /** - * Clones an instance, some objects are async, so using callback method will work for every object. - * Using the direct return does not work for images and groups. + * Clones an instance, using a callback method will work for every object. * @param {Function} callback Callback is invoked with a clone as a first argument * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output - * @return {fabric.Object} clone of an instance */ clone: function(callback, propertiesToInclude) { + var objectForm = this.toObject(propertiesToInclude); if (this.constructor.fromObject) { - return this.constructor.fromObject(this.toObject(propertiesToInclude), callback); + this.constructor.fromObject(objectForm, callback); + } + else { + fabric.Object._fromObject('Object', objectForm, callback); } - return new fabric.Object(this.toObject(propertiesToInclude)); }, /** @@ -13056,13 +12976,13 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, /** @lends fabric.Stati } var origParams = { - active: this.get('active'), - left: this.getLeft(), - top: this.getTop() + active: this.active, + left: this.left, + top: this.top }; this.set('active', false); - this.setPositionByOrigin(new fabric.Point(canvas.getWidth() / 2, canvas.getHeight() / 2), 'center', 'center'); + this.setPositionByOrigin(new fabric.Point(canvas.width / 2, canvas.height / 2), 'center', 'center'); var originalCanvas = this.canvas; canvas.add(this); @@ -13366,7 +13286,7 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, /** @lends fabric.Stati } }); - fabric.util.createAccessors(fabric.Object); + fabric.util.createAccessors && fabric.util.createAccessors(fabric.Object); /** * Alias for {@link fabric.Object.prototype.setAngle} @@ -13387,26 +13307,19 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, /** @lends fabric.Stati */ fabric.Object.NUM_FRACTION_DIGITS = 2; - fabric.Object._fromObject = function(className, object, callback, forceAsync, extraParam) { + fabric.Object._fromObject = function(className, object, callback, extraParam) { var klass = fabric[className]; object = clone(object, true); - if (forceAsync) { - fabric.util.enlivenPatterns([object.fill, object.stroke], function(patterns) { - if (typeof patterns[0] !== 'undefined') { - object.fill = patterns[0]; - } - if (typeof patterns[1] !== 'undefined') { - object.stroke = patterns[1]; - } - var instance = extraParam ? new klass(object[extraParam], object) : new klass(object); - callback && callback(instance); - }); - } - else { + fabric.util.enlivenPatterns([object.fill, object.stroke], function(patterns) { + if (typeof patterns[0] !== 'undefined') { + object.fill = patterns[0]; + } + if (typeof patterns[1] !== 'undefined') { + object.stroke = patterns[1]; + } var instance = extraParam ? new klass(object[extraParam], object) : new klass(object); callback && callback(instance); - return instance; - } + }); }; /** @@ -13603,7 +13516,7 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, /** @lends fabric.Stati */ adjustPosition: function(to) { var angle = degreesToRadians(this.angle), - hypotFull = this.getWidth(), + hypotFull = this.getScaledWidth(), xFull = Math.cos(angle) * hypotFull, yFull = Math.sin(angle) * hypotFull, offsetFrom, offsetTo; @@ -13972,16 +13885,15 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, /** @lends fabric.Stati * Returns width of an object bounding box counting transformations * @return {Number} width value */ - getWidth: function() { + getScaledWidth: function() { return this._getTransformedDimensions().x; }, /** * Returns height of an object bounding box counting transformations - * to be renamed in 2.0 * @return {Number} height value */ - getHeight: function() { + getScaledHeight: function() { return this._getTransformedDimensions().y; }, @@ -14031,7 +13943,7 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, /** @lends fabric.Stati */ scaleToWidth: function(value) { // adjust to bounding rect factor so that rotated shapes would fit as well - var boundingRectFactor = this.getBoundingRect().width / this.getWidth(); + var boundingRectFactor = this.getBoundingRect().width / this.getScaledWidth(); return this.scale(value / this.width / boundingRectFactor); }, @@ -14043,7 +13955,7 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, /** @lends fabric.Stati */ scaleToHeight: function(value) { // adjust to bounding rect factor so that rotated shapes would fit as well - var boundingRectFactor = this.getBoundingRect().height / this.getHeight(); + var boundingRectFactor = this.getBoundingRect().height / this.getScaledHeight(); return this.scale(value / this.height / boundingRectFactor); }, @@ -14440,9 +14352,9 @@ fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prot * @return {String} */ getSvgTransform: function() { - var angle = this.getAngle(), - skewX = (this.getSkewX() % 360), - skewY = (this.getSkewY() % 360), + var angle = this.angle, + skewX = (this.skewX % 360), + skewY = (this.skewY % 360), center = this.getCenterPoint(), NUM_FRACTION_DIGITS = fabric.Object.NUM_FRACTION_DIGITS, @@ -14542,35 +14454,34 @@ fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prot } function _isEqual(origValue, currentValue, firstPass) { - if (!fabric.isLikelyNode && origValue instanceof Element) { - // avoid checking deep html elements - return origValue === currentValue; + if (origValue === currentValue) { + // if the objects are identical, return + return true; } - else if (origValue instanceof Array) { + else if (Array.isArray(origValue)) { if (origValue.length !== currentValue.length) { return false; } for (var i = 0, len = origValue.length; i < len; i++) { - if (origValue[i] !== currentValue[i]) { + if (!_isEqual(origValue[i], currentValue[i])) { return false; } } return true; } else if (origValue && typeof origValue === 'object') { - if (!firstPass && Object.keys(origValue).length !== Object.keys(currentValue).length) { + var keys = Object.keys(origValue), key; + if (!firstPass && keys.length !== Object.keys(currentValue).length) { return false; } - for (var key in origValue) { + for (var i = 0, len = keys.length; i < len; i++) { + key = keys[i]; if (!_isEqual(origValue[key], currentValue[key])) { return false; } } return true; } - else { - return origValue === currentValue; - } } @@ -14583,11 +14494,11 @@ fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prot */ hasStateChanged: function(propertySet) { propertySet = propertySet || originalSet; - propertySet = '_' + propertySet; - if (!Object.keys(this[propertySet]).length) { + var dashedPropertySet = '_' + propertySet; + if (Object.keys(this[dashedPropertySet]).length < this[propertySet].length) { return true; } - return !_isEqual(this[propertySet], this, true); + return !_isEqual(this[dashedPropertySet], this, true); }, /** @@ -14763,20 +14674,26 @@ fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prot * Requires public properties: width, height * Requires public options: padding, borderColor * @param {CanvasRenderingContext2D} ctx Context to draw on - * @param {Object} bordersStyle object to override the object style + * @param {Object} styleOverride object to override the object style * @return {fabric.Object} thisArg * @chainable */ - drawBorders: function(ctx, bordersStyle) { - bordersStyle = bordersStyle || {}; + drawBorders: function(ctx, styleOverride) { + styleOverride = styleOverride || {}; var wh = this._calculateCurrentDimensions(), strokeWidth = 1 / this.borderScaleFactor, width = wh.x + strokeWidth, - height = wh.y + strokeWidth; + height = wh.y + strokeWidth, + drawRotatingPoint = typeof styleOverride.hasRotatingPoint !== 'undefined' ? + styleOverride.hasRotatingPoint : this.hasRotatingPoint, + hasControls = typeof styleOverride.hasControls !== 'undefined' ? + styleOverride.hasControls : this.hasControls, + rotatingPointOffset = typeof styleOverride.rotatingPointOffset !== 'undefined' ? + styleOverride.rotatingPointOffset : this.rotatingPointOffset; ctx.save(); - ctx.strokeStyle = bordersStyle.borderColor || this.borderColor; - this._setLineDash(ctx, bordersStyle.borderDashArray || this.borderDashArray, null); + ctx.strokeStyle = styleOverride.borderColor || this.borderColor; + this._setLineDash(ctx, styleOverride.borderDashArray || this.borderDashArray, null); ctx.strokeRect( -width / 2, @@ -14785,14 +14702,13 @@ fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prot height ); - if (bordersStyle.hasRotatingPoint || - this.hasRotatingPoint && this.isControlVisible('mtr') && !this.get('lockRotation') && this.hasControls) { + if (drawRotatingPoint && this.isControlVisible('mtr') && hasControls) { var rotateHeight = -height / 2; ctx.beginPath(); ctx.moveTo(0, rotateHeight); - ctx.lineTo(0, rotateHeight - this.rotatingPointOffset); + ctx.lineTo(0, rotateHeight - rotatingPointOffset); ctx.closePath(); ctx.stroke(); } @@ -14807,12 +14723,12 @@ fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prot * Requires public options: padding, borderColor * @param {CanvasRenderingContext2D} ctx Context to draw on * @param {object} options object representing current object parameters - * @param {Object} bordersStyle object to override the object style + * @param {Object} styleOverride object to override the object style * @return {fabric.Object} thisArg * @chainable */ - drawBordersInGroup: function(ctx, options, bordersStyle) { - bordersStyle = bordersStyle || {}; + drawBordersInGroup: function(ctx, options, styleOverride) { + styleOverride = styleOverride || {}; var p = this._getNonTransformedDimensions(), matrix = fabric.util.customTransformMatrix(options.scaleX, options.scaleY, options.skewX), wh = fabric.util.transformPoint(p, matrix), @@ -14821,8 +14737,8 @@ fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prot height = wh.y + strokeWidth; ctx.save(); - this._setLineDash(ctx, bordersStyle.borderDashArray || this.borderDashArray, null); - ctx.strokeStyle = bordersStyle.borderColor || this.borderColor; + this._setLineDash(ctx, styleOverride.borderDashArray || this.borderDashArray, null); + ctx.strokeStyle = styleOverride.borderColor || this.borderColor; ctx.strokeRect( -width / 2, @@ -14840,75 +14756,79 @@ fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prot * Requires public properties: width, height * Requires public options: cornerSize, padding * @param {CanvasRenderingContext2D} ctx Context to draw on - * @param {Object} controlsStyle object to override the object style + * @param {Object} styleOverride object to override the object style * @return {fabric.Object} thisArg * @chainable */ - drawControls: function(ctx, controlsStyle) { - controlsStyle = controlsStyle || {}; + drawControls: function(ctx, styleOverride) { + styleOverride = styleOverride || {}; var wh = this._calculateCurrentDimensions(), width = wh.x, height = wh.y, - scaleOffset = controlsStyle.cornerSize || this.cornerSize, + scaleOffset = styleOverride.cornerSize || this.cornerSize, left = -(width + scaleOffset) / 2, top = -(height + scaleOffset) / 2, - methodName = controlsStyle.transparentCorners || this.transparentCorners ? 'stroke' : 'fill'; + transparentCorners = typeof styleOverride.transparentCorners !== 'undefined' ? + styleOverride.transparentCorners : this.transparentCorners, + hasRotatingPoint = typeof styleOverride.hasRotatingPoint !== 'undefined' ? + styleOverride.hasRotatingPoint : this.hasRotatingPoint, + methodName = transparentCorners ? 'stroke' : 'fill'; ctx.save(); - ctx.strokeStyle = ctx.fillStyle = controlsStyle.cornerColor || this.cornerColor; + ctx.strokeStyle = ctx.fillStyle = styleOverride.cornerColor || this.cornerColor; if (!this.transparentCorners) { - ctx.strokeStyle = controlsStyle.cornerStrokeColor || this.cornerStrokeColor; + ctx.strokeStyle = styleOverride.cornerStrokeColor || this.cornerStrokeColor; } - this._setLineDash(ctx, controlsStyle.cornerDashArray || this.cornerDashArray, null); + this._setLineDash(ctx, styleOverride.cornerDashArray || this.cornerDashArray, null); // top-left this._drawControl('tl', ctx, methodName, left, - top, controlsStyle); + top, styleOverride); // top-right this._drawControl('tr', ctx, methodName, left + width, - top, controlsStyle); + top, styleOverride); // bottom-left this._drawControl('bl', ctx, methodName, left, - top + height, controlsStyle); + top + height, styleOverride); // bottom-right this._drawControl('br', ctx, methodName, left + width, - top + height, controlsStyle); + top + height, styleOverride); if (!this.get('lockUniScaling')) { // middle-top this._drawControl('mt', ctx, methodName, left + width / 2, - top, controlsStyle); + top, styleOverride); // middle-bottom this._drawControl('mb', ctx, methodName, left + width / 2, - top + height, controlsStyle); + top + height, styleOverride); // middle-right this._drawControl('mr', ctx, methodName, left + width, - top + height / 2, controlsStyle); + top + height / 2, styleOverride); // middle-left this._drawControl('ml', ctx, methodName, left, - top + height / 2, controlsStyle); + top + height / 2, styleOverride); } // middle-top-rotate - if (controlsStyle.hasRotatingPoint || this.hasRotatingPoint) { + if (hasRotatingPoint) { this._drawControl('mtr', ctx, methodName, left + width / 2, - top - this.rotatingPointOffset, controlsStyle); + top - this.rotatingPointOffset, styleOverride); } ctx.restore(); @@ -14919,13 +14839,13 @@ fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prot /** * @private */ - _drawControl: function(control, ctx, methodName, left, top, controlStyle) { - controlStyle = controlStyle || {}; + _drawControl: function(control, ctx, methodName, left, top, styleOverride) { + styleOverride = styleOverride || {}; if (!this.isControlVisible(control)) { return; } var size = this.cornerSize, stroke = !this.transparentCorners && this.cornerStrokeColor; - switch (controlStyle.cornerStyle || this.cornerStyle) { + switch (styleOverride.cornerStyle || this.cornerStyle) { case 'circle': ctx.beginPath(); ctx.arc(left + size / 2, top + size / 2, size / 2, 0, 2 * Math.PI, false); @@ -15040,12 +14960,12 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, /** @lends fabric.Stati _this = this; fabric.util.animate({ - startValue: object.get('left'), + startValue: object.left, endValue: this.getCenter().left, duration: this.FX_DURATION, onChange: function(value) { object.set('left', value); - _this.renderAll(); + _this.requestRenderAll(); onChange(); }, onComplete: function() { @@ -15075,12 +14995,12 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, /** @lends fabric.Stati _this = this; fabric.util.animate({ - startValue: object.get('top'), + startValue: object.top, endValue: this.getCenter().top, duration: this.FX_DURATION, onChange: function(value) { object.set('top', value); - _this.renderAll(); + _this.requestRenderAll(); onChange(); }, onComplete: function() { @@ -15110,7 +15030,7 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, /** @lends fabric.Stati _this = this; fabric.util.animate({ - startValue: object.get('opacity'), + startValue: object.opacity, endValue: 0, duration: this.FX_DURATION, onStart: function() { @@ -15118,7 +15038,7 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, /** @lends fabric.Stati }, onChange: function(value) { object.set('opacity', value); - _this.renderAll(); + _this.requestRenderAll(); onChange(); }, onComplete: function () { @@ -15216,7 +15136,7 @@ fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prot abort: options.abort && function() { return options.abort.call(_this); }, - onChange: function(value) { + onChange: function(value, valueProgress, timeProgress) { if (propPair) { _this[propPair[0]][propPair[1]] = value; } @@ -15226,15 +15146,15 @@ fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prot if (skipCallbacks) { return; } - options.onChange && options.onChange(); + options.onChange && options.onChange(value, valueProgress, timeProgress); }, - onComplete: function() { + onComplete: function(value, valueProgress, timeProgress) { if (skipCallbacks) { return; } _this.setCoords(); - options.onComplete && options.onComplete(); + options.onComplete && options.onComplete(value, valueProgress, timeProgress); } }); } @@ -15537,9 +15457,9 @@ fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prot * @memberOf fabric.Line * @param {SVGElement} element Element to parse * @param {Object} [options] Options object - * @return {fabric.Line} instance of fabric.Line + * @param {Function} [callback] callback function invoked after parsing */ - fabric.Line.fromElement = function(element, options) { + fabric.Line.fromElement = function(element, callback, options) { options = options || { }; var parsedAttributes = fabric.parseAttributes(element, fabric.Line.ATTRIBUTE_NAMES), points = [ @@ -15550,7 +15470,7 @@ fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prot ]; options.originX = 'left'; options.originY = 'top'; - return new fabric.Line(points, extend(parsedAttributes, options)); + callback(new fabric.Line(points, extend(parsedAttributes, options))); }; /* _FROM_SVG_END_ */ @@ -15560,21 +15480,15 @@ fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prot * @memberOf fabric.Line * @param {Object} object Object to create an instance from * @param {function} [callback] invoked with new instance as first argument - * @param {Boolean} [forceAsync] Force an async behaviour trying to create pattern first - * @return {fabric.Line} instance of fabric.Line */ - fabric.Line.fromObject = function(object, callback, forceAsync) { + fabric.Line.fromObject = function(object, callback) { function _callback(instance) { delete instance.points; callback && callback(instance); }; var options = clone(object, true); options.points = [object.x1, object.y1, object.x2, object.y2]; - var line = fabric.Object._fromObject('Line', options, _callback, forceAsync, 'points'); - if (line) { - delete line.points; - } - return line; + fabric.Object._fromObject('Line', options, _callback, 'points'); }; /** @@ -15795,10 +15709,10 @@ fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prot * @memberOf fabric.Circle * @param {SVGElement} element Element to parse * @param {Object} [options] Options object + * @param {Function} [callback] Options callback invoked after parsing is finished * @throws {Error} If value of `r` attribute is missing or invalid - * @return {fabric.Circle} Instance of fabric.Circle */ - fabric.Circle.fromElement = function(element, options) { + fabric.Circle.fromElement = function(element, callback, options) { options || (options = { }); var parsedAttributes = fabric.parseAttributes(element, fabric.Circle.ATTRIBUTE_NAMES); @@ -15811,7 +15725,7 @@ fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prot parsedAttributes.top = (parsedAttributes.top || 0) - parsedAttributes.radius; parsedAttributes.originX = 'left'; parsedAttributes.originY = 'top'; - return new fabric.Circle(extend(parsedAttributes, options)); + callback(new fabric.Circle(extend(parsedAttributes, options))); }; /** @@ -15828,11 +15742,10 @@ fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prot * @memberOf fabric.Circle * @param {Object} object Object to create an instance from * @param {function} [callback] invoked with new instance as first argument - * @param {Boolean} [forceAsync] Force an async behaviour trying to create pattern first * @return {Object} Instance of fabric.Circle */ - fabric.Circle.fromObject = function(object, callback, forceAsync) { - return fabric.Object._fromObject('Circle', object, callback, forceAsync); + fabric.Circle.fromObject = function(object, callback) { + return fabric.Object._fromObject('Circle', object, callback); }; })(typeof exports !== 'undefined' ? exports : this); @@ -15945,11 +15858,9 @@ fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prot * @memberOf fabric.Triangle * @param {Object} object Object to create an instance from * @param {function} [callback] invoked with new instance as first argument - * @param {Boolean} [forceAsync] Force an async behaviour trying to create pattern first - * @return {fabric.Triangle} */ - fabric.Triangle.fromObject = function(object, callback, forceAsync) { - return fabric.Object._fromObject('Triangle', object, callback, forceAsync); + fabric.Triangle.fromObject = function(object, callback) { + return fabric.Object._fromObject('Triangle', object, callback); }; })(typeof exports !== 'undefined' ? exports : this); @@ -16125,9 +16036,10 @@ fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prot * @memberOf fabric.Ellipse * @param {SVGElement} element Element to parse * @param {Object} [options] Options object + * @param {Function} [callback] Options callback invoked after parsing is finished * @return {fabric.Ellipse} */ - fabric.Ellipse.fromElement = function(element, options) { + fabric.Ellipse.fromElement = function(element, callback, options) { options || (options = { }); var parsedAttributes = fabric.parseAttributes(element, fabric.Ellipse.ATTRIBUTE_NAMES); @@ -16136,7 +16048,7 @@ fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prot parsedAttributes.top = (parsedAttributes.top || 0) - parsedAttributes.ry; parsedAttributes.originX = 'left'; parsedAttributes.originY = 'top'; - return new fabric.Ellipse(extend(parsedAttributes, options)); + callback(new fabric.Ellipse(extend(parsedAttributes, options))); }; /* _FROM_SVG_END_ */ @@ -16146,11 +16058,10 @@ fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prot * @memberOf fabric.Ellipse * @param {Object} object Object to create an instance from * @param {function} [callback] invoked with new instance as first argument - * @param {Boolean} [forceAsync] Force an async behaviour trying to create pattern first * @return {fabric.Ellipse} */ - fabric.Ellipse.fromObject = function(object, callback, forceAsync) { - return fabric.Object._fromObject('Ellipse', object, callback, forceAsync); + fabric.Ellipse.fromObject = function(object, callback) { + return fabric.Object._fromObject('Ellipse', object, callback); }; })(typeof exports !== 'undefined' ? exports : this); @@ -16343,12 +16254,12 @@ fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prot * @static * @memberOf fabric.Rect * @param {SVGElement} element Element to parse + * @param {Function} callback callback function invoked after parsing * @param {Object} [options] Options object - * @return {fabric.Rect} Instance of fabric.Rect */ - fabric.Rect.fromElement = function(element, options) { + fabric.Rect.fromElement = function(element, callback, options) { if (!element) { - return null; + return callback(null); } options = options || { }; @@ -16360,7 +16271,7 @@ fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prot parsedAttributes.originY = 'top'; var rect = new fabric.Rect(extend((options ? fabric.util.object.clone(options) : { }), parsedAttributes)); rect.visible = rect.visible && rect.width > 0 && rect.height > 0; - return rect; + callback(rect); }; /* _FROM_SVG_END_ */ @@ -16370,11 +16281,9 @@ fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prot * @memberOf fabric.Rect * @param {Object} object Object to create an instance from * @param {Function} [callback] Callback to invoke when an fabric.Rect instance is created - * @param {Boolean} [forceAsync] Force an async behaviour trying to create pattern first - * @return {Object} instance of fabric.Rect */ - fabric.Rect.fromObject = function(object, callback, forceAsync) { - return fabric.Object._fromObject('Rect', object, callback, forceAsync); + fabric.Rect.fromObject = function(object, callback) { + return fabric.Object._fromObject('Rect', object, callback); }; })(typeof exports !== 'undefined' ? exports : this); @@ -16603,20 +16512,20 @@ fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prot * Returns fabric.Polyline instance from an SVG element * @static * @memberOf fabric.Polyline - * @param {SVGElement} element Element to parse + * @param {SVGElement} element Element to parser + * @param {Function} callback callback function invoked after parsing * @param {Object} [options] Options object - * @return {fabric.Polyline} Instance of fabric.Polyline */ - fabric.Polyline.fromElement = function(element, options) { + fabric.Polyline.fromElement = function(element, callback, options) { if (!element) { - return null; + return callback(null); } options || (options = { }); var points = fabric.parsePointsAttribute(element.getAttribute('points')), parsedAttributes = fabric.parseAttributes(element, fabric.Polyline.ATTRIBUTE_NAMES); - return new fabric.Polyline(points, fabric.util.object.extend(parsedAttributes, options)); + callback(new fabric.Polyline(points, fabric.util.object.extend(parsedAttributes, options))); }; /* _FROM_SVG_END_ */ @@ -16626,11 +16535,9 @@ fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prot * @memberOf fabric.Polyline * @param {Object} object Object to create an instance from * @param {Function} [callback] Callback to invoke when an fabric.Path instance is created - * @param {Boolean} [forceAsync] Force an async behaviour trying to create pattern first - * @return {fabric.Polyline} Instance of fabric.Polyline */ - fabric.Polyline.fromObject = function(object, callback, forceAsync) { - return fabric.Object._fromObject('Polyline', object, callback, forceAsync, 'points'); + fabric.Polyline.fromObject = function(object, callback) { + return fabric.Object._fromObject('Polyline', object, callback, 'points'); }; })(typeof exports !== 'undefined' ? exports : this); @@ -16700,12 +16607,12 @@ fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prot * @static * @memberOf fabric.Polygon * @param {SVGElement} element Element to parse + * @param {Function} callback callback function invoked after parsing * @param {Object} [options] Options object - * @return {fabric.Polygon} Instance of fabric.Polygon */ - fabric.Polygon.fromElement = function(element, options) { + fabric.Polygon.fromElement = function(element, callback, options) { if (!element) { - return null; + return callback(null); } options || (options = { }); @@ -16713,7 +16620,7 @@ fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prot var points = fabric.parsePointsAttribute(element.getAttribute('points')), parsedAttributes = fabric.parseAttributes(element, fabric.Polygon.ATTRIBUTE_NAMES); - return new fabric.Polygon(points, extend(parsedAttributes, options)); + callback(new fabric.Polygon(points, extend(parsedAttributes, options))); }; /* _FROM_SVG_END_ */ @@ -16723,11 +16630,9 @@ fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prot * @memberOf fabric.Polygon * @param {Object} object Object to create an instance from * @param {Function} [callback] Callback to invoke when an fabric.Path instance is created - * @param {Boolean} [forceAsync] Force an async behaviour trying to create pattern first - * @return {fabric.Polygon} Instance of fabric.Polygon */ - fabric.Polygon.fromObject = function(object, callback, forceAsync) { - return fabric.Object._fromObject('Polygon', object, callback, forceAsync, 'points'); + fabric.Polygon.fromObject = function(object, callback) { + return fabric.Object._fromObject('Polygon', object, callback, 'points'); }; })(typeof exports !== 'undefined' ? exports : this); @@ -16764,8 +16669,11 @@ fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prot return; } + var stateProperties = fabric.Object.prototype.stateProperties.concat(); + stateProperties.push('path'); + var cacheProperties = fabric.Object.prototype.cacheProperties.concat(); - cacheProperties.push('path'); + cacheProperties.push('path', 'fillRule'); /** * Path class @@ -16806,6 +16714,8 @@ fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prot cacheProperties: cacheProperties, + stateProperties: stateProperties, + /** * Constructor * @param {Array|String} path Path data (sequence of coordinates and corresponding "command" tokens) @@ -16814,10 +16724,7 @@ fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prot */ initialize: function(path, options) { options = options || { }; - - if (options) { - this.setOptions(options); - } + this.callSuper('initialize', options); if (!path) { path = []; @@ -16839,10 +16746,6 @@ fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prot } this._setPositionDimensions(options); - - if (this.objectCaching) { - this._createCacheCanvas(); - } }, /** @@ -17648,10 +17551,23 @@ fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prot * @memberOf fabric.Path * @param {Object} object * @param {Function} [callback] Callback to invoke when an fabric.Path instance is created - * @param {Boolean} [forceAsync] Force an async behaviour trying to create pattern first */ - fabric.Path.fromObject = function(object, callback, forceAsync) { - return fabric.Object._fromObject('Path', object, callback, forceAsync, 'path'); + fabric.Path.fromObject = function(object, callback) { + if (typeof object.path === 'string') { + var pathUrl = object.path; + fabric.loadSVGFromURL(pathUrl, function (elements) { + var path = elements[0]; + delete object.path; + + path.setOptions(object); + path.setSourcePath(pathUrl); + + callback && callback(path); + }); + } + else { + fabric.Object._fromObject('Path', object, callback, 'path'); + } }; /* _FROM_SVG_START_ */ @@ -17670,24 +17586,16 @@ fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prot * @param {SVGElement} element to parse * @param {Function} callback Callback to invoke when an fabric.Path instance is created * @param {Object} [options] Options object + * @param {Function} [callback] Options callback invoked after parsing is finished */ fabric.Path.fromElement = function(element, callback, options) { var parsedAttributes = fabric.parseAttributes(element, fabric.Path.ATTRIBUTE_NAMES); parsedAttributes.originX = 'left'; parsedAttributes.originY = 'top'; - callback && callback(new fabric.Path(parsedAttributes.d, extend(parsedAttributes, options))); + callback(new fabric.Path(parsedAttributes.d, extend(parsedAttributes, options))); }; /* _FROM_SVG_END_ */ - /** - * Indicates that instances of this type are async - * @static - * @memberOf fabric.Path - * @type Boolean - * @default - */ - fabric.Path.async = true; - })(typeof exports !== 'undefined' ? exports : this); @@ -17704,18 +17612,6 @@ fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prot return; } - // lock-related properties, for use in fabric.Group#get - // to enable locking behavior on group - // when one of its objects has lock-related properties set - var _lockProperties = { - lockMovementX: true, - lockMovementY: true, - lockRotation: true, - lockScalingX: true, - lockScalingY: true, - lockUniScaling: true - }; - /** * Group class * @class fabric.Group @@ -17734,18 +17630,34 @@ fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prot type: 'group', /** - * Width of stroke - * @type Number + * Width of stroke + * @type Number + * @default + */ + strokeWidth: 0, + + /** + * Indicates if click events should also check for subtargets + * @type Boolean + * @default + */ + subTargetCheck: false, + + /** + * Groups are container, do not render anything on theyr own, ence no cache properties + * @type Array * @default */ - strokeWidth: 0, + cacheProperties: [], /** - * Indicates if click events should also check for subtargets + * setOnGroup is a method used for TextBox that is no more used since 2.0.0 The behavior is still + * available setting this boolean to true. * @type Boolean + * @since 2.0.0 * @default */ - subTargetCheck: false, + useSetOnGroup: false, /** * Constructor @@ -17761,7 +17673,6 @@ fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prot // if objects enclosed in a group have been grouped already, // we cannot change properties of objects. // Thus we need to set options to group without objects, - // because delegatedProperties propagate to objects. isAlreadyGrouped && this.callSuper('initialize', options); this._objects = objects || []; @@ -17820,8 +17731,8 @@ fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prot object.__origHasControls = object.hasControls; object.hasControls = false; - var objectLeft = object.getLeft(), - objectTop = object.getTop(), + var objectLeft = object.left, + objectTop = object.top, ignoreZoom = true, skipAbsolute = true; object.set({ @@ -17909,35 +17820,17 @@ fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prot }, /** - * Properties that are delegated to group objects when reading/writing - * @param {Object} delegatedProperties - */ - delegatedProperties: { - fill: true, - stroke: true, - strokeWidth: true, - fontFamily: true, - fontWeight: true, - fontSize: true, - fontStyle: true, - lineHeight: true, - textDecoration: true, - textAlign: true, - backgroundColor: true - }, - - /** * @private */ _set: function(key, value) { var i = this._objects.length; - if (this.delegatedProperties[key] || key === 'canvas') { + if (key === 'canvas') { while (i--) { this._objects[i].set(key, value); } } - else { + if (this.useSetOnGroup) { while (i--) { this._objects[i].setOnGroup(key, value); } @@ -17999,7 +17892,7 @@ fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prot }, /** - * Decide if the object should cache or not. + * Decide if the object should cache or not. Create its own cache level * objectCaching is a global flag, wins over everything * needsItsOwnCache should be used when the object drawing method requires * a cache step. None of the fabric classes requires it. @@ -18007,17 +17900,17 @@ fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prot * @return {Boolean} */ shouldCache: function() { - var parentCache = this.objectCaching && (!this.group || this.needsItsOwnCache || !this.group.isCaching()); - this.caching = parentCache; - if (parentCache) { + var ownCache = this.objectCaching && (!this.group || this.needsItsOwnCache() || !this.group.isOnACache()); + this.ownCaching = ownCache; + if (ownCache) { for (var i = 0, len = this._objects.length; i < len; i++) { if (this._objects[i].willDrawShadow()) { - this.caching = false; + this.ownCaching = false; return false; } } } - return parentCache; + return ownCache; }, /** @@ -18026,7 +17919,7 @@ fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prot */ willDrawShadow: function() { if (this.shadow) { - return true; + return this.callSuper('willDrawShadow'); } for (var i = 0, len = this._objects.length; i < len; i++) { if (this._objects[i].willDrawShadow()) { @@ -18040,8 +17933,8 @@ fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prot * Check if this group or its parent group are caching, recursively up * @return {Boolean} */ - isCaching: function() { - return this.caching || this.group && this.group.isCaching(); + isOnACache: function() { + return this.ownCaching || (this.group && this.group.isOnACache()); }, /** @@ -18066,8 +17959,11 @@ fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prot } for (var i = 0, len = this._objects.length; i < len; i++) { if (this._objects[i].isCacheDirty(true)) { - var dim = this._getNonTransformedDimensions(); - this._cacheContext.clearRect(-dim.x / 2, -dim.y / 2, dim.x, dim.y); + if (this._cacheCanvas) { + // if this group has not a cache canvas there is nothing to clean + var x = this.cacheWidth / this.zoomX, y = this.cacheHeight / this.zoomY; + this._cacheContext.clearRect(-x / 2, -y / 2, x, y); + } return true; } } @@ -18096,11 +17992,6 @@ fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prot * @private */ _renderObject: function(object, ctx) { - // do not render if object is not visible - if (!object.visible) { - return; - } - var originalHasRotatingPoint = object.hasRotatingPoint; object.hasRotatingPoint = false; object.render(ctx); @@ -18262,33 +18153,6 @@ fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prot return reviver ? reviver(markup.join('')) : markup.join(''); }, /* _TO_SVG_END_ */ - - /** - * Returns requested property - * @param {String} prop Property to get - * @return {*} - */ - get: function(prop) { - if (prop in _lockProperties) { - if (this[prop]) { - return this[prop]; - } - else { - for (var i = 0, len = this._objects.length; i < len; i++) { - if (this._objects[i][prop]) { - return true; - } - } - return false; - } - } - else { - if (prop in this.delegatedProperties) { - return this._objects[0] && this._objects[0].get(prop); - } - return this[prop]; - } - } }); /** @@ -18305,15 +18169,6 @@ fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prot }); }; - /** - * Indicates that instances of this type are async - * @static - * @memberOf fabric.Group - * @type Boolean - * @default - */ - fabric.Group.async = true; - })(typeof exports !== 'undefined' ? exports : this); @@ -18334,9 +18189,8 @@ fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prot var stateProperties = fabric.Object.prototype.stateProperties.concat(); stateProperties.push( - 'alignX', - 'alignY', - 'meetOrSlice' + 'cropX', + 'cropY' ); /** @@ -18364,33 +18218,6 @@ fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prot crossOrigin: '', /** - * AlignX value, part of preserveAspectRatio (one of "none", "mid", "min", "max") - * @see http://www.w3.org/TR/SVG/coords.html#PreserveAspectRatioAttribute - * This parameter defines how the picture is aligned to its viewport when image element width differs from image width. - * @type String - * @default - */ - alignX: 'none', - - /** - * AlignY value, part of preserveAspectRatio (one of "none", "mid", "min", "max") - * @see http://www.w3.org/TR/SVG/coords.html#PreserveAspectRatioAttribute - * This parameter defines how the picture is aligned to its viewport when image element height differs from image height. - * @type String - * @default - */ - alignY: 'none', - - /** - * meetOrSlice value, part of preserveAspectRatio (one of "meet", "slice"). - * if meet the image is always fully visibile, if slice the viewport is always filled with image. - * @see http://www.w3.org/TR/SVG/coords.html#PreserveAspectRatioAttribute - * @type String - * @default - */ - meetOrSlice: 'meet', - - /** * Width of a stroke. * For image quality a stroke multiple of 2 gives better results. * @type Number @@ -18462,6 +18289,22 @@ fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prot cacheKey: '', /** + * Image crop in pixels from original image size. + * since 2.0.0 + * @type Number + * @default + */ + cropX: 0, + + /** + * Image crop in pixels from original image size. + * since 2.0.0 + * @type Number + * @default + */ + cropY: 0, + + /** * Constructor * @param {HTMLImageElement | String} element Image element * @param {Object} [options] Options object @@ -18586,7 +18429,7 @@ fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prot var object = extend( this.callSuper( 'toObject', - ['crossOrigin', 'alignX', 'alignY', 'meetOrSlice'].concat(propertiesToInclude) + ['crossOrigin', 'cropX', 'cropY'].concat(propertiesToInclude) ), { src: this.getSrc(), filters: filters, @@ -18608,10 +18451,7 @@ fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prot */ toSVG: function(reviver) { var markup = this._createBaseSVGMarkup(), x = -this.width / 2, y = -this.height / 2, - preserveAspectRatio = 'none', filtered = true; - if (this.alignX !== 'none' && this.alignY !== 'none') { - preserveAspectRatio = 'x' + this.alignX + 'Y' + this.alignY + ' ' + this.meetOrSlice; - } + filtered = true; markup.push( '\n', '\n' ); @@ -18784,13 +18623,7 @@ fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prot * @param {CanvasRenderingContext2D} ctx Context to render on */ _render: function(ctx) { - var x = -this.width / 2, y = -this.height / 2, imageMargins = this._findMargins(), elementToDraw; - - if (this.meetOrSlice === 'slice') { - ctx.beginPath(); - ctx.rect(x, y, this.width, this.height); - ctx.clip(); - } + var x = -this.width / 2, y = -this.height / 2, elementToDraw; if (this.isMoving === false && this.resizeFilter && this._needsResize()) { this._lastScaleX = this.scaleX; @@ -18799,12 +18632,8 @@ fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prot } elementToDraw = this._element; elementToDraw && ctx.drawImage(elementToDraw, - x + imageMargins.marginX, - y + imageMargins.marginY, - imageMargins.width, - imageMargins.height - ); - + this.cropX, this.cropY, this.width, this.height, + x, y, this.width, this.height); this._stroke(ctx); this._renderStroke(ctx); }, @@ -18819,40 +18648,6 @@ fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prot /** * @private */ - _findMargins: function() { - var width = this.width, height = this.height, scales, - scale, marginX = 0, marginY = 0; - - if (this.alignX !== 'none' || this.alignY !== 'none') { - scales = [this.width / this._element.width, this.height / this._element.height]; - scale = this.meetOrSlice === 'meet' - ? Math.min.apply(null, scales) : Math.max.apply(null, scales); - width = this._element.width * scale; - height = this._element.height * scale; - if (this.alignX === 'Mid') { - marginX = (this.width - width) / 2; - } - if (this.alignX === 'Max') { - marginX = this.width - width; - } - if (this.alignY === 'Mid') { - marginY = (this.height - height) / 2; - } - if (this.alignY === 'Max') { - marginY = this.height - height; - } - } - return { - width: width, - height: height, - marginX: marginX, - marginY: marginY - }; - }, - - /** - * @private - */ _resetWidthHeight: function() { var element = this.getElement(); @@ -18918,6 +18713,55 @@ fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prot ? this.getElement().height || 0 : 0); }, + + parsePreserveAspectRatioAttribute: function() { + if (!this.preserveAspectRatio) { + return; + } + var pAR = fabric.util.parsePreserveAspectRatioAttribute(this.preserveAspectRatio), + width = this._element.width, height = this._element.height, scale, + pWidth = this.width, pHeight = this.height, parsedAttributes = { width: pWidth, height: pHeight }; + if (pAR && (pAR.alignX !== 'none' || pAR.alignY !== 'none')) { + if (pAR.meetOrSlice === 'meet') { + this.width = width; + this.height = height; + this.scaleX = this.scaleY = scale = fabric.util.findScaleToFit(this._element, parsedAttributes); + if (pAR.alignX === 'Mid') { + this.left += (pWidth - width * scale) / 2; + } + if (pAR.alignX === 'Max') { + this.left += pWidth - width * scale; + } + if (pAR.alignY === 'Mid') { + this.top += (pHeight - height * scale) / 2; + } + if (pAR.alignY === 'Max') { + this.top += pHeight - height * scale; + } + } + if (pAR.meetOrSlice === 'slice') { + this.scaleX = this.scaleY = scale = fabric.util.findScaleToCover(this._element, parsedAttributes); + this.width = pWidth / scale; + this.height = pHeight / scale; + if (pAR.alignX === 'Mid') { + this.cropX = (width - this.width) / 2; + } + if (pAR.alignX === 'Max') { + this.cropX = width - this.width; + } + if (pAR.alignY === 'Mid') { + this.cropY = (height - this.height) / 2; + } + if (pAR.alignY === 'Max') { + this.cropY = height - this.height; + } + } + } + else { + this.scaleX = pWidth / width; + this.scaleY = pHeight / height; + } + } }); /** @@ -18983,40 +18827,18 @@ fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prot * Returns {@link fabric.Image} instance from an SVG element * @static * @param {SVGElement} element Element to parse - * @param {Function} callback Callback to execute when fabric.Image object is created * @param {Object} [options] Options object + * @param {Function} callback Callback to execute when fabric.Image object is created * @return {fabric.Image} Instance of fabric.Image */ fabric.Image.fromElement = function(element, callback, options) { - var parsedAttributes = fabric.parseAttributes(element, fabric.Image.ATTRIBUTE_NAMES), - preserveAR; - - if (parsedAttributes.preserveAspectRatio) { - preserveAR = fabric.util.parsePreserveAspectRatioAttribute(parsedAttributes.preserveAspectRatio); - extend(parsedAttributes, preserveAR); - } + var parsedAttributes = fabric.parseAttributes(element, fabric.Image.ATTRIBUTE_NAMES); fabric.Image.fromURL(parsedAttributes['xlink:href'], callback, extend((options ? fabric.util.object.clone(options) : { }), parsedAttributes)); }; /* _FROM_SVG_END_ */ - /** - * Indicates that instances of this type are async - * @static - * @type Boolean - * @default - */ - fabric.Image.async = true; - - /** - * Indicates compression level used when generating PNG under Node (in applyFilters). Any of 0-9 - * @static - * @type Number - * @default - */ - fabric.Image.pngCompression = 1; - })(typeof exports !== 'undefined' ? exports : this); @@ -19027,7 +18849,7 @@ fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prot * @return {Number} angle value */ _getAngleValueForStraighten: function() { - var angle = this.getAngle() % 360; + var angle = this.angle % 360; if (angle > 0) { return Math.round((angle - 1) / 90) * 90; } @@ -19587,8 +19409,8 @@ fabric.Image.filters.BaseFilter = fabric.util.createClass(/** @lends fabric.Imag var attributeLocations = this.getAttributeLocations(gl, program); var uniformLocations = this.getUniformLocations(gl, program) || { }; - uniformLocations.uWidth = gl.getUniformLocation(program, 'uWidth'); - uniformLocations.uHeight = gl.getUniformLocation(program, 'uHeight'); + uniformLocations.uStepW = gl.getUniformLocation(program, 'uStepW'); + uniformLocations.uStepH = gl.getUniformLocation(program, 'uStepH'); return { program: program, attributeLocations: attributeLocations, @@ -20736,7 +20558,7 @@ fabric.Image.filters.BaseFilter.fromObject = function(object, callback) { */ fragmentSource: 'precision highp float;\n' + 'uniform sampler2D uTexture;\n' + - 'uniform float uHeight;\n' + + 'uniform float uStepH;\n' + 'uniform float uNoise;\n' + 'uniform float uSeed;\n' + 'varying vec2 vTexCoord;\n' + @@ -20745,7 +20567,7 @@ fabric.Image.filters.BaseFilter.fromObject = function(object, callback) { '}\n' + 'void main() {\n' + 'vec4 color = texture2D(uTexture, vTexCoord);\n' + - 'color.rgb += (0.5 - rand(vTexCoord, uSeed, uHeight / 10.0)) * uNoise;\n' + + 'color.rgb += (0.5 - rand(vTexCoord, uSeed, 0.1 / uStepH)) * uNoise;\n' + 'gl_FragColor = color;\n' + '}', @@ -20941,8 +20763,8 @@ fabric.Image.filters.BaseFilter.fromObject = function(object, callback) { getUniformLocations: function(gl, program) { return { uBlocksize: gl.getUniformLocation(program, 'uBlocksize'), - uWidth: gl.getUniformLocation(program, 'uWidth'), - uHeight: gl.getUniformLocation(program, 'uHeight'), + uStepW: gl.getUniformLocation(program, 'uStepW'), + uStepH: gl.getUniformLocation(program, 'uStepH'), }; }, @@ -21504,6 +21326,7 @@ fabric.Image.filters.BaseFilter.fromObject = function(object, callback) { */ toObject: function() { return { + type: this.type, color: this.color, mode: this.mode, alpha: this.alpha @@ -22677,160 +22500,6 @@ fabric.Image.filters.BaseFilter.fromObject = function(object, callback) { _reWords: /\S+/g, /** - * Retrieves object's fontSize - * @method getFontSize - * @memberOf fabric.Text.prototype - * @return {String} Font size (in pixels) - */ - - /** - * Sets object's fontSize - * Does not update the object .width and .height, - * call .initDimensions() to update the values. - * @method setFontSize - * @memberOf fabric.Text.prototype - * @param {Number} fontSize Font size (in pixels) - * @return {fabric.Text} - * @chainable - */ - - /** - * Retrieves object's fontWeight - * @method getFontWeight - * @memberOf fabric.Text.prototype - * @return {(String|Number)} Font weight - */ - - /** - * Sets object's fontWeight - * Does not update the object .width and .height, - * call .initDimensions() to update the values. - * @method setFontWeight - * @memberOf fabric.Text.prototype - * @param {(Number|String)} fontWeight Font weight - * @return {fabric.Text} - * @chainable - */ - - /** - * Retrieves object's fontFamily - * @method getFontFamily - * @memberOf fabric.Text.prototype - * @return {String} Font family - */ - - /** - * Sets object's fontFamily - * Does not update the object .width and .height, - * call .initDimensions() to update the values. - * @method setFontFamily - * @memberOf fabric.Text.prototype - * @param {String} fontFamily Font family - * @return {fabric.Text} - * @chainable - */ - - /** - * Retrieves object's text - * @method getText - * @memberOf fabric.Text.prototype - * @return {String} text - */ - - /** - * Sets object's text - * Does not update the object .width and .height, - * call .initDimensions() to update the values. - * @method setText - * @memberOf fabric.Text.prototype - * @param {String} text Text - * @return {fabric.Text} - * @chainable - */ - - /** - * Retrieves object's underline - * @method getUnderline - * @memberOf fabric.Text.prototype - * @return {Boolean} underline enabled or disabled - */ - - /** - * Sets object's underline - * @method setUnderline - * @memberOf fabric.Text.prototype - * @param {Boolean} underline Text decoration - * @return {fabric.Text} - * @chainable - */ - - /** - * Retrieves object's fontStyle - * @method getFontStyle - * @memberOf fabric.Text.prototype - * @return {String} Font style - */ - - /** - * Sets object's fontStyle - * Does not update the object .width and .height, - * call .initDimensions() to update the values. - * @method setFontStyle - * @memberOf fabric.Text.prototype - * @param {String} fontStyle Font style - * @return {fabric.Text} - * @chainable - */ - - /** - * Retrieves object's lineHeight - * @method getLineHeight - * @memberOf fabric.Text.prototype - * @return {Number} Line height - */ - - /** - * Sets object's lineHeight - * @method setLineHeight - * @memberOf fabric.Text.prototype - * @param {Number} lineHeight Line height - * @return {fabric.Text} - * @chainable - */ - - /** - * Retrieves object's textAlign - * @method getTextAlign - * @memberOf fabric.Text.prototype - * @return {String} Text alignment - */ - - /** - * Sets object's textAlign - * @method setTextAlign - * @memberOf fabric.Text.prototype - * @param {String} textAlign Text alignment - * @return {fabric.Text} - * @chainable - */ - - /** - * Retrieves object's textBackgroundColor - * @method getTextBackgroundColor - * @memberOf fabric.Text.prototype - * @return {String} Text background color - */ - - /** - * Sets object's textBackgroundColor - * @method setTextBackgroundColor - * @memberOf fabric.Text.prototype - * @param {String} textBackgroundColor Text background color - * @return {fabric.Text} - * @chainable - */ - - /** * Type of an object * @type String * @default @@ -23070,7 +22739,7 @@ fabric.Image.filters.BaseFilter.fromObject = function(object, callback) { * @return {Boolean} */ styleHas: function(property, lineIndex) { - if (!this.styles) { + if (!this.styles || !property || property === '') { return false; } if (typeof lineIndex !== 'undefined' && !this.styles[lineIndex]) { @@ -23090,6 +22759,86 @@ fabric.Image.filters.BaseFilter.fromObject = function(object, callback) { }, /** + * Check if characters in a text have a value for a property + * whose value matches the textbox's value for that property. If so, + * the character-level property is deleted. If the character + * has no other properties, then it is also deleted. Finally, + * if the line containing that character has no other characters + * then it also is deleted. + * + * @param {string} property The property to compare between characters and text. + */ + cleanStyle: function(property) { + if (!this.styles || !property || property === '') { + return false; + } + var obj = this.styles, stylesCount = 0, letterCount, foundStyle = false, style, + canBeSwapped = true, graphemeCount = 0; + // eslint-disable-next-line + for (var p1 in obj) { + letterCount = 0; + // eslint-disable-next-line + for (var p2 in obj[p1]) { + stylesCount++; + if (!foundStyle) { + style = obj[p1][p2][property]; + foundStyle = true; + } + else if (obj[p1][p2][property] !== style) { + canBeSwapped = false; + } + if (obj[p1][p2][property] === this[property]) { + delete obj[p1][p2][property]; + } + if (Object.keys(obj[p1][p2]).length !== 0) { + letterCount++; + } + else { + delete obj[p1][p2]; + } + } + if (letterCount === 0) { + delete obj[p1]; + } + } + // if every grapheme has the same style set then + // delete those styles and set it on the parent + for (var i = 0; i < this._textLines.length; i++) { + graphemeCount += this._textLines[i].length; + } + if (canBeSwapped && stylesCount === graphemeCount) { + this[property] = style; + this.removeStyle(property); + } + }, + + /** + * Remove a style property or properties from all individual character styles + * in a text object. Deletes the character style object if it contains no other style + * props. Deletes a line style object if it contains no other character styles. + * + * @param {String} props The property to remove from character styles. + */ + removeStyle: function(property) { + if (!this.styles || !property || property === '') { + return; + } + var obj = this.styles, line, lineNum, charNum; + for (lineNum in obj) { + var line = obj[lineNum]; + for (charNum in line) { + delete line[charNum][property]; + if (Object.keys(line[charNum]).length === 0) { + delete line[charNum]; + } + } + if (Object.keys(line).length === 0) { + delete obj[lineNum]; + } + } + }, + + /** * @private */ _extendStyles: function(index, styles) { @@ -24054,12 +23803,12 @@ fabric.Image.filters.BaseFilter.fromObject = function(object, callback) { * @static * @memberOf fabric.Text * @param {SVGElement} element Element to parse + * @param {Function} callback callback function invoked after parsing * @param {Object} [options] Options object - * @return {fabric.Text} Instance of fabric.Text */ - fabric.Text.fromElement = function(element, options) { + fabric.Text.fromElement = function(element, callback, options) { if (!element) { - return null; + return callback(null); } var parsedAttributes = fabric.parseAttributes(element, fabric.Text.ATTRIBUTE_NAMES); @@ -24113,10 +23862,10 @@ fabric.Image.filters.BaseFilter.fromObject = function(object, callback) { textContent = textContent.replace(/^\s+|\s+$|\n+/g, '').replace(/\s+/g, ' '); var text = new fabric.Text(textContent, options), - textHeightScaleFactor = text.getHeight() / text.height, + textHeightScaleFactor = text.getScaledHeight() / text.height, lineHeightDiff = (text.height + text.strokeWidth) * text.lineHeight - text.height, scaledDiff = lineHeightDiff * textHeightScaleFactor, - textHeight = text.getHeight() + scaledDiff, + textHeight = text.getScaledHeight() + scaledDiff, offX = 0; /* Adjust positioning: @@ -24124,18 +23873,18 @@ fabric.Image.filters.BaseFilter.fromObject = function(object, callback) { fabric output by default at top, left. */ if (text.originX === 'center') { - offX = text.getWidth() / 2; + offX = text.getScaledWidth() / 2; } if (text.originX === 'right') { - offX = text.getWidth(); + offX = text.getScaledWidth(); } text.set({ - left: text.getLeft() - offX, - top: text.getTop() - (textHeight - text.fontSize * (0.18 + text._fontSizeFraction)) / text.lineHeight + left: text.left - offX, + top: text.top - (textHeight - text.fontSize * (0.18 + text._fontSizeFraction)) / text.lineHeight }); text.originX = 'left'; text.originY = 'top'; - return text; + callback(text); }; /* _FROM_SVG_END_ */ @@ -24145,14 +23894,12 @@ fabric.Image.filters.BaseFilter.fromObject = function(object, callback) { * @memberOf fabric.Text * @param {Object} object Object to create an instance from * @param {Function} [callback] Callback to invoke when an fabric.Text instance is created - * @param {Boolean} [forceAsync] Force an async behaviour trying to create pattern first - * @return {fabric.Text} Instance of fabric.Text */ - fabric.Text.fromObject = function(object, callback, forceAsync) { - return fabric.Object._fromObject('Text', object, callback, forceAsync, 'text'); + fabric.Text.fromObject = function(object, callback) { + return fabric.Object._fromObject('Text', object, callback, 'text'); }; - fabric.util.createAccessors(fabric.Text); + fabric.util.createAccessors && fabric.util.createAccessors(fabric.Text); })(typeof exports !== 'undefined' ? exports : this); @@ -24433,7 +24180,7 @@ fabric.Image.filters.BaseFilter.fromObject = function(object, callback) { * @private */ initDimensions: function() { - this.abortCursorAnimation(); + this.isEditing && this.initDelayedCursor(); this.clearContextTop(); this.callSuper('initDimensions'); }, @@ -24723,10 +24470,8 @@ fabric.Image.filters.BaseFilter.fromObject = function(object, callback) { * @memberOf fabric.IText * @param {Object} object Object to create an instance from * @param {function} [callback] invoked with new instance as argument - * @param {Boolean} [forceAsync] Force an async behaviour trying to create pattern first - * @return {fabric.IText} instance of fabric.IText */ - fabric.IText.fromObject = function(object, callback, forceAsync) { + fabric.IText.fromObject = function(object, callback) { parseDecoration(object); if (object.styles) { for (var i in object.styles) { @@ -24735,7 +24480,7 @@ fabric.Image.filters.BaseFilter.fromObject = function(object, callback) { } } } - return fabric.Object._fromObject('IText', object, callback, forceAsync, 'text'); + fabric.Object._fromObject('IText', object, callback, 'text'); }; })(); @@ -25089,7 +24834,7 @@ fabric.Image.filters.BaseFilter.fromObject = function(object, callback) { } this.canvas.fire('text:editing:entered', { target: this }); this.initMouseMoveHandler(); - this.canvas.renderAll(); + this.canvas.requestRenderAll(); return this; }, @@ -25649,11 +25394,6 @@ fabric.util.object.extend(fabric.IText.prototype, /** @lends fabric.IText.protot this.fire('tripleclick', options); this._stopEvent(options.e); } - else if (this.isDoubleClick(newPointer)) { - this.fire('dblclick', options); - this._stopEvent(options.e); - } - this.__lastLastClickTime = this.__lastClickTime; this.__lastClickTime = this.__newClickTime; this.__lastPointer = newPointer; @@ -25661,12 +25401,6 @@ fabric.util.object.extend(fabric.IText.prototype, /** @lends fabric.IText.protot this.__lastSelected = this.selected; }, - isDoubleClick: function(newPointer) { - return this.__newClickTime - this.__lastClickTime < 500 && - this.__lastPointer.x === newPointer.x && - this.__lastPointer.y === newPointer.y && this.__lastIsEditing; - }, - isTripleClick: function(newPointer) { return this.__newClickTime - this.__lastClickTime < 500 && this.__lastClickTime - this.__lastLastClickTime < 500 && @@ -25695,7 +25429,7 @@ fabric.util.object.extend(fabric.IText.prototype, /** @lends fabric.IText.protot * Initializes double and triple click event handlers */ initClicks: function() { - this.on('dblclick', function(options) { + this.on('mousedblclick', function(options) { this.selectWord(this.getSelectionStartFromPointer(options.e)); }); this.on('tripleclick', function(options) { @@ -25862,6 +25596,7 @@ fabric.util.object.extend(fabric.IText.prototype, /** @lends fabric.IText.protot this.hiddenTextarea.setAttribute('autocorrect', 'off'); this.hiddenTextarea.setAttribute('autocomplete', 'off'); this.hiddenTextarea.setAttribute('spellcheck', 'false'); + this.hiddenTextarea.setAttribute('data-fabric-hiddentextarea', ''); var style = this._calcTextareaPosition(); this.hiddenTextarea.style.cssText = 'white-space: nowrap; position: absolute; top: ' + style.top + @@ -25886,9 +25621,17 @@ fabric.util.object.extend(fabric.IText.prototype, /** @lends fabric.IText.protot }, /** - * @private + * For functionalities on keyDown + * Map a special key to a function of the instance/prototype + * If you need different behaviour for ESC or TAB or arrows, you have to change + * this map setting the name of a function that you build on the fabric.Itext or + * your prototype. + * the map change will affect all Instances unless you need for only some text Instances + * in that case you have to clone this object and assign your Instance. + * this.keysMap = fabric.util.object.clone(this.keysMap); + * The function must be in fabric.Itext.prototype.myFunction And will receive event as args[0] */ - _keysMap: { + keysMap: { 9: 'exitEditing', 27: 'exitEditing', 33: 'moveCursorUp', @@ -25902,17 +25645,17 @@ fabric.util.object.extend(fabric.IText.prototype, /** @lends fabric.IText.protot }, /** - * @private + * For functionalities on keyUp + ctrl || cmd */ - _ctrlKeysMapUp: { + ctrlKeysMapUp: { 67: 'copy', 88: 'cut' }, /** - * @private + * For functionalities on keyDown + ctrl || cmd */ - _ctrlKeysMapDown: { + ctrlKeysMapDown: { 65: 'selectAll' }, @@ -25929,11 +25672,11 @@ fabric.util.object.extend(fabric.IText.prototype, /** @lends fabric.IText.protot if (!this.isEditing || this.inCompositionMode) { return; } - if (e.keyCode in this._keysMap) { - this[this._keysMap[e.keyCode]](e); + if (e.keyCode in this.keysMap) { + this[this.keysMap[e.keyCode]](e); } - else if ((e.keyCode in this._ctrlKeysMapDown) && (e.ctrlKey || e.metaKey)) { - this[this._ctrlKeysMapDown[e.keyCode]](e); + else if ((e.keyCode in this.ctrlKeysMapDown) && (e.ctrlKey || e.metaKey)) { + this[this.ctrlKeysMapDown[e.keyCode]](e); } else { return; @@ -25946,7 +25689,7 @@ fabric.util.object.extend(fabric.IText.prototype, /** @lends fabric.IText.protot this.renderCursorOrSelection(); } else { - this.canvas && this.canvas.renderAll(); + this.canvas && this.canvas.requestRenderAll(); } }, @@ -25961,15 +25704,15 @@ fabric.util.object.extend(fabric.IText.prototype, /** @lends fabric.IText.protot this._copyDone = false; return; } - if ((e.keyCode in this._ctrlKeysMapUp) && (e.ctrlKey || e.metaKey)) { - this[this._ctrlKeysMapUp[e.keyCode]](e); + if ((e.keyCode in this.ctrlKeysMapUp) && (e.ctrlKey || e.metaKey)) { + this[this.ctrlKeysMapUp[e.keyCode]](e); } else { return; } e.stopImmediatePropagation(); e.preventDefault(); - this.canvas && this.canvas.renderAll(); + this.canvas && this.canvas.requestRenderAll(); }, /** @@ -25996,7 +25739,7 @@ fabric.util.object.extend(fabric.IText.prototype, /** @lends fabric.IText.protot this.fire('changed'); if (this.canvas) { this.canvas.fire('text:changed', { target: this }); - this.canvas.renderAll(); + this.canvas.requestRenderAll(); } } @@ -26037,7 +25780,7 @@ fabric.util.object.extend(fabric.IText.prototype, /** @lends fabric.IText.protot this.fire('changed'); if (this.canvas) { this.canvas.fire('text:changed', { target: this }); - this.canvas.renderAll(); + this.canvas.requestRenderAll(); } }, /** @@ -26445,7 +26188,7 @@ fabric.util.object.extend(fabric.IText.prototype, /** @lends fabric.IText.protot this._removeExtraneousStyles(); - this.canvas && this.canvas.renderAll(); + this.canvas && this.canvas.requestRenderAll(); this.setCoords(); this.fire('changed'); @@ -26751,11 +26494,6 @@ fabric.util.object.extend(fabric.IText.prototype, /** @lends fabric.IText.protot /** * Override standard Object class values */ - lockScalingY: true, - - /** - * Override standard Object class values - */ lockScalingFlip: true, /** @@ -26775,7 +26513,6 @@ fabric.util.object.extend(fabric.IText.prototype, /** @lends fabric.IText.protot initialize: function(text, options) { this.callSuper('initialize', text, options); - this.setControlsVisibility(fabric.Textbox.getTextboxControlVisibility()); this.ctx = this.objectCaching ? this._cacheContext : fabric.util.createCanvasElement().getContext('2d'); // add width to this list of props that effect line wrapping. this._dimensionAffectingProps.push('width'); @@ -26791,7 +26528,7 @@ fabric.util.object.extend(fabric.IText.prototype, /** @lends fabric.IText.protot if (this.__skipDimension) { return; } - this.initDelayedCursor(); + this.isEditing && this.initDelayedCursor(); this.clearContextTop(); this._clearCache(); // clear dynamicMinWidth as it will be different after we re-wrap line @@ -27056,25 +26793,6 @@ fabric.util.object.extend(fabric.IText.prototype, /** @lends fabric.IText.protot return newText; }, - /** - * When part of a group, we don't want the Textbox's scale to increase if - * the group's increases. That's why we reduce the scale of the Textbox by - * the amount that the group's increases. This is to maintain the effective - * scale of the Textbox at 1, so that font-size values make sense. Otherwise - * the same font-size value would result in different actual size depending - * on the value of the scale. - * @param {String} key - * @param {*} value - */ - setOnGroup: function(key, value) { - if (key === 'scaleX') { - this.set('scaleX', Math.abs(1 / value)); - this.set('width', (this.get('width') * value) / - (typeof this.__oldScaleX === 'undefined' ? 1 : this.__oldScaleX)); - this.__oldScaleX = value; - } - }, - getMinWidth: function() { return Math.max(this.minWidth, this.dynamicMinWidth); }, @@ -27096,31 +26814,10 @@ fabric.util.object.extend(fabric.IText.prototype, /** @lends fabric.IText.protot * @memberOf fabric.Textbox * @param {Object} object Object to create an instance from * @param {Function} [callback] Callback to invoke when an fabric.Textbox instance is created - * @param {Boolean} [forceAsync] Force an async behaviour trying to create pattern first - * @return {fabric.Textbox} instance of fabric.Textbox - */ - fabric.Textbox.fromObject = function(object, callback, forceAsync) { - return fabric.Object._fromObject('Textbox', object, callback, forceAsync, 'text'); - }; - - /** - * Returns the default controls visibility required for Textboxes. - * @returns {Object} */ - fabric.Textbox.getTextboxControlVisibility = function() { - return { - tl: false, - tr: false, - br: false, - bl: false, - ml: true, - mt: false, - mr: true, - mb: false, - mtr: true - }; + fabric.Textbox.fromObject = function(object, callback) { + return fabric.Object._fromObject('Textbox', object, callback, 'text'); }; - })(typeof exports !== 'undefined' ? exports : this); @@ -27136,8 +26833,9 @@ fabric.util.object.extend(fabric.IText.prototype, /** @lends fabric.IText.protot lockScalingX, lockScalingY, by, lockScalingFlip, _dim) { var t = transform.target; - if (t instanceof fabric.Textbox) { - var w = t.width * ((localMouse.x / transform.scaleX) / (t.width + t.strokeWidth)); + if (by === 'x' && t instanceof fabric.Textbox) { + var tw = t._getTransformedDimensions().x; + var w = t.width * (localMouse.x / tw); if (w >= t.getMinWidth()) { t.set('width', w); return true; @@ -27149,23 +26847,6 @@ fabric.util.object.extend(fabric.IText.prototype, /** @lends fabric.IText.protot } }; - /** - * Sets controls of this group to the Textbox's special configuration if - * one is present in the group. Deletes _controlsVisibility otherwise, so that - * it gets initialized to default value at runtime. - */ - fabric.Group.prototype._refreshControlsVisibility = function() { - if (typeof fabric.Textbox === 'undefined') { - return; - } - for (var i = this._objects.length; i--;) { - if (this._objects[i] instanceof fabric.Textbox) { - this.setControlsVisibility(fabric.Textbox.getTextboxControlVisibility()); - return; - } - } - }; - fabric.util.object.extend(fabric.Textbox.prototype, /** @lends fabric.IText.prototype */ { /** * @private @@ -27393,3 +27074,4 @@ fabric.util.object.extend(fabric.IText.prototype, /** @lends fabric.IText.protot } })(); + diff --git a/dist/fabric.min.js b/dist/fabric.min.js index bce268d69..f39edd74c 100644 --- a/dist/fabric.min.js +++ b/dist/fabric.min.js @@ -1,9 +1,9 @@ -var fabric=fabric||{version:"2.0.0-beta2"};"undefined"!=typeof exports&&(exports.fabric=fabric),"undefined"!=typeof document&&"undefined"!=typeof window?(fabric.document=document,fabric.window=window,window.fabric=fabric):(fabric.document=require("jsdom").jsdom(decodeURIComponent("%3C!DOCTYPE%20html%3E%3Chtml%3E%3Chead%3E%3C%2Fhead%3E%3Cbody%3E%3C%2Fbody%3E%3C%2Fhtml%3E"),{features:{FetchExternalResources:["img"]}}),fabric.window=fabric.document.defaultView),fabric.isTouchSupported="ontouchstart"in fabric.document.documentElement,fabric.isLikelyNode="undefined"!=typeof Buffer&&"undefined"==typeof window,fabric.SHARED_ATTRIBUTES=["display","transform","fill","fill-opacity","fill-rule","opacity","stroke","stroke-dasharray","stroke-linecap","stroke-linejoin","stroke-miterlimit","stroke-opacity","stroke-width","id"],fabric.DPI=96,fabric.reNum="(?:[-+]?(?:\\d+|\\d*\\.\\d+)(?:e[-+]?\\d+)?)",fabric.fontPaths={},fabric.iMatrix=[1,0,0,1,0,0],fabric.canvasModule="canvas-prebuilt",fabric.charWidthsCache={},fabric.textureSize=2048,fabric.enableGLFiltering=!0,fabric.devicePixelRatio=fabric.window.devicePixelRatio||fabric.window.webkitDevicePixelRatio||fabric.window.mozDevicePixelRatio||1,fabric.initFilterBackend=function(){return fabric.isWebglSupported&&fabric.isWebglSupported(fabric.textureSize)&&fabric.enableGLFiltering?(console.log("max texture size: "+fabric.maxTextureSize),new fabric.WebglFilterBackend({tileSize:fabric.textureSize})):fabric.Canvas2dFilterBackend?new fabric.Canvas2dFilterBackend:void 0},function(){function t(t,e){if(this.__eventListeners[t]){var i=this.__eventListeners[t];e?i[i.indexOf(e)]=!1:fabric.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){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 r(t,e){if(this.__eventListeners){var i=this.__eventListeners[t];if(i){for(var r=0,n=i.length;r-1},complexity:function(){return this.getObjects().reduce(function(t,e){return t+=e.complexity?e.complexity():0},0)}},fabric.CommonMethods={_setOptions:function(t){for(var e in t)this.set(e,t[e])},_initGradient:function(t,e){!t||!t.colorStops||t instanceof fabric.Gradient||this.set(e,new fabric.Gradient(t))},_initPattern:function(t,e,i){!t||!t.source||t instanceof fabric.Pattern?i&&i():this.set(e,new fabric.Pattern(t,i))},_initClipping:function(t){if(t.clipTo&&"string"==typeof t.clipTo){var e=fabric.util.getFunctionBody(t.clipTo);"undefined"!=typeof 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,r=Math.pow,n=Math.abs,s=Math.PI/180;fabric.util={removeFromArray:function(t,e){var i=t.indexOf(e);return i!==-1&&t.splice(i,1),t},getRandomInt:function(t,e){return Math.floor(Math.random()*(e-t+1))+t},degreesToRadians:function(t){return t*s},radiansToDegrees:function(t){return t/s},rotatePoint:function(t,e,i){t.subtractEquals(e);var r=fabric.util.rotateVector(t,i);return new fabric.Point(r.x,r.y).addEquals(e)},rotateVector:function(t,e){var i=Math.sin(e),r=Math.cos(e),n=t.x*r-t.y*i,s=t.x*i+t.y*r;return{x:n,y:s}},transformPoint:function(t,e,i){return i?new fabric.Point(e[0]*t.x+e[2]*t.y,e[1]*t.x+e[3]*t.y):new fabric.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=fabric.util.array.min(e),r=fabric.util.array.max(e),n=Math.abs(i-r),s=[t[0].y,t[1].y,t[2].y,t[3].y],o=fabric.util.array.min(s),a=fabric.util.array.max(s),h=Math.abs(o-a);return{left:i,top:o,width:n,height:h}},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]],r=fabric.util.transformPoint({x:t[4],y:t[5]},i,!0);return i[4]=-r.x,i[5]=-r.y,i},toFixed:function(t,e){return parseFloat(Number(t).toFixed(e))},parseUnit:function(t,e){var i=/\D{0,2}$/.exec(t),r=parseFloat(t);switch(e||(e=fabric.Text.DEFAULT_SVG_FONT_SIZE),i[0]){case"mm":return r*fabric.DPI/25.4;case"cm":return r*fabric.DPI/2.54;case"in":return r*fabric.DPI;case"pt":return r*fabric.DPI/72;case"pc":return r*fabric.DPI/72*12;case"em":return r*e;default:return r}},falseFunction:function(){return!1},getKlass:function(t,e){return t=fabric.util.string.camelize(t.charAt(0).toUpperCase()+t.slice(1)),fabric.util.resolveNamespace(e)[t]},resolveNamespace:function(e){if(!e)return fabric;var i,r=e.split("."),n=r.length,s=t||fabric.window;for(i=0;ir;)r+=a[d++%f],r>l&&(r=l),t[g?"lineTo":"moveTo"](r,0),g=!g;t.restore()},createCanvasElement:function(t){return t||(t=fabric.document.createElement("canvas")),t},createImage:function(){return fabric.document.createElement("img")},createAccessors:function(t){var e,i,r,n,s,o=t.prototype;for(e=o.stateProperties.length;e--;)i=o.stateProperties[e],r=i.charAt(0).toUpperCase()+i.slice(1),n="set"+r,s="get"+r,o[s]||(o[s]=function(t){return new Function('return this.get("'+t+'")')}(i)),o[n]||(o[n]=function(t){return new Function("value",'return this.set("'+t+'", value)')}(i))},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 n=i(t[1],t[0]),o=r(t[0],2)+r(t[1],2),a=e(o),h=(t[0]*t[3]-t[2]*t[1])/a,c=i(t[0]*t[2]+t[1]*t[3],o);return{angle:n/s,scaleX:a,scaleY:h,skewX:c/s,skewY:0,translateX:t[4],translateY:t[5]}},customTransformMatrix:function(t,e,i){var r=[1,0,n(Math.tan(i*s)),1],o=[n(t),0,0,n(e)];return fabric.util.multiplyTransformMatrices(o,r,!0)},resetObjectTransform:function(t){t.scaleX=1,t.scaleY=1,t.skewX=0,t.skewY=0,t.flipX=!1,t.flipY=!1,t.setAngle(0)},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,o=!0,a=t.getImageData(e,i,2*r||1,2*r||1),h=a.data.length;for(n=3;n0?A-=2*f:1===c&&A<0&&(A+=2*f);for(var M=Math.ceil(Math.abs(A/f*2)),L=[],I=A/M,F=8/3*Math.sin(I/4)*Math.sin(I/4)/Math.sin(I/2),R=P+I,B=0;B=n?s-n:2*Math.PI-(n-s)}function r(t,e,i,r,n,s,h,c){var l=a.call(arguments);if(o[l])return o[l];var u,f,d,g,p,v,m,b,_=Math.sqrt,y=Math.min,x=Math.max,C=Math.abs,S=[],T=[[],[]];f=6*t-12*i+6*n,u=-3*t+9*i-9*n+3*h,d=3*i-3*t;for(var w=0;w<2;++w)if(w>0&&(f=6*e-12*r+6*s,u=-3*e+9*r-9*s+3*c,d=3*r-3*e),C(u)<1e-12){if(C(f)<1e-12)continue;g=-d/f,0=e})}function i(t,e){return n(t,e,function(t,e){return t/g,">")}function r(t){for(var e,i=0,r=[],i=0;i57343)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}fabric.util.string={camelize:t,capitalize:e,escapeXml:i,graphemeSplit:r}}(),function(){function t(){}function e(t){for(var e=null,i=this;i.constructor.superclass;){var n=i.constructor.superclass.prototype[t];if(i[t]!==n){e=n;break}i=i.constructor.superclass.prototype}return e?arguments.length>1?e.apply(this,r.call(arguments,1)):e.call(this):console.log("tried to callSuper "+t+", method not found in prototype chain",this)}function i(){function i(){this.initialize.apply(this,arguments)}var s=null,a=r.call(arguments,0);"function"==typeof a[0]&&(s=a.shift()),i.superclass=s,i.subclasses=[],s&&(t.prototype=s.prototype,i.prototype=new t,s.subclasses.push(i));for(var h=0,c=a.length;h-1?t.prototype[r]=function(t){return function(){var r=this.constructor.superclass;this.constructor.superclass=i;var n=e[t].apply(this,arguments);if(this.constructor.superclass=r,"initialize"!==t)return n}}(r):t.prototype[r]=e[r],s&&(e.toString!==Object.prototype.toString&&(t.prototype.toString=e.toString),e.valueOf!==Object.prototype.valueOf&&(t.prototype.valueOf=e.valueOf))};fabric.util.createClass=i}(),function(){function t(t){var e,i,r=Array.prototype.slice.call(arguments,1),n=r.length;for(i=0;i-1?s(t,e.match(/opacity:\s*(\d?\.?\d*)/)[1]):t;for(var r in e)if("opacity"===r)s(t,e[r]);else{var n="float"===r||"cssFloat"===r?"undefined"==typeof i.styleFloat?"cssFloat":"styleFloat":r;i[n]=e[r]}return t}var e=fabric.document.createElement("div"),i="string"==typeof e.style.opacity,r="string"==typeof e.style.filter,n=/alpha\s*\(\s*opacity\s*=\s*([^\)]+)\)/,s=function(t){return t};i?s=function(t,e){return t.style.opacity=e,t}:r&&(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}),fabric.util.setStyle=t}(),function(){function t(t){return"string"==typeof t?fabric.document.getElementById(t):t}function e(t,e){var i=fabric.document.createElement(t);for(var r in e)"class"===r?i.className=e[r]:"for"===r?i.htmlFor=e[r]:i.setAttribute(r,e[r]);return i}function i(t,e){t&&(" "+t.className+" ").indexOf(" "+e+" ")===-1&&(t.className+=(t.className?" ":"")+e)}function r(t,i,r){return"string"==typeof i&&(i=e(i,r)),t.parentNode&&t.parentNode.replaceChild(i,t),i.appendChild(t),i}function n(t){for(var e=0,i=0,r=fabric.document.documentElement,n=fabric.document.body||{scrollLeft:0,scrollTop:0};t&&(t.parentNode||t.host)&&(t=t.parentNode||t.host,t===fabric.document?(e=n.scrollLeft||r.scrollLeft||0,i=n.scrollTop||r.scrollTop||0):(e+=t.scrollLeft||0,i+=t.scrollTop||0),1!==t.nodeType||"fixed"!==fabric.util.getElementStyle(t,"position")););return{left:e,top:i}}function s(t){var e,i,r=t&&t.ownerDocument,s={left:0,top:0},o={left:0,top:0},a={borderLeftWidth:"left",borderTopWidth:"top",paddingLeft:"left",paddingTop:"top"};if(!r)return o;for(var h in a)o[a[h]]+=parseInt(c(t,h),10)||0;return e=r.documentElement,"undefined"!=typeof t.getBoundingClientRect&&(s=t.getBoundingClientRect()),i=n(t),{left:s.left+i.left-(e.clientLeft||0)+o.left,top:s.top+i.top-(e.clientTop||0)+o.top}}var o,a=Array.prototype.slice,h=function(t){return a.call(t,0)};try{o=h(fabric.document.childNodes)instanceof Array}catch(t){}o||(h=function(t){for(var e=new Array(t.length),i=t.length;i--;)e[i]=t[i];return e});var c;c=fabric.document.defaultView&&fabric.document.defaultView.getComputedStyle?function(t,e){var i=fabric.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(){function t(t){return"undefined"!=typeof t.onselectstart&&(t.onselectstart=fabric.util.falseFunction),r?t.style[r]="none":"string"==typeof t.unselectable&&(t.unselectable="on"),t}function e(t){return"undefined"!=typeof t.onselectstart&&(t.onselectstart=null),r?t.style[r]="":"string"==typeof t.unselectable&&(t.unselectable=""),t}var i=fabric.document.documentElement.style,r="userSelect"in i?"userSelect":"MozUserSelect"in i?"MozUserSelect":"WebkitUserSelect"in i?"WebkitUserSelect":"KhtmlUserSelect"in i?"KhtmlUserSelect":"";fabric.util.makeElementUnselectable=t,fabric.util.makeElementSelectable=e}(),function(){function t(t,e){var i=fabric.document.getElementsByTagName("head")[0],r=fabric.document.createElement("script"),n=!0;r.onload=r.onreadystatechange=function(t){if(n){if("string"==typeof this.readyState&&"loaded"!==this.readyState&&"complete"!==this.readyState)return;n=!1,e(t||fabric.window.event),r=r.onload=r.onreadystatechange=null}},r.src=t,i.appendChild(r)}fabric.util.getScript=t}(),fabric.util.getById=t,fabric.util.toArray=h,fabric.util.makeElement=e,fabric.util.addClass=i,fabric.util.wrapElement=r,fabric.util.getScrollLeftTop=n,fabric.util.getElementOffset=s,fabric.util.getElementStyle=c}(),function(){function t(t,e){return t+(/\?/.test(t)?"&":"?")+e}function e(){}function i(i,n){n||(n={});var s=n.method?n.method.toUpperCase():"GET",o=n.onComplete||function(){},a=r(),h=n.body||n.parameters;return a.onreadystatechange=function(){4===a.readyState&&(o(a),a.onreadystatechange=e)},"GET"===s&&(h=null,"string"==typeof n.parameters&&(i=t(i,n.parameters))),a.open(s,i,!0),"POST"!==s&&"PUT"!==s||a.setRequestHeader("Content-Type","application/x-www-form-urlencoded"),a.send(h),a}var r=function(){for(var t=[function(){return new ActiveXObject("Microsoft.XMLHTTP")},function(){return new ActiveXObject("Msxml2.XMLHTTP")},function(){return new ActiveXObject("Msxml2.XMLHTTP.3.0")},function(){return new XMLHttpRequest}],e=t.length;e--;)try{var i=t[e]();if(i)return t[e]}catch(t){}}();fabric.util.request=i}(),fabric.log=function(){},fabric.warn=function(){},"undefined"!=typeof console&&["log","warn"].forEach(function(t){"undefined"!=typeof console[t]&&"function"==typeof console[t].apply&&(fabric[t]=function(){return console[t].apply(console,arguments)})}),function(){function t(t){e(function(i){t||(t={});var r,n=i||+new Date,s=t.duration||500,o=n+s,a=t.onChange||function(){},h=t.abort||function(){return!1},c=t.easing||function(t,e,i,r){return-i*Math.cos(t/r*(Math.PI/2))+i+e},l="startValue"in t?t.startValue:0,u="endValue"in t?t.endValue:100,f=t.byValue||u-l;t.onStart&&t.onStart(),function i(u){r=u||+new Date;var d=r>o?s:r-n;return h()?void(t.onComplete&&t.onComplete()):(a(c(d,l,f,s)),r>o?void(t.onComplete&&t.onComplete()):void e(i))}(n)})}function e(){return i.apply(fabric.window,arguments)}var i=fabric.window.requestAnimationFrame||fabric.window.webkitRequestAnimationFrame||fabric.window.mozRequestAnimationFrame||fabric.window.oRequestAnimationFrame||fabric.window.msRequestAnimationFrame||function(t){fabric.window.setTimeout(t,1e3/60)};fabric.util.animate=t,fabric.util.requestAnimFrame=e}(),function(){function t(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+=")"}function e(e,i,r,n){var s=new fabric.Color(e).getSource(),o=new fabric.Color(i).getSource();n=n||{},fabric.util.animate(fabric.util.object.extend(n,{duration:r||500,startValue:s,endValue:o,byValue:o,easing:function(e,i,r,s){var o=n.colorEasing?n.colorEasing(e,s):1-Math.cos(e/s*(Math.PI/2));return t(i,r,o)}}))}fabric.util.animateColor=e}(),function(){function t(t,e,i,r){return ta?a:o),1===o&&1===a&&0===h&&0===c&&0===f&&0===d)return y;if((f||d)&&(x=" translate("+_(f)+" "+_(d)+") "),r=x+" matrix("+o+" 0 0 "+a+" "+h*o+" "+c*a+") ","svg"===t.nodeName){for(n=t.ownerDocument.createElement("g");t.firstChild;)n.appendChild(t.firstChild);t.appendChild(n)}else n=t,r=n.getAttribute("transform")+r;return n.setAttribute("transform",r),y}function g(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}var p=t.fabric||(t.fabric={}),v=p.util.object.extend,m=p.util.object.clone,b=p.util.toFixed,_=p.util.parseUnit,y=p.util.multiplyTransformMatrices,x=/^(path|circle|polygon|polyline|ellipse|rect|line|image|text)$/i,C=/^(symbol|image|marker|pattern|view|svg)$/i,S=/^(?:pattern|defs|symbol|metadata|clipPath|mask)$/i,T=/^(symbol|g|a|svg)$/i,w={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","stroke-dasharray":"strokeDashArray","stroke-linecap":"strokeLineCap","stroke-linejoin":"strokeLineJoin","stroke-miterlimit":"strokeMiterLimit", -"stroke-opacity":"strokeOpacity","stroke-width":"strokeWidth","text-decoration":"textDecoration","text-anchor":"originX",opacity:"opacity"},O={stroke:"strokeOpacity",fill:"fillOpacity"};p.cssRules={},p.gradientDefs={},p.parseTransformAttribute=function(){function t(t,e){var i=Math.cos(e[0]),r=Math.sin(e[0]),n=0,s=0;3===e.length&&(n=e[1],s=e[2]),t[0]=i,t[1]=r,t[2]=-r,t[3]=i,t[4]=n-(i*n-r*s),t[5]=s-(r*n+i*s)}function e(t,e){var i=e[0],r=2===e.length?e[1]:e[0];t[0]=i,t[3]=r}function i(t,e,i){t[i]=Math.tan(p.util.degreesToRadians(e[0]))}function r(t,e){t[4]=e[0],2===e.length&&(t[5]=e[1])}var n=[1,0,0,1,0,0],s=p.reNum,o="(?:\\s+,?\\s*|,\\s*)",a="(?:(skewX)\\s*\\(\\s*("+s+")\\s*\\))",h="(?:(skewY)\\s*\\(\\s*("+s+")\\s*\\))",c="(?:(rotate)\\s*\\(\\s*("+s+")(?:"+o+"("+s+")"+o+"("+s+"))?\\s*\\))",l="(?:(scale)\\s*\\(\\s*("+s+")(?:"+o+"("+s+"))?\\s*\\))",u="(?:(translate)\\s*\\(\\s*("+s+")(?:"+o+"("+s+"))?\\s*\\))",f="(?:(matrix)\\s*\\(\\s*("+s+")"+o+"("+s+")"+o+"("+s+")"+o+"("+s+")"+o+"("+s+")"+o+"("+s+")\\s*\\))",d="(?:"+f+"|"+u+"|"+l+"|"+c+"|"+a+"|"+h+")",g="(?:"+d+"(?:"+o+"*"+d+")*)",v="^\\s*(?:"+g+"?)\\s*$",m=new RegExp(v),b=new RegExp(d,"g");return function(s){var o=n.concat(),a=[];if(!s||s&&!m.test(s))return o;s.replace(b,function(s){var h=new RegExp(d).exec(s).filter(function(t){return!!t}),c=h[1],l=h.slice(2).map(parseFloat);switch(c){case"translate":r(o,l);break;case"rotate":l[0]=p.util.degreesToRadians(l[0]),t(o,l);break;case"scale":e(o,l);break;case"skewX":i(o,l,2);break;case"skewY":i(o,l,1);break;case"matrix":o=l}a.push(o.concat()),o=n.concat()});for(var h=a[0];a.length>1;)a.shift(),h=p.util.multiplyTransformMatrices(h,a[0]);return h}}();var k=new RegExp("^\\s*("+p.reNum+"+)\\s*,?\\s*("+p.reNum+"+)\\s*,?\\s*("+p.reNum+"+)\\s*,?\\s*("+p.reNum+"+)\\s*$");p.parseSVGDocument=function(t,e,i,r){if(t){f(t);var n=p.Object.__uid++,s=d(t),o=p.util.toArray(t.getElementsByTagName("*"));if(s.crossOrigin=r&&r.crossOrigin,s.svgUid=n,0===o.length&&p.isLikelyNode){o=t.selectNodes('//*[name(.)!="svg"]');for(var a=[],h=0,c=o.length;h/i,""))),n&&n.documentElement||e&&e(null),p.parseSVGDocument(n.documentElement,function(t,i){e&&e(t,i)},i,r)}t=t.replace(/^\n\s*/,"").trim(),new p.util.request(t,{method:"get",onComplete:n})},loadSVGFromString:function(t,e,i,r){t=t.trim();var n;if("undefined"!=typeof DOMParser){var s=new DOMParser;s&&s.parseFromString&&(n=s.parseFromString(t,"text/xml"))}else p.window.ActiveXObject&&(n=new ActiveXObject("Microsoft.XMLDOM"),n.async="false",n.loadXML(t.replace(//i,"")));p.parseSVGDocument(n.documentElement,function(t,i){e(t,i)},i,r)}})}("undefined"!=typeof exports?exports:this),fabric.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},fabric.ElementsParser.prototype.parse=function(){this.instances=new Array(this.elements.length),this.numElements=this.elements.length,this.createObjects()},fabric.ElementsParser.prototype.createObjects=function(){for(var t=0,e=this.elements.length;tt.x&&this.y>t.y},gte:function(t){return this.x>=t.x&&this.y>=t.y},lerp:function(t,i){return"undefined"==typeof i&&(i=.5),i=Math.max(Math.min(1,i),0),new e(this.x+(t.x-this.x)*i,this.y+(t.y-this.y)*i)},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 e(Math.min(this.x,t.x),Math.min(this.y,t.y))},max:function(t){return new e(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 e(this.x,this.y)}}))}("undefined"!=typeof exports?exports:this),function(t){"use strict";function e(t){this.status=t,this.points=[]}var i=t.fabric||(t.fabric={});return i.Intersection?void i.warn("fabric.Intersection is already defined"):(i.Intersection=e,i.Intersection.prototype={constructor:e,appendPoint:function(t){return this.points.push(t),this},appendPoints:function(t){return this.points=this.points.concat(t),this}},i.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 e("Intersection"),o.appendPoint(new i.Point(t.x+l*(r.x-t.x),t.y+l*(r.y-t.y)))):o=new e}else o=new e(0===a||0===h?"Coincident":"Parallel");return o},i.Intersection.intersectLinePolygon=function(t,i,r){for(var n,s,o,a=new e,h=r.length,c=0;c0&&(a.status="Intersection"),a},i.Intersection.intersectPolygonPolygon=function(t,i){for(var r=new e,n=t.length,s=0;s0&&(r.status="Intersection"),r},void(i.Intersection.intersectPolygonRectangle=function(t,r,n){var s=r.min(n),o=r.max(n),a=new i.Point(o.x,s.y),h=new i.Point(s.x,o.y),c=e.intersectLinePolygon(s,a,t),l=e.intersectLinePolygon(a,o,t),u=e.intersectLinePolygon(o,h,t),f=e.intersectLinePolygon(h,s,t),d=new e;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}))}("undefined"!=typeof exports?exports:this),function(t){"use strict";function e(t){t?this._tryParsingColor(t):this.setSource([0,0,0,1])}function i(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}var r=t.fabric||(t.fabric={});return r.Color?void r.warn("fabric.Color is already defined."):(r.Color=e,r.Color.prototype={_tryParsingColor:function(t){var i;t in e.colorNameMap&&(t=e.colorNameMap[t]),"transparent"===t&&(i=[255,255,255,0]),i||(i=e.sourceFromHex(t)),i||(i=e.sourceFromRgb(t)),i||(i=e.sourceFromHsl(t)),i||(i=[0,0,0,1]),i&&this.setSource(i)},_rgbToHsl:function(t,e,i){t/=255,e/=255,i/=255;var n,s,o,a=r.util.array.max([t,e,i]),h=r.util.array.min([t,e,i]);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=(e-i)/c+(e1?1:s,n){var o=n.split(/\s*;\s*/);""===o[o.length-1]&&o.pop();for(var a=o.length;a--;){var h=o[a].split(/\s*:\s*/),c=h[0].trim(),l=h[1].trim();"stop-color"===c?e=l:"stop-opacity"===c&&(r=l)}}return e||(e=t.getAttribute("stop-color")||"rgb(0,0,0)"),r||(r=t.getAttribute("stop-opacity")),e=new fabric.Color(e),i=e.getAlpha(),r=isNaN(parseFloat(r))?1:parseFloat(r),r*=i,{offset:s,color:e.toRgb(),opacity:r}}function e(t){return{x1:t.getAttribute("x1")||0,y1:t.getAttribute("y1")||0,x2:t.getAttribute("x2")||"100%",y2:t.getAttribute("y2")||0}}function i(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%"}}function r(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+%$/.test(e[a])?.01:1,"x1"===a||"x2"===a||"r2"===a?(s*="objectBoundingBox"===i?t.width:1,n="objectBoundingBox"===i?t.left||0:0):"y1"!==a&&"y2"!==a||(s*="objectBoundingBox"===i?t.height:1,n="objectBoundingBox"===i?t.top||0: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}var n=fabric.util.object.clone;fabric.Gradient=fabric.util.createClass({offsetX:0,offsetY:0,initialize:function(t){t||(t={});var e={};this.id=fabric.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 fabric.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 fabric.util.populateWithProperties(this,e,t),e},toSVG:function(t){var e,i,r=n(this.coords,!0),s=n(this.colorStops,!0),o=r.r1>r.r2;s.sort(function(t,e){return t.offset-e.offset});for(var a in r)"x1"===a||"x2"===a?r[a]+=this.offsetX-t.width/2:"y1"!==a&&"y2"!==a||(r[a]+=this.offsetY-t.height/2);if(i='id="SVGID_'+this.id+'" gradientUnits="userSpaceOnUse"',this.gradientTransform&&(i+=' gradientTransform="matrix('+this.gradientTransform.join(" ")+')" '),"linear"===this.type?e=["\n']:"radial"===this.type&&(e=["\n']),"radial"===this.type){if(o){s=s.concat(),s.reverse();for(var h=0;h0)for(var l=Math.max(r.r1,r.r2),u=c/l,h=0;h\n')}return e.push("linear"===this.type?"\n":"\n"),e.join("")},toLive:function(t){var e,i=fabric.util.object.clone(this.coords);if(this.type){"linear"===this.type?e=t.createLinearGradient(i.x1,i.y1,i.x2,i.y2):"radial"===this.type&&(e=t.createRadialGradient(i.x1,i.y1,i.r1,i.x2,i.y2,i.r2));for(var r=0,n=this.colorStops.length;r\n\n\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("undefined"!=typeof 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;return e.Shadow?void 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,initialize:function(t){"string"==typeof t&&(t=this._parseShadow(t));for(var i in t)this[i]=t[i];this.id=e.Object.__uid++},_parseShadow:function(t){var i=t.trim(),r=e.Shadow.reOffsetsAndBlur.exec(i)||[],n=i.replace(e.Shadow.reOffsetsAndBlur,"")||"rgb(0,0,0)";return{color:n.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=20;return t.width&&t.height&&(r=100*i((Math.abs(o.x)+this.blur)/t.width,s)+a,n=100*i((Math.abs(o.y)+this.blur)/t.height,s)+a),t.flipX&&(o.x*=-1),t.flipY&&(o.y*=-1),'\n\t\n\t\n\t\n\t\n\t\n\t\t\n\t\t\n\t\n\n'},toObject:function(){if(this.includeDefaultValues)return{color:this.color,blur:this.blur,offsetX:this.offsetX,offsetY:this.offsetY,affectStroke:this.affectStroke};var t={},i=e.Shadow.prototype;return["color","blur","offsetX","offsetY","affectStroke"].forEach(function(e){this[e]!==i[e]&&(t[e]=this[e])},this),t}}),void(e.Shadow.reOffsetsAndBlur=/(?:\s|^)(-?\d+(?:px)?(?:\s?|$))?(-?\d+(?:px)?(?:\s?|$))?(\d+(?:px)?)?(?:\s?|$)(?:$|\s)/))}("undefined"!=typeof exports?exports:this),function(){"use strict";if(fabric.StaticCanvas)return void fabric.warn("fabric.StaticCanvas is already defined.");var t=fabric.util.object.extend,e=fabric.util.getElementOffset,i=fabric.util.removeFromArray,r=fabric.util.toFixed,n=fabric.util.transformPoint,s=fabric.util.invertTransform,o=new Error("Could not initialize `canvas` element");fabric.StaticCanvas=fabric.util.createClass(fabric.CommonMethods,{initialize:function(t,e){e||(e={}),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:fabric.iMatrix.concat(),backgroundVpt:!0,overlayVpt:!0,onBeforeScaleRotate:function(){},enableRetinaScaling:!0,vptCoords:{},skipOffscreen:!0,_initStatic:function(t,e){var i=fabric.StaticCanvas.prototype.renderAll.bind(this);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!==fabric.devicePixelRatio&&this.enableRetinaScaling},getRetinaScaling:function(){return this._isRetinaScaling()?fabric.devicePixelRatio:1},_initRetinaScaling:function(){this._isRetinaScaling()&&(this.lowerCanvasEl.setAttribute("width",this.width*fabric.devicePixelRatio),this.lowerCanvasEl.setAttribute("height",this.height*fabric.devicePixelRatio),this.contextContainer.scale(fabric.devicePixelRatio,fabric.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,r){return"string"==typeof e?fabric.util.loadImage(e,function(e){e&&(this[t]=new fabric.Image(e,r)),i&&i(e)},this,r&&r.crossOrigin):(r&&e.setOptions(r),this[t]=e,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(t){var e=fabric.util.createCanvasElement(t);if(e.style||(e.style={}),!e)throw o;if("undefined"==typeof e.getContext)throw o;return e},_initOptions:function(t){this._setOptions(t),this.width=this.width||parseInt(this.lowerCanvasEl.width,10)||0,this.height=this.height||parseInt(this.lowerCanvasEl.height,10)||0,this.lowerCanvasEl.style&&(this.lowerCanvasEl.width=this.width,this.lowerCanvasEl.height=this.height,this.lowerCanvasEl.style.width=this.width+"px",this.lowerCanvasEl.style.height=this.height+"px",this.viewportTransform=this.viewportTransform.slice())},_createLowerCanvas:function(t){this.lowerCanvasEl=fabric.util.getById(t)||this._createCanvasElement(t),fabric.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;e=e||{};for(var r in t)i=t[r],e.cssOnly||(this._setBackstoreDimension(r,t[r]),i+="px"),e.backstoreOnly||this._setCssDimension(r,i);return this._initRetinaScaling(),this._setImageSmoothing(),this.calcOffset(),e.cssOnly||this.renderAll(),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=this._activeGroup,r=!1,n=!0;this.viewportTransform=t;for(var s=0,o=this._objects.length;s"),i.join("")},_setSVGPreamble:function(t,e){e.suppressPreamble||t.push('\n','\n')},_setSVGHeader:function(t,e){var i,n=e.width||this.width,s=e.height||this.height,o='viewBox="0 0 '+this.width+" "+this.height+'" ',a=fabric.Object.NUM_FRACTION_DIGITS;e.viewBox?o='viewBox="'+e.viewBox.x+" "+e.viewBox.y+" "+e.viewBox.width+" "+e.viewBox.height+'" ':this.svgViewportTransformation&&(i=this.viewportTransform,o='viewBox="'+r(-i[4]/i[0],a)+" "+r(-i[5]/i[3],a)+" "+r(this.width/i[0],a)+" "+r(this.height/i[3],a)+'" '),t.push("\n',"Created with Fabric.js ",fabric.version,"\n","\n",this.createSVGFontFacesMarkup(),this.createSVGRefElementsMarkup(),"\n")},createSVGRefElementsMarkup:function(){var t=this,e=["backgroundColor","overlayColor"].map(function(e){var i=t[e];if(i&&i.toLive)return i.toSVG(t,!1)});return e.join("")},createSVGFontFacesMarkup:function(){for(var t,e,i,r,n,s,o,a="",h={},c=fabric.fontPaths,l=this.getObjects(),u=0,f=l.length;u',"\n",a,"","\n"].join("")),a},_setSVGObjects:function(t,e){for(var i,r=0,n=this.getObjects(),s=n.length;r\n")}else t.push('\n")},sendToBack:function(t){if(!t)return this;var e,r,n,s=this._activeGroup;if(t===s)for(n=s._objects,e=n.length;e--;)r=n[e],i(this._objects,r),this._objects.unshift(r);else i(this._objects,t),this._objects.unshift(t);return this.renderAll&&this.renderAll()},bringToFront:function(t){if(!t)return this;var e,r,n,s=this._activeGroup;if(t===s)for(n=s._objects,e=0;e=0;--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},bringForward:function(t,e){if(!t)return this;var r,n,s,o,a,h=this._activeGroup;if(t===h)for(a=h._objects,r=a.length;r--;)n=a[r],s=this._objects.indexOf(n),s!==this._objects.length-1&&(o=s+1,i(this._objects,n),this._objects.splice(o,0,n));else s=this._objects.indexOf(t),s!==this._objects.length-1&&(o=this._findNewUpperIndex(t,s,e),i(this._objects,t),this._objects.splice(o,0,t));return this.renderAll&&this.renderAll(),this},_findNewUpperIndex:function(t,e,i){var r;if(i){r=e;for(var n=e+1;n"}}),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;n0?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&&cs?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)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._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;i1)){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||!e.selectable)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))},_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)1&&(e=new fabric.Group(e.reverse(),{canvas:this}),e.addWithUpdate(),this.setActiveGroup(e,t),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);this.clear();var n=this;return this._enlivenObjects(r.objects,function(){n._setBgOverlay(r,function(){delete r.objects,delete r.backgroundImage,delete r.overlayImage,delete r.background,delete r.overlay,n._setOptions(r),e&&e()})},i),this}},_setBgOverlay:function(t,e){var i=this,r={backgroundColor:!1,overlayColor:!1,backgroundImage:!1,overlayImage:!1};if(!(t.backgroundImage||t.overlayImage||t.background||t.overlay))return void(e&&e());var n=function(){r.backgroundImage&&r.overlayImage&&r.backgroundColor&&r.overlayColor&&(i.renderAll(),e&&e())};this.__setBgOverlay("backgroundImage",t.backgroundImage,r,n),this.__setBgOverlay("overlayImage",t.overlayImage,r,n),this.__setBgOverlay("backgroundColor",t.background,r,n),this.__setBgOverlay("overlayColor",t.overlay,r,n)},__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){var r=this;if(!t||0===t.length)return void(e&&e());var n=this.renderOnAddRemove;this.renderOnAddRemove=!1,fabric.util.enlivenObjects(t,function(t){t.forEach(function(t,e){r.insertAt(t,e)}),r.renderOnAddRemove=n,e&&e()},null,i)},_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;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,strokeLineCap:"butt",strokeLineJoin:"miter",strokeMiterLimit:10,shadow:null,borderOpacityWhenMoving:.4,borderScaleFactor:1,transformMatrix:null,minScaleLimit:.01,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,dirty:!0,needsItsOwnCache:!1,stateProperties:"top left width height scaleX scaleY flipX flipY originX originY transformMatrix stroke strokeWidth strokeDashArray strokeLineCap strokeLineJoin strokeMiterLimit angle opacity fill fillRule globalCompositeOperation shadow clipTo visible backgroundColor skewX skewY".split(" "),cacheProperties:"fill stroke strokeWidth strokeDashArray width height stroke strokeWidth strokeDashArray strokeLineCap strokeLineJoin strokeMiterLimit fillRule backgroundColor".split(" "),initialize:function(t){t=t||{},t&&this.setOptions(t),this.objectCaching&&this._createCacheCanvas()},_createCacheCanvas:function(){this._cacheProperties={},this._cacheCanvas=e.document.createElement("canvas"),this._cacheContext=this._cacheCanvas.getContext("2d"),this._updateCacheCanvas()},_getCacheCanvasDimensions:function(){var t=this.canvas&&this.canvas.getZoom()||1,i=this.getObjectScaling(),r=this._getNonTransformedDimensions(),n=this.canvas&&this.canvas._isRetinaScaling()?e.devicePixelRatio:1,s=i.scaleX*t*n,o=i.scaleY*t*n,a=r.x*s,h=r.y*o;return{width:a+2,height:h+2,zoomX:s,zoomY:o}},_updateCacheCanvas:function(){if(this.noScaleCache&&this.canvas&&this.canvas._currentTransform){var t=this.canvas._currentTransform.action;if("scale"===t.slice(0,5))return!1}var e=this._getCacheCanvasDimensions(),i=e.width,r=e.height,n=e.zoomX,s=e.zoomY;return(i!==this.cacheWidth||r!==this.cacheHeight)&&(this._cacheCanvas.width=Math.ceil(i),this._cacheCanvas.height=Math.ceil(r),this._cacheContext.translate(i/2,r/2),this._cacheContext.scale(n,s),this.cacheWidth=i,this.cacheHeight=r,this.zoomX=n,this.zoomY=s,!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,e){this.group&&!this.group._transformDone&&this.group.transform(t);var i=e?this._getLeftTopCoords():this.getCenterPoint();t.translate(i.x,i.y),this.angle&&t.rotate(o(this.angle)),t.scale(this.scaleX*(this.flipX?-1:1),this.scaleY*(this.flipY?-1:1)),this.skewX&&t.transform(1,0,Math.tan(o(this.skewX)),1,0,0),this.skewY&&t.transform(1,Math.tan(o(this.skewY)),0,1,0,0)},toObject:function(t){var i=e.Object.NUM_FRACTION_DIGITS,r={type:this.type,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,strokeLineJoin:this.strokeLineJoin,strokeMiterLimit:n(this.strokeMiterLimit,i),scaleX:n(this.scaleX,i),scaleY:n(this.scaleY,i),angle:n(this.getAngle(),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,globalCompositeOperation:this.globalCompositeOperation,transformMatrix:this.transformMatrix?this.transformMatrix.concat():null,skewX:n(this.skewX,i),skewY:n(this.skewY,i)};return 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,r=i.stateProperties;return r.forEach(function(e){t[e]===i[e]&&delete t[e];var r="[object Array]"===Object.prototype.toString.call(t[e])&&"[object Array]"===Object.prototype.toString.call(i[e]);r&&0===t[e].length&&0===i[e].length&&delete t[e]}),t},toString:function(){return"#"},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}},getObjectOpacity:function(){var t=this.opacity;return this.group&&(t*=this.group.getObjectOpacity()),t},_set:function(t,i){var r="scaleX"===t||"scaleY"===t;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,this.cacheProperties.indexOf(t)>-1&&(this.group&&this.group.set("dirty",!0),this.dirty=!0),this.group&&this.stateProperties.indexOf(t)>-1&&this.group.set("dirty",!0),"width"!==t&&"height"!==t||(this.minScaleLimit=Math.min(.1,1/Math.max(this.width,this.height))),this},setOnGroup:function(){},getViewportTransform:function(){return this.canvas&&this.canvas.viewportTransform?this.canvas.viewportTransform:e.iMatrix.concat()},render:function(t){0===this.width&&0===this.height||!this.visible||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._cacheCanvas||this._createCacheCanvas(),this.isCacheDirty()&&(this.statefullCache&&this.saveState({propertySet:"cacheProperties"}),this.drawObject(this._cacheContext),this.dirty=!1),this.drawCacheOnCanvas(t)):(this.drawObject(t),this.objectCaching&&this.statefullCache&&this.saveState({propertySet:"cacheProperties"})),this.clipTo&&t.restore(),t.restore())},shouldCache:function(){return this.objectCaching&&(!this.group||this.needsItsOwnCache||!this.group.isCaching())},willDrawShadow:function(){return!!this.shadow},drawObject:function(t){this._renderBackground(t),this._setStrokeStyles(t,this),this._setFillStyles(t,this),this._render(t)},drawCacheOnCanvas:function(t){t.scale(1/this.zoomX,1/this.zoomY),t.drawImage(this._cacheCanvas,-this.cacheWidth/2,-this.cacheHeight/2)},isCacheDirty:function(t){if(!t&&this._updateCacheCanvas())return!0;if(this.dirty||this.statefullCache&&this.hasStateChanged("cacheProperties")){if(!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.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)},_setLineDash:function(t,e,i){e&&(1&e.length&&e.push.apply(e,e),a?t.setLineDash(e):i&&i(t))},_renderControls:function(t,i){var r,n=this.getViewportTransform(),s=this.calcTransformMatrix();i=i||{},s=e.util.multiplyTransformMatrices(n,s),r=e.util.qrDecompose(s),t.save(),t.translate(r.translateX,r.translateY),t.lineWidth=1*this.borderScaleFactor,this.group||(t.globalAlpha=this.isMoving?this.borderOpacityWhenMoving:1),this.group&&this.group===this.canvas.getActiveGroup()?(t.rotate(o(r.angle)),(this.hasBorders||i.hasBorders)&&this.drawBordersInGroup(t,r,i)):(t.rotate(o(this.angle)),(this.hasBorders||i.hasBorders)&&this.drawBorders(t,i)),(this.hasControls||i.hasControls)&&this.drawControls(t,i),t.restore()},_setShadow:function(t){if(this.shadow){var i=this.canvas&&this.canvas.viewportTransform[0]||1,r=this.canvas&&this.canvas.viewportTransform[3]||1,n=this.getObjectScaling();this.canvas&&this.canvas._isRetinaScaling()&&(i*=e.devicePixelRatio,r*=e.devicePixelRatio),t.shadowColor=this.shadow.color,t.shadowBlur=this.shadow.blur*(i+r)*(n.scaleX+n.scaleY)/4,t.shadowOffsetX=this.shadow.offsetX*i*n.scaleX,t.shadowOffsetY=this.shadow.offsetY*r*n.scaleY}},_removeShadow:function(t){this.shadow&&(t.shadowColor="",t.shadowBlur=t.shadowOffsetX=t.shadowOffsetY=0)},_applyPatternGradientTransform:function(t,e){if(e.toLive){var i=e.gradientTransform||e.patternTransform,r=-this.width/2+e.offsetX||0,n=-this.height/2+e.offsetY||0;t.translate(r,n),i&&t.transform.apply(t,i)}},_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._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}},_removeTransformMatrix:function(){var t=this._findCenterFromElement();if(this.transformMatrix){var i=e.util.qrDecompose(this.transformMatrix);this.flipX=!1,this.flipY=!1,this.set("scaleX",i.scaleX),this.set("scaleY",i.scaleY),this.angle=i.angle,this.skewX=i.skewX,this.skewY=0,t=e.util.transformPoint(t,this.transformMatrix)}this.transformMatrix=null,this.setPositionByOrigin(t,"center","center")},clone:function(t,i){return this.constructor.fromObject?this.constructor.fromObject(this.toObject(i),t):new e.Object(this.toObject(i))},cloneAsImage:function(t,i){var r=this.toDataURL(i);return e.util.loadImage(r,function(i){t&&t(new e.Image(i))}),this},toDataURL:function(t){t||(t={});var i=e.util.createCanvasElement(),r=this.getBoundingRect();i.width=r.width,i.height=r.height,e.util.wrapElement(i,"div");var n=new e.StaticCanvas(i,{enableRetinaScaling:t.enableRetinaScaling});"jpg"===t.format&&(t.format="jpeg"),"jpeg"===t.format&&(n.backgroundColor="#fff");var s={active:this.get("active"),left:this.getLeft(),top:this.getTop()};this.set("active",!1),this.setPositionByOrigin(new e.Point(n.getWidth()/2,n.getHeight()/2),"center","center");var o=this.canvas;n.add(this);var a=n.toDataURL(t);return this.set(s).setCoords(),this.canvas=o,n.dispose(),n=null,a},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){return this.set("fill",new e.Pattern(t))},setShadow:function(t){return this.set("shadow",t?new e.Shadow(t):null)},setColor:function(t){return this.set("fill",t),this},setAngle: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},remove:function(){return this.canvas&&this.canvas.remove(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.Object),e.Object.prototype.rotate=e.Object.prototype.setAngle,i(e.Object.prototype,e.Observable),e.Object.NUM_FRACTION_DIGITS=2,e.Object._fromObject=function(t,i,n,s,o){var a=e[t];if(i=r(i,!0),!s){var h=o?new a(i[o],i):new a(i);return n&&n(h),h}e.util.enlivenPatterns([i.fill,i.stroke],function(t){"undefined"!=typeof t[0]&&(i.fill=t[0]),"undefined"!=typeof t[1]&&(i.stroke=t[1]);var e=o?new a(i[o],i):new a(i);n&&n(e)})},e.Object.__uid=0)}("undefined"!=typeof exports?exports:this),function(){var t=fabric.util.degreesToRadians,e={left:-.5,center:0,right:.5},i={top:-.5,center:0,bottom:.5};fabric.util.object.extend(fabric.Object.prototype,{translateToGivenOrigin:function(t,r,n,s,o){var a,h,c,l=t.x,u=t.y;return"string"==typeof r?r=e[r]:r-=.5,"string"==typeof s?s=e[s]:s-=.5,a=s-r,"string"==typeof n?n=i[n]:n-=.5,"string"==typeof o?o=i[o]:o-=.5,h=o-n,(a||h)&&(c=this._getTransformedDimensions(),l=t.x+a*c.x,u=t.y+h*c.y),new fabric.Point(l,u)},translateToCenterPoint:function(e,i,r){var n=this.translateToGivenOrigin(e,i,r,"center","center");return this.angle?fabric.util.rotatePoint(n,e,t(this.angle)):n},translateToOriginPoint:function(e,i,r){var n=this.translateToGivenOrigin(e,"center","center",i,r);return this.angle?fabric.util.rotatePoint(n,e,t(this.angle)):n},getCenterPoint:function(){var t=new fabric.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,r){var n,s,o=this.getCenterPoint();return n="undefined"!=typeof i&&"undefined"!=typeof r?this.translateToGivenOrigin(o,"center","center",i,r):new fabric.Point(this.left,this.top),s=new fabric.Point(e.x,e.y),this.angle&&(s=fabric.util.rotatePoint(s,o,-t(this.angle))),s.subtractEquals(n)},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 r,n,s=t(this.angle),o=this.getWidth(),a=Math.cos(s)*o,h=Math.sin(s)*o;r="string"==typeof this.originX?e[this.originX]:this.originX-.5,n="string"==typeof i?e[i]:i-.5,this.left+=a*(n-r),this.top+=h*(n-r),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")},onDeselect:function(){}})}(),function(){function t(t){return[new fabric.Point(t.tl.x,t.tl.y),new fabric.Point(t.tr.x,t.tr.y),new fabric.Point(t.br.x,t.br.y),new fabric.Point(t.bl.x,t.bl.y)]}var e=fabric.util.degreesToRadians,i=fabric.util.multiplyTransformMatrices;fabric.util.object.extend(fabric.Object.prototype,{oCoords:null,aCoords:null,getCoords:function(e,i){this.oCoords||this.setCoords();var r=e?this.aCoords:this.oCoords;return t(i?this.calcCoords(e):r)},intersectsWithRect:function(t,e,i,r){var n=this.getCoords(i,r),s=fabric.Intersection.intersectPolygonRectangle(n,t,e);return"Intersection"===s.status},intersectsWithObject:function(t,e,i){var r=fabric.Intersection.intersectPolygonPolygon(this.getCoords(e,i),t.getCoords(e,i));return"Intersection"===r.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){var e=e||this._getImageLines(r?this.calcCoords(i):i?this.aCoords:this.oCoords),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],e.x<=r.x&&e.x>=i.x&&e.y<=r.y&&e.y>=i.y)return!0;if(this.intersectsWithRect(i,r,!0))return!0;var o={x:(i.x+r.x)/2,y:(i.y+r.y)/2};return!!this.containsPoint(o,null,!0)},_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,a,h=0;for(var c in e)if(a=e[c],!(a.o.y=t.y&&a.d.y>=t.y||(a.o.x===a.d.x&&a.o.x>=t.x?o=a.o.x:(i=0,r=(a.d.y-a.o.y)/(a.d.x-a.o.x),n=t.y-i*t.x,s=a.o.y-r*a.o.x,o=-(n-s)/(i-r)),o>=t.x&&(h+=1),2!==h)))break;return h},getBoundingRectWidth:function(){return this.getBoundingRect().width},getBoundingRectHeight:function(){return this.getBoundingRect().height},getBoundingRect:function(t,e){var i=this.getCoords(t,e);return fabric.util.makeBoundingBoxFromPoints(i)},getWidth:function(){return this._getTransformedDimensions().x},getHeight:function(){return this._getTransformedDimensions().y},_constrainScale:function(t){return Math.abs(t)0?Math.atan(o/s):0,l=s/Math.cos(c)/2,u=Math.cos(c+i)*l,f=Math.sin(c+i)*l,d=this.getCenterPoint(),g=t?d:fabric.util.transformPoint(d,r),p=new fabric.Point(g.x-u,g.y-f),v=new fabric.Point(p.x+s*h,p.y+s*a),m=new fabric.Point(p.x-o*a,p.y+o*h),b=new fabric.Point(g.x+u,g.y+f);if(!t)var _=new fabric.Point((p.x+m.x)/2,(p.y+m.y)/2),y=new fabric.Point((v.x+p.x)/2,(v.y+p.y)/2),x=new fabric.Point((b.x+v.x)/2,(b.y+v.y)/2),C=new fabric.Point((b.x+m.x)/2,(b.y+m.y)/2),S=new fabric.Point(y.x+a*this.rotatingPointOffset,y.y-h*this.rotatingPointOffset);var g={tl:p,tr:v,br:b,bl:m};return t||(g.ml=_,g.mt=y,g.mr=x,g.mb=C,g.mtr=S),g},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 t=e(this.angle),i=Math.cos(t),r=Math.sin(t);return 6.123233995736766e-17!==i&&i!==-1.8369701987210297e-16||(i=0),[i,r,-r,i,0,0]}return fabric.iMatrix.concat()},calcTransformMatrix:function(t){var e=this.getCenterPoint(),r=[1,0,0,1,e.x,e.y],n=this._calcRotateMatrix(),s=this._calcDimensionsTransformMatrix(this.skewX,this.skewY,!0),o=this.group&&!t?this.group.calcTransformMatrix():fabric.iMatrix.concat();return o=i(o,r),o=i(o,n),o=i(o,s)},_calcDimensionsTransformMatrix:function(t,r,n){var s=[1,0,Math.tan(e(t)),1],o=[1,Math.tan(e(r)),0,1],a=this.scaleX*(n&&this.flipX?-1:1),h=this.scaleY*(n&&this.flipY?-1:1),c=[a,0,0,h],l=i(c,s,!0);return i(l,o,!0)},_getNonTransformedDimensions:function(){var t=this.strokeWidth,e=this.width+t,i=this.height+t;return{x:e,y:i}},_getTransformedDimensions:function(t,e){"undefined"==typeof t&&(t=this.skewX),"undefined"==typeof e&&(e=this.skewY);var i,r,n=this._getNonTransformedDimensions(),s=n.x/2,o=n.y/2,a=[{x:-s,y:-o},{x:s,y:-o},{x:-s,y:o},{x:s,y:o}],h=this._calcDimensionsTransformMatrix(t,e,!1);for(i=0;i\n')},_createBaseSVGMarkup:function(){var t=[];return this.fill&&this.fill.toLive&&t.push(this.fill.toSVG(this,!1)),this.stroke&&this.stroke.toLive&&t.push(this.stroke.toSVG(this,!1)),this.shadow&&t.push(this.shadow.toSVG(this)),t}})}(),function(){function t(t,e,r){var n={},s=!0;r.forEach(function(e){n[e]=t[e]}),i(t[e],n,s)}function e(t,i,r){if(!fabric.isLikelyNode&&t instanceof Element)return t===i;if(t instanceof Array){if(t.length!==i.length)return!1;for(var n=0,s=t.length;n\n'),t?t(e.join("")):e.join("")}}),i.Line.ATTRIBUTE_NAMES=i.SHARED_ATTRIBUTES.concat("x1 y1 x2 y2".split(" ")),i.Line.fromElement=function(t,e){e=e||{};var n=i.parseAttributes(t,i.Line.ATTRIBUTE_NAMES),s=[n.x1||0,n.y1||0,n.x2||0,n.y2||0];return e.originX="left",e.originY="top",new i.Line(s,r(n,e))},i.Line.fromObject=function(t,e,r){function s(t){delete t.points,e&&e(t)}var o=n(t,!0);o.points=[t.x1,t.y1,t.x2,t.y2];var a=i.Object._fromObject("Line",o,s,r,"points");return a&&delete a.points,a}}("undefined"!=typeof exports?exports:this),function(t){"use strict";function e(t){return"radius"in t&&t.radius>=0}var i=t.fabric||(t.fabric={}),r=Math.PI,n=i.util.object.extend;if(i.Circle)return void i.warn("fabric.Circle is already defined.");var s=i.Object.prototype.cacheProperties.concat();s.push("radius"),i.Circle=i.util.createClass(i.Object,{type:"circle",radius:0,startAngle:0,endAngle:2*r,cacheProperties:s,initialize:function(t){this.callSuper("initialize",t),this.set("radius",t&&t.radius||0)},_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(t){var e=this._createBaseSVGMarkup(),i=0,n=0,s=(this.endAngle-this.startAngle)%(2*r);if(0===s)e.push("\n');else{var o=Math.cos(this.startAngle)*this.radius,a=Math.sin(this.startAngle)*this.radius,h=Math.cos(this.endAngle)*this.radius,c=Math.sin(this.endAngle)*this.radius,l=s>r?"1":"0";e.push('\n')}return t?t(e.join("")):e.join("")},_render:function(t){t.beginPath(),t.arc(0,0,this.radius,this.startAngle,this.endAngle,!1),this._renderFill(t),this._renderStroke(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)}}),i.Circle.ATTRIBUTE_NAMES=i.SHARED_ATTRIBUTES.concat("cx cy r".split(" ")),i.Circle.fromElement=function(t,r){r||(r={});var s=i.parseAttributes(t,i.Circle.ATTRIBUTE_NAMES);if(!e(s))throw new Error("value of `r` attribute is required and can not be negative");return s.left=(s.left||0)-s.radius,s.top=(s.top||0)-s.radius,s.originX="left",s.originY="top",new i.Circle(n(s,r))},i.Circle.fromObject=function(t,e,r){return i.Object._fromObject("Circle",t,e,r)}}("undefined"!=typeof exports?exports:this),function(t){"use strict";var e=t.fabric||(t.fabric={});return e.Triangle?void e.warn("fabric.Triangle is already defined"):(e.Triangle=e.util.createClass(e.Object,{type:"triangle",initialize:function(t){this.callSuper("initialize",t),this.set("width",t&&t.width||100).set("height",t&&t.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._renderFill(t),this._renderStroke(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(t){var e=this._createBaseSVGMarkup(),i=this.width/2,r=this.height/2,n=[-i+" "+r,"0 "+-r,i+" "+r].join(",");return e.push("'),t?t(e.join("")):e.join("")}}),void(e.Triangle.fromObject=function(t,i,r){return e.Object._fromObject("Triangle",t,i,r)}))}("undefined"!=typeof exports?exports:this),function(t){"use strict";var e=t.fabric||(t.fabric={}),i=2*Math.PI,r=e.util.object.extend;if(e.Ellipse)return void e.warn("fabric.Ellipse is already defined.");var n=e.Object.prototype.cacheProperties.concat();n.push("rx","ry"),e.Ellipse=e.util.createClass(e.Object,{type:"ellipse",rx:0,ry:0,cacheProperties:n,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(t){var e=this._createBaseSVGMarkup(),i=0,r=0;return e.push("\n'),t?t(e.join("")):e.join("")},_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._renderFill(t),this._renderStroke(t)}}),e.Ellipse.ATTRIBUTE_NAMES=e.SHARED_ATTRIBUTES.concat("cx cy rx ry".split(" ")),e.Ellipse.fromElement=function(t,i){i||(i={});var n=e.parseAttributes(t,e.Ellipse.ATTRIBUTE_NAMES);return n.left=(n.left||0)-n.rx,n.top=(n.top||0)-n.ry,n.originX="left",n.originY="top",new e.Ellipse(r(n,i))},e.Ellipse.fromObject=function(t,i,r){return e.Object._fromObject("Ellipse",t,i,r)}}("undefined"!=typeof exports?exports:this),function(t){"use strict";var e=t.fabric||(t.fabric={}),i=e.util.object.extend;if(e.Rect)return void e.warn("fabric.Rect is already defined");var r=e.Object.prototype.stateProperties.concat();r.push("rx","ry");var n=e.Object.prototype.cacheProperties.concat();n.push("rx","ry"),e.Rect=e.util.createClass(e.Object,{stateProperties:r,type:"rect",rx:0,ry:0,cacheProperties:n,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){if(1===this.width&&1===this.height)return void t.fillRect(-.5,-.5,1,1);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._renderFill(t),this._renderStroke(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(t){var e=this._createBaseSVGMarkup(),i=-this.width/2,r=-this.height/2;return e.push("\n'),t?t(e.join("")):e.join("")}}),e.Rect.ATTRIBUTE_NAMES=e.SHARED_ATTRIBUTES.concat("x y rx ry width height".split(" ")),e.Rect.fromElement=function(t,r){if(!t)return null;r=r||{};var n=e.parseAttributes(t,e.Rect.ATTRIBUTE_NAMES);n.left=n.left||0,n.top=n.top||0,n.originX="left",n.originY="top";var s=new e.Rect(i(r?e.util.object.clone(r):{},n));return s.visible=s.visible&&s.width>0&&s.height>0,s},e.Rect.fromObject=function(t,i,r){return e.Object._fromObject("Rect",t,i,r)}}("undefined"!=typeof exports?exports:this),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,o=e.Object.NUM_FRACTION_DIGITS;if(e.Polyline)return void e.warn("fabric.Polyline is already defined");var a=e.Object.prototype.cacheProperties.concat();a.push("points"),e.Polyline=e.util.createClass(e.Object,{type:"polyline",points:null,minX:0,minY:0,cacheProperties:a,initialize:function(t,e){e=e||{},this.points=t||[],this.callSuper("initialize",e),this._calcDimensions(),"top"in e||(this.top=this.minY),"left"in e||(this.left=this.minX),this.pathOffset={x:this.minX+this.width/2,y:this.minY+this.height/2}},_calcDimensions:function(){var t=this.points,e=r(t,"x"),i=r(t,"y"),s=n(t,"x"),o=n(t,"y");this.width=s-e||0,this.height=o-i||0,this.minX=e||0,this.minY=i||0},toObject:function(t){return i(this.callSuper("toObject",t),{points:this.points.concat()})},toSVG:function(t){for(var e=[],i=this.pathOffset.x,r=this.pathOffset.y,n=this._createBaseSVGMarkup(),a=0,h=this.points.length;a\n'),t?t(n.join("")):n.join("")},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"},toObject:function(t){var e=n(this.callSuper("toObject",["sourcePath","pathOffset"].concat(t)),{path:this.path.map(function(t){return t.slice()}),top:this.top,left:this.left});return e},toDatalessObject:function(t){var e=this.toObject(t);return this.sourcePath&&(e.path=this.sourcePath),delete e.sourcePath,e},toSVG:function(t){for(var e=[],i=this._createBaseSVGMarkup(),r="",n=0,s=this.path.length;n\n"),t?t(i.join("")):i.join("")},complexity:function(){return this.path.length},_parsePath:function(){for(var t,e,i,r,n,s=[],o=[],c=/([-+]?((\d+\.\d+)|((\d+)|(\.\d+)))(?:e[-+]?\d+)?)/gi,l=0,u=this.path.length;lp)for(var m=1,b=n.length;m"},addWithUpdate:function(t){return this._restoreObjectsState(),e.util.resetObjectTransform(this),t&&(this._objects.push(t),t.group=this,t._set("canvas",this.canvas)),this.forEachObject(this._setObjectActive,this),this._calcBounds(),this._updateObjectsCoords(),this.setCoords(),this.dirty=!0,this},_setObjectActive:function(t){t.set("active",!0),t.group=this},removeWithUpdate:function(t){return this._restoreObjectsState(),e.util.resetObjectTransform(this),this.forEachObject(this._setObjectActive,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,t.set("active",!1)},delegatedProperties:{fill:!0,stroke:!0,strokeWidth:!0,fontFamily:!0,fontWeight:!0,fontSize:!0,fontStyle:!0,lineHeight:!0,textDecoration:!0,textAlign:!0,backgroundColor:!0},_set:function(t,e){var i=this._objects.length;if(this.delegatedProperties[t]||"canvas"===t)for(;i--;)this._objects[i].set(t,e);else for(;i--;)this._objects[i].setOnGroup(t,e);this.callSuper("_set",t,e)},toObject:function(t){var e=this.getObjects().map(function(e){var i=e.includeDefaultValues;e.includeDefaultValues=e.group.includeDefaultValues;var r=e.toObject(t);return e.includeDefaultValues=i,r});return i(this.callSuper("toObject",t),{objects:e})},toDatalessObject:function(t){var e,r=this.sourcePath;return e=r?r:this.getObjects().map(function(e){var i=e.includeDefaultValues;e.includeDefaultValues=e.group.includeDefaultValues;var r=e.toDatalessObject(t);return e.includeDefaultValues=i,r}),i(this.callSuper("toDatalessObject",t),{objects:e})},render:function(t){this._transformDone=!0,this.callSuper("render",t),this._transformDone=!1},shouldCache:function(){var t=this.objectCaching&&(!this.group||this.needsItsOwnCache||!this.group.isCaching());if(this.caching=t,t)for(var e=0,i=this._objects.length;e\n');for(var i=0,r=this._objects.length;i\n"),t?t(e.join("")):e.join("")},get:function(t){if(t in s){if(this[t])return this[t];for(var e=0,i=this._objects.length;e\n',"\n"),this.stroke||this.strokeDashArray){var o=this.fill;this.fill=null,e.push("\n'),this.fill=o}return e.push("\n"),t?t(e.join("")):e.join("")},getSrc:function(t){var e=t?this._element:this._originalElement;return e?fabric.isLikelyNode?e._src:e.src:this.src||""},setSrc:function(t,e,i){return fabric.util.loadImage(t,function(t){this.setElement(t,i),e(this)},this,i&&i.crossOrigin),this},toString:function(){return'#'},applyResizeFilters:function(){var t=this.resizeFilter,e=this.canvas?this.canvas.getRetinaScaling():1,i=this.minimumScaleTrigger,r=this.scaleX=1&&n>=1)return void(this._element=this._filteredEl);fabric.filterBackend||(fabric.filterBackend=fabric.initFilterBackend());var s,o=this._filteredEl||this._originalElement;if(this._element===this._originalElement){var a=fabric.util.createCanvasElement();a.width=o.width,a.height=o.height,this._element=a}var h=this._element.getContext("2d");o.getContext?s=o.getContext("2d").getImageData(0,0,o.width,o.height):(h.drawImage(o,0,0),s=h.getImageData(0,0,o.width,o.height));var c={imageData:s,scaleX:r,scaleY:n};t.applyTo2d(c),this.width=this._element.width=c.imageData.width,this.height=this._element.height=c.imageData.height,h.putImageData(c.imageData,0,0)},applyFilters:function(t){if(t=t||this.filters||[],t=t.filter(function(t){return t}),0===t.length)return this._element=this._originalElement,this._filterScalingX=1,this._filterScalingY=1,this;var e=this._originalElement,i=e.naturalWidth||e.width,r=e.naturalHeight||e.height;if(this._element===this._originalElement){var n=fabric.util.createCanvasElement();n.width=e.width,n.height=e.height,this._element=n}else this._element.getContext("2d").clearRect(0,0,i,r);return fabric.filterBackend||(fabric.filterBackend=fabric.initFilterBackend()),fabric.filterBackend.applyFilters(t,this._originalElement,i,r,this._element,this.cacheKey),this.width===this._element.width&&this.height===this._element.height||(this._filterScalingX=this._element.width/this.width,this._filterScalingY=this._element.height/this.height,this.width=this._element.width,this.height=this._element.height),this},_render:function(t){var e,i=-this.width/2,r=-this.height/2,n=this._findMargins();"slice"===this.meetOrSlice&&(t.beginPath(),t.rect(i,r,this.width,this.height),t.clip()),this.isMoving===!1&&this.resizeFilter&&this._needsResize()&&(this._lastScaleX=this.scaleX,this._lastScaleY=this.scaleY,this.applyResizeFilters()),e=this._element,e&&t.drawImage(e,i+n.marginX,r+n.marginY,n.width,n.height),this._stroke(t),this._renderStroke(t)},_needsResize:function(){return this.scaleX!==this._lastScaleX||this.scaleY!==this._lastScaleY},_findMargins:function(){var t,e,i=this.width,r=this.height,n=0,s=0;return"none"===this.alignX&&"none"===this.alignY||(t=[this.width/this._element.width,this.height/this._element.height],e="meet"===this.meetOrSlice?Math.min.apply(null,t):Math.max.apply(null,t),i=this._element.width*e,r=this._element.height*e,"Mid"===this.alignX&&(n=(this.width-i)/2),"Max"===this.alignX&&(n=this.width-i),"Mid"===this.alignY&&(s=(this.height-r)/2),"Max"===this.alignY&&(s=this.height-r)),{width:i,height:r,marginX:n,marginY:s}},_resetWidthHeight:function(){var t=this.getElement();this.set("width",t.width),this.set("height",t.height)},_initElement:function(t,e){this.setElement(fabric.util.getById(t),e),fabric.util.addClass(this.getElement(),fabric.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?fabric.util.enlivenObjects(t,function(t){e&&e(t)},"fabric.Image.filters"):e&&e()},_setWidthHeight:function(t){this.width="width"in t?t.width:this.getElement()?this.getElement().width||0:0,this.height="height"in t?t.height:this.getElement()?this.getElement().height||0:0}}),fabric.Image.CSS_CANVAS="canvas-img",fabric.Image.prototype.getSvgSrc=fabric.Image.prototype.getSrc,fabric.Image.fromObject=function(t,e){fabric.util.loadImage(t.src,function(i,r){return r?void(e&&e(null,r)):void fabric.Image.prototype._initFilters.call(t,t.filters,function(r){t.filters=r||[],fabric.Image.prototype._initFilters.call(t,[t.resizeFilter],function(r){t.resizeFilter=r[0];var n=new fabric.Image(i,t);e(n)})})},null,t.crossOrigin)},fabric.Image.fromURL=function(t,e,i){fabric.util.loadImage(t,function(t){e&&e(new fabric.Image(t,i))},null,i&&i.crossOrigin)},fabric.Image.ATTRIBUTE_NAMES=fabric.SHARED_ATTRIBUTES.concat("x y width height preserveAspectRatio xlink:href crossOrigin".split(" ")),fabric.Image.fromElement=function(t,i,r){var n,s=fabric.parseAttributes(t,fabric.Image.ATTRIBUTE_NAMES);s.preserveAspectRatio&&(n=fabric.util.parsePreserveAspectRatioAttribute(s.preserveAspectRatio),e(s,n)),fabric.Image.fromURL(s["xlink:href"],i,e(r?fabric.util.object.clone(r):{},s))},fabric.Image.async=!0,fabric.Image.pngCompression=1}("undefined"!=typeof exports?exports:this),fabric.util.object.extend(fabric.Object.prototype,{_getAngleValueForStraighten:function(){var t=this.getAngle()%360;return t>0?90*Math.round((t-1)/90):90*Math.round(t/90)},straighten:function(){return this.setAngle(this._getAngleValueForStraighten()),this},fxStraighten:function(t){t=t||{};var e=function(){},i=t.onComplete||e,r=t.onChange||e,n=this;return fabric.util.animate({startValue:this.get("angle"),endValue:this._getAngleValueForStraighten(),duration:this.FX_DURATION,onChange:function(t){n.setAngle(t),r()},onComplete:function(){n.setCoords(),i()},onStart:function(){n.set("active",!1)}}),this}}),fabric.util.object.extend(fabric.StaticCanvas.prototype,{straightenObject:function(t){return t.straighten(),this.renderAll(),this},fxStraightenObject:function(t){return t.fxStraighten({onChange:this.renderAll.bind(this)}),this}}),function(){"use strict";function t(t){t&&t.tileSize&&(this.tileSize=t.tileSize),this.setupGLContext(this.tileSize,this.tileSize),this.captureGPUInfo()}fabric.isWebglSupported=function(t){if(fabric.isLikelyNode)return!1;t=t||fabric.WebglFilterBackend.prototype.tileSize;var e=document.createElement("canvas"),i=e.getContext("webgl")||e.getContext("experimental-webgl"),r=!1;return i&&(fabric.maxTextureSize=i.getParameter(i.MAX_TEXTURE_SIZE),r=fabric.maxTextureSize>=t),this.isSupported=r,r},fabric.WebglFilterBackend=t,t.prototype={tileSize:2048,resources:{},setupGLContext:function(t,e){this.dispose(),this.createWebGLCanvas(t,e),this.squareVertices=new Float32Array([0,0,0,1,1,0,1,1])},createWebGLCanvas:function(t,e){var i=fabric.util.createCanvasElement();i.width=t,i.height=e;var r={premultipliedAlpha:!1},n=i.getContext("webgl",r);n||(n=i.getContext("experimental-webgl",r)),n&&(n.clearColor(0,0,0,0),this.canvas=i,this.gl=n)},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,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,squareVertices:this.squareVertices,programCache:this.programCache,pass:0},c=a.createFramebuffer();return a.bindFramebuffer(a.FRAMEBUFFER,c),t.forEach(function(t){t&&t.applyTo(h)}),this.copyGLTo2D(a.canvas,n),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},applyFiltersDebug:function(t,e,i,r,n,s){var o=this.gl,a=this.applyFilters(t,e,i,r,n,s),h=o.getError();if(h!==o.NO_ERROR){var c=this.glErrorToString(o,h),l=new Error("WebGL Error "+c);throw l.glErrorCode=h,l}return a},glErrorToString:function(t,e){if(!t)return"Context undefined for error code: "+e;if("number"!=typeof e)return"Error code is not a number";switch(e){case t.NO_ERROR:return"NO_ERROR";case t.INVALID_ENUM:return"INVALID_ENUM";case t.INVALID_VALUE:return"INVALID_VALUE";case t.INVALID_OPERATION:return"INVALID_OPERATION";case t.INVALID_FRAMEBUFFER_OPERATION:return"INVALID_FRAMEBUFFER_OPERATION";case t.OUT_OF_MEMORY:return"OUT_OF_MEMORY";case t.CONTEXT_LOST_WEBGL:return"CONTEXT_LOST_WEBGL";default:return"UNKNOWN_ERROR"}},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},copyGLTo2D:function(t,e){var i=e.getContext("2d");i.translate(0,e.height),i.scale(1,-1);var r=t.height-e.height;i.drawImage(t,0,r,e.width,e.height,0,0,e.width,e.height)},evictCachesForKey:function(t){this.textureCache[t]&&(this.gl.deleteTexture(this.textureCache[t]),delete this.textureCache[t])},captureGPUInfo:function(){if(this.gpuInfo)return this.gpuInfo;var t=this.gl,e=t.getExtension("WEBGL_debug_renderer_info"),i={renderer:"",vendor:""};if(e){var r=t.getParameter(e.UNMASKED_RENDERER_WEBGL),n=t.getParameter(e.UNMASKED_VENDOR_WEBGL);r&&(i.renderer=r.toLowerCase()),n&&(i.vendor=n.toLowerCase())}return this.gpuInfo=i,i}}}(),function(){"use strict";function t(){}var e=function(){};fabric.Canvas2dFilterBackend=t,t.prototype={evictCachesForKey:e,dispose:e,clearWebGLCaches:e,resources:{},applyFilters:function(t,e,i,r,n){var s=n.getContext("2d");s.drawImage(e,0,0,i,r);var o=s.getImageData(0,0,i,r),a=s.getImageData(0,0,i,r),h={sourceWidth:i,sourceHeight:r,imageData:o,originalEl:e,originalImageData:a,canvasEl:n,ctx:s};return t.forEach(function(t){t.applyTo(h)}),h.imageData.width===i&&h.imageData.height===r||(n.width=h.imageData.width,n.height=h.imageData.height),s.putImageData(h.imageData,0,0),h}}}(),fabric.Image.filters=fabric.Image.filters||{},fabric.Image.filters.BaseFilter=fabric.util.createClass({type:"BaseFilter",vertexSource:"attribute vec2 aPosition;\nattribute vec2 aTexCoord;\nvarying vec2 vTexCoord;\nvoid main() {\nvTexCoord = aTexCoord;\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){if(this.vertexSource&&this.fragmentSource){var r=t.createShader(t.VERTEX_SHADER);if(t.shaderSource(r,i||this.vertexSource),t.compileShader(r),!t.getShaderParameter(r,t.COMPILE_STATUS))throw new Error('Vertex shader compile error for "${this.type}": '+t.getShaderInfoLog(r));var n=t.createShader(t.FRAGMENT_SHADER);if(t.shaderSource(n,e||this.fragmentSource),t.compileShader(n),!t.getShaderParameter(n,t.COMPILE_STATUS))throw new Error('Fragment shader compile error for "${this.type}": '+t.getShaderInfoLog(n));var s=t.createProgram();if(t.attachShader(s,r),t.attachShader(s,n),t.linkProgram(s),!t.getProgramParameter(s,t.LINK_STATUS))throw new Error('Shader link error for "${this.type}" '+t.getProgramInfoLog(s));var o=this.getAttributeLocations(t,s),a=this.getUniformLocations(t,s)||{};return a.uWidth=t.getUniformLocation(s,"uWidth"),a.uHeight=t.getUniformLocation(s,"uHeight"),{program:s,attributeLocations:o,uniformLocations:a}}},getAttributeLocations:function(t,e){return{aPosition:t.getAttribLocation(e,"aPosition"),aTexCoord:t.getAttribLocation(e,"aTexCoord")}},getUniformLocations:function(){},sendAttributeData:function(t,e,i){["aPosition","aTexCoord"].forEach(function(r){var n=e[r],s=t.createBuffer();t.bindBuffer(t.ARRAY_BUFFER,s),t.enableVertexAttribArray(n),t.vertexAttribPointer(n,2,t.FLOAT,!1,0,0),t.bufferData(t.ARRAY_BUFFER,i,t.STATIC_DRAW)})},_setupFrameBuffer:function(t){var e=t.context;t.passes>1?e.framebufferTexture2D(e.FRAMEBUFFER,e.COLOR_ATTACHMENT0,e.TEXTURE_2D,t.targetTexture,0):(e.bindFramebuffer(e.FRAMEBUFFER,null),e.finish())},_swapTextures:function(t){t.passes--,t.pass++;var e=t.targetTexture;t.targetTexture=t.sourceTexture,t.sourceTexture=e},isNeutralState:function(){return!1},applyTo:function(t){if(t.webgl){if(t.passes>1&&this.isNeutralState(t))return;this._setupFrameBuffer(t),this.applyToWebGL(t),this._swapTextures(t)}else 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.squareVertices),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.sourceWidth,t.sourceHeight),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()}}),fabric.Image.filters.BaseFilter.fromObject=function(t,e){var i=new fabric.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,a=o.data,h=a.length,c=this.matrix,l=this.colorsOnly;for(s=0;sy||o<0||o>_||(h=4*(a*_+o),c=v[d*m+f],e+=p[h]*c,i+=p[h+1]*c,r+=p[h+2]*c,S||(n+=p[h+3]*c));C[s]=e,C[s+1]=i,C[s+2]=r,S?C[s+3]=p[s+3]:C[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}("undefined"!=typeof exports?exports:this),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,n=r.data,s=n.length,o=this.mode;for(e=0;el[0]&&n>l[1]&&s>l[2]&&rt)return 0;if(e*=Math.PI,s(e)<1e-16)return 1;var i=e/t;return a(e)*a(i)/e/i}}function f(t){var a,h,u,O,k,j,D,E,P,A,M;for(T.x=(t+.5)*m,w.x=r(T.x),a=0;a=e)){A=r(1e3*s(h-T.x)),S[A]||(S[A]={});for(var L=w.y-C;L<=w.y+C;L++)L<0||L>=o||(M=r(1e3*s(L-T.y)),S[A][M]||(S[A][M]=v(n(i(A*_,2)+i(M*y,2))/1e3)),u=S[A][M],u>0&&(O=4*(L*e+h),k+=u,j+=u*d[O],D+=u*d[O+1],E+=u*d[O+2],P+=u*d[O+3]))}O=4*(a*c+t),p[O]=j/k,p[O+1]=D/k,p[O+2]=E/k,p[O+3]=P/k}return++t1&&L<-1||(y=2*L*L*L-3*L*L+1,y>0&&(M=4*(A+j*e),O+=y*g[M+3],C+=y,g[M+3]<255&&(y=y*g[M+3]/250),S+=y*g[M],T+=y*g[M+1],w+=y*g[M+2],x+=y))}v[_]=S/x,v[_+1]=T/x,v[_+2]=w/x,v[_+3]=O/C}return p},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}("undefined"!=typeof exports?exports:this),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,r=t.imageData,n=r.data,i=n.length,s=Math.floor(255*this.contrast),o=259*(s+255)/(255*(259-s));for(e=0;e1&&(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}("undefined"!=typeof exports?exports:this),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",applyTo2d:function(t){var e,i=t.imageData,r=i.data,n=this.gamma,s=r.length,o=1/n[0],a=1/n[1],h=1/n[2];for(this.rVals||(this.rVals=new Uint8Array(256),this.gVals=new Uint8Array(256),this.bVals=new Uint8Array(256)),e=0,s=256;e'},_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){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;et&&(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;ds)){var v=h-s;c[t]=h,c[f]+=v,s=h}return{width:s*g,kernedWidth:h*g}},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=0,h=new Array(o.length);for(this.__charBounds[t]=h,e=0;e0&&!n){var u=this.__charBounds[e][i-1];l.left=u.left+u.width+a.kernedWidth-a.width}return l},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;ri&&(i=s)}return this.__lineHeights[t]=i*this.lineHeight*this._fontSizeMult,this.__lineHeights[t]},calcTextHeight:function(){for(var t,e=0,i=0,r=this._textLines.length;i0?(t.fillStyle=f,s&&f&&t.fillRect(d+r+o,g+l*(1-this._fontSizeFraction)+this.offsets[e]*this.fontSize,a,this.fontSize/15),o=h.left,a=h.width,s=c,f=u):a+=h.kernedWidth;t.fillStyle=u,c&&u&&t.fillRect(d+r+o,g+l*(1-this._fontSizeFraction)+this.offsets[e]*this.fontSize,a,this.fontSize/15),g+=i}else g+=i;this._removeShadow(t)}},_getFontDeclaration:function(t,i){var r=t||this;return[e.isLikelyNode?r.fontWeight:r.fontStyle,e.isLikelyNode?r.fontStyle:r.fontWeight,i?n+"px":r.fontSize+"px",e.isLikelyNode?'"'+r.fontFamily+'"':r.fontFamily].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-1&&(this.initDimensions(),this.setCoords())},complexity:function(){return 1}}),e.Text.ATTRIBUTE_NAMES=e.SHARED_ATTRIBUTES.concat("x y dx dy font-family font-style font-weight font-size text-decoration text-anchor".split(" ")),e.Text.DEFAULT_SVG_FONT_SIZE=16,e.Text.fromElement=function(t,r){if(!t)return null;var n=e.parseAttributes(t,e.Text.ATTRIBUTE_NAMES);if(r=e.util.object.extend(r?i(r):{},n),r.top=r.top||0,r.left=r.left||0,n.textDecoration){var s=n.textDecoration;s.indexOf("underline")!==-1&&(r.underline=!0),s.indexOf("overline")!==-1&&(r.overline=!0),s.indexOf("line-through")!==-1&&(r.linethrough=!0),delete r.textDecoration}"dx"in n&&(r.left+=n.dx),"dy"in n&&(r.top+=n.dy),"fontSize"in r||(r.fontSize=e.Text.DEFAULT_SVG_FONT_SIZE),r.originX||(r.originX="left");var o="";"textContent"in t?o=t.textContent:"firstChild"in t&&null!==t.firstChild&&"data"in t.firstChild&&null!==t.firstChild.data&&(o=t.firstChild.data),o=o.replace(/^\s+|\s+$|\n+/g,"").replace(/\s+/g," ");var a=new e.Text(o,r),h=a.getHeight()/a.height,c=(a.height+a.strokeWidth)*a.lineHeight-a.height,l=c*h,u=a.getHeight()+l,f=0;return"center"===a.originX&&(f=a.getWidth()/2),"right"===a.originX&&(f=a.getWidth()),a.set({left:a.getLeft()-f,top:a.getTop()-(u-a.fontSize*(.18+a._fontSizeFraction))/a.lineHeight}),a.originX="left",a.originY="top",a},e.Text.fromObject=function(t,i,r){return e.Object._fromObject("Text",t,i,r,"text")},e.util.createAccessors(e.Text)}("undefined"!=typeof exports?exports:this),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)}fabric.IText=fabric.util.createClass(fabric.Text,fabric.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.styles=e?e.styles||{}:{},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})},getSelectionStyles:function(t,e){if(2===arguments.length){for(var i=[],r=t;r0?o:0)},this.cursorOffsetCache=i,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;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,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=this.get2DCursorLocation(i),s=this.get2DCursorLocation(r),o=n.lineIndex,a=s.lineIndex,h=n.charIndex<0?0:n.charIndex,c=s.charIndex<0?0:s.charIndex,l=o;l<=a;l++){var u=this._getLineLeftOffset(l)||0,f=this.getHeightOfLine(l),d=0,g=0,p=0;l===o&&(g=this.__charBounds[o][h].left),l>=o&&l1)&&(f/=this.lineHeight),this.inCompositionMode?(e.fillStyle=this.compositionColor||"black",e.fillRect(t.left+u+g,t.top+t.topOffset+f,p-g,1)):(e.fillStyle=this.selectionColor,e.fillRect(t.left+u+g,t.top+t.topOffset,p-g,f)),t.topOffset+=d}},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}}}),fabric.IText.fromObject=function(e,i,r){if(t(e),e.styles)for(var n in e.styles)for(var s in e.styles[n])t(e.styles[n][s]);return fabric.Object._fromObject("IText",e,i,r,"text")}}(),function(){var t=fabric.util.object.clone;fabric.util.object.extend(fabric.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,this.callSuper("onDeselect")},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||[],fabric.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})}.bind(this),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;this._currentTickState&&this._currentTickState.abort(),this._currentTickCompleteState&&this._currentTickCompleteState.abort(),clearTimeout(this._cursorTimeout1),clearTimeout(this._cursorTimeout2),this._currentCursorOpacity=0,t&&this.canvas&&this.canvas.clearContext(this.canvas.contextTop||this.ctx)},selectAll:function(){this.selectionStart=0,this.selectionEnd=this._text.length,this._fireSelectionChanged(),this._updateTextarea()},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-1;)e++,i--;return t-e},findLineBoundaryRight:function(t){for(var e=0,i=t;!/\n/.test(this._text[i])&&i0&&ithis.__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 r=i.slice(0,t),n=fabric.util.string.graphemeSplit(r).length;if(t===e)return{selectionStart:n,selectionEnd:n};var s=i.slice(t,e),o=fabric.util.string.graphemeSplit(s).length;return{selectionStart:n,selectionEnd:n+o}},fromGraphemeToStringSelection:function(t,e,i){var r=i.slice(0,t),n=r.join("").length;if(t===e)return{selectionStart:n,selectionEnd:n};var s=i.slice(t,e),o=s.join("").length;return{selectionStart:n,selectionEnd:n+o}},_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;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),r=i.lineIndex,n=i.charIndex,s=this.getValueOfPropertyAt(r,n,"fontSize")*this.lineHeight,o=e.leftOffset,a=this.calcTransformMatrix(),h={x:e.left+o,y:e.top+e.topOffset+s},c=this.canvas.upperCanvasEl,l=c.width-s,u=c.height-s;return h=fabric.util.transformPoint(h,a),h=fabric.util.transformPoint(h,this.canvas.viewportTransform),h.x<0&&(h.x=0),h.x>l&&(h.x=l),h.y<0&&(h.y=0),h.y>u&&(h.y=u),h.x+=this.canvas._offset.left,h.y+=this.canvas._offset.top,{left:h.x+"px",top:h.y+"px",fontSize:s+"px",charHeight:s}},_saveEditingProps:function(){this._savedProps={hasControls:this.hasControls,borderColor:this.borderColor,lockMovementX:this.lockMovementX,lockMovementY:this.lockMovementY,hoverCursor:this.hoverCursor,defaultCursor:this.canvas&&this.canvas.defaultCursor,moveCursor:this.canvas&&this.canvas.moveCursor}},_restoreEditingProps:function(){this._savedProps&&(this.hoverCursor=this._savedProps.overCursor,this.hasControls=this._savedProps.hasControls,this.borderColor=this._savedProps.borderColor,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.selectable=!0,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.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;ie&&(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;r||(r=1),this.shiftLineStyles(e,r),this.styles[e]&&this.styles[e][i-1]&&(s=this.styles[e][i-1]);for(var h in 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[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){var s=this.styles[e],o=t(s);r||(r=1);for(var a in o){var h=parseInt(a,10);h>=i&&(s[h+r]=o[h],o[h-r]||delete s[h])}if(this._forceClearCache=!0,s)if(n)for(;r--;)this.styles[e][i+r]=t(n[r]);else 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;ot&&it?this.selectionStart=t:this.selectionStart<0&&(this.selectionStart=0),this.selectionEnd>t?this.selectionEnd=t:this.selectionEnd<0&&(this.selectionEnd=0)}})}(),fabric.util.object.extend(fabric.IText.prototype,{initDoubleClickSimulation:function(){this.__lastClickTime=+new Date,this.__lastLastClickTime=+new Date,this.__lastPointer={},this.on("mousedown",this.onMouseDown.bind(this))},onMouseDown:function(t){this.__newClickTime=+new Date;var e=this.canvas.getPointer(t.e);this.isTripleClick(e,t.e)?(this.fire("tripleclick",t),this._stopEvent(t.e)):this.isDoubleClick(e)&&(this.fire("dblclick",t),this._stopEvent(t.e)),this.__lastLastClickTime=this.__lastClickTime,this.__lastClickTime=this.__newClickTime,this.__lastPointer=e,this.__lastIsEditing=this.isEditing,this.__lastSelected=this.selected},isDoubleClick:function(t){return this.__newClickTime-this.__lastClickTime<500&&this.__lastPointer.x===t.x&&this.__lastPointer.y===t.y&&this.__lastIsEditing},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("dblclick",function(t){this.selectWord(this.getSelectionStartFromPointer(t.e))}),this.on("tripleclick",function(t){this.selectLine(this.getSelectionStartFromPointer(t.e))})},initMousedownHandler:function(){this.on("mousedown",function(t){if(this.editable&&(!t.e.button||1===t.e.button)){var e=this.canvas.getPointer(t.e);this.__mousedownX=e.x,this.__mousedownY=e.y,this.__isMousedown=!0,this.selected&&this.setCursorByClick(t.e),this.isEditing&&(this.__selectionStartOnMouseDown=this.selectionStart,this.selectionStart===this.selectionEnd&&this.abortCursorAnimation(),this.renderCursorOrSelection())}})},_isObjectMoved:function(t){var e=this.canvas.getPointer(t);return this.__mousedownX!==e.x||this.__mousedownY!==e.y},initMouseupHandler:function(){this.on("mouseup",function(t){this.__isMousedown=!1,!this.editable||this._isObjectMoved(t.e)||t.e.button&&1!==t.e.button||(this.__lastSelected&&!this.__corner&&(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,i,r=this.getLocalPointer(t),n=0,s=0,o=0,a=0,h=0,c=0,l=this._textLines.length;c0&&(a+=this._textLines[c-1].length+1);e=this._getLineLeftOffset(h),s=e*this.scaleX,i=this._textLines[h];for(var u=0,f=i.length;us?0:1,h=r+a;return this.flipX&&(h=n-h),h>this._text.length&&(h=this._text.length),h}}),fabric.util.object.extend(fabric.IText.prototype,{initHiddenTextarea:function(){this.hiddenTextarea=fabric.document.createElement("textarea"),this.hiddenTextarea.setAttribute("autocapitalize","off"),this.hiddenTextarea.setAttribute("autocorrect","off"),this.hiddenTextarea.setAttribute("autocomplete","off"),this.hiddenTextarea.setAttribute("spellcheck","false");var t=this._calcTextareaPosition();this.hiddenTextarea.style.cssText="white-space: nowrap; position: absolute; top: "+t.top+"; left: "+t.left+"; z-index: -999; opacity: 0; width: 1px; height: 1px; font-size: 1px; line-height: 1px; paddingーtop: "+t.fontSize+";",fabric.document.body.appendChild(this.hiddenTextarea),fabric.util.addListener(this.hiddenTextarea,"keydown",this.onKeyDown.bind(this)),fabric.util.addListener(this.hiddenTextarea,"keyup",this.onKeyUp.bind(this)),fabric.util.addListener(this.hiddenTextarea,"input",this.onInput.bind(this)),fabric.util.addListener(this.hiddenTextarea,"copy",this.copy.bind(this)),fabric.util.addListener(this.hiddenTextarea,"cut",this.copy.bind(this)),fabric.util.addListener(this.hiddenTextarea,"paste",this.paste.bind(this)),fabric.util.addListener(this.hiddenTextarea,"compositionstart",this.onCompositionStart.bind(this)),fabric.util.addListener(this.hiddenTextarea,"compositionupdate",this.onCompositionUpdate.bind(this)),fabric.util.addListener(this.hiddenTextarea,"compositionend",this.onCompositionEnd.bind(this)),!this._clickHandlerInitialized&&this.canvas&&(fabric.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.renderAll()}},onKeyUp:function(t){return!this.isEditing||this._copyDone||this.inCompositionMode?void(this._copyDone=!1):void(t.keyCode in this._ctrlKeysMapUp&&(t.ctrlKey||t.metaKey)&&(this[this._ctrlKeysMapUp[t.keyCode]](t),t.stopImmediatePropagation(),t.preventDefault(),this.canvas&&this.canvas.renderAll()))},onInput:function(t){var e=this.fromPaste;if(this.fromPaste=!1,t&&t.stopPropagation(),this.isEditing){var i,r,n=this._splitTextIntoLines(this.hiddenTextarea.value).graphemeText,s=this._text.length,o=n.length,a=o-s;""===this.hiddenTextarea.value&&(this.styles={},this.updateFromTextArea(),this.fire("changed"),this.canvas&&(this.canvas.fire("text:changed",{target:this}),this.canvas.renderAll())),this.selectionStart!==this.selectionEnd?(i=this._text.slice(this.selectionStart,this.selectionEnd), -a+=this.selectionEnd-this.selectionStart):oh.selectionStart?this.removeStyleFromTo(this.selectionEnd-i.length,this.selectionEnd):this.removeStyleFromTo(this.selectionEnd,this.selectionEnd+i.length)),r.length&&(e&&r.join("")===fabric.copiedText?this.insertNewStyleBlock(r,this.selectionStart,fabric.copiedTextStyle):this.insertNewStyleBlock(r,this.selectionStart)),this.updateFromTextArea(),this.fire("changed"),this.canvas&&(this.canvas.fire("text:changed",{target:this}),this.canvas.renderAll())}},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(){if(this.selectionStart!==this.selectionEnd){var t=this.getSelectedText();fabric.copiedText=t,fabric.copiedTextStyle=this.getSelectionStyles(this.selectionStart,this.selectionEnd),this._copyDone=!0}},paste:function(){this.fromPaste=!0},_getClipboardData:function(t){return t&&t.clipboardData||fabric.window.clipboardData},_getWidthBeforeCursor:function(t,e){var i,r=this._getLineLeftOffset(t);return e>0&&(i=this.__charBounds[t][e-1],r+=i.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),h=this._textLines[n].slice(s);return h.length+a+2},_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);return-this._textLines[n-1].length+a-h.length},_getIndexOnLine:function(t,e){for(var i,r,n=this._textLines[t],s=this._getLineLeftOffset(t),o=s,a=0,h=0,c=n.length;he){r=!0;var l=o-i,u=o,f=Math.abs(l-e),d=Math.abs(u-e);a=d=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="get"+t+"CursorOffset",r=this[i](e,"right"===this._selectionDirection);e.shiftKey?this.moveCursorWithShift(r):this.moveCursorWithoutShift(r),0!==r&&(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,i+=e.shiftKey?"Shift":"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){this.selectionStart===this.selectionEnd?this._removeCharsNearCursor(t):this._removeCharsFromTo(this.selectionStart,this.selectionEnd),this.set("dirty",!0),this.setSelectionEnd(this.selectionStart),this._removeExtraneousStyles(),this.canvas&&this.canvas.renderAll(),this.setCoords(),this.fire("changed"),this.canvas&&this.canvas.fire("text:changed",{target:this})},_removeCharsNearCursor:function(t){if(0!==this.selectionStart)if(t.metaKey){var e=this.findLineBoundaryLeft(this.selectionStart);this._removeCharsFromTo(e,this.selectionStart),this.setSelectionStart(e)}else if(t.altKey){var i=this.findWordBoundaryLeft(this.selectionStart);this._removeCharsFromTo(i,this.selectionStart),this.setSelectionStart(i)}else this._removeSingleCharAndStyle(this.selectionStart),this.setSelectionStart(this.selectionStart-1)}}),function(){var t=fabric.util.toFixed,e=fabric.Object.NUM_FRACTION_DIGITS;fabric.util.object.extend(fabric.Text.prototype,{toSVG:function(t){var e=this._createBaseSVGMarkup(),i=this._getSVGLeftTopOffsets(),r=this._getSVGTextAndBg(i.textTop,i.textLeft);return this._wrapSVGTextAndBg(e,r),t?t(e.join("")):e.join("")},_getSVGLeftTopOffsets:function(){return{textLeft:-this.width/2,textTop:-this.height/2,lineTop:this.getHeightOfLine(0)}},_wrapSVGTextAndBg:function(t,e){var i=!0,r=this.getSvgFilter(),n=""===r?"":' style="'+r+'"';t.push("\t\n",e.textBgRects.join(""),"\t\t\n',e.textSpans.join(""),"\t\t\n","\t\n")},_getSVGTextAndBg:function(t,e){var i,r=[],n=[],s=t;this._setSVGBg(n);for(var o=0,a=this._textLines.length;o",fabric.util.string.escapeXml(i),"\n"].join("")},_setSVGTextLineText:function(t,e,i,r){var n,s,o,a,h,c=this.getHeightOfLine(e),l="",u=0,f=this._textLines[e];r+=c*(1-this._fontSizeFraction)/this.lineHeight;for(var d=0,g=f.length-1;d<=g;d++)h=d===g||this.charSpacing,l+=f[d],o=this.__charBounds[e][d],0===u&&(i+=o.kernedWidth-o.width),u+=o.kernedWidth,"justify"!==this.textAlign||h||this._reSpaceAndTab.test(f[d])&&(h=!0),h||(n=n||this.getCompleteStyleDeclaration(e,d),s=this.getCompleteStyleDeclaration(e,d+1),h=this._hasStyleChanged(n,s)),h&&(a=this._getStyleDeclaration(e,d)||{},t.push(this._createTextCharSpan(l,a,i,r)),l="",n=s,i+=u,u=0)},_pushTextBgRect:function(i,r,n,s,o,a){i.push("\t\t\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;uthis.width&&this._set("width",this.dynamicMinWidth),"justify"===this.textAlign&&this.enlargeSpaces(),this.height=this.calcTextHeight()}},_generateStyleMap:function(t){for(var e=0,i=0,r=0,n={},s=0;s0?(i=0,r++,e++):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)},_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,e){var i=this._styleMap[t];this.styles[i.line]=e},_deleteLineStyle:function(t){var e=this._styleMap[t];delete this.styles[e.line]},_wrapText:function(t,e){var i,r=[];for(this.isWrapping=!0,i=0;i=r&&!g&&(s.push(o),o=[],n=u,g=!0),g||o.push(l),o=o.concat(h),f=this._measureWord([l],i,c),c++,g=!1,u>d&&(d=u);return v&&s.push(o),d>this.dynamicMinWidth&&(this.dynamicMinWidth=d-p),s},_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=h.getMinWidth()?(h.set("width",c),!0):void 0},fabric.Group.prototype._refreshControlsVisibility=function(){if("undefined"!=typeof fabric.Textbox)for(var t=this._objects.length;t--;)if(this._objects[t]instanceof fabric.Textbox)return void this.setControlsVisibility(fabric.Textbox.getTextboxControlVisibility())},fabric.util.object.extend(fabric.Textbox.prototype,{_removeExtraneousStyles:function(){for(var t in this._styleMap)this._textLines[t]||delete this.styles[this._styleMap[t].line]}})}(),function(){function request(t,e,i){var r=URL.parse(t);r.port||(r.port=0===r.protocol.indexOf("https:")?443:80);var n=0===r.protocol.indexOf("https:")?HTTPS:HTTP,s=n.request({hostname:r.hostname,port:r.port,path:r.path,method:"GET"},function(t){var r="";e&&t.setEncoding(e),t.on("end",function(){i(r)}),t.on("data",function(e){200===t.statusCode&&(r+=e)})});s.on("error",function(t){t.errno===process.ECONNREFUSED?fabric.log("ECONNREFUSED: connection refused to "+r.hostname+":"+r.port):fabric.log(t.message),i(null)}),s.end()}function requestFs(t,e){var i=require("fs");i.readFile(t,function(t,i){if(t)throw fabric.log(t),t;e(i)})}if("undefined"==typeof document||"undefined"==typeof window){var DOMParser=require("xmldom").DOMParser,URL=require("url"),HTTP=require("http"),HTTPS=require("https"),Canvas=require(fabric.canvasModule),Image=require(fabric.canvasModule).Image;fabric.util.loadImage=function(t,e,i){function r(r){r?(n.src=new Buffer(r,"binary"),n._src=t,e&&e.call(i,n)):(n=null,e&&e.call(i,null,!0))}var n=new Image;t&&(t instanceof Buffer||0===t.indexOf("data"))?(n.src=n._src=t,e&&e.call(i,n)):t&&0!==t.indexOf("http")?requestFs(t,r):t?request(t,"binary",r):e&&e.call(i,t)},fabric.loadSVGFromURL=function(t,e,i){t=t.replace(/^\n\s*/,"").replace(/\?.*$/,"").trim(),0!==t.indexOf("http")?requestFs(t,function(t){fabric.loadSVGFromString(t.toString(),e,i)}):request(t,"",function(t){fabric.loadSVGFromString(t,e,i)})},fabric.loadSVGFromString=function(t,e,i){var r=(new DOMParser).parseFromString(t);fabric.parseSVGDocument(r.documentElement,function(t,i){e&&e(t,i)},i)},fabric.util.getScript=function(url,callback){request(url,"",function(body){eval(body),callback&&callback()})},fabric.createCanvasForNode=function(t,e,i,r){r=r||i;var n=fabric.document.createElement("canvas"),s=new Canvas(t||600,e||600,r),o=new Canvas(t||600,e||600,r);n.width=s.width,n.height=s.height,i=i||{},i.nodeCanvas=s,i.nodeCacheCanvas=o;var a=fabric.Canvas||fabric.StaticCanvas,h=new a(n,i);return h.nodeCanvas=s,h.nodeCacheCanvas=o,h.contextContainer=s.getContext("2d"),h.contextCache=o.getContext("2d"),h.Font=Canvas.Font,h};var originaInitStatic=fabric.StaticCanvas.prototype._initStatic;fabric.StaticCanvas.prototype._initStatic=function(t,e){t=t||fabric.document.createElement("canvas"),this.nodeCanvas=new Canvas(t.width,t.height),this.nodeCacheCanvas=new Canvas(t.width,t.height),originaInitStatic.call(this,t,e),this.contextContainer=this.nodeCanvas.getContext("2d"),this.contextCache=this.nodeCacheCanvas.getContext("2d"),this.Font=Canvas.Font},fabric.StaticCanvas.prototype.createPNGStream=function(){return this.nodeCanvas.createPNGStream()},fabric.StaticCanvas.prototype.createJPEGStream=function(t){return this.nodeCanvas.createJPEGStream(t)},fabric.StaticCanvas.prototype._initRetinaScaling=function(){if(this._isRetinaScaling())return this.lowerCanvasEl.setAttribute("width",this.width*fabric.devicePixelRatio),this.lowerCanvasEl.setAttribute("height",this.height*fabric.devicePixelRatio),this.nodeCanvas.width=this.width*fabric.devicePixelRatio,this.nodeCanvas.height=this.height*fabric.devicePixelRatio,this.contextContainer.scale(fabric.devicePixelRatio,fabric.devicePixelRatio),this},fabric.Canvas&&(fabric.Canvas.prototype._initRetinaScaling=fabric.StaticCanvas.prototype._initRetinaScaling);var origSetBackstoreDimension=fabric.StaticCanvas.prototype._setBackstoreDimension;fabric.StaticCanvas.prototype._setBackstoreDimension=function(t,e){return origSetBackstoreDimension.call(this,t,e),this.nodeCanvas[t]=e,this},fabric.Canvas&&(fabric.Canvas.prototype._setBackstoreDimension=fabric.StaticCanvas.prototype._setBackstoreDimension)}}(); +var fabric=fabric||{version:"2.0.0-beta3"};"undefined"!=typeof exports&&(exports.fabric=fabric),"undefined"!=typeof document&&"undefined"!=typeof window?(fabric.document=document,fabric.window=window,window.fabric=fabric):(fabric.document=require("jsdom").jsdom(decodeURIComponent("%3C!DOCTYPE%20html%3E%3Chtml%3E%3Chead%3E%3C%2Fhead%3E%3Cbody%3E%3C%2Fbody%3E%3C%2Fhtml%3E"),{features:{FetchExternalResources:["img"]}}),fabric.window=fabric.document.defaultView),fabric.isTouchSupported="ontouchstart"in fabric.document.documentElement,fabric.isLikelyNode="undefined"!=typeof Buffer&&"undefined"==typeof window,fabric.SHARED_ATTRIBUTES=["display","transform","fill","fill-opacity","fill-rule","opacity","stroke","stroke-dasharray","stroke-linecap","stroke-linejoin","stroke-miterlimit","stroke-opacity","stroke-width","id"],fabric.DPI=96,fabric.reNum="(?:[-+]?(?:\\d+|\\d*\\.\\d+)(?:e[-+]?\\d+)?)",fabric.fontPaths={},fabric.iMatrix=[1,0,0,1,0,0],fabric.canvasModule="canvas",fabric.perfLimitSizeTotal=2097152,fabric.maxCacheSideLimit=4096,fabric.minCacheSideLimit=256,fabric.charWidthsCache={},fabric.textureSize=2048,fabric.enableGLFiltering=!0,fabric.devicePixelRatio=fabric.window.devicePixelRatio||fabric.window.webkitDevicePixelRatio||fabric.window.mozDevicePixelRatio||1,fabric.initFilterBackend=function(){return fabric.isWebglSupported&&fabric.isWebglSupported(fabric.textureSize)&&fabric.enableGLFiltering?(console.log("max texture size: "+fabric.maxTextureSize),new fabric.WebglFilterBackend({tileSize:fabric.textureSize})):fabric.Canvas2dFilterBackend?new fabric.Canvas2dFilterBackend:void 0},function(){function t(t,e){if(this.__eventListeners[t]){var i=this.__eventListeners[t];e?i[i.indexOf(e)]=!1:fabric.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){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 r(t,e){if(this.__eventListeners){var i=this.__eventListeners[t];if(i){for(var r=0,n=i.length;r-1},complexity:function(){return this.getObjects().reduce(function(t,e){return t+=e.complexity?e.complexity():0},0)}},fabric.CommonMethods={_setOptions:function(t){for(var e in t)this.set(e,t[e])},_initGradient:function(t,e){!t||!t.colorStops||t instanceof fabric.Gradient||this.set(e,new fabric.Gradient(t))},_initPattern:function(t,e,i){!t||!t.source||t instanceof fabric.Pattern?i&&i():this.set(e,new fabric.Pattern(t,i))},_initClipping:function(t){if(t.clipTo&&"string"==typeof t.clipTo){var e=fabric.util.getFunctionBody(t.clipTo);"undefined"!=typeof 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,r=Math.pow,n=Math.abs,s=Math.PI/180;fabric.util={removeFromArray:function(t,e){var i=t.indexOf(e);return i!==-1&&t.splice(i,1),t},getRandomInt:function(t,e){return Math.floor(Math.random()*(e-t+1))+t},degreesToRadians:function(t){return t*s},radiansToDegrees:function(t){return t/s},rotatePoint:function(t,e,i){t.subtractEquals(e);var r=fabric.util.rotateVector(t,i);return new fabric.Point(r.x,r.y).addEquals(e)},rotateVector:function(t,e){var i=Math.sin(e),r=Math.cos(e),n=t.x*r-t.y*i,s=t.x*i+t.y*r;return{x:n,y:s}},transformPoint:function(t,e,i){return i?new fabric.Point(e[0]*t.x+e[2]*t.y,e[1]*t.x+e[3]*t.y):new fabric.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=fabric.util.array.min(e),r=fabric.util.array.max(e),n=Math.abs(i-r),s=[t[0].y,t[1].y,t[2].y,t[3].y],o=fabric.util.array.min(s),a=fabric.util.array.max(s),h=Math.abs(o-a);return{left:i,top:o,width:n,height:h}},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]],r=fabric.util.transformPoint({x:t[4],y:t[5]},i,!0);return i[4]=-r.x,i[5]=-r.y,i},toFixed:function(t,e){return parseFloat(Number(t).toFixed(e))},parseUnit:function(t,e){var i=/\D{0,2}$/.exec(t),r=parseFloat(t);switch(e||(e=fabric.Text.DEFAULT_SVG_FONT_SIZE),i[0]){case"mm":return r*fabric.DPI/25.4;case"cm":return r*fabric.DPI/2.54;case"in":return r*fabric.DPI;case"pt":return r*fabric.DPI/72;case"pc":return r*fabric.DPI/72*12;case"em":return r*e;default:return r}},falseFunction:function(){return!1},getKlass:function(t,e){return t=fabric.util.string.camelize(t.charAt(0).toUpperCase()+t.slice(1)),fabric.util.resolveNamespace(e)[t]},resolveNamespace:function(e){if(!e)return fabric;var i,r=e.split("."),n=r.length,s=t||fabric.window;for(i=0;ir;)r+=a[d++%f],r>l&&(r=l),t[g?"lineTo":"moveTo"](r,0),g=!g;t.restore()},createCanvasElement:function(t){return t||(t=fabric.document.createElement("canvas")),t},createImage:function(){return fabric.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 n=i(t[1],t[0]),o=r(t[0],2)+r(t[1],2),a=e(o),h=(t[0]*t[3]-t[2]*t[1])/a,c=i(t[0]*t[2]+t[1]*t[3],o);return{angle:n/s,scaleX:a,scaleY:h,skewX:c/s,skewY:0,translateX:t[4],translateY:t[5]}},customTransformMatrix:function(t,e,i){var r=[1,0,n(Math.tan(i*s)),1],o=[n(t),0,0,n(e)];return fabric.util.multiplyTransformMatrices(o,r,!0)},resetObjectTransform:function(t){t.scaleX=1,t.scaleY=1,t.skewX=0,t.skewY=0,t.flipX=!1,t.flipY=!1,t.setAngle(0)},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,o=!0,a=t.getImageData(e,i,2*r||1,2*r||1),h=a.data.length;for(n=3;n0?P-=2*f:1===c&&P<0&&(P+=2*f);for(var M=Math.ceil(Math.abs(P/f*2)),L=[],I=P/M,R=8/3*Math.sin(I/4)*Math.sin(I/4)/Math.sin(I/2),F=A+I,B=0;B=n?s-n:2*Math.PI-(n-s)}function r(t,e,i,r,n,s,h,c){var l=a.call(arguments);if(o[l])return o[l];var u,f,d,g,p,v,m,b,_=Math.sqrt,y=Math.min,x=Math.max,C=Math.abs,S=[],w=[[],[]];f=6*t-12*i+6*n,u=-3*t+9*i-9*n+3*h,d=3*i-3*t;for(var T=0;T<2;++T)if(T>0&&(f=6*e-12*r+6*s,u=-3*e+9*r-9*s+3*c,d=3*r-3*e),C(u)<1e-12){if(C(f)<1e-12)continue;g=-d/f,0=e})}function i(t,e){return n(t,e,function(t,e){return t/g,">")}function r(t){for(var e,i=0,r=[],i=0;i57343)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}fabric.util.string={camelize:t,capitalize:e,escapeXml:i,graphemeSplit:r}}(),function(){function t(){}function e(t){for(var e=null,i=this;i.constructor.superclass;){var n=i.constructor.superclass.prototype[t];if(i[t]!==n){e=n;break}i=i.constructor.superclass.prototype}return e?arguments.length>1?e.apply(this,r.call(arguments,1)):e.call(this):console.log("tried to callSuper "+t+", method not found in prototype chain",this)}function i(){function i(){this.initialize.apply(this,arguments)}var s=null,a=r.call(arguments,0);"function"==typeof a[0]&&(s=a.shift()),i.superclass=s,i.subclasses=[],s&&(t.prototype=s.prototype,i.prototype=new t,s.subclasses.push(i));for(var h=0,c=a.length;h-1?t.prototype[r]=function(t){return function(){var r=this.constructor.superclass;this.constructor.superclass=i;var n=e[t].apply(this,arguments);if(this.constructor.superclass=r,"initialize"!==t)return n}}(r):t.prototype[r]=e[r],s&&(e.toString!==Object.prototype.toString&&(t.prototype.toString=e.toString),e.valueOf!==Object.prototype.valueOf&&(t.prototype.valueOf=e.valueOf))};fabric.util.createClass=i}(),function(){function t(t){var e,i,r=Array.prototype.slice.call(arguments,1),n=r.length;for(i=0;i-1?s(t,e.match(/opacity:\s*(\d?\.?\d*)/)[1]):t;for(var r in e)if("opacity"===r)s(t,e[r]);else{var n="float"===r||"cssFloat"===r?"undefined"==typeof i.styleFloat?"cssFloat":"styleFloat":r;i[n]=e[r]}return t}var e=fabric.document.createElement("div"),i="string"==typeof e.style.opacity,r="string"==typeof e.style.filter,n=/alpha\s*\(\s*opacity\s*=\s*([^\)]+)\)/,s=function(t){return t};i?s=function(t,e){return t.style.opacity=e,t}:r&&(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}),fabric.util.setStyle=t}(),function(){function t(t){return"string"==typeof t?fabric.document.getElementById(t):t}function e(t,e){var i=fabric.document.createElement(t);for(var r in e)"class"===r?i.className=e[r]:"for"===r?i.htmlFor=e[r]:i.setAttribute(r,e[r]);return i}function i(t,e){t&&(" "+t.className+" ").indexOf(" "+e+" ")===-1&&(t.className+=(t.className?" ":"")+e)}function r(t,i,r){return"string"==typeof i&&(i=e(i,r)),t.parentNode&&t.parentNode.replaceChild(i,t),i.appendChild(t),i}function n(t){for(var e=0,i=0,r=fabric.document.documentElement,n=fabric.document.body||{scrollLeft:0,scrollTop:0};t&&(t.parentNode||t.host)&&(t=t.parentNode||t.host,t===fabric.document?(e=n.scrollLeft||r.scrollLeft||0,i=n.scrollTop||r.scrollTop||0):(e+=t.scrollLeft||0,i+=t.scrollTop||0),1!==t.nodeType||"fixed"!==fabric.util.getElementStyle(t,"position")););return{left:e,top:i}}function s(t){var e,i,r=t&&t.ownerDocument,s={left:0,top:0},o={left:0,top:0},a={borderLeftWidth:"left",borderTopWidth:"top",paddingLeft:"left",paddingTop:"top"};if(!r)return o;for(var h in a)o[a[h]]+=parseInt(c(t,h),10)||0;return e=r.documentElement,"undefined"!=typeof t.getBoundingClientRect&&(s=t.getBoundingClientRect()),i=n(t),{left:s.left+i.left-(e.clientLeft||0)+o.left,top:s.top+i.top-(e.clientTop||0)+o.top}}var o,a=Array.prototype.slice,h=function(t){return a.call(t,0)};try{o=h(fabric.document.childNodes)instanceof Array}catch(t){}o||(h=function(t){for(var e=new Array(t.length),i=t.length;i--;)e[i]=t[i];return e});var c;c=fabric.document.defaultView&&fabric.document.defaultView.getComputedStyle?function(t,e){var i=fabric.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(){function t(t){return"undefined"!=typeof t.onselectstart&&(t.onselectstart=fabric.util.falseFunction),r?t.style[r]="none":"string"==typeof t.unselectable&&(t.unselectable="on"),t}function e(t){return"undefined"!=typeof t.onselectstart&&(t.onselectstart=null),r?t.style[r]="":"string"==typeof t.unselectable&&(t.unselectable=""),t}var i=fabric.document.documentElement.style,r="userSelect"in i?"userSelect":"MozUserSelect"in i?"MozUserSelect":"WebkitUserSelect"in i?"WebkitUserSelect":"KhtmlUserSelect"in i?"KhtmlUserSelect":"";fabric.util.makeElementUnselectable=t,fabric.util.makeElementSelectable=e}(),function(){function t(t,e){var i=fabric.document.getElementsByTagName("head")[0],r=fabric.document.createElement("script"),n=!0;r.onload=r.onreadystatechange=function(t){if(n){if("string"==typeof this.readyState&&"loaded"!==this.readyState&&"complete"!==this.readyState)return;n=!1,e(t||fabric.window.event),r=r.onload=r.onreadystatechange=null}},r.src=t,i.appendChild(r)}fabric.util.getScript=t}(),fabric.util.getById=t,fabric.util.toArray=h,fabric.util.makeElement=e,fabric.util.addClass=i,fabric.util.wrapElement=r,fabric.util.getScrollLeftTop=n,fabric.util.getElementOffset=s,fabric.util.getElementStyle=c}(),function(){function t(t,e){return t+(/\?/.test(t)?"&":"?")+e}function e(){}function i(i,n){n||(n={});var s=n.method?n.method.toUpperCase():"GET",o=n.onComplete||function(){},a=r(),h=n.body||n.parameters;return a.onreadystatechange=function(){4===a.readyState&&(o(a),a.onreadystatechange=e)},"GET"===s&&(h=null,"string"==typeof n.parameters&&(i=t(i,n.parameters))),a.open(s,i,!0),"POST"!==s&&"PUT"!==s||a.setRequestHeader("Content-Type","application/x-www-form-urlencoded"),a.send(h),a}var r=function(){for(var t=[function(){return new ActiveXObject("Microsoft.XMLHTTP")},function(){return new ActiveXObject("Msxml2.XMLHTTP")},function(){return new ActiveXObject("Msxml2.XMLHTTP.3.0")},function(){return new XMLHttpRequest}],e=t.length;e--;)try{var i=t[e]();if(i)return t[e]}catch(t){}}();fabric.util.request=i}(),fabric.log=function(){},fabric.warn=function(){},"undefined"!=typeof console&&["log","warn"].forEach(function(t){"undefined"!=typeof console[t]&&"function"==typeof console[t].apply&&(fabric[t]=function(){return console[t].apply(console,arguments)})}),function(){function t(){return!1}function e(e){i(function(r){e||(e={});var n,s=r||+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(r){if(c())return void l(d,1,1);n=r||+new Date;var p=n>a?o:n-s,v=p/o,m=u(p,f,g,o),b=Math.abs((m-f)/g);return h(m,b,v),n>a?void(e.onComplete&&e.onComplete()):void i(t)}(s)})}function i(){return r.apply(fabric.window,arguments)}var r=fabric.window.requestAnimationFrame||fabric.window.webkitRequestAnimationFrame||fabric.window.mozRequestAnimationFrame||fabric.window.oRequestAnimationFrame||fabric.window.msRequestAnimationFrame||function(t){fabric.window.setTimeout(t,1e3/60)};fabric.util.animate=e,fabric.util.requestAnimFrame=i}(),function(){function t(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+=")"}function e(e,i,r,n){var s=new fabric.Color(e).getSource(),o=new fabric.Color(i).getSource();n=n||{},fabric.util.animate(fabric.util.object.extend(n,{duration:r||500,startValue:s,endValue:o,byValue:o,easing:function(e,i,r,s){var o=n.colorEasing?n.colorEasing(e,s):1-Math.cos(e/s*(Math.PI/2));return t(i,r,o)}}))}fabric.util.animateColor=e}(),function(){function t(t,e,i,r){return ta?a:o),1===o&&1===a&&0===h&&0===c&&0===f&&0===d)return y;if((f||d)&&(x=" translate("+_(f)+" "+_(d)+") "),r=x+" matrix("+o+" 0 0 "+a+" "+h*o+" "+c*a+") ","svg"===t.nodeName){for(n=t.ownerDocument.createElement("g");t.firstChild;)n.appendChild(t.firstChild);t.appendChild(n)}else n=t,r=n.getAttribute("transform")+r;return n.setAttribute("transform",r),y}function g(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}var p=t.fabric||(t.fabric={}),v=p.util.object.extend,m=p.util.object.clone,b=p.util.toFixed,_=p.util.parseUnit,y=p.util.multiplyTransformMatrices,x=/^(path|circle|polygon|polyline|ellipse|rect|line|image|text)$/i,C=/^(symbol|image|marker|pattern|view|svg)$/i,S=/^(?:pattern|defs|symbol|metadata|clipPath|mask)$/i,w=/^(symbol|g|a|svg)$/i,T={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","stroke-dasharray":"strokeDashArray", +"stroke-linecap":"strokeLineCap","stroke-linejoin":"strokeLineJoin","stroke-miterlimit":"strokeMiterLimit","stroke-opacity":"strokeOpacity","stroke-width":"strokeWidth","text-decoration":"textDecoration","text-anchor":"originX",opacity:"opacity"},O={stroke:"strokeOpacity",fill:"fillOpacity"};p.cssRules={},p.gradientDefs={},p.parseTransformAttribute=function(){function t(t,e){var i=Math.cos(e[0]),r=Math.sin(e[0]),n=0,s=0;3===e.length&&(n=e[1],s=e[2]),t[0]=i,t[1]=r,t[2]=-r,t[3]=i,t[4]=n-(i*n-r*s),t[5]=s-(r*n+i*s)}function e(t,e){var i=e[0],r=2===e.length?e[1]:e[0];t[0]=i,t[3]=r}function i(t,e,i){t[i]=Math.tan(p.util.degreesToRadians(e[0]))}function r(t,e){t[4]=e[0],2===e.length&&(t[5]=e[1])}var n=[1,0,0,1,0,0],s=p.reNum,o="(?:\\s+,?\\s*|,\\s*)",a="(?:(skewX)\\s*\\(\\s*("+s+")\\s*\\))",h="(?:(skewY)\\s*\\(\\s*("+s+")\\s*\\))",c="(?:(rotate)\\s*\\(\\s*("+s+")(?:"+o+"("+s+")"+o+"("+s+"))?\\s*\\))",l="(?:(scale)\\s*\\(\\s*("+s+")(?:"+o+"("+s+"))?\\s*\\))",u="(?:(translate)\\s*\\(\\s*("+s+")(?:"+o+"("+s+"))?\\s*\\))",f="(?:(matrix)\\s*\\(\\s*("+s+")"+o+"("+s+")"+o+"("+s+")"+o+"("+s+")"+o+"("+s+")"+o+"("+s+")\\s*\\))",d="(?:"+f+"|"+u+"|"+l+"|"+c+"|"+a+"|"+h+")",g="(?:"+d+"(?:"+o+"*"+d+")*)",v="^\\s*(?:"+g+"?)\\s*$",m=new RegExp(v),b=new RegExp(d,"g");return function(s){var o=n.concat(),a=[];if(!s||s&&!m.test(s))return o;s.replace(b,function(s){var h=new RegExp(d).exec(s).filter(function(t){return!!t}),c=h[1],l=h.slice(2).map(parseFloat);switch(c){case"translate":r(o,l);break;case"rotate":l[0]=p.util.degreesToRadians(l[0]),t(o,l);break;case"scale":e(o,l);break;case"skewX":i(o,l,2);break;case"skewY":i(o,l,1);break;case"matrix":o=l}a.push(o.concat()),o=n.concat()});for(var h=a[0];a.length>1;)a.shift(),h=p.util.multiplyTransformMatrices(h,a[0]);return h}}();var k=new RegExp("^\\s*("+p.reNum+"+)\\s*,?\\s*("+p.reNum+"+)\\s*,?\\s*("+p.reNum+"+)\\s*,?\\s*("+p.reNum+"+)\\s*$");p.parseSVGDocument=function(t,e,i,r){if(t){f(t);var n=p.Object.__uid++,s=d(t),o=p.util.toArray(t.getElementsByTagName("*"));if(s.crossOrigin=r&&r.crossOrigin,s.svgUid=n,0===o.length&&p.isLikelyNode){o=t.selectNodes('//*[name(.)!="svg"]');for(var a=[],h=0,c=o.length;h/i,""))),n&&n.documentElement||e&&e(null),p.parseSVGDocument(n.documentElement,function(t,i,r,n){e&&e(t,i,r,n)},i,r)}t=t.replace(/^\n\s*/,"").trim(),new p.util.request(t,{method:"get",onComplete:n})},loadSVGFromString:function(t,e,i,r){t=t.trim();var n;if("undefined"!=typeof DOMParser){var s=new DOMParser;s&&s.parseFromString&&(n=s.parseFromString(t,"text/xml"))}else p.window.ActiveXObject&&(n=new ActiveXObject("Microsoft.XMLDOM"),n.async="false",n.loadXML(t.replace(//i,"")));p.parseSVGDocument(n.documentElement,function(t,i,r,n){e(t,i,r,n)},i,r)}})}("undefined"!=typeof exports?exports:this),fabric.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},fabric.ElementsParser.prototype.parse=function(){this.instances=new Array(this.elements.length),this.numElements=this.elements.length,this.createObjects()},fabric.ElementsParser.prototype.createObjects=function(){for(var t=0,e=this.elements.length;tt.x&&this.y>t.y},gte:function(t){return this.x>=t.x&&this.y>=t.y},lerp:function(t,i){return"undefined"==typeof i&&(i=.5),i=Math.max(Math.min(1,i),0),new e(this.x+(t.x-this.x)*i,this.y+(t.y-this.y)*i)},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 e(Math.min(this.x,t.x),Math.min(this.y,t.y))},max:function(t){return new e(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 e(this.x,this.y)}}))}("undefined"!=typeof exports?exports:this),function(t){"use strict";function e(t){this.status=t,this.points=[]}var i=t.fabric||(t.fabric={});return i.Intersection?void i.warn("fabric.Intersection is already defined"):(i.Intersection=e,i.Intersection.prototype={constructor:e,appendPoint:function(t){return this.points.push(t),this},appendPoints:function(t){return this.points=this.points.concat(t),this}},i.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 e("Intersection"),o.appendPoint(new i.Point(t.x+l*(r.x-t.x),t.y+l*(r.y-t.y)))):o=new e}else o=new e(0===a||0===h?"Coincident":"Parallel");return o},i.Intersection.intersectLinePolygon=function(t,i,r){for(var n,s,o,a=new e,h=r.length,c=0;c0&&(a.status="Intersection"),a},i.Intersection.intersectPolygonPolygon=function(t,i){for(var r=new e,n=t.length,s=0;s0&&(r.status="Intersection"),r},void(i.Intersection.intersectPolygonRectangle=function(t,r,n){var s=r.min(n),o=r.max(n),a=new i.Point(o.x,s.y),h=new i.Point(s.x,o.y),c=e.intersectLinePolygon(s,a,t),l=e.intersectLinePolygon(a,o,t),u=e.intersectLinePolygon(o,h,t),f=e.intersectLinePolygon(h,s,t),d=new e;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}))}("undefined"!=typeof exports?exports:this),function(t){"use strict";function e(t){t?this._tryParsingColor(t):this.setSource([0,0,0,1])}function i(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}var r=t.fabric||(t.fabric={});return r.Color?void r.warn("fabric.Color is already defined."):(r.Color=e,r.Color.prototype={_tryParsingColor:function(t){var i;t in e.colorNameMap&&(t=e.colorNameMap[t]),"transparent"===t&&(i=[255,255,255,0]),i||(i=e.sourceFromHex(t)),i||(i=e.sourceFromRgb(t)),i||(i=e.sourceFromHsl(t)),i||(i=[0,0,0,1]),i&&this.setSource(i)},_rgbToHsl:function(t,e,i){t/=255,e/=255,i/=255;var n,s,o,a=r.util.array.max([t,e,i]),h=r.util.array.min([t,e,i]);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=(e-i)/c+(e1?1:s,n){var o=n.split(/\s*;\s*/);""===o[o.length-1]&&o.pop();for(var a=o.length;a--;){var h=o[a].split(/\s*:\s*/),c=h[0].trim(),l=h[1].trim();"stop-color"===c?e=l:"stop-opacity"===c&&(r=l)}}return e||(e=t.getAttribute("stop-color")||"rgb(0,0,0)"),r||(r=t.getAttribute("stop-opacity")),e=new fabric.Color(e),i=e.getAlpha(),r=isNaN(parseFloat(r))?1:parseFloat(r),r*=i,{offset:s,color:e.toRgb(),opacity:r}}function e(t){return{x1:t.getAttribute("x1")||0,y1:t.getAttribute("y1")||0,x2:t.getAttribute("x2")||"100%",y2:t.getAttribute("y2")||0}}function i(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%"}}function r(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+%$/.test(e[a])?.01:1,"x1"===a||"x2"===a||"r2"===a?(s*="objectBoundingBox"===i?t.width:1,n="objectBoundingBox"===i?t.left||0:0):"y1"!==a&&"y2"!==a||(s*="objectBoundingBox"===i?t.height:1,n="objectBoundingBox"===i?t.top||0: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}var n=fabric.util.object.clone;fabric.Gradient=fabric.util.createClass({offsetX:0,offsetY:0,initialize:function(t){t||(t={});var e={};this.id=fabric.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 fabric.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 fabric.util.populateWithProperties(this,e,t),e},toSVG:function(t){var e,i,r=n(this.coords,!0),s=n(this.colorStops,!0),o=r.r1>r.r2;s.sort(function(t,e){return t.offset-e.offset});for(var a in r)"x1"===a||"x2"===a?r[a]+=this.offsetX-t.width/2:"y1"!==a&&"y2"!==a||(r[a]+=this.offsetY-t.height/2);if(i='id="SVGID_'+this.id+'" gradientUnits="userSpaceOnUse"',this.gradientTransform&&(i+=' gradientTransform="matrix('+this.gradientTransform.join(" ")+')" '),"linear"===this.type?e=["\n']:"radial"===this.type&&(e=["\n']),"radial"===this.type){if(o){s=s.concat(),s.reverse();for(var h=0;h0)for(var l=Math.max(r.r1,r.r2),u=c/l,h=0;h\n')}return e.push("linear"===this.type?"\n":"\n"),e.join("")},toLive:function(t){var e,i=fabric.util.object.clone(this.coords);if(this.type){"linear"===this.type?e=t.createLinearGradient(i.x1,i.y1,i.x2,i.y2):"radial"===this.type&&(e=t.createRadialGradient(i.x1,i.y1,i.r1,i.x2,i.y2,i.r2));for(var r=0,n=this.colorStops.length;r\n\n\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("undefined"!=typeof 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;return e.Shadow?void 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,initialize:function(t){"string"==typeof t&&(t=this._parseShadow(t));for(var i in t)this[i]=t[i];this.id=e.Object.__uid++},_parseShadow:function(t){var i=t.trim(),r=e.Shadow.reOffsetsAndBlur.exec(i)||[],n=i.replace(e.Shadow.reOffsetsAndBlur,"")||"rgb(0,0,0)";return{color:n.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=20;return t.width&&t.height&&(r=100*i((Math.abs(o.x)+this.blur)/t.width,s)+a,n=100*i((Math.abs(o.y)+this.blur)/t.height,s)+a),t.flipX&&(o.x*=-1),t.flipY&&(o.y*=-1),'\n\t\n\t\n\t\n\t\n\t\n\t\t\n\t\t\n\t\n\n'},toObject:function(){if(this.includeDefaultValues)return{color:this.color,blur:this.blur,offsetX:this.offsetX,offsetY:this.offsetY,affectStroke:this.affectStroke};var t={},i=e.Shadow.prototype;return["color","blur","offsetX","offsetY","affectStroke"].forEach(function(e){this[e]!==i[e]&&(t[e]=this[e])},this),t}}),void(e.Shadow.reOffsetsAndBlur=/(?:\s|^)(-?\d+(?:px)?(?:\s?|$))?(-?\d+(?:px)?(?:\s?|$))?(\d+(?:px)?)?(?:\s?|$)(?:$|\s)/))}("undefined"!=typeof exports?exports:this),function(){"use strict";if(fabric.StaticCanvas)return void fabric.warn("fabric.StaticCanvas is already defined.");var t=fabric.util.object.extend,e=fabric.util.getElementOffset,i=fabric.util.removeFromArray,r=fabric.util.toFixed,n=fabric.util.transformPoint,s=fabric.util.invertTransform,o=new Error("Could not initialize `canvas` element");fabric.StaticCanvas=fabric.util.createClass(fabric.CommonMethods,{initialize:function(t,e){e||(e={}),this.renderAndResetBound=this.renderAndReset.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:fabric.iMatrix.concat(),backgroundVpt:!0,overlayVpt:!0,onBeforeScaleRotate:function(){},enableRetinaScaling:!0,vptCoords:{},skipOffscreen:!0,_initStatic:function(t,e){var i=fabric.StaticCanvas.prototype.renderAll.bind(this);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!==fabric.devicePixelRatio&&this.enableRetinaScaling},getRetinaScaling:function(){return this._isRetinaScaling()?fabric.devicePixelRatio:1},_initRetinaScaling:function(){this._isRetinaScaling()&&(this.lowerCanvasEl.setAttribute("width",this.width*fabric.devicePixelRatio),this.lowerCanvasEl.setAttribute("height",this.height*fabric.devicePixelRatio),this.contextContainer.scale(fabric.devicePixelRatio,fabric.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,r){return"string"==typeof e?fabric.util.loadImage(e,function(e){e&&(this[t]=new fabric.Image(e,r)),i&&i(e)},this,r&&r.crossOrigin):(r&&e.setOptions(r),this[t]=e,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(t){var e=fabric.util.createCanvasElement(t);if(e.style||(e.style={}),!e)throw o;if("undefined"==typeof e.getContext)throw o;return e},_initOptions:function(t){this._setOptions(t),this.width=this.width||parseInt(this.lowerCanvasEl.width,10)||0,this.height=this.height||parseInt(this.lowerCanvasEl.height,10)||0,this.lowerCanvasEl.style&&(this.lowerCanvasEl.width=this.width,this.lowerCanvasEl.height=this.height,this.lowerCanvasEl.style.width=this.width+"px",this.lowerCanvasEl.style.height=this.height+"px",this.viewportTransform=this.viewportTransform.slice())},_createLowerCanvas:function(t){this.lowerCanvasEl=fabric.util.getById(t)||this._createCanvasElement(t),fabric.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;e=e||{};for(var r in t)i=t[r],e.cssOnly||(this._setBackstoreDimension(r,t[r]),i+="px"),e.backstoreOnly||this._setCssDimension(r,i);return this._initRetinaScaling(),this._setImageSmoothing(),this.calcOffset(),e.cssOnly||this.renderAll(),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=this._activeGroup,r=!1,n=!0;this.viewportTransform=t;for(var s=0,o=this._objects.length;s"),i.join("")},_setSVGPreamble:function(t,e){e.suppressPreamble||t.push('\n','\n')},_setSVGHeader:function(t,e){var i,n=e.width||this.width,s=e.height||this.height,o='viewBox="0 0 '+this.width+" "+this.height+'" ',a=fabric.Object.NUM_FRACTION_DIGITS;e.viewBox?o='viewBox="'+e.viewBox.x+" "+e.viewBox.y+" "+e.viewBox.width+" "+e.viewBox.height+'" ':this.svgViewportTransformation&&(i=this.viewportTransform,o='viewBox="'+r(-i[4]/i[0],a)+" "+r(-i[5]/i[3],a)+" "+r(this.width/i[0],a)+" "+r(this.height/i[3],a)+'" '),t.push("\n',"Created with Fabric.js ",fabric.version,"\n","\n",this.createSVGFontFacesMarkup(),this.createSVGRefElementsMarkup(),"\n")},createSVGRefElementsMarkup:function(){var t=this,e=["backgroundColor","overlayColor"].map(function(e){var i=t[e];if(i&&i.toLive)return i.toSVG(t,!1)});return e.join("")},createSVGFontFacesMarkup:function(){for(var t,e,i,r,n,s,o,a="",h={},c=fabric.fontPaths,l=this.getObjects(),u=0,f=l.length;u',"\n",a,"","\n"].join("")),a},_setSVGObjects:function(t,e){for(var i,r=0,n=this.getObjects(),s=n.length;r\n")}else t.push('\n")},sendToBack:function(t){if(!t)return this;var e,r,n,s=this._activeGroup;if(t===s)for(n=s._objects,e=n.length;e--;)r=n[e],i(this._objects,r),this._objects.unshift(r);else i(this._objects,t),this._objects.unshift(t);return this.renderAll&&this.renderAll(),this},bringToFront:function(t){if(!t)return this;var e,r,n,s=this._activeGroup;if(t===s)for(n=s._objects,e=0;e=0;--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},bringForward:function(t,e){if(!t)return this;var r,n,s,o,a,h=this._activeGroup;if(t===h)for(a=h._objects,r=a.length;r--;)n=a[r],s=this._objects.indexOf(n),s!==this._objects.length-1&&(o=s+1,i(this._objects,n),this._objects.splice(o,0,n));else s=this._objects.indexOf(t),s!==this._objects.length-1&&(o=this._findNewUpperIndex(t,s,e),i(this._objects,t),this._objects.splice(o,0,t));return this.renderAll&&this.renderAll(),this},_findNewUpperIndex:function(t,e,i){var r;if(i){r=e;for(var n=e+1;n"}}),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;n0?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&&cs?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)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.width+"px",height:this.height+"px",position:"relative"}),fabric.util.makeElementUnselectable(this.wrapperEl)},_applyCanvasStyle:function(t){var e=this.width||t.width,i=this.height||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.requestRenderAll(),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;i1)){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.requestRenderAll()},_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 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.getActiveGroup(),n=e._findTargetCorner&&(!r||!r.contains(e))&&e._findTargetCorner(this.getPointer(t,!0));n?this.setCursor(this.getCornerCursor(n,e,t)):this.setCursor(i)},getCornerCursor:function(t,i,r){return this.actionIsDisabled(t,i,r)?this.notAllowedCursor:t in e?this._getRotatedCornerCursor(t,i,r):"mtr"===t&&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(t,i,r){var n=Math.round(i.angle%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))},_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)1&&(e=new fabric.Group(e.reverse(),{canvas:this}),e.addWithUpdate(),this.setActiveGroup(e,t),this.fire("selection:created",{target:e,e:t}),this.requestRenderAll())},_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.width,s=this.height,o=(i.width||this.width)*r,a=(i.height||this.height)*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.width,e.height=this.height;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:"",stroke:null,strokeWidth:1,strokeDashArray:null,strokeLineCap:"butt",strokeLineJoin:"miter",strokeMiterLimit:10,shadow:null,borderOpacityWhenMoving:.4,borderScaleFactor:1,transformMatrix:null,minScaleLimit:.01,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,dirty:!0,stateProperties:"top left width height scaleX scaleY flipX flipY originX originY transformMatrix stroke strokeWidth strokeDashArray strokeLineCap strokeLineJoin strokeMiterLimit angle opacity fill globalCompositeOperation shadow clipTo visible backgroundColor skewX skewY fillRule".split(" "),cacheProperties:"fill stroke strokeWidth strokeDashArray width height strokeLineCap strokeLineJoin strokeMiterLimit backgroundColor".split(" "),initialize:function(t){t=t||{},t&&this.setOptions(t)},_createCacheCanvas:function(){this._cacheProperties={},this._cacheCanvas=e.document.createElement("canvas"),this._cacheContext=this._cacheCanvas.getContext("2d"),this._updateCacheCanvas()},_limitCacheSize:function(t){var i=e.perfLimitSizeTotal,r=e.cacheSideLimit,n=t.width,s=t.height,o=n/s,a=e.util.limitDimsByArea(o,i,r),h=e.util.capValue,c=e.maxCacheSideLimit,l=e.minCacheSideLimit,u=h(l,a.x,c),f=h(l,a.y,c);return n>u?(t.zoomX/=n/u,t.width=u):nf?(t.zoomY/=s/f,t.height=f):sg||s>p,m=(n<.9*g||s<.9*p)&&g>r&&p>r;d=v||m,v&&(u=.1*n&-2,f=.1*s&-2)}return!!l&&(d?(this._cacheCanvas.width=Math.max(Math.ceil(n)+u,r),this._cacheCanvas.height=Math.max(Math.ceil(s)+f,r),this.cacheTranslationX=(n+u)/2,this.cacheTranslationY=(s+f)/2):(this._cacheContext.setTransform(1,0,0,1,0,0),this._cacheContext.clearRect(0,0,this._cacheCanvas.width,this._cacheCanvas.height)),this.cacheWidth=n,this.cacheHeight=s,this._cacheContext.translate(this.cacheTranslationX,this.cacheTranslationY),this._cacheContext.scale(o,a),this.zoomX=o,this.zoomY=a,!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,e){this.group&&!this.group._transformDone&&this.group.transform(t);var i=e?this._getLeftTopCoords():this.getCenterPoint();t.translate(i.x,i.y),this.angle&&t.rotate(o(this.angle)),t.scale(this.scaleX*(this.flipX?-1:1),this.scaleY*(this.flipY?-1:1)),this.skewX&&t.transform(1,0,Math.tan(o(this.skewX)),1,0,0),this.skewY&&t.transform(1,Math.tan(o(this.skewY)),0,1,0,0)},toObject:function(t){var i=e.Object.NUM_FRACTION_DIGITS,r={type:this.type,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,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,globalCompositeOperation:this.globalCompositeOperation,transformMatrix:this.transformMatrix?this.transformMatrix.concat():null,skewX:n(this.skewX,i),skewY:n(this.skewY,i)};return 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,r=i.stateProperties;return r.forEach(function(e){t[e]===i[e]&&delete t[e];var r="[object Array]"===Object.prototype.toString.call(t[e])&&"[object Array]"===Object.prototype.toString.call(i[e]);r&&0===t[e].length&&0===i[e].length&&delete t[e]}),t},toString:function(){return"#"},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}},getObjectOpacity:function(){var t=this.opacity;return this.group&&(t*=this.group.getObjectOpacity()),t},_set:function(t,i){var r="scaleX"===t||"scaleY"===t;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,this.cacheProperties.indexOf(t)>-1&&(this.group&&this.group.set("dirty",!0),this.dirty=!0),this.group&&this.stateProperties.indexOf(t)>-1&&this.group.isOnACache()&&this.group.set("dirty",!0),"width"!==t&&"height"!==t||(this.minScaleLimit=Math.min(.1,1/Math.max(this.width,this.height))),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||!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._cacheCanvas||this._createCacheCanvas(),this.isCacheDirty()&&(this.statefullCache&&this.saveState({propertySet:"cacheProperties"}),this.drawObject(this._cacheContext),this.dirty=!1),this.drawCacheOnCanvas(t)):(this.dirty=!1,this.drawObject(t),this.objectCaching&&this.statefullCache&&this.saveState({propertySet:"cacheProperties"})),this.clipTo&&t.restore(),t.restore())},needsItsOwnCache:function(){return!1},shouldCache:function(){return this.ownCaching=this.objectCaching&&(!this.group||this.needsItsOwnCache()||!this.group.isOnACache()),this.ownCaching},willDrawShadow:function(){return!!this.shadow&&(0!==this.shadow.offsetX||0!==this.shadow.offsetY)},drawObject:function(t){this._renderBackground(t),this._setStrokeStyles(t,this),this._setFillStyles(t,this),this._render(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.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.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)},_setLineDash:function(t,e,i){e&&(1&e.length&&e.push.apply(e,e),a?t.setLineDash(e):i&&i(t))},_renderControls:function(t,i){var r,n,s,a=this.getViewportTransform(),h=this.calcTransformMatrix();i=i||{},n="undefined"!=typeof i.hasBorders?i.hasBorders:this.hasBorders,s="undefined"!=typeof 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),this.group&&this.group===this.canvas.getActiveGroup()?(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=this.canvas&&this.canvas.viewportTransform[0]||1,r=this.canvas&&this.canvas.viewportTransform[3]||1,n=this.getObjectScaling();this.canvas&&this.canvas._isRetinaScaling()&&(i*=e.devicePixelRatio,r*=e.devicePixelRatio),t.shadowColor=this.shadow.color,t.shadowBlur=this.shadow.blur*(i+r)*(n.scaleX+n.scaleY)/4,t.shadowOffsetX=this.shadow.offsetX*i*n.scaleX,t.shadowOffsetY=this.shadow.offsetY*r*n.scaleY}},_removeShadow:function(t){this.shadow&&(t.shadowColor="",t.shadowBlur=t.shadowOffsetX=t.shadowOffsetY=0)},_applyPatternGradientTransform:function(t,e){if(e.toLive){var i=e.gradientTransform||e.patternTransform,r=-this.width/2+e.offsetX||0,n=-this.height/2+e.offsetY||0;t.translate(r,n),i&&t.transform.apply(t,i)}},_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._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}},_removeTransformMatrix:function(){var t=this._findCenterFromElement();if(this.transformMatrix){var i=e.util.qrDecompose(this.transformMatrix);this.flipX=!1,this.flipY=!1,this.set("scaleX",i.scaleX),this.set("scaleY",i.scaleY),this.angle=i.angle,this.skewX=i.skewX,this.skewY=0,t=e.util.transformPoint(t,this.transformMatrix)}this.transformMatrix=null,this.setPositionByOrigin(t,"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.toDataURL(i);return e.util.loadImage(r,function(i){t&&t(new e.Image(i))}),this},toDataURL:function(t){t||(t={});var i=e.util.createCanvasElement(),r=this.getBoundingRect();i.width=r.width,i.height=r.height,e.util.wrapElement(i,"div");var n=new e.StaticCanvas(i,{enableRetinaScaling:t.enableRetinaScaling});"jpg"===t.format&&(t.format="jpeg"),"jpeg"===t.format&&(n.backgroundColor="#fff");var s={active:this.active,left:this.left,top:this.top};this.set("active",!1),this.setPositionByOrigin(new e.Point(n.width/2,n.height/2),"center","center");var o=this.canvas;n.add(this);var a=n.toDataURL(t);return this.set(s).setCoords(),this.canvas=o,n.dispose(),n=null,a},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){return this.set("fill",new e.Pattern(t))},setShadow:function(t){return this.set("shadow",t?new e.Shadow(t):null)},setColor:function(t){return this.set("fill",t),this},setAngle: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},remove:function(){return this.canvas&&this.canvas.remove(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),e.Object.prototype.rotate=e.Object.prototype.setAngle,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){"undefined"!=typeof t[0]&&(i.fill=t[0]),"undefined"!=typeof t[1]&&(i.stroke=t[1]);var e=s?new o(i[s],i):new o(i);n&&n(e)})},e.Object.__uid=0)}("undefined"!=typeof exports?exports:this),function(){var t=fabric.util.degreesToRadians,e={left:-.5,center:0,right:.5},i={top:-.5,center:0,bottom:.5};fabric.util.object.extend(fabric.Object.prototype,{translateToGivenOrigin:function(t,r,n,s,o){var a,h,c,l=t.x,u=t.y;return"string"==typeof r?r=e[r]:r-=.5,"string"==typeof s?s=e[s]:s-=.5,a=s-r,"string"==typeof n?n=i[n]:n-=.5,"string"==typeof o?o=i[o]:o-=.5,h=o-n,(a||h)&&(c=this._getTransformedDimensions(),l=t.x+a*c.x,u=t.y+h*c.y),new fabric.Point(l,u)},translateToCenterPoint:function(e,i,r){var n=this.translateToGivenOrigin(e,i,r,"center","center");return this.angle?fabric.util.rotatePoint(n,e,t(this.angle)):n},translateToOriginPoint:function(e,i,r){var n=this.translateToGivenOrigin(e,"center","center",i,r);return this.angle?fabric.util.rotatePoint(n,e,t(this.angle)):n},getCenterPoint:function(){var t=new fabric.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,r){var n,s,o=this.getCenterPoint();return n="undefined"!=typeof i&&"undefined"!=typeof r?this.translateToGivenOrigin(o,"center","center",i,r):new fabric.Point(this.left,this.top),s=new fabric.Point(e.x,e.y),this.angle&&(s=fabric.util.rotatePoint(s,o,-t(this.angle))),s.subtractEquals(n)},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 r,n,s=t(this.angle),o=this.getScaledWidth(),a=Math.cos(s)*o,h=Math.sin(s)*o;r="string"==typeof this.originX?e[this.originX]:this.originX-.5,n="string"==typeof i?e[i]:i-.5,this.left+=a*(n-r),this.top+=h*(n-r),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")},onDeselect:function(){}})}(),function(){function t(t){return[new fabric.Point(t.tl.x,t.tl.y),new fabric.Point(t.tr.x,t.tr.y),new fabric.Point(t.br.x,t.br.y),new fabric.Point(t.bl.x,t.bl.y)]}var e=fabric.util.degreesToRadians,i=fabric.util.multiplyTransformMatrices;fabric.util.object.extend(fabric.Object.prototype,{oCoords:null,aCoords:null,getCoords:function(e,i){this.oCoords||this.setCoords();var r=e?this.aCoords:this.oCoords;return t(i?this.calcCoords(e):r)},intersectsWithRect:function(t,e,i,r){var n=this.getCoords(i,r),s=fabric.Intersection.intersectPolygonRectangle(n,t,e);return"Intersection"===s.status},intersectsWithObject:function(t,e,i){var r=fabric.Intersection.intersectPolygonPolygon(this.getCoords(e,i),t.getCoords(e,i));return"Intersection"===r.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){var e=e||this._getImageLines(r?this.calcCoords(i):i?this.aCoords:this.oCoords),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],e.x<=r.x&&e.x>=i.x&&e.y<=r.y&&e.y>=i.y)return!0;if(this.intersectsWithRect(i,r,!0))return!0;var o={x:(i.x+r.x)/2,y:(i.y+r.y)/2};return!!this.containsPoint(o,null,!0)},_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,a,h=0;for(var c in e)if(a=e[c],!(a.o.y=t.y&&a.d.y>=t.y||(a.o.x===a.d.x&&a.o.x>=t.x?o=a.o.x:(i=0,r=(a.d.y-a.o.y)/(a.d.x-a.o.x),n=t.y-i*t.x,s=a.o.y-r*a.o.x,o=-(n-s)/(i-r)),o>=t.x&&(h+=1),2!==h)))break;return h},getBoundingRectWidth:function(){return this.getBoundingRect().width},getBoundingRectHeight:function(){return this.getBoundingRect().height},getBoundingRect:function(t,e){var i=this.getCoords(t,e);return fabric.util.makeBoundingBoxFromPoints(i)},getScaledWidth:function(){return this._getTransformedDimensions().x},getScaledHeight:function(){return this._getTransformedDimensions().y},_constrainScale:function(t){return Math.abs(t)0?Math.atan(o/s):0,l=s/Math.cos(c)/2,u=Math.cos(c+i)*l,f=Math.sin(c+i)*l,d=this.getCenterPoint(),g=t?d:fabric.util.transformPoint(d,r),p=new fabric.Point(g.x-u,g.y-f),v=new fabric.Point(p.x+s*h,p.y+s*a),m=new fabric.Point(p.x-o*a,p.y+o*h),b=new fabric.Point(g.x+u,g.y+f);if(!t)var _=new fabric.Point((p.x+m.x)/2,(p.y+m.y)/2),y=new fabric.Point((v.x+p.x)/2,(v.y+p.y)/2),x=new fabric.Point((b.x+v.x)/2,(b.y+v.y)/2),C=new fabric.Point((b.x+m.x)/2,(b.y+m.y)/2),S=new fabric.Point(y.x+a*this.rotatingPointOffset,y.y-h*this.rotatingPointOffset);var g={tl:p,tr:v,br:b,bl:m};return t||(g.ml=_,g.mt=y,g.mr=x,g.mb=C,g.mtr=S),g},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 t=e(this.angle),i=Math.cos(t),r=Math.sin(t);return 6.123233995736766e-17!==i&&i!==-1.8369701987210297e-16||(i=0),[i,r,-r,i,0,0]}return fabric.iMatrix.concat()},calcTransformMatrix:function(t){var e=this.getCenterPoint(),r=[1,0,0,1,e.x,e.y],n=this._calcRotateMatrix(),s=this._calcDimensionsTransformMatrix(this.skewX,this.skewY,!0),o=this.group&&!t?this.group.calcTransformMatrix():fabric.iMatrix.concat();return o=i(o,r),o=i(o,n),o=i(o,s)},_calcDimensionsTransformMatrix:function(t,r,n){var s=[1,0,Math.tan(e(t)),1],o=[1,Math.tan(e(r)),0,1],a=this.scaleX*(n&&this.flipX?-1:1),h=this.scaleY*(n&&this.flipY?-1:1),c=[a,0,0,h],l=i(c,s,!0);return i(l,o,!0)},_getNonTransformedDimensions:function(){var t=this.strokeWidth,e=this.width+t,i=this.height+t;return{x:e,y:i}},_getTransformedDimensions:function(t,e){"undefined"==typeof t&&(t=this.skewX),"undefined"==typeof e&&(e=this.skewY);var i,r,n=this._getNonTransformedDimensions(),s=n.x/2,o=n.y/2,a=[{x:-s,y:-o},{x:s,y:-o},{x:-s,y:o},{x:s,y:o}],h=this._calcDimensionsTransformMatrix(t,e,!1);for(i=0;i\n')},_createBaseSVGMarkup:function(){var t=[];return this.fill&&this.fill.toLive&&t.push(this.fill.toSVG(this,!1)),this.stroke&&this.stroke.toLive&&t.push(this.stroke.toSVG(this,!1)),this.shadow&&t.push(this.shadow.toSVG(this)),t}})}(),function(){function t(t,e,r){var n={},s=!0;r.forEach(function(e){n[e]=t[e]}),i(t[e],n,s)}function e(t,i,r){if(t===i)return!0;if(Array.isArray(t)){if(t.length!==i.length)return!1;for(var n=0,s=t.length;n\n'),t?t(e.join("")):e.join("")}}),i.Line.ATTRIBUTE_NAMES=i.SHARED_ATTRIBUTES.concat("x1 y1 x2 y2".split(" ")),i.Line.fromElement=function(t,e,n){n=n||{};var s=i.parseAttributes(t,i.Line.ATTRIBUTE_NAMES),o=[s.x1||0,s.y1||0,s.x2||0,s.y2||0];n.originX="left",n.originY="top",e(new i.Line(o,r(s,n)))},i.Line.fromObject=function(t,e){function r(t){delete t.points,e&&e(t)}var s=n(t,!0);s.points=[t.x1,t.y1,t.x2,t.y2],i.Object._fromObject("Line",s,r,"points")}}("undefined"!=typeof exports?exports:this),function(t){"use strict";function e(t){return"radius"in t&&t.radius>=0}var i=t.fabric||(t.fabric={}),r=Math.PI,n=i.util.object.extend;if(i.Circle)return void i.warn("fabric.Circle is already defined.");var s=i.Object.prototype.cacheProperties.concat();s.push("radius"),i.Circle=i.util.createClass(i.Object,{type:"circle",radius:0,startAngle:0,endAngle:2*r,cacheProperties:s,initialize:function(t){this.callSuper("initialize",t),this.set("radius",t&&t.radius||0)},_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(t){var e=this._createBaseSVGMarkup(),i=0,n=0,s=(this.endAngle-this.startAngle)%(2*r);if(0===s)e.push("\n');else{var o=Math.cos(this.startAngle)*this.radius,a=Math.sin(this.startAngle)*this.radius,h=Math.cos(this.endAngle)*this.radius,c=Math.sin(this.endAngle)*this.radius,l=s>r?"1":"0";e.push('\n')}return t?t(e.join("")):e.join("")},_render:function(t){t.beginPath(),t.arc(0,0,this.radius,this.startAngle,this.endAngle,!1),this._renderFill(t),this._renderStroke(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)}}),i.Circle.ATTRIBUTE_NAMES=i.SHARED_ATTRIBUTES.concat("cx cy r".split(" ")),i.Circle.fromElement=function(t,r,s){s||(s={});var o=i.parseAttributes(t,i.Circle.ATTRIBUTE_NAMES);if(!e(o))throw new Error("value of `r` attribute is required and can not be negative");o.left=(o.left||0)-o.radius,o.top=(o.top||0)-o.radius,o.originX="left",o.originY="top",r(new i.Circle(n(o,s)))},i.Circle.fromObject=function(t,e){return i.Object._fromObject("Circle",t,e)}}("undefined"!=typeof exports?exports:this),function(t){"use strict";var e=t.fabric||(t.fabric={});return e.Triangle?void e.warn("fabric.Triangle is already defined"):(e.Triangle=e.util.createClass(e.Object,{type:"triangle",initialize:function(t){this.callSuper("initialize",t),this.set("width",t&&t.width||100).set("height",t&&t.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._renderFill(t),this._renderStroke(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(t){var e=this._createBaseSVGMarkup(),i=this.width/2,r=this.height/2,n=[-i+" "+r,"0 "+-r,i+" "+r].join(",");return e.push("'),t?t(e.join("")):e.join("")}}),void(e.Triangle.fromObject=function(t,i){return e.Object._fromObject("Triangle",t,i)}))}("undefined"!=typeof exports?exports:this),function(t){"use strict";var e=t.fabric||(t.fabric={}),i=2*Math.PI,r=e.util.object.extend;if(e.Ellipse)return void e.warn("fabric.Ellipse is already defined.");var n=e.Object.prototype.cacheProperties.concat();n.push("rx","ry"),e.Ellipse=e.util.createClass(e.Object,{type:"ellipse",rx:0,ry:0,cacheProperties:n,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(t){var e=this._createBaseSVGMarkup(),i=0,r=0;return e.push("\n'),t?t(e.join("")):e.join("")},_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._renderFill(t),this._renderStroke(t)}}),e.Ellipse.ATTRIBUTE_NAMES=e.SHARED_ATTRIBUTES.concat("cx cy rx ry".split(" ")),e.Ellipse.fromElement=function(t,i,n){n||(n={});var s=e.parseAttributes(t,e.Ellipse.ATTRIBUTE_NAMES);s.left=(s.left||0)-s.rx,s.top=(s.top||0)-s.ry,s.originX="left",s.originY="top",i(new e.Ellipse(r(s,n)))},e.Ellipse.fromObject=function(t,i){return e.Object._fromObject("Ellipse",t,i)}}("undefined"!=typeof exports?exports:this),function(t){"use strict";var e=t.fabric||(t.fabric={}),i=e.util.object.extend;if(e.Rect)return void e.warn("fabric.Rect is already defined");var r=e.Object.prototype.stateProperties.concat();r.push("rx","ry");var n=e.Object.prototype.cacheProperties.concat();n.push("rx","ry"),e.Rect=e.util.createClass(e.Object,{stateProperties:r,type:"rect",rx:0,ry:0,cacheProperties:n,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){if(1===this.width&&1===this.height)return void t.fillRect(-.5,-.5,1,1);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._renderFill(t),this._renderStroke(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(t){var e=this._createBaseSVGMarkup(),i=-this.width/2,r=-this.height/2;return e.push("\n'),t?t(e.join("")):e.join("")}}),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.originX="left",s.originY="top";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)}}("undefined"!=typeof exports?exports:this),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,o=e.Object.NUM_FRACTION_DIGITS;if(e.Polyline)return void e.warn("fabric.Polyline is already defined");var a=e.Object.prototype.cacheProperties.concat();a.push("points"),e.Polyline=e.util.createClass(e.Object,{type:"polyline",points:null,minX:0,minY:0,cacheProperties:a,initialize:function(t,e){e=e||{},this.points=t||[],this.callSuper("initialize",e),this._calcDimensions(),"top"in e||(this.top=this.minY),"left"in e||(this.left=this.minX),this.pathOffset={x:this.minX+this.width/2,y:this.minY+this.height/2}},_calcDimensions:function(){var t=this.points,e=r(t,"x"),i=r(t,"y"),s=n(t,"x"),o=n(t,"y");this.width=s-e||0,this.height=o-i||0,this.minX=e||0,this.minY=i||0},toObject:function(t){return i(this.callSuper("toObject",t),{points:this.points.concat()})},toSVG:function(t){for(var e=[],i=this.pathOffset.x,r=this.pathOffset.y,n=this._createBaseSVGMarkup(),a=0,h=this.points.length;a\n'),t?t(n.join("")):n.join("")},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"},toObject:function(t){var e=n(this.callSuper("toObject",["sourcePath","pathOffset"].concat(t)),{path:this.path.map(function(t){return t.slice()}),top:this.top,left:this.left});return e},toDatalessObject:function(t){var e=this.toObject(t);return this.sourcePath&&(e.path=this.sourcePath),delete e.sourcePath,e},toSVG:function(t){for(var e=[],i=this._createBaseSVGMarkup(),r="",n=0,s=this.path.length;n\n"),t?t(i.join("")):i.join("")},complexity:function(){return this.path.length},_parsePath:function(){for(var t,e,i,r,n,s=[],o=[],c=/([-+]?((\d+\.\d+)|((\d+)|(\.\d+)))(?:e[-+]?\d+)?)/gi,l=0,u=this.path.length;lp)for(var m=1,b=n.length;m"},addWithUpdate:function(t){return this._restoreObjectsState(),e.util.resetObjectTransform(this),t&&(this._objects.push(t),t.group=this,t._set("canvas",this.canvas)),this.forEachObject(this._setObjectActive,this),this._calcBounds(),this._updateObjectsCoords(),this.setCoords(),this.dirty=!0,this},_setObjectActive:function(t){t.set("active",!0),t.group=this},removeWithUpdate:function(t){return this._restoreObjectsState(),e.util.resetObjectTransform(this),this.forEachObject(this._setObjectActive,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,t.set("active",!1)},_set:function(t,e){var i=this._objects.length;if("canvas"===t)for(;i--;)this._objects[i].set(t,e);if(this.useSetOnGroup)for(;i--;)this._objects[i].setOnGroup(t,e);this.callSuper("_set",t,e)},toObject:function(t){var e=this.getObjects().map(function(e){var i=e.includeDefaultValues;e.includeDefaultValues=e.group.includeDefaultValues;var r=e.toObject(t);return e.includeDefaultValues=i,r});return i(this.callSuper("toObject",t),{objects:e})},toDatalessObject:function(t){var e,r=this.sourcePath;return e=r?r:this.getObjects().map(function(e){var i=e.includeDefaultValues;e.includeDefaultValues=e.group.includeDefaultValues;var r=e.toDatalessObject(t);return e.includeDefaultValues=i,r}),i(this.callSuper("toDatalessObject",t),{objects:e})},render:function(t){this._transformDone=!0,this.callSuper("render",t),this._transformDone=!1},shouldCache:function(){var t=this.objectCaching&&(!this.group||this.needsItsOwnCache()||!this.group.isOnACache());if(this.ownCaching=t,t)for(var e=0,i=this._objects.length;e\n');for(var i=0,r=this._objects.length;i\n"),t?t(e.join("")):e.join("")}}),e.Group.fromObject=function(t,i){e.util.enlivenObjects(t.objects,function(r){delete t.objects,i&&i(new e.Group(r,t,!0))})})}("undefined"!=typeof exports?exports:this),function(t){"use strict";var e=fabric.util.object.extend;if(t.fabric||(t.fabric={}),t.fabric.Image)return void fabric.warn("fabric.Image is already defined.");var i=fabric.Object.prototype.stateProperties.concat();i.push("cropX","cropY"),fabric.Image=fabric.util.createClass(fabric.Object,{type:"image",crossOrigin:"",strokeWidth:0,_lastScaleX:1,_lastScaleY:1,_filterScalingX:1,_filterScalingY:1,minimumScaleTrigger:.5,stateProperties:i,objectCaching:!1,cacheKey:"",cropX:0,cropY:0,initialize:function(t,e){e||(e={}),this.filters=[],this.callSuper("initialize",e),this._initElement(t,e),this.cacheKey="texture"+fabric.Object.__uid++},getElement:function(){return this._element},setElement:function(t,e){return this._element=t,this._originalElement=t,this._initConfig(e),this.resizeFilter&&this.applyResizeFilters(),0!==this.filters.length&&this.applyFilters(),this},setCrossOrigin:function(t){return this.crossOrigin=t,this._element.crossOrigin=t,this},getOriginalSize:function(){var t=this.getElement();return{width:t.width,height: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,r=this.width,n=this.height;t.save(),this._setStrokeStyles(t,this),t.beginPath(),fabric.util.drawDashedLine(t,e,i,e+r,i,this.strokeDashArray),fabric.util.drawDashedLine(t,e+r,i,e+r,i+n,this.strokeDashArray),fabric.util.drawDashedLine(t,e+r,i+n,e,i+n,this.strokeDashArray),fabric.util.drawDashedLine(t,e,i+n,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.width/=this._filterScalingX,r.height/=this._filterScalingY,r},toSVG:function(t){var e=this._createBaseSVGMarkup(),i=-this.width/2,r=-this.height/2,n=!0;if(e.push('\n',"\n"),this.stroke||this.strokeDashArray){var s=this.fill;this.fill=null,e.push("\n'),this.fill=s}return e.push("\n"),t?t(e.join("")):e.join("")},getSrc:function(t){var e=t?this._element:this._originalElement;return e?fabric.isLikelyNode?e._src:e.src:this.src||""},setSrc:function(t,e,i){return fabric.util.loadImage(t,function(t){this.setElement(t,i),e(this)},this,i&&i.crossOrigin),this},toString:function(){return'#'},applyResizeFilters:function(){var t=this.resizeFilter,e=this.canvas?this.canvas.getRetinaScaling():1,i=this.minimumScaleTrigger,r=this.scaleX=1&&n>=1)return void(this._element=this._filteredEl);fabric.filterBackend||(fabric.filterBackend=fabric.initFilterBackend());var s,o=this._filteredEl||this._originalElement;if(this._element===this._originalElement){var a=fabric.util.createCanvasElement();a.width=o.width,a.height=o.height,this._element=a}var h=this._element.getContext("2d");o.getContext?s=o.getContext("2d").getImageData(0,0,o.width,o.height):(h.drawImage(o,0,0),s=h.getImageData(0,0,o.width,o.height));var c={imageData:s,scaleX:r,scaleY:n};t.applyTo2d(c),this.width=this._element.width=c.imageData.width,this.height=this._element.height=c.imageData.height,h.putImageData(c.imageData,0,0)},applyFilters:function(t){if(t=t||this.filters||[],t=t.filter(function(t){return t}),0===t.length)return this._element=this._originalElement,this._filterScalingX=1,this._filterScalingY=1,this;var e=this._originalElement,i=e.naturalWidth||e.width,r=e.naturalHeight||e.height;if(this._element===this._originalElement){var n=fabric.util.createCanvasElement();n.width=e.width,n.height=e.height,this._element=n}else this._element.getContext("2d").clearRect(0,0,i,r);return fabric.filterBackend||(fabric.filterBackend=fabric.initFilterBackend()),fabric.filterBackend.applyFilters(t,this._originalElement,i,r,this._element,this.cacheKey),this.width===this._element.width&&this.height===this._element.height||(this._filterScalingX=this._element.width/this.width,this._filterScalingY=this._element.height/this.height,this.width=this._element.width,this.height=this._element.height),this},_render:function(t){var e,i=-this.width/2,r=-this.height/2;this.isMoving===!1&&this.resizeFilter&&this._needsResize()&&(this._lastScaleX=this.scaleX,this._lastScaleY=this.scaleY,this.applyResizeFilters()),e=this._element,e&&t.drawImage(e,this.cropX,this.cropY,this.width,this.height,i,r,this.width,this.height),this._stroke(t),this._renderStroke(t)},_needsResize:function(){return this.scaleX!==this._lastScaleX||this.scaleY!==this._lastScaleY},_resetWidthHeight:function(){var t=this.getElement();this.set("width",t.width),this.set("height",t.height)},_initElement:function(t,e){this.setElement(fabric.util.getById(t),e),fabric.util.addClass(this.getElement(),fabric.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?fabric.util.enlivenObjects(t,function(t){e&&e(t)},"fabric.Image.filters"):e&&e()},_setWidthHeight:function(t){this.width="width"in t?t.width:this.getElement()?this.getElement().width||0:0,this.height="height"in t?t.height:this.getElement()?this.getElement().height||0:0},parsePreserveAspectRatioAttribute:function(){if(this.preserveAspectRatio){var t,e=fabric.util.parsePreserveAspectRatioAttribute(this.preserveAspectRatio),i=this._element.width,r=this._element.height,n=this.width,s=this.height,o={width:n,height:s};!e||"none"===e.alignX&&"none"===e.alignY?(this.scaleX=n/i,this.scaleY=s/r):("meet"===e.meetOrSlice&&(this.width=i,this.height=r,this.scaleX=this.scaleY=t=fabric.util.findScaleToFit(this._element,o),"Mid"===e.alignX&&(this.left+=(n-i*t)/2),"Max"===e.alignX&&(this.left+=n-i*t),"Mid"===e.alignY&&(this.top+=(s-r*t)/2),"Max"===e.alignY&&(this.top+=s-r*t)),"slice"===e.meetOrSlice&&(this.scaleX=this.scaleY=t=fabric.util.findScaleToCover(this._element,o),this.width=n/t,this.height=s/t,"Mid"===e.alignX&&(this.cropX=(i-this.width)/2),"Max"===e.alignX&&(this.cropX=i-this.width),"Mid"===e.alignY&&(this.cropY=(r-this.height)/2),"Max"===e.alignY&&(this.cropY=r-this.height)))}}}),fabric.Image.CSS_CANVAS="canvas-img",fabric.Image.prototype.getSvgSrc=fabric.Image.prototype.getSrc,fabric.Image.fromObject=function(t,e){fabric.util.loadImage(t.src,function(i,r){return r?void(e&&e(null,r)):void fabric.Image.prototype._initFilters.call(t,t.filters,function(r){t.filters=r||[],fabric.Image.prototype._initFilters.call(t,[t.resizeFilter],function(r){t.resizeFilter=r[0];var n=new fabric.Image(i,t);e(n)})})},null,t.crossOrigin)},fabric.Image.fromURL=function(t,e,i){fabric.util.loadImage(t,function(t){e&&e(new fabric.Image(t,i))},null,i&&i.crossOrigin)},fabric.Image.ATTRIBUTE_NAMES=fabric.SHARED_ATTRIBUTES.concat("x y width height preserveAspectRatio xlink:href crossOrigin".split(" ")),fabric.Image.fromElement=function(t,i,r){var n=fabric.parseAttributes(t,fabric.Image.ATTRIBUTE_NAMES);fabric.Image.fromURL(n["xlink:href"],i,e(r?fabric.util.object.clone(r):{},n))}}("undefined"!=typeof exports?exports:this),fabric.util.object.extend(fabric.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.setAngle(this._getAngleValueForStraighten()),this},fxStraighten:function(t){t=t||{};var e=function(){},i=t.onComplete||e,r=t.onChange||e,n=this;return fabric.util.animate({startValue:this.get("angle"),endValue:this._getAngleValueForStraighten(),duration:this.FX_DURATION,onChange:function(t){n.setAngle(t),r()},onComplete:function(){n.setCoords(),i()},onStart:function(){n.set("active",!1)}}),this}}),fabric.util.object.extend(fabric.StaticCanvas.prototype,{straightenObject:function(t){return t.straighten(),this.renderAll(),this},fxStraightenObject:function(t){return t.fxStraighten({onChange:this.renderAll.bind(this)}),this}}),function(){"use strict";function t(t){t&&t.tileSize&&(this.tileSize=t.tileSize),this.setupGLContext(this.tileSize,this.tileSize),this.captureGPUInfo()}fabric.isWebglSupported=function(t){if(fabric.isLikelyNode)return!1;t=t||fabric.WebglFilterBackend.prototype.tileSize;var e=document.createElement("canvas"),i=e.getContext("webgl")||e.getContext("experimental-webgl"),r=!1;return i&&(fabric.maxTextureSize=i.getParameter(i.MAX_TEXTURE_SIZE),r=fabric.maxTextureSize>=t),this.isSupported=r,r},fabric.WebglFilterBackend=t,t.prototype={tileSize:2048,resources:{},setupGLContext:function(t,e){this.dispose(),this.createWebGLCanvas(t,e),this.squareVertices=new Float32Array([0,0,0,1,1,0,1,1])},createWebGLCanvas:function(t,e){var i=fabric.util.createCanvasElement();i.width=t,i.height=e;var r={premultipliedAlpha:!1},n=i.getContext("webgl",r);n||(n=i.getContext("experimental-webgl",r)),n&&(n.clearColor(0,0,0,0),this.canvas=i,this.gl=n)},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,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,squareVertices:this.squareVertices,programCache:this.programCache,pass:0},c=a.createFramebuffer();return a.bindFramebuffer(a.FRAMEBUFFER,c),t.forEach(function(t){t&&t.applyTo(h)}),this.copyGLTo2D(a.canvas,n),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},applyFiltersDebug:function(t,e,i,r,n,s){var o=this.gl,a=this.applyFilters(t,e,i,r,n,s),h=o.getError();if(h!==o.NO_ERROR){var c=this.glErrorToString(o,h),l=new Error("WebGL Error "+c);throw l.glErrorCode=h,l}return a},glErrorToString:function(t,e){if(!t)return"Context undefined for error code: "+e;if("number"!=typeof e)return"Error code is not a number";switch(e){case t.NO_ERROR:return"NO_ERROR";case t.INVALID_ENUM:return"INVALID_ENUM";case t.INVALID_VALUE:return"INVALID_VALUE";case t.INVALID_OPERATION:return"INVALID_OPERATION";case t.INVALID_FRAMEBUFFER_OPERATION:return"INVALID_FRAMEBUFFER_OPERATION";case t.OUT_OF_MEMORY:return"OUT_OF_MEMORY";case t.CONTEXT_LOST_WEBGL:return"CONTEXT_LOST_WEBGL";default:return"UNKNOWN_ERROR"}},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},copyGLTo2D:function(t,e){var i=e.getContext("2d");i.translate(0,e.height),i.scale(1,-1);var r=t.height-e.height;i.drawImage(t,0,r,e.width,e.height,0,0,e.width,e.height)},evictCachesForKey:function(t){this.textureCache[t]&&(this.gl.deleteTexture(this.textureCache[t]),delete this.textureCache[t])},captureGPUInfo:function(){if(this.gpuInfo)return this.gpuInfo;var t=this.gl,e=t.getExtension("WEBGL_debug_renderer_info"),i={renderer:"",vendor:""};if(e){var r=t.getParameter(e.UNMASKED_RENDERER_WEBGL),n=t.getParameter(e.UNMASKED_VENDOR_WEBGL);r&&(i.renderer=r.toLowerCase()),n&&(i.vendor=n.toLowerCase())}return this.gpuInfo=i,i}}}(),function(){"use strict";function t(){}var e=function(){};fabric.Canvas2dFilterBackend=t,t.prototype={evictCachesForKey:e,dispose:e,clearWebGLCaches:e,resources:{},applyFilters:function(t,e,i,r,n){var s=n.getContext("2d");s.drawImage(e,0,0,i,r);var o=s.getImageData(0,0,i,r),a=s.getImageData(0,0,i,r),h={sourceWidth:i,sourceHeight:r,imageData:o,originalEl:e,originalImageData:a,canvasEl:n,ctx:s};return t.forEach(function(t){t.applyTo(h)}),h.imageData.width===i&&h.imageData.height===r||(n.width=h.imageData.width,n.height=h.imageData.height),s.putImageData(h.imageData,0,0),h}}}(),fabric.Image.filters=fabric.Image.filters||{},fabric.Image.filters.BaseFilter=fabric.util.createClass({type:"BaseFilter",vertexSource:"attribute vec2 aPosition;\nattribute vec2 aTexCoord;\nvarying vec2 vTexCoord;\nvoid main() {\nvTexCoord = aTexCoord;\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){if(this.vertexSource&&this.fragmentSource){var r=t.createShader(t.VERTEX_SHADER);if(t.shaderSource(r,i||this.vertexSource),t.compileShader(r),!t.getShaderParameter(r,t.COMPILE_STATUS))throw new Error('Vertex shader compile error for "${this.type}": '+t.getShaderInfoLog(r));var n=t.createShader(t.FRAGMENT_SHADER);if(t.shaderSource(n,e||this.fragmentSource),t.compileShader(n),!t.getShaderParameter(n,t.COMPILE_STATUS))throw new Error('Fragment shader compile error for "${this.type}": '+t.getShaderInfoLog(n));var s=t.createProgram();if(t.attachShader(s,r),t.attachShader(s,n),t.linkProgram(s),!t.getProgramParameter(s,t.LINK_STATUS))throw new Error('Shader link error for "${this.type}" '+t.getProgramInfoLog(s));var o=this.getAttributeLocations(t,s),a=this.getUniformLocations(t,s)||{};return a.uStepW=t.getUniformLocation(s,"uStepW"),a.uStepH=t.getUniformLocation(s,"uStepH"),{program:s,attributeLocations:o,uniformLocations:a}}},getAttributeLocations:function(t,e){return{aPosition:t.getAttribLocation(e,"aPosition"),aTexCoord:t.getAttribLocation(e,"aTexCoord")}},getUniformLocations:function(){},sendAttributeData:function(t,e,i){["aPosition","aTexCoord"].forEach(function(r){var n=e[r],s=t.createBuffer();t.bindBuffer(t.ARRAY_BUFFER,s),t.enableVertexAttribArray(n),t.vertexAttribPointer(n,2,t.FLOAT,!1,0,0),t.bufferData(t.ARRAY_BUFFER,i,t.STATIC_DRAW)})},_setupFrameBuffer:function(t){var e=t.context;t.passes>1?e.framebufferTexture2D(e.FRAMEBUFFER,e.COLOR_ATTACHMENT0,e.TEXTURE_2D,t.targetTexture,0):(e.bindFramebuffer(e.FRAMEBUFFER,null),e.finish())},_swapTextures:function(t){t.passes--,t.pass++;var e=t.targetTexture;t.targetTexture=t.sourceTexture,t.sourceTexture=e},isNeutralState:function(){return!1},applyTo:function(t){if(t.webgl){if(t.passes>1&&this.isNeutralState(t))return;this._setupFrameBuffer(t),this.applyToWebGL(t),this._swapTextures(t)}else 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.squareVertices),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.sourceWidth,t.sourceHeight),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()}}),fabric.Image.filters.BaseFilter.fromObject=function(t,e){var i=new fabric.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,a=o.data,h=a.length,c=this.matrix,l=this.colorsOnly;for(s=0;sy||o<0||o>_||(h=4*(a*_+o),c=v[d*m+f],e+=p[h]*c,i+=p[h+1]*c,r+=p[h+2]*c,S||(n+=p[h+3]*c));C[s]=e,C[s+1]=i,C[s+2]=r,S?C[s+3]=p[s+3]:C[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}("undefined"!=typeof exports?exports:this),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,n=r.data,s=n.length,o=this.mode;for(e=0;el[0]&&n>l[1]&&s>l[2]&&rt)return 0;if(e*=Math.PI,s(e)<1e-16)return 1;var i=e/t;return a(e)*a(i)/e/i}}function f(t){var a,h,u,O,k,D,j,E,A,P,M;for(w.x=(t+.5)*m,T.x=r(w.x),a=0;a=e)){P=r(1e3*s(h-w.x)),S[P]||(S[P]={});for(var L=T.y-C;L<=T.y+C;L++)L<0||L>=o||(M=r(1e3*s(L-w.y)),S[P][M]||(S[P][M]=v(n(i(P*_,2)+i(M*y,2))/1e3)),u=S[P][M],u>0&&(O=4*(L*e+h),k+=u,D+=u*d[O],j+=u*d[O+1],E+=u*d[O+2],A+=u*d[O+3]))}O=4*(a*c+t),p[O]=D/k,p[O+1]=j/k,p[O+2]=E/k,p[O+3]=A/k}return++t1&&L<-1||(y=2*L*L*L-3*L*L+1,y>0&&(M=4*(P+D*e),O+=y*g[M+3],C+=y,g[M+3]<255&&(y=y*g[M+3]/250),S+=y*g[M],w+=y*g[M+1],T+=y*g[M+2],x+=y))}v[_]=S/x,v[_+1]=w/x,v[_+2]=T/x,v[_+3]=O/C}return p},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}("undefined"!=typeof exports?exports:this),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,r=t.imageData,n=r.data,i=n.length,s=Math.floor(255*this.contrast),o=259*(s+255)/(255*(259-s));for(e=0;e1&&(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}("undefined"!=typeof exports?exports:this),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",applyTo2d:function(t){var e,i=t.imageData,r=i.data,n=this.gamma,s=r.length,o=1/n[0],a=1/n[1],h=1/n[2];for(this.rVals||(this.rVals=new Uint8Array(256),this.gVals=new Uint8Array(256),this.bVals=new Uint8Array(256)),e=0,s=256;e'},_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){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;et&&(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;ds)){var v=h-s;c[t]=h,c[f]+=v,s=h}return{width:s*g,kernedWidth:h*g}},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=0,h=new Array(o.length);for(this.__charBounds[t]=h,e=0;e0&&!n){var u=this.__charBounds[e][i-1];l.left=u.left+u.width+a.kernedWidth-a.width}return l},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;ri&&(i=s)}return this.__lineHeights[t]=i*this.lineHeight*this._fontSizeMult,this.__lineHeights[t]},calcTextHeight:function(){for(var t,e=0,i=0,r=this._textLines.length;i0?(t.fillStyle=f,s&&f&&t.fillRect(d+r+o,g+l*(1-this._fontSizeFraction)+this.offsets[e]*this.fontSize,a,this.fontSize/15),o=h.left,a=h.width,s=c,f=u):a+=h.kernedWidth;t.fillStyle=u,c&&u&&t.fillRect(d+r+o,g+l*(1-this._fontSizeFraction)+this.offsets[e]*this.fontSize,a,this.fontSize/15),g+=i}else g+=i;this._removeShadow(t)}},_getFontDeclaration:function(t,i){var r=t||this;return[e.isLikelyNode?r.fontWeight:r.fontStyle,e.isLikelyNode?r.fontStyle:r.fontWeight,i?n+"px":r.fontSize+"px",e.isLikelyNode?'"'+r.fontFamily+'"':r.fontFamily].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-1&&(this.initDimensions(),this.setCoords())},complexity:function(){return 1}}),e.Text.ATTRIBUTE_NAMES=e.SHARED_ATTRIBUTES.concat("x y dx dy font-family font-style font-weight font-size 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);if(n=e.util.object.extend(n?i(n):{},s),n.top=n.top||0,n.left=n.left||0,s.textDecoration){var o=s.textDecoration;o.indexOf("underline")!==-1&&(n.underline=!0),o.indexOf("overline")!==-1&&(n.overline=!0),o.indexOf("line-through")!==-1&&(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),n.originX||(n.originX="left");var a="";"textContent"in t?a=t.textContent:"firstChild"in t&&null!==t.firstChild&&"data"in t.firstChild&&null!==t.firstChild.data&&(a=t.firstChild.data),a=a.replace(/^\s+|\s+$|\n+/g,"").replace(/\s+/g," ");var h=new e.Text(a,n),c=h.getScaledHeight()/h.height,l=(h.height+h.strokeWidth)*h.lineHeight-h.height,u=l*c,f=h.getScaledHeight()+u,d=0;"center"===h.originX&&(d=h.getScaledWidth()/2),"right"===h.originX&&(d=h.getScaledWidth()),h.set({left:h.left-d,top:h.top-(f-h.fontSize*(.18+h._fontSizeFraction))/h.lineHeight}),h.originX="left",h.originY="top",r(h)},e.Text.fromObject=function(t,i){return e.Object._fromObject("Text",t,i,"text")},e.util.createAccessors&&e.util.createAccessors(e.Text)}("undefined"!=typeof exports?exports:this),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)}fabric.IText=fabric.util.createClass(fabric.Text,fabric.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.styles=e?e.styles||{}:{},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})},getSelectionStyles:function(t,e){if(2===arguments.length){for(var i=[],r=t;r0?o:0)},this.cursorOffsetCache=i,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;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,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=this.get2DCursorLocation(i),s=this.get2DCursorLocation(r),o=n.lineIndex,a=s.lineIndex,h=n.charIndex<0?0:n.charIndex,c=s.charIndex<0?0:s.charIndex,l=o;l<=a;l++){var u=this._getLineLeftOffset(l)||0,f=this.getHeightOfLine(l),d=0,g=0,p=0;l===o&&(g=this.__charBounds[o][h].left),l>=o&&l1)&&(f/=this.lineHeight),this.inCompositionMode?(e.fillStyle=this.compositionColor||"black",e.fillRect(t.left+u+g,t.top+t.topOffset+f,p-g,1)):(e.fillStyle=this.selectionColor,e.fillRect(t.left+u+g,t.top+t.topOffset,p-g,f)),t.topOffset+=d}},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}}}),fabric.IText.fromObject=function(e,i){if(t(e),e.styles)for(var r in e.styles)for(var n in e.styles[r])t(e.styles[r][n]);fabric.Object._fromObject("IText",e,i,"text")}}(),function(){var t=fabric.util.object.clone;fabric.util.object.extend(fabric.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,this.callSuper("onDeselect")},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||[],fabric.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})}.bind(this),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;this._currentTickState&&this._currentTickState.abort(),this._currentTickCompleteState&&this._currentTickCompleteState.abort(),clearTimeout(this._cursorTimeout1),clearTimeout(this._cursorTimeout2),this._currentCursorOpacity=0,t&&this.canvas&&this.canvas.clearContext(this.canvas.contextTop||this.ctx)},selectAll:function(){this.selectionStart=0,this.selectionEnd=this._text.length,this._fireSelectionChanged(),this._updateTextarea()},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-1;)e++,i--;return t-e},findLineBoundaryRight:function(t){for(var e=0,i=t;!/\n/.test(this._text[i])&&i0&&ithis.__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 r=i.slice(0,t),n=fabric.util.string.graphemeSplit(r).length;if(t===e)return{selectionStart:n,selectionEnd:n};var s=i.slice(t,e),o=fabric.util.string.graphemeSplit(s).length;return{selectionStart:n,selectionEnd:n+o}},fromGraphemeToStringSelection:function(t,e,i){var r=i.slice(0,t),n=r.join("").length;if(t===e)return{selectionStart:n,selectionEnd:n};var s=i.slice(t,e),o=s.join("").length;return{selectionStart:n,selectionEnd:n+o}},_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;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),r=i.lineIndex,n=i.charIndex,s=this.getValueOfPropertyAt(r,n,"fontSize")*this.lineHeight,o=e.leftOffset,a=this.calcTransformMatrix(),h={x:e.left+o,y:e.top+e.topOffset+s},c=this.canvas.upperCanvasEl,l=c.width-s,u=c.height-s;return h=fabric.util.transformPoint(h,a),h=fabric.util.transformPoint(h,this.canvas.viewportTransform),h.x<0&&(h.x=0),h.x>l&&(h.x=l),h.y<0&&(h.y=0),h.y>u&&(h.y=u),h.x+=this.canvas._offset.left,h.y+=this.canvas._offset.top,{left:h.x+"px",top:h.y+"px",fontSize:s+"px",charHeight:s}},_saveEditingProps:function(){this._savedProps={hasControls:this.hasControls,borderColor:this.borderColor,lockMovementX:this.lockMovementX,lockMovementY:this.lockMovementY,hoverCursor:this.hoverCursor,defaultCursor:this.canvas&&this.canvas.defaultCursor,moveCursor:this.canvas&&this.canvas.moveCursor}},_restoreEditingProps:function(){this._savedProps&&(this.hoverCursor=this._savedProps.overCursor,this.hasControls=this._savedProps.hasControls,this.borderColor=this._savedProps.borderColor,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.selectable=!0,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.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;ie&&(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;r||(r=1),this.shiftLineStyles(e,r),this.styles[e]&&this.styles[e][i-1]&&(s=this.styles[e][i-1]);for(var h in 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[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){var s=this.styles[e],o=t(s);r||(r=1);for(var a in o){var h=parseInt(a,10);h>=i&&(s[h+r]=o[h],o[h-r]||delete s[h])}if(this._forceClearCache=!0,s)if(n)for(;r--;)this.styles[e][i+r]=t(n[r]);else 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;ot&&it?this.selectionStart=t:this.selectionStart<0&&(this.selectionStart=0),this.selectionEnd>t?this.selectionEnd=t:this.selectionEnd<0&&(this.selectionEnd=0)}})}(),fabric.util.object.extend(fabric.IText.prototype,{initDoubleClickSimulation:function(){this.__lastClickTime=+new Date,this.__lastLastClickTime=+new Date,this.__lastPointer={},this.on("mousedown",this.onMouseDown.bind(this))},onMouseDown:function(t){this.__newClickTime=+new Date;var e=this.canvas.getPointer(t.e);this.isTripleClick(e,t.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))})},initMousedownHandler:function(){this.on("mousedown",function(t){if(this.editable&&(!t.e.button||1===t.e.button)){var e=this.canvas.getPointer(t.e);this.__mousedownX=e.x,this.__mousedownY=e.y,this.__isMousedown=!0,this.selected&&this.setCursorByClick(t.e),this.isEditing&&(this.__selectionStartOnMouseDown=this.selectionStart,this.selectionStart===this.selectionEnd&&this.abortCursorAnimation(),this.renderCursorOrSelection())}})},_isObjectMoved:function(t){var e=this.canvas.getPointer(t);return this.__mousedownX!==e.x||this.__mousedownY!==e.y},initMouseupHandler:function(){this.on("mouseup",function(t){this.__isMousedown=!1,!this.editable||this._isObjectMoved(t.e)||t.e.button&&1!==t.e.button||(this.__lastSelected&&!this.__corner&&(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,i,r=this.getLocalPointer(t),n=0,s=0,o=0,a=0,h=0,c=0,l=this._textLines.length;c0&&(a+=this._textLines[c-1].length+1);e=this._getLineLeftOffset(h),s=e*this.scaleX,i=this._textLines[h];for(var u=0,f=i.length;us?0:1,h=r+a;return this.flipX&&(h=n-h),h>this._text.length&&(h=this._text.length),h}}),fabric.util.object.extend(fabric.IText.prototype,{initHiddenTextarea:function(){this.hiddenTextarea=fabric.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","");var t=this._calcTextareaPosition();this.hiddenTextarea.style.cssText="white-space: nowrap; position: absolute; top: "+t.top+"; left: "+t.left+"; z-index: -999; opacity: 0; width: 1px; height: 1px; font-size: 1px; line-height: 1px; paddingーtop: "+t.fontSize+";", +fabric.document.body.appendChild(this.hiddenTextarea),fabric.util.addListener(this.hiddenTextarea,"keydown",this.onKeyDown.bind(this)),fabric.util.addListener(this.hiddenTextarea,"keyup",this.onKeyUp.bind(this)),fabric.util.addListener(this.hiddenTextarea,"input",this.onInput.bind(this)),fabric.util.addListener(this.hiddenTextarea,"copy",this.copy.bind(this)),fabric.util.addListener(this.hiddenTextarea,"cut",this.copy.bind(this)),fabric.util.addListener(this.hiddenTextarea,"paste",this.paste.bind(this)),fabric.util.addListener(this.hiddenTextarea,"compositionstart",this.onCompositionStart.bind(this)),fabric.util.addListener(this.hiddenTextarea,"compositionupdate",this.onCompositionUpdate.bind(this)),fabric.util.addListener(this.hiddenTextarea,"compositionend",this.onCompositionEnd.bind(this)),!this._clickHandlerInitialized&&this.canvas&&(fabric.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){return!this.isEditing||this._copyDone||this.inCompositionMode?void(this._copyDone=!1):void(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,r,n=this._splitTextIntoLines(this.hiddenTextarea.value).graphemeText,s=this._text.length,o=n.length,a=o-s;""===this.hiddenTextarea.value&&(this.styles={},this.updateFromTextArea(),this.fire("changed"),this.canvas&&(this.canvas.fire("text:changed",{target:this}),this.canvas.requestRenderAll())),this.selectionStart!==this.selectionEnd?(i=this._text.slice(this.selectionStart,this.selectionEnd),a+=this.selectionEnd-this.selectionStart):oh.selectionStart?this.removeStyleFromTo(this.selectionEnd-i.length,this.selectionEnd):this.removeStyleFromTo(this.selectionEnd,this.selectionEnd+i.length)),r.length&&(e&&r.join("")===fabric.copiedText?this.insertNewStyleBlock(r,this.selectionStart,fabric.copiedTextStyle):this.insertNewStyleBlock(r,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(){if(this.selectionStart!==this.selectionEnd){var t=this.getSelectedText();fabric.copiedText=t,fabric.copiedTextStyle=this.getSelectionStyles(this.selectionStart,this.selectionEnd),this._copyDone=!0}},paste:function(){this.fromPaste=!0},_getClipboardData:function(t){return t&&t.clipboardData||fabric.window.clipboardData},_getWidthBeforeCursor:function(t,e){var i,r=this._getLineLeftOffset(t);return e>0&&(i=this.__charBounds[t][e-1],r+=i.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),h=this._textLines[n].slice(s);return h.length+a+2},_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);return-this._textLines[n-1].length+a-h.length},_getIndexOnLine:function(t,e){for(var i,r,n=this._textLines[t],s=this._getLineLeftOffset(t),o=s,a=0,h=0,c=n.length;he){r=!0;var l=o-i,u=o,f=Math.abs(l-e),d=Math.abs(u-e);a=d=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="get"+t+"CursorOffset",r=this[i](e,"right"===this._selectionDirection);e.shiftKey?this.moveCursorWithShift(r):this.moveCursorWithoutShift(r),0!==r&&(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,i+=e.shiftKey?"Shift":"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){this.selectionStart===this.selectionEnd?this._removeCharsNearCursor(t):this._removeCharsFromTo(this.selectionStart,this.selectionEnd),this.set("dirty",!0),this.setSelectionEnd(this.selectionStart),this._removeExtraneousStyles(),this.canvas&&this.canvas.requestRenderAll(),this.setCoords(),this.fire("changed"),this.canvas&&this.canvas.fire("text:changed",{target:this})},_removeCharsNearCursor:function(t){if(0!==this.selectionStart)if(t.metaKey){var e=this.findLineBoundaryLeft(this.selectionStart);this._removeCharsFromTo(e,this.selectionStart),this.setSelectionStart(e)}else if(t.altKey){var i=this.findWordBoundaryLeft(this.selectionStart);this._removeCharsFromTo(i,this.selectionStart),this.setSelectionStart(i)}else this._removeSingleCharAndStyle(this.selectionStart),this.setSelectionStart(this.selectionStart-1)}}),function(){var t=fabric.util.toFixed,e=fabric.Object.NUM_FRACTION_DIGITS;fabric.util.object.extend(fabric.Text.prototype,{toSVG:function(t){var e=this._createBaseSVGMarkup(),i=this._getSVGLeftTopOffsets(),r=this._getSVGTextAndBg(i.textTop,i.textLeft);return this._wrapSVGTextAndBg(e,r),t?t(e.join("")):e.join("")},_getSVGLeftTopOffsets:function(){return{textLeft:-this.width/2,textTop:-this.height/2,lineTop:this.getHeightOfLine(0)}},_wrapSVGTextAndBg:function(t,e){var i=!0,r=this.getSvgFilter(),n=""===r?"":' style="'+r+'"';t.push("\t\n",e.textBgRects.join(""),"\t\t\n',e.textSpans.join(""),"\t\t\n","\t\n")},_getSVGTextAndBg:function(t,e){var i,r=[],n=[],s=t;this._setSVGBg(n);for(var o=0,a=this._textLines.length;o",fabric.util.string.escapeXml(i),"\n"].join("")},_setSVGTextLineText:function(t,e,i,r){var n,s,o,a,h,c=this.getHeightOfLine(e),l="",u=0,f=this._textLines[e];r+=c*(1-this._fontSizeFraction)/this.lineHeight;for(var d=0,g=f.length-1;d<=g;d++)h=d===g||this.charSpacing,l+=f[d],o=this.__charBounds[e][d],0===u&&(i+=o.kernedWidth-o.width),u+=o.kernedWidth,"justify"!==this.textAlign||h||this._reSpaceAndTab.test(f[d])&&(h=!0),h||(n=n||this.getCompleteStyleDeclaration(e,d),s=this.getCompleteStyleDeclaration(e,d+1),h=this._hasStyleChanged(n,s)),h&&(a=this._getStyleDeclaration(e,d)||{},t.push(this._createTextCharSpan(l,a,i,r)),l="",n=s,i+=u,u=0)},_pushTextBgRect:function(i,r,n,s,o,a){i.push("\t\t\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;uthis.width&&this._set("width",this.dynamicMinWidth),"justify"===this.textAlign&&this.enlargeSpaces(),this.height=this.calcTextHeight()}},_generateStyleMap:function(t){for(var e=0,i=0,r=0,n={},s=0;s0?(i=0,r++,e++):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)},_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,e){var i=this._styleMap[t];this.styles[i.line]=e},_deleteLineStyle:function(t){var e=this._styleMap[t];delete this.styles[e.line]},_wrapText:function(t,e){var i,r=[];for(this.isWrapping=!0,i=0;i=r&&!g&&(s.push(o),o=[],n=u,g=!0),g||o.push(l),o=o.concat(h),f=this._measureWord([l],i,c),c++,g=!1,u>d&&(d=u);return v&&s.push(o),d>this.dynamicMinWidth&&(this.dynamicMinWidth=d-p),s},_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=h.getMinWidth()?(h.set("width",l),!0):void 0},fabric.util.object.extend(fabric.Textbox.prototype,{_removeExtraneousStyles:function(){for(var t in this._styleMap)this._textLines[t]||delete this.styles[this._styleMap[t].line]}})}(),function(){function request(t,e,i){var r=URL.parse(t);r.port||(r.port=0===r.protocol.indexOf("https:")?443:80);var n=0===r.protocol.indexOf("https:")?HTTPS:HTTP,s=n.request({hostname:r.hostname,port:r.port,path:r.path,method:"GET"},function(t){var r="";e&&t.setEncoding(e),t.on("end",function(){i(r)}),t.on("data",function(e){200===t.statusCode&&(r+=e)})});s.on("error",function(t){t.errno===process.ECONNREFUSED?fabric.log("ECONNREFUSED: connection refused to "+r.hostname+":"+r.port):fabric.log(t.message),i(null)}),s.end()}function requestFs(t,e){var i=require("fs");i.readFile(t,function(t,i){if(t)throw fabric.log(t),t;e(i)})}if("undefined"==typeof document||"undefined"==typeof window){var DOMParser=require("xmldom").DOMParser,URL=require("url"),HTTP=require("http"),HTTPS=require("https"),Canvas=require(fabric.canvasModule),Image=require(fabric.canvasModule).Image;fabric.util.loadImage=function(t,e,i){function r(r){r?(n.src=new Buffer(r,"binary"),n._src=t,e&&e.call(i,n)):(n=null,e&&e.call(i,null,!0))}var n=new Image;t&&(t instanceof Buffer||0===t.indexOf("data"))?(n.src=n._src=t,e&&e.call(i,n)):t&&0!==t.indexOf("http")?requestFs(t,r):t?request(t,"binary",r):e&&e.call(i,t)},fabric.loadSVGFromURL=function(t,e,i){t=t.replace(/^\n\s*/,"").replace(/\?.*$/,"").trim(),0!==t.indexOf("http")?requestFs(t,function(t){fabric.loadSVGFromString(t.toString(),e,i)}):request(t,"",function(t){fabric.loadSVGFromString(t,e,i)})},fabric.loadSVGFromString=function(t,e,i){var r=(new DOMParser).parseFromString(t);fabric.parseSVGDocument(r.documentElement,function(t,i){e&&e(t,i)},i)},fabric.util.getScript=function(url,callback){request(url,"",function(body){eval(body),callback&&callback()})},fabric.createCanvasForNode=function(t,e,i,r){r=r||i;var n=fabric.document.createElement("canvas"),s=new Canvas(t||600,e||600,r),o=new Canvas(t||600,e||600,r);n.width=s.width,n.height=s.height,i=i||{},i.nodeCanvas=s,i.nodeCacheCanvas=o;var a=fabric.Canvas||fabric.StaticCanvas,h=new a(n,i);return h.nodeCanvas=s,h.nodeCacheCanvas=o,h.contextContainer=s.getContext("2d"),h.contextCache=o.getContext("2d"),h.Font=Canvas.Font,h};var originaInitStatic=fabric.StaticCanvas.prototype._initStatic;fabric.StaticCanvas.prototype._initStatic=function(t,e){t=t||fabric.document.createElement("canvas"),this.nodeCanvas=new Canvas(t.width,t.height),this.nodeCacheCanvas=new Canvas(t.width,t.height),originaInitStatic.call(this,t,e),this.contextContainer=this.nodeCanvas.getContext("2d"),this.contextCache=this.nodeCacheCanvas.getContext("2d"),this.Font=Canvas.Font},fabric.StaticCanvas.prototype.createPNGStream=function(){return this.nodeCanvas.createPNGStream()},fabric.StaticCanvas.prototype.createJPEGStream=function(t){return this.nodeCanvas.createJPEGStream(t)},fabric.StaticCanvas.prototype._initRetinaScaling=function(){if(this._isRetinaScaling())return this.lowerCanvasEl.setAttribute("width",this.width*fabric.devicePixelRatio),this.lowerCanvasEl.setAttribute("height",this.height*fabric.devicePixelRatio),this.nodeCanvas.width=this.width*fabric.devicePixelRatio,this.nodeCanvas.height=this.height*fabric.devicePixelRatio,this.contextContainer.scale(fabric.devicePixelRatio,fabric.devicePixelRatio),this},fabric.Canvas&&(fabric.Canvas.prototype._initRetinaScaling=fabric.StaticCanvas.prototype._initRetinaScaling);var origSetBackstoreDimension=fabric.StaticCanvas.prototype._setBackstoreDimension;fabric.StaticCanvas.prototype._setBackstoreDimension=function(t,e){return origSetBackstoreDimension.call(this,t,e),this.nodeCanvas[t]=e,this},fabric.Canvas&&(fabric.Canvas.prototype._setBackstoreDimension=fabric.StaticCanvas.prototype._setBackstoreDimension)}}(); \ No newline at end of file diff --git a/dist/fabric.min.js.gz b/dist/fabric.min.js.gz index 1d1f20fc272b675d77c5535959ebb6b721fe241d..c8b7e43b388b421d3be68e5563cab67b1806b1da 100644 GIT binary patch literal 75119 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

p?+!m`M3D`8?%2ovMu z1X!N7lL9NGq)_7=Lg#EEwZxE33LQ_za!ol1sN*25=wiy_m`;KE3x?-D+c~Af=uria zjdE#4uSkw9MC^qcn?6$tLq$1Vh?gH6aM`y|nv^#7LxmjfK9QV}&WP>-Ek1`wuB6fU+73rNcd(ilQo zZUgcR5w22k&IwU!S-T@tg3<(4MM5X+E`#jDbu6T^TOjvIMw+Nf6RcFsyXtVM7RrxV z<=itJf_3(eD#eJMKL5O%{w=%7Q8zjV4j6dlduLq}S$0#lj_?kw*J;~bXWU!VLpt)~ z#_gJCSvu&Od#(9S&IZ_3*K%I*3EAEy*D{;A7wdX^03Edsg4KFtIYq2Rv43uo+=za{ zGq01(h(4z1$jtkkA{Q8GY-~+Y$PEFU2!rvPykeIFOxesA%26c6IXFnm+SF-j;}(5qR8W;qu~$F?(V|pNB=l{dgzoVotLFd$0(@@kNu-( zhl3x4P8RR%vCrBACts$?we=G);CtC7O_N2Cv%TvuUnZLz05yt|YrMvTpCa8FNtC4b z7b>GxpB)bS&(piRRCMmIwNM>WyZDBtc0$LTiTdB^#Z~p|lua4kLoSW>EpbU|j-WFr z=IwcWcNahBv-a0oP?y`)yKDbeUS8vF4c1{EP=L8CgCP5T6#?p8q``U#xb76Cb5h;9 zb~`(_#y->_mCFpde(NagqOC`sZcw$Sn{8lIPVwGxq~zoc84C0-mD%AJpgTq^8;>qi z7JS`>k0`!V$fT@V{CoiTrBDQS(=yF4a2$^nit&zT*sZ{{ve{mq>|useY*Ll7+zmT_x$D7C8&9u@S5rrD3wFE>q zRo8B#Mxz0WnE)2BJ^^4u?~D!^C@I!cIiEV6c39tAdBN!oc1ToMGK{yOQg>p1Aa`gVH&){7r=F`@Yj6`1`q8Ex=!5EN zYUyOmVdGERvI^a1OAXgTE$6XWLhD3v30MqLvo2`Z$@ioI^}%;JZsK|f9!dL*h8j}W zDpr^@SDk`f1Om=0jRyY^xE6QL`}f>On{ch7{o)hvE3Z%h{$XBMkw_}lBVv8^1=Pi; zsvdK~C+S|INu2&}1B6y_mZl73X#OCffK8AjJPd1qxSkTbT?X+iVkw+0*KnS!+3Y6~!Filr6Vp?uoZvk&4J<+FVpz6tBx59} zYAjV#4~%$Cw=DP<8InTrK*R|BlC(^yBTJ}RMLpaJe$%7h#~V3ELLa)D!)h_gCwFj` zP6dkrAhsOq5gy`pr=-vc#ZRXx&@u1WJU>g;1)&FA_Z4)bjcms}2gZBFLwT~+dYYLx zxfYpA10heyiWGvz793OYg3ZXbnq`(JGGzswMCgY2y#8b?eqla4w)QPQ!-;cuhrFnV ze+cE0Km+Zp3D7Ke>X*dX0%_a z|8_Uhkg&!|K-W>Yr3+zTX-WTysv=P?iqV1TddRxmLS1Lwdd_k!u3c`%0w1R;6V~L9 zE=nS>hdYwz!E{MQp`sZpLbYu-=XMt;{9EJv&Bu0BI>(T?&b#HV6WhH%1Kz~hxtrP| zHAB-&Io_<)m?pYMHP}&L$0)X6z|IAbz#p=4#Sefw5rqPg^NAxg?idtFosmf3)Cw8^ zcD3Q#796Cf#7fMQ9VepfWF2>=~G{w>a0}sWWsf`Q3 zDIv^{N_x5ogDP=DgT1OFl1QZq7U1`tySgv^vpV_9o+@A|YimaIY^{R@`yDo(Xau#c zYMW7+Kda22t@3!`z#z>+7*Xt21vyV? z^PORb)}(Vc3$HAs0ICxx=1q(UbzPdWaHCE@OT8dkF9VpZFE;!UCE?4*2|WMfi!*6E zU!0!K>1ZIm8-?S{*tib#(01I{1JlCs(s?P3<ciGXQ?_0RCITlWI0Ox zbH6Ud&0#7_?cm0M^H8;Ncb6I=9Dq!RhKpnh^nq}I#mLJ=iYSrI9ndXO481vn`3K}V zN24ZW+e@dBm=W46bbuvUNOBFw8JQ+wj7-8plY7zGV$$>n4uYkxq}Qy>=Vkj;wojMU zW<=oMUMA^`r8pQ;s`D(&VYxgS1|(vkfaR`%U;wzH1rqs06fP6x+0l`gDlLve-h~@3 zaFTPBZcWeW0;a;PmmaE%Q=)?&f`=8(>Cw$wGMshx% z^mX`bWW*#2Ua?~{L9mGRb=nDMB5}$xN)<_$?JcIU?o@_Z}hM$qMg84Q9%8)Iv5Xxk1+z zr32TdyC5wJsctl7eCQCXh0P?+7&>Pm7i@&Vj2HtO7^ZrTn~r6F(}_^c^=d5nH=;hI zOsN4q0$spaXzXBKQT$hW%*8Nf=l)8^s9O!oZf<+t5E6A8Ai+Q9>GHTqpDYsNC(KD%eq0c3X zFd>3+EotEZ@mX5SJRyYYFPl~v7=RMTEu`H>G|DVwfwbJLA>%ADuEqL)n9qSI^|OX# zPLEF?05avY#qNC>3z2v3jI9Fz^)b?%Ix5lcK0~rzy^Z1YLEShhR*Jj)5^yX(%8Cp> zzCN=^ev!l{0uo@E^}D9PPi-{hhy{@tBdrHe4opd=3^eYAR_FF98k-t$XD4>xxV7cb z69e^&+hf9MO81HtIM+ME4-T9IEfVc6palRnJLBf^uJ!T5=^27Ll(0Vj!awis0^}z? zu|GF3-#iyt->T|GaAMMw9`>U9sPV<*W5RL{r~no_BwL|L&)=vyUixd0fftW)%(pi^aN! z-F|aX%#`PAF=e|6y3>+m3?qFnAfm*v4=1?IH98z!u3eB!D9JWuUsS8OkW%*5<`t+! zML}A+8?8H6#fAC7!8zc<1*|3(vnDk*yUy)B<>>;a=I*md=9i18pG@6Dr!>_GEN7Q~ zDD?|G?BqoUQX6f#(jcfM`wi;}C)}3uqg6F%tqduB* zW$gs^IYU%HI}tcJcM9PEcoB5Ngtn^&p2*z|#IPWPeW_uM!k&ye+6h~Q#(pnt+0xm~ z&~e%!pfq=m0wbVq$iN4Wda{60F&-+HTClT>bQ$&reN;SU-ODY7@9t)u`3O6D%4sO| zsi9t&N3MD|wH?DuJ+f!+z(oTzW4>q-0rx)-#)%hqGWW_~_Y!yIZ|t=@cNeJOdRf@M z*sIRm=`9p>ytGkq{t6EH=iGwc)+ds8QHG#HoQy{8uboY>U}$7WRVo2I=5vg4($E_S?9mOc$4dZM7BqoRji)i@fY~xScJq(rrL8dY*yEGvF>^YV!<5 zo*}otr94V;uI*!PRFP$4-N_0nfm126+C7{A^bCL|gY1q~Ql{kU?t(DT{LG>wHb5Xm z>W~RODTP#Wghme7ATe5&x;1mH3-C*#{n)*gXva%A;?XvG=BiztxMDxU7soJ~OA;E3 z@I8ve3;B|JO}WNK2(o4{A)Uf3sFxWCNC|#XGzYtQw{uL2R1Arx-~k>%M|yktvBCz- z8QVyQrheFa>UgP7+It5F?A-9I*++)FLX0hk}KO< zX)^JkCH;=sLjWsu<>e0?%`VJlt*`^Up3~Br?B(5cSvA}kBmf>t|9WX>;I#4Tk*>~7t})=X~n&BwJWx~b`YVU1TVsui49+r)mV zW<{|U)ZvsCYgTEK?;;p#8N~T48l@N2xufd^)()Y(-O+03Ko!`2Y4+ER?H4uKr3ESX zi}#AJO}WWVCwFLtw0(C~2h+OstAw!fWUU$(NS0HeW|X_U55%;!64m6gWv`MXL9aZG z7q&1-lsJ6Q{YQUr^gU3aedIMqLdRLL3@I@XJz%c~MszzK1wiQre)q7I2|+0^f=j47 zC>&IDm_3E@WKLUCK;M?nMA--K`Y0VKJ!?66WNp&(W9mZ@-A+d+^-Zu3G4I0?`VioO zqN$NCO)QM7%}fj&ca~)g47r^)?25K_>vQv$Cl8izSU-JmDnjoE-6N-Q68Az}{q9k# zm`rb49g`iFkCw2Nb*ANkO<`bY1U`kaX^V1F*sChw<3eTVcTC1QVziE{p;p_D+X%*; z*Z{NBZ>vp5y|Tu3T!!82Z>Y3{3GAF|w&NCLIT{{0veQllS66ajM@-axR^8s64|dwg z-9E+Yc|Vl%@~Jx>^oHGk9F1Y{|L7h)8y?{aft|^ZhvgLP8uW*vu|N33bBf4P-eGsB zW&YuiXD{b@W@P&QDbH4P{A&$m1yec(I6MP*D#q$T%m<9=q%sa-=)ls*IUps0E5^TX zuVgKBn(R z?|G@P=oODhT{RzR?#0?zA($CsfQUrpM&G4DksE_cJvT;7MZ_t3$ckiU3T=wK6rPLl z>zj4r&16;zEsCrZUdw3+)2Vl*hKHe*HaZMn%37l!%VDq=s$vnb)#?^eHzEq(-0)6h z0ScWKxhZ@tvnH?>%sW$=dH92toyUANjaf+Gl(9V&ZccM+RCiNEn*Doc<1=)^lGoDX zQpWS`KG2lPE`I_DZvnW=YJB1cLw9$YV;YfwUeBlnixWTMf(%c^F$!xvRv4AJXjF!} z7TncN?@QM1q2Ho)-GdE=`_P@^6>k)AA5gMAwCw7Z(#Bi666dbFRHbsN!N^uP=)!`Y0*6mqFIBDc>i-yr)w+U@9SUQ~%TLgrw}T7P&_eF-aS z`6@^ilJCdg)y(tfrD*E8N`Pkx6>5k`(Y*}BaIb!r7yH?m(d1t^-USdqspH{opu3;J z7|7x-c7T|To9zD(5K`G<2hK^ZAQ4(V%}S&K_5nYh31mLU|Alw$_ccCO7s zc5tGdLXl^aMz-b1>pB!-tcCo7n&kCy{UK7Px&)wE$N(TrJ_Hvy7T74CP}bw@3PriH z^`bI&Mrwd8l+Y#4F;nWGXzbuKQlRx4ZVN;13=~E@1)#Xcx*~Nn8)cK@72|c&k!B}4 z`jWN&-g7Or_bjybtdn_5lR%Npvz$>#-Vk6vg)6&cp^B~@(T<*{xumg>>Qc(Y?2=NN zg_MpEeOgSD^^3$Y`gUudl-IV_eCP znq;IRS&oIc8V$3hF;=?66?uGOt%V0L-07@v4MzIKsNje3DHjFFOSO!vp8m;0O5&f1ne-aijI|9a8+&o5s(leS|u zR0aF2sLQ#N*KGIv6r0*n^FeCb;4_&k|BzS-Tq)4I{7m5k6z%9cVUrlf&M zkW=ubLfK!=ca26uON=lE{1hLnS8ZZ$jFtKs?J^W$)GU}{7Yz}Pq1gnZI7dPTpYFR_ zc=$yw&-wge=5LaVf+a4M2F$GV-PAdpMx;qckEGH$5k#lM2Waw$mXzgF_ivCQ$p+B%Dc)hN=0d&E( z5~D3}DM?=mUr!oe`PzU`Yqxy`q}*c$55qC@>5pJuIc_T!7tAm4;yG5g~8=pIb*m9qWF!-%-rbwT8 z@{)Z-N_*yCx|b4vZL!3a3W=f@cH|VLFVKZDWnB6ljabj<)^1vg!&^ForqA#S4)C54 z^%SC3W7Styv=%y^eNR6UUnKSzEVNAPg=qP<<^qieJ)+tR*ol&JS#-JIP}p68pZLl1 zU>tY}e||CH#6-ZUktP3`@}D{XnHe)_&+qPLr~nR&VW7whd+yM-ys&5R;q1}AxPhn@ zab=Jtfj}Srv)TdWT(%PWowfohK*tET163e%%MY;pVf>jJ*ey0S=nd?a8)>odf&+~p zk=uMQw3Tc1xEY_Mu$-m42R;U_O>Yok&d8y|zd(Piyk!(sK_{$56b)IZEFMHz%4k|r zr~88)*J#Ma^UY`mEMIa)gS#sUU&i$=`eLKWvqBT#Jw<}6JHR4UAun3<1*~& z-XHcl$d`B1Fr7y1ZkAy_9*zF z=KW@#@`*p?jPD+I=D{kAs0f7K@PJ6d$L>S|K3c1yQH4>))3->tWq2G9*=5=VV zB0X~dSNXwcnFl@UpVU4et>^f+rWd7UruP{2uKtl}ndd|Oqti0^H}M2D!dM3%E$7+` zXo(InuZjqfC5WfXB((}bjVo;fl`LrIe(-O3?UhcDFEL{occX$6C41-YLOgx<3ILYJ zG>EYb{li*)=0Y)oG*?p1WhzB*rv&}cp~k$>6$kmZ&wNHlAgaCiA-T5qQ+l4s@1*oT z6U9EA_;CmQrFPO58RZ^L{H%k{QrqaQy}^`>asBC`*76uz^)O+inmk0|Ls=$@R`TJ* zS5Dyt?kT@o#s^vTVn^OW~Jp$c6L;A*-JAnu;g7 z)Ph?cu!q1~b9Y$$Z7dFsmKWhZZQ6bj;h4Nqn1ImoSTzB+jpc=y;0`NEpJmd(NaC<% zd5ItG0&e=BsQD&cHx=6H4x-RQ)kw0q&j%w%d8&fl`4Bl{FI_BOT>mSN9bZk^mw-jFu9*UtDa$S-TC`jqFd8g4&bD zY>hG}?#A1EvuT{!IP+r{d5lD1+qK~f)44@|sobcCtnln7ytDlM~|oSsqyPo|}ot6@jFOUsbIb_QP= zJ)5<2SLh@Imw&gTRexoGrX2%32S7=qlfEfO+A=PKKT!urw#N zV-e7Fc>ZiMO3BBUB8lluHWl@o;PUBWO%n;k(9_s6BZRjwNp$-ci1FP(MRF3|4`2gQ z91_Go@%k-37050pfS{`9a{gKo`MQenHgRCAa;(l2!!rRE{rVYB}ygbJZBAZ6}kn7obQy^eBr zzdXmx6I1p}`IwJ|Mv);fV1`gYPgBDDrFe@*bEH=$W!E3J)^ zqeQFXEZ|z=pwf*G2}p2Ke1QRqjv1M$Yj}K34-TdZ*wAL*Y`@?Gox8jBJ&$&BA5?IH zmLDP46_Ati_(B22xL}FnvK`{UQRH6%!n(2p4ny+T!hKZ~#h0OrcM0^nzXh&&kpMHQjl7uVU)a?S#QL|+-LUbNOiUeg5N5W)ake1X@rt;M48O1wyt`8|KvN{e ztbFNxX^H2!#$Q@rdN@hY1gS_QVyZ}AB$2*^#3Np+(5|=O*NP2FGr6c`hgS=A*Zaji zojm1w@`W(qUNU+x?2nyzF3b)2;E}VJE1A*$mTCotP5~@!3l$A|j?kOUiYuXju7ufE93Dp$aeIJ?SO-J6rN8fK%?hex}fwC+y=D;1N!jVtw$HGve%Z-X0p@sd@`<+ zXHp9K)W_dC(I$F~MO!?D_f!5vEucVr7Wrf8v%u|AD0d7 z5g`eyCc`olog~P@h=)o1@{qyks}Jwdro0!EJ%2A}CP;tivK1k_|}E5;U*uquH{9ARrr=i&$tq=d309T zSZs*A7%-8~&t2};7r2$nVEPsPfnhjVV=;6CAe4%aNmpq z_15ZrwC%2Gag-mk5jr(B649tRtD|J~iFHcvENDiY`ZO8616WmUunD?yL}xwRCvN_Y zBdzrWCoHyWpIeu1>hYOsPAk;0{@g!2!VJD(Eg$PZOL!Xlg)tleJRF3wg4f;=&&9^) zOS)v!uW#qC@GyGBFfSU%NkVbGXExJ;=0t1|P7vyQ@G;!hMi$tUS0 z7ip*b-U^w&x-_Ah3`AP@f~#PZ-ibx6LH$t_(Rq5Ol%Aw`@W!0+rU@nBa*9tBXRLM4@o?>LCo4QZ0L`6k?7 zGVW4a*+k2(81V6kieT$KX29A6=|~2}eVtAjzu`5Di6PD4Jz_c}Jm4JJIVRFC)#n-* z%h8=&+^3FD7eiR`Mjk3#pY7yo)n20)F9;A@#h;1~$!P_!*y1U8OxX*wy&xi2D0}ii zbUa&>gF{O=4Je*CxW&JowZ?SI)x6ew%nfFhI$E(uv|F?)+uU5{X)vvQj9hQBQ*^n*2P#WG z)M`f?ZKpEY(?_?jT6fB2AJK!NebKtSZ+NKPmMq%JwHMAGYO$qSY^fG!;Z-YFY{1qJ=I!IwZ{Hz&QIz8ZrAmj77ft{sZVuGfFet6$tx z{c|n*bCLU=>YwY?KNr1c=~`z!l+di!!!KzAcaM-sSI-Npr;7(r7>FX**l~c5Za9j) zaay6=Mi9H@v0I3x1>?vOd661HleU-mQOw0?`$QW>LKYY%NbL*v=4XF@A6BSJsQ zOQ$#8J>0*Ld_-JInmb|{wSvt^SImW8i@5ui_3X+$4P^jTuJE5uu9;uNEOAOm&yOopOX?v8hT6tNfqqQT;jD$T{@x*a&>TdjHZ#wE9 z`_aKcbnFif4&ZxpaIk^zvCX~Q028N=7Zt0!+FaV0M^IweEqdo!^aJ6Zhj}01f1aq6 z^Kh~SBz1$kJJPHjTPIN06b{H3HPwJx20E2Rg~&d+e+fQvwaCf~6w0QFn^o|ZVW#Di zGN>aynjSAlQ+%MnPtT`#rRV3ozD+GD!Y(`O~K69GS}+kpfqp)i5( zGzW4kmZvyq9-|mv-7vMcsl@PNb$uXg?_x5#6H@vdE$;&Ou`?WFJRt{Xb+c)sAqv_+ znS)%)K`H@o%^=gJL8d!SxIZvb^oktBi>SP@q&P99b1p^+drBu&?1<%+V3`0~MV#s` zjcCNS2}VzwMvc$&!p4u9(gT2`+#x@24YRhy^m$V{tO};j_-aW=nVFM3m6Pn25~8Mr zO;f^LOQSujLFr88y*jO&&GNC8M<}Kfu8fi>X27d;<)#`sT2KO-G=r`r3%wBygI;vqCPHze@bR3SK zd3{~6ZjWJx5P%CZ4E2N%6Y>tjgr~c>=RXtp^PH&d6rIA`htK-0SkT`*24A$uDlv&O zp=(_}wN3Q+1z#tkgv&W4St#=OIgdR9QYKn|KuK9?Sjrk4w}uoz}_mgS_@juDVW3;jKkg2iLTN>x!y zHohfX>Vous(6q6%K0u?ize@Q{jX;rNRLmF2V8PC_p=M&W>uxJ39|1 zEqj1Yxlq>+kbS{plifynY@uR7CE<{=Pd~m4{N5jkF30p(l>KFPJ8%zos0P~oGHW~I zFW-?Gi~E-oF+ya)&smG!?}Btpgj~+wds>fvI(>&dLVRZSsNBw%@9JZ;=Af0LH}$PC zw2S-O7)Zp<4?$->x&3~3r@o(Q-%qt~=nUGV$!c`E$-fQ$+ytKWw|@T({LgYP5!5M+ z|HJTxi6AD=H`8SnVu3erc+4V2qqV<%-^c$j$Vx#LQ~B?yx+q*R(HaI$@C z!PQnYhsBd9ykep{OiohtMNO^0IKqhaCS6BNRDdN?HWQu0>SnP7KyP7{e%0;;}06SX5#p`4w7MX=E`0>Zba!!gQpE z40x<(_r8;F;bNRK1`5d=0CiuE2h`!wE4*4A!;HN7}z-FWUp4{M*aUw6z32f7qIKqEXD1XWgJZ=p7;eh#;N-;!PCni;o zFGMi$=PJ=H?66~Avz%=iO%%OHJ`1EJ8?zVW#`QgTN!ukQ{?4pd|wXqg9Q=Aru( z&uA_4P|G|tGe32ok^E?^Wk1xiADY>px!*gU1sJrlwPEu<)An*=27@BVSKU@gOHAqk za16w$#+j@;L|0(5(=qcSk4I`Q@22GIDk@y4@nr1HTSdl5H@o2BCM+8-yRxNQ-2d3IHBHXm)hwd$3EtqoZm&dp}IHZAvId{q9 zx_Wm0X5dvkstma2lx;O>E0S)8)lx&64RV0uZma2AO7ENR*x%QUIeB)eIP0QV>xf#Z zDYUIEv@Hsy1FyFKM#VMBdKJ~=RHg1p_SyRL)~KRCKma>H#J_86s{nEFvgq3wHo1U9 z2Jk(`KmNe8I^`6yM1eHo&vXZkXrP3INLKTrEtTv20ff8SwixG(yZwPTaB~ z_)7WL*v?wM#r4eP`-te#2hW3X&ON?B74bcJBK|m{2d4vq&_4NXL5SF=mhNwWyODXI zg`8ehga%xio3xd+xdOCs!oi)hs_Javmx}NzDiPKzoCaY)2+li_}#z zNdW8ty4T{C*sQxHUz+gK12P7~LmnPtc&F~mxRQO%vlDb7Jt}Fr85xD{B6_T|#isuq z;F*7YhA#w_kkmg-_L?|q`M?g^;_wUda3-rSna^@549dXyv;jPDqdFL;&$sI|Nzz%? zy%{KEA!4=zg(GC1A?49xwivUM=6kd}vPGJ+bl|JJDbaHG07~HiVl{bKJrnNt_9$4_AIZgq8C__ba+nuqx$C960K1x=684EuG7k!qb+; zE&An^`sqplHYQHOvOZC6Wfi>o1sm5#D~tJtVmqbmtL-(QMKKc)Tf12hZWpa0Gw~M4hc)!f3Wrd_Fo% zd}s~;=pad*DkdMNfDzliKF1w_wtK^Rd|WBVQZ$n zv1o02gLNchY|oPwPq#91i;+}6zTU*+QjAL}ZeElgda}#&qBKTQA#EqWzpF>!9u zpPh2!K}IEv%sDle68+J#@V<$j2(t6#M1X`p=xCuGzpqnjZrE#dC&-~?`n<1v*hYme zV37$}`Drh5?{Bf~Z%{s~#W=fr`bs--?ql{5<0#QOMoJu3;)xgo%p2a>&1DM~P_n@iK}f?El147?j6T{S0%C}O7a~Bz7clFMJ406T z$rzGRNvhR^!J&2skOCDQ`{ff)tb2MKk5akzSvl8vIuVPQ)Fp{ULk*moL;{de9Xp5O&YZ$;cT)K0#&y$AeLHXqeI2&j?aYT{O$*QxY3SZ+77)ea>pE^^%pW&e5GQL3 zdF8V6Km&;rYf~kYVb3-dJ1cw-x^pz2270;Vk^x^IQC8_t|GT$8zkc!Q$4@U_y?y=j znVCG6;HZE~$MMNH@R=PO5SNh4$PhhMD8QNdQwb(B6ei4tLZUrApG_d&(oadjDB?8o zLSIn@rJUYLB%KrJ)XiMcGadd&ydq^f^b)+%Rk6`)D4w-Tw549uke#C0CV&6D0;jzM zXj<%CNURWO8r7g4*K~;?l>|xoXy&Te_kV?`ghrOwusP$9&`t3!B-P zl&v8I%SXSK`)IbtRX0snx+$}m%NX&%=n_hKw`pL$u^lmlU+VXhW zf}uSY%Gz??Y>2!<9fMH#UU%cta{T)5^O}5-ijR1Yg+_Q0;|XL|TSV$c@!WaxD#(LhKE30P&FfMSqo>NiiNm_( z@?0K_p941)<=+L@V;g)AYD`MjM^E`oM#zt4Oj0z6OdA;!|A9Hyz9q9HzyPI_oM{lu z13AMHOo8MMY=!HSj)2owsBBLXy0l;TLz8451K1!e253(>77*$K?1G zOZKT$Un?Od+$<;OoZ3^)hcG3<8jpKaA=cazy+!Ji6k!D7yHC!5gTXgP=+Wy&s`4*G z5jh!?c$E9ZuD#&E)!-gn@VMfh5R6j%d4f2Am>?pjr(9iK#c^j-s*Dn72;3(QC23X6 zfueHMmGxz%TatP&#JEF@15gqCr^{fLTyxb_W~!$0q$b@|Sya|+oSU38(eEEn86s8Z zrg?$}^Eu$WQ|`xg9|-Jt8f|9m6`Kc}h`(r?dHan5#44KQUZF{uj=NZ(o|^hP8c>A@ zRN+L49a-sk-nn`;RXtnf-GcBA&jsuDfd-hph-WWh?A(832n6dnIYLv0?~NtU7T&zX z5z8i~HS~Y>^L@@_ngOMTfrTakYmhW8Cv_Gha;m?TSG>-b6JDq%ue1Vg8}pq=MUAJ zGvaVSQ9DOzbp3|>cxc<|J>sN$${Oi^1N_2igaZ8zb0z|$Q<^xx^28P$K=!&dB2{0-$v>04oRktO9>05N~bkLT>i zV3TDqQwWc+W1vYwmc%-uFk<$KU4`WCi_Q^S4R5TzdPCUaFhn{5%o=4Y9PamKH@p%u z!oUK1v#pHTikOsTfD?Qx!Sc{gtdbX(mA#3QWVScQzg$9sRTR+J=0Xq3ik@teEX?tQ z8LB#wY6)^I7sl3}%KVLtMM#a$i$QPL(k5v+u z^A@z|HK@`tutYI(zT1l(`gjqyfuJcxkJ$-Ei=3z_Y^E#~q*{Z;@1 z!xo!w6POHHA)evWR}$NC&mpMyL#}t=1gzn=U6aLD&iBdI2oS!W7{*t?G$_e}%MJft zrzv20>m=Dkv%NS$m0U>+?ERl9jrRZS2~QN3a^0a%MkAB2Bx9>p62B)`SDAa;$ki7j z3qhX2LZ<*ypBPLI38DO&gzjY+&ujskM3`U$ynj^h&P4|s3sURi<~)|AMG@ocp@3Ja zDXUB(tmSB;pU`HD%{LL!SiE~5;ukaMATA+hz&9Gs5?%>D9GE6i_Tmx}KkzoNV1Qbl zXUS%|Je@*%gcJhOY}owiDoJ2;@#1wHTt;k$b>c%22=B%9n3(X8dzmQ&{l#d1UFTR- zj7)~&mki3YQ@q^%M2EkQ5#fxdMnADUj04O>J%bLc^Aj!-gFM;SaE)+0CEZ#`)z+cb zoox*y84hS@k)udkUrt6|B*GUIPxvTVqmfDMdn) zyMVlvi91`Wz!*5H_jh&3C=9DUXtB1L3H=_hZVBp&k}u5!yOOnBo?x`DyihDEXXWK} z0Izggmee!3Vd1A{%CQvMV_bxp2@F-ci~(Mk@D-i`Av0wk0bNDp#YnVV15{+`@lefT zU9!@uj2l|>20OR9ih8{b6-xbpsDP{2QOR={e}{ul5q-BBdLgFqzPiM7S3DyRJWv}V z65-x6fFmgFa_y9cLT*!Ku%N~AHcq&>JYzMJBF#KXTcBc7Xw-+h@a4kTGM2t$ESHy} zYD@d$+iNauC!=y5{_pXRVb;rci=}TCi~CD+tNZa=Yb|YFS#cF{HQOScaM-Z%{ixa# z#BYd4q4+hs{2G>;(vnxnznass#-yY+#ck{#VdT0bn2G8dH$F99)r%X~3%@m~HzOyX z1nTHPO}itJSyTQnYKV6wE*HXtD)=k68H`S(9$qMyg5hWjeijdx6hn>nI_kJNlD&U zEQ1E7DzCZ{b@ijW&P>+0(kT$IUwq!(Dfvqc^5p^rA+6DHuCIOHUxSb_=v9>PJI+S^ zF;ebpUGZvv8XKw9*S6L-R&(}h)mniHUFp|HOXWI80hC69RhP`@N0||#Cu4I*QeE}X zX55G1bvkhw)yiFqf*sDiSXJUqP#_n)H#0XxRg7NzKN8{=7-<-mTZs%?Cj3#~`PwvS*bNngsvi>uNnS*DjO zo``NH-ydKCbW&IEvCex&k*#oP?GWynVFPG1G``^$&pcjY4I`2=t6ol*teo43)N&WC z@c!zP_Sl|s%<)bA)rv?IouVt0w8*a_DtT#J{AZ$jW;1(N!AIwPZuNlj4==#+ z-7KJl&`z3-gv}4S1uERLoIjnk{jht}LBVr+eng>dClP+#x^=4sR1z(tx%MR=VcGy~ zjXL8Ic%$PMKF2PzB--HZUtB}uJTwc+J;2k6PtFAyzOUEG?;Qc+%9KR`!dAIieH2>P zs-x&Aw}@3pe>!nH%0FT?`3PSObPM@n(-tx|IG~0k=JN0tvl*LJPjD&a625siYn0t^ z?Rvy2wj~Z+DJj-KSwQMMOp(pwLiYe$vE17{NTI79`NS1Dc#@-aiHp)|I%QPJWu^_4 z%0$PVF}z#GdtvG@It64wDh}`3)#_3X^nyh@7aM@KX@aB9x(#Cy-86CRPT%~ zU{~B|{ee@RH53l(Y)ojdE2-ajd=&S=c?74%?Ty!Ww_bmT{>$_3Wy<3i#DyX*PyGsx z#GK?LHILAT90a4fOptm*wNfVPkQ7~`&lkCD70yNZ)4u=wHG$Ot%u5oid%S*2<;Tl_ zg9C%VhBzJG3of3QEhI|RLN^PpIObJXK3(EwBw$u&+^9}Iz>t$GeRTJZffa3aH`BG3s?29pIG~`Txr;ij!jwnbmxwhckV=rL`?w%=AgYM38Xd zaXM$_oLS=M+KId0K5mw8UyP|CC*?$>p0(IxL+044tTfS3`tRHL@y zb+c6?%W0fYd~BvTv-IVxO!%Yf66c&?%}*EtRu#kEqFJ6cmA#>hirro@(Y@ggP$U)S zfb~-&iFcuA!*};8*l8&Qwv^9yxDt6@MDc76cloT>_UnJ4(Q5U=>9O7umGbYpD6B|9aImBf4o=KXJI$b>!FofsWL!GUI@x zReR4Rf@l`b_y-SiI#1W9$N7NTWRrf8IpWDo}cu`AzG!k}P zWjA73_HU;jes0_tMK(EWPJ^YZG0`#y*I}?N8Ma(r-mLUn>M=|5`bya}{d(nAz`qrA zr)O52Q66R3iav~Z2H?+9u5_WU7$~dr4Lar_>6jO7-6J^y*ilbB-SezBD#nmP1!}px zCgq)-W4<9+zTA_o%h!qcS*dlaa%n;nCNxlM)Hj6hj=ChbJ{q|c@c=byNZBQsV?!ei zb>U;Y{PL%~KDE@u?apYcq7VRdLJ{ZJ<>|_a8sD30Goiy>${-El4NU^1PI!c0NiDTk zo1_}kQ=M8Sw=_h~;g&$7t{g#&+4-VAgI%tx%uwavH33_aT`elIAO3tZ@Ly$RT;e4R zhYaZ0&_w9y3h37#Kc*~LT}BK+T$5Hq%1yqKh&;y<4>GnoNzovFGf$K#t- zw1>vdq)zA`Po$rNBZ~(j>8qVSi*4Ew_^+w$%>LtQG z=;YqVUtYd@d$MPBdcEHcPkOyqXRr34mwSWmpx1l-v$Y2$tYx0ByX`yig7YJs5On`OM+ONbtnPfL6!HN8Y_?~I~@_NjBlRc8U8Xs1Twmxg=dxsbxz-9t_r@I-CNvI7kL$gocT8nq( z2*OcAIE=`Hvv z%iag+*UegqNo4vbHkWqEDhE}}YeP1tF>5`s>Z0$3iq?#YiY6vuQ84ImhO1{0ISVdz zfiVo7fZYa1e&Kaqx4~~3wBAqkQl)$WRCryqEcpPvm}Pv``(uzVGdEH+xT2%njo)|Y zek7$7o8$RtgHCPdaHd4(n~6(SO4N;27~!)wq)Dk90HSQka`t_{GdMWdUy_dZlxuop z0ELD*zlO^k=azg3Qh;u~V!X&jVvL@Zrl^EFAHnxI5^Oxv8?UY3*(u)*Gc3Gxf;KE1 zs`dYGdd__g6S#Lvz=e@tauJJFdV5bScjj78Mp`-=@a=8V$c8jD>4s#dNZ-NNL@kzj z1cdCw&!2qBk7pAX<{qvJoFV0?^V_ku3O(xF~;Cocyxlt`W6k;Be zO=2cj^J8EvExul@ycuNV%^>t+yfP1~B(iqUn0U9aMD=|?1^S_|KgEc#w4WAU z)3ifcxAAlfTi6GxkvbXLsg4d|!YJ}B+zNk_#!DetF5!65EC%O{qgVcPt1*|lDXKoU zrq0$j{zQlZClFO`)6IZqKTA+BXYj{p?kO!ci3;ZSmK;k~FX_o;2~0;uu4V9jYIy^L z{uSjOV(982g$)E<5tdUbo4S^gcWRqBTZVIVt4OBwd*uRoQ-R#6xgL5EMM6kj6;fQ{ z-OO16JGrE8_un}Q{SiAZCIS%2W9Nau;n9;I-u3#%89*RF5V#J|YM|oOp=J`)Y3VMT zCt^tx5%^1OcrX#^aiFj&y(bkQM$Jlk8}fXN9T(r`%E$;j>kKM07MJG$y^&6tow$J1 z9WilDwdZ>6Jj)!?erDICH1`&>p}Ga}Ko3p6)^P58>l#$sZ4jAoFW;%pl-dih8lAx? zehzcn>8Q7#^5R{k3?)Z8W4Cd{5?5RC8HUL(Q*B53p_PU`sEEC-vgi$1Ve-WpE#wetKqgon(z~7|~s~CU$SKWVily zEY1J8#iVUXQ(^S%a1-WR8yITG+q>P9vTP}RFr>$P;ehqtJ-5*GG_Nz>EDXn7C9FUu z7tIA8T?7c!h(EXX=pw>T2&c==<%1MuISwKvq8@X3Ow!FWnmXViKK3VQ7r@3w^mBO9(ADbXTm&#tAZVNa3 zg|ionj7@s~T(gCR8if1(-82v*7p_G12csDm-+S5&>Hgaq%o+0p7ykj9M=5jO75EuN3D!`6AWn<@H(+Q>(K!EPeJpAK zj;`vd!%!dRo=dc=NaZ0!*O$f-k@`c8N)g8rd~Sq3)>*P1p)>-!#I+^_DnS#)yo+w( zeybQ%P&ABGcyQ7OFA{OU=}Ux@^vGEG)ryg1kC)9O>R#)D+9uP37qffiHgAEd`)EsJ29E4e<`0m2Mar!Apg};w5J{iQl7E zd(0&g9uW4c4%wn21M-pj}c2!;@N6|30~@dq?n|I^wMr%25>sMjlcqfBWU@sVb8v8n(le|% znJ9X{K`B@F20yp-xuv_=n+`to1_^EW#p=Y;hWPF~&P_r04-|uCR1UmAHj0ZEm&5KV zz*smE!)tu+@Ti;bjQIT z1wKQuX#-RMjTqK|20nWN(1AZ&bdOb&W59C^Fo*Jn{C>}JMPW;RZt=4+laHQ0S@nOQ zyK7Nz$SbA!)3AVnuoZ=D(t%=|7;nnqj z&|m!T9sZ@KQVcIXdPmBN^|sW(;F%Ou0B#-WP#ybK(x|1Wj;&l_(dzM(-hVue zLV5Ir+R>BJF@;ADx!xl$duVe;re>J6P_t(A4N>}O6n2AjDv1PqYb2P3o6POI!xs6L z`}h_wej%F%xuRB^>p&}XelM+8OE`Qx{8XSvOgs@S_fms38GmWGN-sdNkTh zv2rWQ&#b;&RP!`O?fOt2C$XO6JVX(x?o*wB*}moL;>B`-NF6&y{GY7h_Ys)T<#?Qy zZYOrQM2A@e#&gA4k~uqJ+^DB#SFS-B$GUL%O|`45d>6T&-?)d zMbFq&De4C(*^-YlboUd)vt)%X7St0Fx=ll8C?EXc8bT244NY=KJc^^vWz7YDV_SWE z0>bIxALXRKQ19Si=7%oF8uArjoljtR9%^ErH5|x)8SBo_6g%H~L-$AD;C9+&OOZ~5DZ8r+jzkN~3iJevseQ>X`MF&tfD z_@+JJI1>X~2s{#T7MrV#Jc9?2XW;B8x&~1B!yp6<3+~MYGt545J$8o^Xv@Ehb(fF9 zy35C6-R1vRux@p(>Ro%gs4OlOj>=D^F!IMi#u{zQYEuB4G=RB zoHMQjCQx8V&yWeEscc`rfgdQSvjV;h#-NE9{0njj?K%0HE&B063Z(11_=BSSapWN`3X1% z5DO;_`Psv9OvOQIablu3f*5*!(~j>w#nCMR=G$UEG129dZ2T|{FmR2Mo!WXFGgG@h zlV?PaDzu!CsiE(fL^x6s2flIKlCNm7gw4a(2#fLo`%xnw5`h-=Q$i`yRmwOTr6C-8 zJ&M-Qgx&5fbW@Z)O{dje3bY6FkBXI@CDRRFCW?CH)uQzAKu^_HZx5B?ET6|vd75f7 zH?7_95UsOhDY0azWheiYxv|vX#!|(Nkxg4M!Z%`oH5b|Xiy}rDN4bu-iVmV7K*`PZ z6Gv~X@v6Kcl{TLt;7cuEqN#MoR&QKL(}#v@Gtn4K?Pd+sj#bKPH44cq7ivZOw)23f ztlVgk8I9P;T{WIm@8E=irljPAJX8iLoOk3bPKnR(fk8!m^Z1f5jyiQKURZfx=H95e zDIRA+S)h8EDeP`{l727mgVN5X4am}x>*lhz`?Bk19($I&;`v~&a9{O#5Dx(tOULzv zgXYIvDgss5J(3QXALn}6)I#{b?Ri;?eOuV@s~ZxjxuASjA<%8&klYX#&YOVCk&*w- zww^`Gm+)l?V`w&0E{O*!io6(;B~}qfrGtob)D)- z;;vl8oT&Tx0AB)d_vp{?=*ZpccMlz_$XSScft66PFJbGjRIi1~7Jo{$ypy-#z%MS* z0^($oW>^*pOpBC>%ow53AR|Q(D1QK5abYFX$i3w<2mvXkVuovy;sn@l^er@#i4fBX zc$7u{ugSX#fvP7?l#YtFT)-&gpZ1KL_`Cry!*$G6=q!m~k&q?sliz7GUzmwrzfWfL z>WQ>?;o21dpwq7cT(US=zra^2up;SN-KKrfLeqw`?m2}Unbys&RV!z+Js&>_{ zmUAWYuM{Z9>%6?e9LOQO#VhUEvY7p*LS7g1`7+l*{*rG$CC;wu+HwA7q2dro7%!-* zwj;3AUlm}QX!AgW;i|yU_;v=MeRWz#{hS!Y>g5y~;@6Z_*J@N3NeLkCT`#kVK zqi2f>?rqWRf}=CcE+pnIdTMknV=X$?;i5)|gb4Y4IXY&or-u(86mlzsC%&&9?nDoZ zJ*a&KwA;#!CTKTAdX*L2FpwoVDKFKl@}$-()9mY-5wlbo5o&YRO0-1Kvhr2vr>(jJ zzsNwg@V)-Ls8<>y(OFCq=xh)LAJmDsWH?!`3T+2{Z}6nxiikB%0_S;GbqZ|^Gucv6 z^x=5)@u;vroq`=G@R1e;LA113I zOF6P71ATu;=+9v*;t&qS{C77422k*!AABh2CMJ{-NDu_Ygpn&tCAwRnvj_%@cGaPqomG!5!XJf-RwQO=2axLA7M57=89cHQ}PCR_GM90Ir(+!$EOg zrn~5c-ug!8aP6Yd*H3g>tya~AUDly0>(DFfP?e=?O|`U1XVyW`e3Q-^HVLwFv?32# z8GufXHe#dJbS7j?U0gxGBbo#*Q79}ndgqSQEZZ#E*8cJOw56xU;4U=IFNz+y)3-`H68utuD zq86_abMAPM@cVY5!6Ffjv^ziQ!!=3_*0i9Tnr;*@B^7Vj0k{U|8fu6wrSGL7wg}A8 zYHpnb8(eN{Z?(??Y-eU0Yw)4XD667&2S~ks_Zi=a2__#)7^BbdPJ6>PeNlJN7g8^( zQ^VjCNM4wmKJP;ioH9sttd88923Ub(%JU!}=174d3_gEy8q`jQdmjFeC72$#2di%> z*21uD-5v_}9`6D?>k2u9KYik`523(AJ8-HPe3!#QQwX2wvJQKd+X(i3cFZn7g#jZz zg&}3eY@&W_MAA)1Bq|#5A`63}TP{L`s}Rbiz>7vvurJx;ImuT%atMa46@Vt^r{ zD+ApDuk^1|{)J+3Op2EyT>n-{7b{(Qt;$@d>aLk!O;XgwX{b<0%PzSK?lbeH9eu`A z$?>NNB+GfEbo6u4(Z7I}C_Qi4yZU|^u*A}LXLRavi6 z-ulBNN*%Ms!zs|&BH?{7Y2ad~87vc_;R=s*D_n}La0sPM&=!sfM^smLo-mx8HxZHeC{TTR2`y2-Y|HoF71Hnc(OZAX6bkzc%~;K{*1`t z9ziX=N^tPFLzzB@6Wzu`^m>1^J3dY;_zQosMCVqHLTBs~)CoT{;pla^nW79EYGcM> zv9sElCHYZ(oI>HNW8esyv{6m9QZ_14v$NQl9g}Py;?8(m z!}y_|!`ZEwVVUD`mGIxgu7c)J(1{}Caa{7b<-)?pOzc|M@zw4bgWN6d)~i~R9JS`; zusJi#u1<${6_?KWmcdN=N@|qdBQ`HyU~7_jU%LMRLHl_i(mW}Hh>5d~^7)!IWe0pE z(Nnjwb;kKlu9CB4uJ=`f_|(Z|Y8J90u6XrKW7ukI+RBF!j6nn^0Rz^|c}v26fE3r1 z;sd2P#1wNm70%KTUcB=yGYJjq!#b4LK=k{&>hD%KjI@JAM>bN7=Czv^ehfJqMcp%S~KDlJgYvKr^uvI(6rKW=dEh&;dHt;+W2)ZJoi2 zYiv#f|LoXp(uGSvLQTLa#DG71OxPy@lkgwtX{jB4*g82l{ChYH`S55SKCHZ>qI>ZN z&X3?~o!x)?(J8fU%&$;m%ZJ>fsz^NyHxMTBw_9B8 zwFMbzK-9d{7Bt)M47cAL|2en%FiTg%>zykheI6khvxK0v3Oam*Bw&`R6tGBVumM#p zd@d81#M$F?g#W5!uzJrBt_kCo6t`4ycnQuaF3SIQl`WTRWMqJ`gZrbNmQ&c_{C#EC z&3k^nLnmzgX|&#+;L|7Il531My8up#CHiALPk{wp^e1Ojot*+t6rCc2v*y+$$*t8; zJ&+2%WkHw?_=5WmlXnHvSD|&p5Y{P8?FSfR^K}SA%;j()NJ%KvOFTHdoh=1-pU^nH z15~H2&_oL8a8LI8D3>1tpz>SMA5`=QqpD%r-AcXFJc0#p^`%uEr9cKumx6q)WQRF0 zc}@5s8=07Sv2ypFxI;VckfBn|0Q%^frj*AcB4wD_7IN1UAZwwn;{DrVW>VqO>6r0H zNtkXBRdcPYL5kB8Eo(Wkkp{Fy&{jQ%A`1|W4|6mH84P_o7`B+re^E|6yv*hZX!)q# zH+{>k5x7QLR#WPBBsB=4_jYniu#U=K*yA{Nr0@0@43E{p+!}~=S7qG$wN=@nRJOJ& zJ9H{Ll*&qMXa7kvrKaJ(gS45Tsv7@6?MEz~ldLJpnv<+K$vPe3YYoXrI$620OVS2+ zV5wLHeVQr37R;h^H#TVvsq^)2Nqj5(yxuK|lf(PBj&q4v>Ch}K;%c`UKsa*aNSZzv zIhE=M>?b2`D&3x599@f6pnm24^l1in4AD!oyjaHBqgfxAm@^JKTULl`Lt*=x=E`=@ z`j3~>EIpf8VOJ1FuzFYexiX{a%hE5u84aN6*}vhhL^p(_3a}2cDRgQ)@xtK-Bqva! zK+w{74EPxv&M0lVQm=13onblZN=~ShWbAyl(N82s(~Q#p19d-+Y zxMK@6-LZ}P03Er8Z9H3VM8npq?kA-Cmdjx8m#7Lr zFwr;pBu|ukIMfaMSO7^O3o(!tjVPQv?IcNwN+8PPToOo;qAtl)HKJ5D*sNK?zSOF# zRfJ2pv_mD(QACmCA5joi^tF3CPA{ST$>-NWQr~>`Ti2c>9jA{4O+EgUH%+-bT-^ZD zT0>XV_DXDN_0d~sI~dgpisr=}SZlpff$p({>Vda=^l+`#iNw`d0w5$hR2KqXwac~LE!r3)~!}J0G>*j zNe(Yo7(?hkhLckq9%@o~iV`6Jr!5*2t7Mx(Mu)0_D9QW!AIdp9JKks!bK+V9#~+O> zk;^?7C1g}YU80lox2*V=rIkXy9|0{@X~6rD1@#P(%$XJR0HW9v{)!h`7dx(yGTW_& zoB%l)=9(lQv44^)vvW}@$VVi5KcM=UG{A^7%9-a0zwa z5q(Pg5QTvJAKHkcU^DgV*i$mD-*L$_ezgtt;K?uAW%u1pq^} z%lY=yMf2igl-$sQoan|Gb@q+B;L!5Z%%iSR*?ybx8K9%{qz&!O;g=$3o125NA#>e zO5nV{nk{x&iy}hvfs#5bZ9xy@%CM}s+bGZma5rY#dkjkvng(6cD(?sCo9?m$!+w`{ zaPRvLU7*?7ZgI!#Y+)7v+T2Q~upzS&iFP@OP&qsztGN{mDf1!lZ8?t&TxzOBpjb47 zrk%k4QhM2LeQ2@l)iz@P-5pKuQp5Aq?Z_88lgot=t8-}x8D#@OZuF78GF-iFaSd(d z)x^IPA_>E#cR=&d#D=@*c`UO>>n;whTO*P((_nQ;yviEmB<1+n^?Oa#&x>Z3)pO5g z!Yb^xQre@h7lO;;Sk3fekQ*?Bk+xIxhC;mG1sdF?H}5R`6+1I+E&SV7yqjQk`-&&X z*JNumw{1{m=lHo(n!|GagVV|d<-VpH*ssXdTj}AR!ZY9#a2ewSEeIx+NTkL0bbSBTFr~sN!k?NI%*HM>j~7Yc8Awo z#D#udG?$3;+=-*nZac$j6m3|I0%88?p55B^K-1Nw6>7Q$PY!^y`=_cTi5$}`O#pf} zS$OU`c7YPMg~w^9a0ui+jPEjEqXhq7alo!#toHhQ5Z{Mi> zo_qFmkM-`fvfWOqMUaXn23Yb zt@VabS0j3ejFN~{Lgnuv{8enKXt8P~2CcEcny117lTqqQnPjcDn`E`Uyuw{w)h~eA zbsX0TK2LtE4spMrp>)@h(V=;Pjai>;9XOvkQm66lF2>j`$K9qo4-kcR;cCK@JIr*B zMqL|&^OGS~Q2+*^AL)lKRNO#ka1NxxQFa^xWq{!R{=Y~>(Y!+j^?-32Pz3Il;k~8t zBQ`m3Ly>uE9ZiDWY2BIfv$wLzB=ia~TcG%HH3cRZKTw5YvKpRVtyWcuAG_lXFWs99 z;-qWT$FC=Q$!R_LGPyXNe3hIoCtoKQ%gHy%YB~9KWzwX3 zNtKQr_Mgv-A)JeFI&_Ula>MWRud~a^QB>~Mc>@as_Dh+Y-`3B@{%!sI-TbzGmiqT` z5-@#lU7Ud{kd_)kTgVF(y1J3R;PR_}M_3lFPL9d)Eq!aBIG$XQ9$6q?X)Ka==q=K0!Pc&&vYYSFm(^V17ueIBwnExiHP)o2 zt&q;-?=MsDJCu~qgVg;DC6xJ1z3)&`oYU0)2qmJiPo1w&GCj~~DwIFI!Ao_HNtBre3Nk8 zJuj0jnYZ01Te5xbm9nL%?YGL7jJIAadL(@PaY_x*nz@j43LPd8MLDTV9HXuRG0rLk zKTSrn!UJ+vC!X1Cv++9R&93Sbg|)PR!eZsN+@4u~UtQ?N&Q#z7*~=34L^;bF)loOJ z&Bu}!u2%Cw26Iu&=Xr_QGT<8_$LtC*;jB)-@SsFwn2b^#K`#aLo=7c9b(y=hwbxu{ zYvp!La4VrT+pRb=^|YwF%A`oE9QrnS^_uR=uM=2h=rB``jc?ZJ)y>60N79vv;yfvoxpb#c;pu?2o>asOd!O_{;Icw_P zyAK;$pU%X`L`r-{YXXTor@6c6Efe!uOX1IC%Rh$))m_#L!M+Xln|$@IxWHpOwy4e` z&bO?S++8G_NNvcP{HAX*T2&BNi- z2fNZg7WF>g5`&aEuC=3PFZJ*mRb|(m(QDd&p$(|Ug{0GDh-iCGG8d?Ux>OCekLeth z=Axt^chgc*(@~NIk-4>~rf-z;9iT!@S2Tjiv0O`R+v$_(^2^dH0^z~* z@%?;~iC!-?S@F*HLXQhA{ny}aIC`-7W`gc^k*!a8wX4U=9HHvk{j+gKgW#luNf{S< z!Kb8L!EI`ZxMNFdADZQ9!9-Y<%v8B2CyexgH~_{mb-@3DRbIe|T6y=jSSqdQQM3kn z)km-%9$HbN{`BeS7?yzjR^B99hr5|%35(n(u#2k%79$ZgC5-ua(&$J%B5Y%u6&N3-L04$A}E7RV%*8ECCh~Auu(HR<1im7d%bG8JUbCx zWHxsHaELZ+aqh2aIaM1psXV({q5{_fb?#7)lnCHCP=-PEj*DtuoE5fuMyWD_OlxmrZUvg_(oZ{hJp|E$aR4jtlA(3!SaKlhiI;*K_bK13{GUIfQ0qN)0`|F z;OI%waaph^dqaDrum+P$R6FNnfWmH{x(e*HLt~-ar`@u+d{=3A$_!l&VfOpFuj1_Z z3v|H0WXpMg#Y3AP$U`R)au`VJ^j)H+dl>Xe3fw<8_iG)IIl1x#p$^g5&%?nTogf;~ zp|bBYlVf*kywSH&BDeMDy-~pNS_y}~O^LW%oJ*tG*I@q-lP65h>igzTp;NpvI|-I< zvZS@)q^l3YCw3R~9gzw9LDDa+#m`BQYCwBnCq_9|Doj^`aGI2aZ_!RQDx@$BLBwN6 z%(A=mmRE{b&6 zySj55hIf_%9jLb5+IPx(sBWkhfv|rk0O@Tvd#h$jDJEoHjYGR2LhYvU5=_~uh2i)A zCyFOI>6BlHZrtY{9~o)@^#pzZq5%+fo-%(l23C! zXExS^biIFgCGg{5U*T_>hHg=>w18qe5tGT4Z@xl8NMUnYjP3}}UqLWUEihAsRh$Ok zOqCvyIl(MlJady=GSj5vo~omiY=H}(wc5rPhl}b^#zc2WsKC6o@HvwzRlFR+ijMa! zXy*#?{e%a!uySJLxYc=m!Z#8-hAGdZ1hEe$28P-yqbeCw4cinbLfBBJgb!X37G@T< zB8je}yA*SHTQTcfiy>rVuM`d7+1VCG-Lwm7HN`6=&=RK*ozcUhrAbL_nG|!*A9Yqu zA_&LP42@SH;oeO^pTNz$g_s7o{!Bm`T1&3Y=tqN<^8i^Gvy>H*F$F#Pg*HzcmcT5q zJcM)Z2OipiE>dsUuZ7wk{rwopQOmW2#>;}T+o6Xj3x*tFfUOV`mKKV10S}{#az3Y& zG(LIL%7`ZI9fD=!jlj)NL(08&%1~%`-5m*4 zDd2YxorZA%6GFjH#e{T`HE-o& zqRw&&o)fe7ByAGEd9Bk;`554bSVXQqrC-w^Fn&I?v6(0GDS)dJLA|C@>bsV5=$7)q zbX?MDXLy~*0a6=Nw-j73PTSmQe0Z{>*>yo+Hd=GffO-U=LGD2m!u-E|`OWCjS6^%E zj*{@>%0c??u+Rr-ezZDH>cC(?Lm}$l_MpR(VGlC=Tl()J(^A^zN9FORrEbqQQtWlM zfCZf@2ekK5Y`29e_po>l`4554u`!v&{Rhtil9iArlD_|jsNYPK6z1*^r2BFHfS|!c zOaPq~cxTDG%E{H`93>W30eCcRKr*hS$AScw5SZuq~JbY)nq@{1VQv0Sj#3RHY{8el&TSvHm0&A9dAk#FSr z#WSdF4`TZU;?cG(j$u9M7h*fyb5lS?D_g{Uzx`nw*1~xCY?(-R*pPPgcM~!owi~sD z!?SHl^C4>8UcU(qME|iBOAd^uN9|O}>UeUr3iRrDztgVY(PL}J=GVna;_=q@9opB) z4WrJ`Rw2^YV*m5G^soDcuUcY4Jq-I}qAFRkFbytPa+VHzGq->jW5?&Ntok8pYSaxb z0Jo9I6Wn2ib!DlU!S)aw}%3&i-W>Gq^E~?ui5H{m0ptXAw?Y}Zv!ZopP zJk-HFw$u^=KJD-1urahx@c7zlVXF{Qw85-$PHnw+=eDAQ&o2jvd36kao>D~@L9*Q| z^s0KEt+MxTU*UxPC$L1t3V5R1DHf+Vi*C{7xwC*TA?OrZOSZAu8PcYgC`dr}eShQ1 zKYbb_k21V~@hC2r1v+pUqazscEQx;*qm6w^!oT<-2uK!!n}8n~7`Kgk;+{Aie*jlN zsK2c%BS<-R>erd33sBv{I#Oo?R}Tk5Txbv^ov6Q4!)Xu~1_;Sy!8r5uBS_q{bOFJl zzS9E9gRLGfkG?to z23k|9*5Gw?=}f)@H|R*#eJ`~`zSZ`l|GGRUX$)P2@Rgqnh61dSDIWEzKT&a!o#&5G zBd0*WzM&Yy#cYzhtw@(CHf7%MuA8h9v%BD`l$}SCGC4%L*0{`@=6@Z$ z`Dtt8R0d2a@tedB40)_uX-`qjsz#BD0pOWp9z=s^kWQWiIx<^UWp2;`5)F-ri|TqaG?yP5S^W8TSDxHhSs!?i}G~m)RN!Hd`GvVA_DR zcnK@K$?MfqeiPYXG3_Qb3d+K?K?j^_7n(0|U0Er)9bTwO-byJwcyqa;{ZpH^@cS|{ znQUnxFB9UKPj@-&ck$Hq@rka_r9%Df^}$M_zBl|}w(`4+7;|<~{5DCfSXYsQyQ1_w zZH;HY0wj{`3h>+Ok(ETgWu!#w!d(`TR{=ii`g2Ii7s1SSQ|N`*p5*RqUW?s2Z?8^g zQY)p9d$e=*{mWBBRZMC8TZ16-ET?-UoU-@1w;_-6W3$C@FCDFpQ{q_){Pkdzpx0Df zv2+U^0b8+(1`ZS<9WrpZUluFUmt=XxG293Cn(#_Pa|j8d&Tu%f9&QUe&&P)kN91%` zm@g6;Z0YFAIdN!lq24>ujc~b`6@7HvXN;9LsixH~_>|NU&?+`g%oo32HB!O0nqbYK0X!=qI^*0Ts?+42%IP ziI_H6r34sg&%k5IOsT^EjF>h6Iv^M1NsC&{6$GV40g61|V)w-3J?eLfdYzCV^qaS) zw_~QvO?~Hv#-XIcrk*+L**Vo|Fp542le~;?F0&bs4{4}SiEC#%SivfvErOXO4)&u| zy6HPhJGyG}9?tq~6&Z$t#t8Wg`HAcX331v~3}J<}XaafyVZ`d{`{FvE(|dOK1fchA zcB#P5-QHDi+1(pZ^m!MvW%)vg$N>v-hOdg>^5q(ltAM`WgVn+N8Rew%Q&lDSxdb|# z51&;R7ghN>hb1|0fbjwXXd-W-k#fbT5Q5PX^v^6e4vh%^V4xcs6}|& z5^ND&yF9HBN8)zOMV?Vd;uCcw&T0?P+-Ce`(suAYfn(8nmSXis^H9v+;&lj$J2h@U zCQ*HUn#JSMUNZjr%Vh8CuanX6+pqhPB+{-VxD0MccTUVGjU~4eoYKn50IyL^jk7#Xk;)Jq;$uCVm7D*v9>Rg|1BtJ7==b4!@Fuz!HBp#q|& zx~gaSE}NhF)Dn7d@9>sRanv=@F{R(X3dT2oc^%?FT&mBq%SnVr3Xv7~zp4V-b5W44 z83(_{k5>hRO~$YY7TLV|oy+1$k#peJMP9NbWHS6pqUhQ5`wV3q&>pRe^E!h)cP;Cp z;KymMU^p5lMm&WhE8YX}r%0-3d1VH_j6cQaynH!tco%o^cu{r2X5>-6R+S*K7>fbRF9R{}a)#Gw3| znodv8*LXD1mZp;fVX?8`MWXaBmxPp!Dawi_LB2=Hyr|&_fFG0;?RSAgDPR=vl$^}G$(qw|mcJ?yD%9Ss|xWZ>%W!D&w@I$?qz(z}n+@IfA}mpy-s*11?q(K~|GOj2uG;;2yIf!}YXJb{{TG!;AexMBusp>Ol-l1_~Tol{+8*U#K4&_5NNdtT^Ox`>xaHoQh-w=?-z z!-tj;J-M0!3H0}>y7=%28g!+B&ae8Dk{qk4fMq{vo}8)FhmX?c(U}25KkH8#NiHFX z*vU`x*0>r;S_hmhPp7g2(UZm!O%(0=n5c4C5i+V)&G^ZJ%V_z&?X2gdXx`>F=M1PAr952CCd3@hl?UXQ)%HcbGW+{5VY+&ZlNoFM@Epo$bFjJ({0)EoC zPa67rIH@-JNxEals7F@&Y<2qJbtr7k;S6;^ft&SC7(KFCLhm0wG@5P_1VqW##>wEu ze$I8bO{^y+xD3$tq7JTI)DcyirZAhP;Khm#3V9*oE0}s@rhWG-3(gxS@JG%+;~*-6 z<<9yWy@Y14j~48j5dBAw$n7l-#DYieJaD9N8!rPf(&mq8`Q#kh^W-wQNaOPH@Gm>~ ziGMHq4 z3VCCCU!Z?OXE+N&>0uDlbq#-4&-!);*o|PB_^TpqLKSP();K%_9bFH0f_4ua>6ygR z`b#VGaR^IK0hh}K8c<1hZdZkX0~hlT=sTSB)X6JjLc~JUk%F)NB;vnLs%Jp7kgb$c z`p?-4NQAPxaFf6t*D4z4A;^VqVdo=f|bnUDmKC7dY9*rsT@B1#c~fR)9LPbqKwkzE-Rf53d|AP?aQ$ z+-8iWsa6oS*JqZkG&*n^3dEPfS>{!!V?BP`N+Ll%@9m|)ur?p=bissEKUl<5+KXR@ zA3EWO7|ueT(%L{Ydn6VzTSmk~W|wF&k>sqDFtD#A1Y8gOR`W(5{=B(?dKf8Kv;6Yv zOCO32x8$P_A0ChtFSf$^EkTMWk7P%)T27-E9)5MpYWS$?h;4~Dc>lP8(@>yUMJ%Nu zky~ko06C0!QO0Ax$ z@c}q+P`Pi@+Bl5R7g{9-k2vZBTm}EZ{?{0%$a;oGnZ>oHQzEl0Pj>OcvJ(a9}j22$|zGh!2fnPWs4EJa>_IH0fttafgQ zHB%+E{S`$2`dHo&qJcQ9qcIyqPa@K=cUZ3uPEO8=-1<7yMvio&yZW_s$G6$K{nd_U zw~}1{J`{5JMh>TyI*sy;)k2XYcC=6q80Y0)NRk+84K+&&B=!=cGQ#~~Wf ztk7EM)2E_W2xKBT<2s=DX+&~6Dc2q%Yj{WjkJI7PA-_VY5@LDR$H&dWBAU%+vovF$ z?2fgX`POP4D4K}AQ~hb@^7gb}ja72dyeXd&{~7nURw=F(*gKf=$G}6#t#)M3TDw0U zj+5~t&1G5Sjz!`q51z~flr5(}w61^g)s#9N!3E?2Egh%n*4RltEWE2^lN8NQ6|};$ zdeU`|l!FP`T#Q>~IxHuZ={3TYSvN7_6?;f(!YtSoYy7lOFVS^3isNT>o|g`Hp+0cB z4=6e&BnLtY(AMP)vCz7Rjhmc0`~9H(dZOcPKE)KNP7XUvHVA8c`?-1K9cq6_4iqK5 zpVGs)$-Cff6feORhrH$k(gbBj*OK6>aVi=Le2$wV*7k$$JAm4V8i?WMlDFgf08Y-x zI|rhTHNxtmZ!y#Ez8_mzsLD5`G!yN^Vkc?4aLMdEX4r?v{X62##>xh=F~3pYBG2c| z%T@E{cNT!P_Y?w|TC>%);VUix)rLczimiPhbL&?f_tj=>pNeXvbR`>L-j++mAK+CS zX!iq$UXMpgASd)W`yBoNCqyvfP}~>=NJ2$W;z1GEfV8!UkDWDmT47}w`2Gi@RdU(MMYKG0fgQ}it(A+IHlQHhb&*<)L@gt^vW@3)T$OK`ZG zKiW%n3;2ihMYVHwv%OktDLB3!pXXY_Y<+duXW1DoIbVl`c}7kk%^hB2gY)4Un~ZQm zT1q86kGeSeqAb~>b64FGHb=lVT?ym)ba}bRyr&gS>`t6iJI)0!PMNIj7VvJ%k`}mV zfuP_cf(jjL$u5*YlE*za0-aaIM|5`Pe5;dS zqQb@S+ME@wjg7JD1!*3rIB21hTYDLy$9M_$(?E zQ~P70jtlutn(q9n`BUdhm!Ja7GpT5*uie(p;GoYC4O44!{jGkU&xpp$;{}O#g#@$& z#I^bTA+bK_Y&R=;yu&-%S5L7R5+X8N8%>${Os)KF&6jb2vvFLxnO9QB*a%;0wJf{V zf^22fgm;rnz{^r>FOwQ^#3pf<5Im5VmJ^|j8Zu0~<|Co6p?2h`@W=)0faUw&5ewXj zjX4?}iyhG2vwV5XhC=Ra^Qos+eZK7`1vonl92^^zZkh_IbnB|qF~ky~I2T~g2O zVH9~?@>}UOW2Ak>%gd5_z1jlBqE2xm^*i@7A#T7W7if&2>U7sIr;qjqxkZ-3>e#h7 zRV(%oVx6}n!o4ZN%v#ak=;IhKlaLb$xkns6bn6HxCXjBDBtn(8YR)+9Dj0>%Q@)#G zodEB03i0_6X&_(ZfvJ@{+|cUg_SU?gOutR{53{o~+*kHvi%-NPZ3bN5Y0^#q3B;z> zF*KiZ4WBi3jmjdw+GB#41N?wU+Hb6L)aG<mW zjR#v28_Y~!7~l%O?b|MxTo3|Sx+sjYhz^YjYOEcODuHa@k2}LHx&j#Pj)tQSxe z2qso z^si@UXVS7Jy{!?!HN?h6GXSdAxUqp$CF}sJxldVX$9Rm#w!!nBQlrgZw@S1pUzT**dOQb_r0TC2mEaH5yd8KU*}5 zzfM>qD3N8Vl!2s>0Ik@{FHcd)YU(^3t@?u2nb0y^R`p$)p*_|k90+M5v~90!C_NTt z1km)Xh(q-%)zH+plTxmp|p0=HHb%-WitYs}MOyI&$=v2kKwpgK`+z@K| zZV43;a60^2i)1tO66b8_e_@iNLwkm<_^!xwYgV!&bjY2jvsvCWRo$4^H8)(F;9yJp%SOo_(_R_s1L|>-%0zjc3AA=PE+wB)A;_~C;cJ9~- z%R%16M+Ga-6~ZPRd)Ac!wCSVKF(LC{z7)U0jz(8UV@}5fr}(WfUmCg#s<=36j!~&V zzWVzxrzP9jTAe+)D&{CR2!dbdWVO^x|N*D4?*i17QM48>;*Xk%4B{k_O4!=fs z_BTl4IkBhJYE@le^zHaKtx3PJFwuV?vuz(fJz@E6#m&!>MKVLI7uZ8r@UPNpX+d7p zQ`nbB_3@ER31;ta4FTag81rqQc?UOt#->K z&OUuwARRO_2T7Ni2K8i+?aWkv1`GJTb|B37L|Gw%hLFDuvk3co$vs2!Vp2- zI^rA@0sD+2bW%rhIw_qNS|IoLYGJE&l=Tm{(AAc1OCs7}V}`#G-o|Z2cv2KI?|42? zbQZOOk}39QD4hIMfcL_w8$dl!DtU-JYy^ z%R;f3Xf|30>cJ+p$#fm)2xxIO|F5e?H+o`AMD#mY>h#^3d3w;9lbka~-!*I@Q#HUH z?^KDH+cYqR_`M&(7_z!B&5!KQV@Hu5FORaFzkp1|@ua|LBV|mpow(dp_BkkDOc!=Y zi*Z-3FpBM7Oq6m3C(o9S6BE~0iJRom;g|L;*=5@Z!)}l9LSkk2LdEIGweBol2<(1M z^`t{?+T~d!)UIH+Iy&ohVoOff#fVqTmhOdHW5fFS<1dazeCoW5nfR=skv&Gc3U*Xg zJ{RXdj)GzfQc(Tutqj9{)IQRNt0ntbSq5)-d{p81x+DIS<4-%|x%^Ws|9IozuY}3H z!inyDRK5>kSIM-n$jtsYS9{ijkmGg4QAz{HY;WP%#1u*uXy?)QqJm4t=X}YY_a_Lt z)JEytj#{Xj$}YY1z4B6(0~rnU=g-x0eO?i~C!McAf8Z^wNK`u$ie6d4=&JFX)zSpB zFPpnGK>oyD7uda)7tq;5@9=8i;-4xbDGtUu#jd8-J(e^6+@W3*yNImh)A^w@*H))=;?Ul_J->j(z0 zevz3%uy&o6B@Z{(6O=0rpprg4lfu_}fXDZvJtdYG{ZV%vRt!+a7~Rgq1!Tj>lcU&v za#JDr>oS?+pL)ZLyA@MY%qhe$({7?pB?@jbr^N+ zfS0^V;NWM#ch3+}IU80m*tEQ};hcYd`b43!>M59hfBHnpuMxZ%0*s5f6#*0BZ z?k9WbJ`mW2(>l+7Q|o;}jGVp6*;2BD7->Bj@`i5}!kV9VFNKeVRx#UoO5Py$?sbTP z?6+K%^<8z1&+)R~#r=rIF?2O_i{xW?Z56V;yW2`x6J)tQNRHS3R zGF?3$O?TVjlTgrx4X}bQG+{d@e5fHu8x-5NY|=kn`=u4xFIlG6Kz`eX*ZRwlNYb`< zl{YCZIRDTZd=%sa-N#by52xfzxvA8j#M^3JSlZ3rO4wGfWW$Qh-4(KjbQoPjNrcot z5r6o$rKX&0K%HbHDlV5CXq$)4?4vn$M z3%Wu3$vTksBc#2Qv>zeurKG(Mq&Uz&eNOKa&noh>dD9Cw4R(Mr_0HOfoq2g@qBo(Oiy3{FIMRq|J3O<{y9yb zQDB`Oz$%beWp9@l?_E8c$TMot>UQWSxw84oI?^EBlPH{a^5G@mf*5N(7~8@64VX3* zJ2h%+hAD!JH?asj+>KqB9YPLA^zJZ<9^VYddtdH-`Q=~!^7Xf0e)H`&-{iaFZ_()v zyYtx{5C8qkZ~pS_X#AId|8{RY+WX75kl-6qsTlQ>Bcy0{YoMq{$>@0F-jr>-!GH?+ zmLt*Kv2}W+U}8kBY20l1!$hZzi89BKufNVGsHcKP?_f&!r)(#t<}<7bKk4YT8t5u5 zfN-s`Wc*R8A5CB8xwDntdk+s&!^5G0KkzE;C*xx%^=NDd*9-%4td#r}Zi&+4wxLTF zww<<{MDR=CbUw;x8WzWJBp2}v$XRp)F1;+`B~Z7TGVij6=`t6$tU+?iV05rj91mY` z17$)DEJU6l3O!eMOI@_FExEiA&msYmn#JI}RO(a=&2QF;sKX_-{V2W#b&M`RI3Vc? zguhvO1nu8#paZ+r1|Pt!pA>9DtIe^Ro!gc)Ft`uKec~-(kM0+bGv&ag00u8RDvr}F z_a4S43*#*%y&Kt^$pb#C_TdA*P~Eb)!&E`XGUy;gEGw(7AuhIcEl*a?Ql)jC)lcX1 zc#kg}0gt`2OM|vxuYuTi721$>@+WwNs7JZ5PlTZiz0c_Al7darZr`jS(m5OxXc?#Ps~Y3}P_yiU z?$jzfgV!ih3a|c9bGV2*HH4G8P1tnG@RhNJYjUBQH;5*^t9lv#>%lKSynKEV4f0_z zA4L8AUKBtlM}5ASIS|Yk4G=H>?fGfkA4HIY@c+=J3GJoKRXS!lT3in>+pdBPg6yS+ zMv)Q_TE=c#S(P~iyW;;X@K@e}!XV%Gk@zDM_wn4fA#~*q8YQT1U58UYU=ocYb?@8> zPU^ql3?vv=LXOTOMIkwsmeY2S!g8+s)~ zlBf2^BpOEw%~7BurcpGB7;(2C2Q|G#F`wtpCZ@epyA zC}!cDOI;CUy=mYBm7le;;q<4r!)dX zbjGRN3&u(zSB+ip%XwF!#eDijF;Al}2J$)hBIA^8xqtJqz9I@k%6% z=U;yK?%dg`l)L5dX~k|Uqra~Hx_XQbBznpn{W-%BJY7LGa3u@&UJH;S`J#6Xi#jP{ z$EX#t0$_cw?I>kCBynt>Me!!5#EGeviBu+A82jY$BW&rDzm{JZy!Y?2CWlVH&g$P> z2rJ$}N3J{DHkjutau+DWVMjorOsYOGaH>HV&vpqqDpZDol(f?;5J{DuAm6rXxB&O9 zpSf><>q#Gs_QL>zB?1Tv5??{+f25YZ(WT|eWjRXv5XsMZY-OshXy~tUJ*^x+p#V>Q zwx5rcihxK3%Eyg<@rNq$jUTmoL(lwJ!^4NlV~i1>h%PxCLUNS-maoYVDwbK}bEIyT zouKI7(#9;%#wyLQiPY2zn_2~%Drn@LlzKv1dJZ;RbRW9jL%eA_MyQ4DiSVjYYu*_q zSXW2Iu^J0{gF9L&%*Icj9^@(sGj9wLtw5+kG#lZB7-%YJ1L_n){e`{fU=*jZsHrd> zHnt*RhwtvlpvkDDYsK|#ApjX`FgRAuYNGNPau}igFu85jZM4HvHXA;|Uck0d{viw& zm*HEtd9)2GdfjK*@g0)@E`Bkr1}P<+7#H;{(hsY4Shyt$Z;Q=9%~BRk5Atk#&2RI{ z?H{`ovJ?m!R3Nb5D*6TwO6pOVPz@^IM;9wHZ&RvdzH6Jl!3rbgTE~S<)CU6cf*=oJ zWkeUX{&lKLAZwv`f`NW*VO-;PJ$u(;4TtO7c%+0kz;CF%&vH@>!% zeLYbNoT$2=r}fd|7;UQf$2y@u(sX>>Ldo`ShO%uG2(M}i7*rIHZScK|Qc%DE10)4y z8C0l{(t%OvoEUmRcDaI*1tJJG_Dc287j2a#+qteiJNvnSJnV1L;MYDpw!S7iEfc2hh+_n;ZI^v%%@#Is8H?9i2@OTz(SJzlcN(S(%8NjP1Q9r7t)?BrP0Z5`g z3rEMtmO||`IVOv{j7gme_*@%?2nA`^gPPoEtl@7Jl(gingJ9YYngmY_Sn-`DY5=GF zHUOt^5rKE$X)siLLboHtkBNeJauLBSM{%;It&kubiOQp;Yfe6cP(qf=x;|bPC9aAF zZTErLODZ8+TgNn=&~Sccd_K)m%(K55p5~~fosl8JN=a@<=-P)_ZvNUOIIG#RYI2=c z;hSiA=(eT!(ubZ^o|GBxYu{2pz17!_eZ9`EpvnvX%_`T}&Wg3n)k9pf?M0{NXVlJB z52rA!dbH4JP}Rav7F(cZihIp1uchL)wdAaX3|9iOW`s%>o{kW7+x?D)f{2I$B?jo6 zN?%>-7`N}T-MAh!eR`tYjZ6O7wK>~<8mFN^3$oq`PiBAmNwiG0q%vZkX;FLToq2P? z`z-g5&fr+*LAxIeA?%zhEfG?b z+z4H1PE9F;vMY^Uj+Lr|c#H!@06nRSpdAse2q;WDRcC`P+y=3TBb3hW9Hr_fGo_W| zwXb%n-tD?-sHWClwhL=1qq8|STu}`YPB z1m+IhFaMnbhkl~E#|>leH*91b{AZ8aTMxYDpFdp6Ws)AU(bn-fz`U*QIjCftt-~nw z-D@Zfbd5WZn|mo=$#{55vRQpjPGcJaBxwn+?P!q};;oDi6nN~e@W^%26!Jh|j^#QX z5os;L>iTiHUk?WTRazX?$4Q>nsIRg+RpQiekVG}wGSK5<8W?lJAw=spSgZecrQN4QLu5{4luC+&UH-j# zL{Q_zj&&DJXm@Z;W^3fh=~~5{!j{Pz#11Tm{KM>5}f^;a@ri>03GuHrTIkTvcYyh$T*et;Y0IVa)-ARPIU=Qfl+ns{|oDsk<#Q# z@{rP_t@TB?J`FjVE?~p#JMU6PaY>BZNlcwx7Y*Sl)2}^xWtuBClr%07J`auu(xhPX ze$tybgBe;txIX2qBZ3K4y?BZ~6Q#XsVjD1_gB_iww)hX|**>Mu?wo!w{CY=!H+430@*j}@d?;UT93pV@=qk^h#3#ONR?hNZM}pc1_@V?KnBN%EI8hf7hH!5YOXE` z+9-}JJ~E;=xMGOkN)r3AD(0|Cf6wYNj%3GRe6MJF*%B!8`MReVa)lCEv;nJp2Toey zJ(DNw>oM%n>pl2qjlb4==t7)oQXLfpQF6(qYDn1MB&m!<33Ppgy&hrzN7(gI%Po2q zc1%tlMu~(z8j;32B2bCY7?}Ml$R0-~XQWv~y4A4p3|eKv))Y2&!mxjxNtD)L95 z-GD>gfVFAB+HHV%5VKoAq-l2p*g%{oT4Q5%g`I6??Wy|WA)bB z>L;FWIZAjPNJ!or-Hvwj<9hs9e(aGIlzOFJtMIji!fr1bm{XI<<3Z4~J-eERO)+n3+HfA`|#r>C!993U0-(WL4Ig*|Momf|qHjd47C#B}TN0=GY^foeRZYi@N66}p~7(2YA+bL07MA+E`kgShD~N`reeI6lZy+g~+!Q80W^T!7VPO zgLmPPZfj%)2tL#RMaODB2XQ=f%C`rFP`J&e6EcfrvI-?`E72W6bKFYP^CCk{Sdp+Ksqi&V@aYekYP*--+$7HE8uu2K8zked(<94y<^(hX8|9$JF5~cCWgJGV!^&lJo*tatf}Dwkr%d*CR(%c-9*;tp7~%8! zv&fOzHEiWx?UN!>QU@`DmKHatp3rC?7*z*35^fS}aRU+2@1q6J?>!_eUet93r{zbK zo%Z00{y+8q>1C=kyyoy7ps4eCFDvK0SyuMSYSlZc5BWw4U8(I39%WdqPHPrpBX8jnWaW}sN*0UV>l zM~`)nDq|K04We5wZdXtpwPM_^{V9=-mfYRXr@IIh3b)nu)>h{ovV~pL5E&uLN?4-M zm2bqrET5Z=5M8>ndGd=tz=(E?3J^p`y9M2jz!|``Ilyl4w=&{NqBh%l$+(^&Qb?E+ zxIN21>%PV7^j3}&_p7x7JI7alFfCm+68 zE{n^?<$SyYN|J10eaetKj84|4RIJZ6EQ5L-;YyY|?sCNCoD{B!YjobQ4!kFnf1Js= zRt(NHUS4+0TE(n8*&h4FE6nz+L@x{K5tZlbG!Ky@92JLONhm#~f7FD0)@ z6Ck_jnyT3q=s)I;I>ErV*KgPK0;N7${vYaVWz|&+?h2e-5~J=Bo#I+yxWaKKaUEw0 z%*@T_9>Rwfs#Si{wf%t3X=|%- z%Fs;g-5b|cG}=nI)GOmK_*j_S^B-dtZ+_*_39GCzZvRG=q9K7p-Q@ z^7kUIpIy}-Ror3+Re%~a;~Fe>3i(yIB|u1t>`u50ij}-v-k?mR-a+YdLarlR_WbOpk{sflx2w`E16E^3cD7=015LS8<=b zD(77}zW;vWZ2J_ps5To$!+Fuv6q_N~ENV^Dw;s`^iB|_S!&)^CUWR>o{7<3vHtKTv zEGp`{Co~jyTKeb{R8(xIEV2}noS0_Z zMT&4KX`_S-VC;tr)Il5JpTo~nQxy9E-q<3og0*~fd?$TH4-gh#gG60Vqf?VVDg1$L zQ=Xjc1nhoFQhbnt@vV!E+R#^rjvY9s?^;J34xD3n)510GP_I#{1!)bV5#f1T@J~Eq zS;>GxEB=Y(xoJV#>>{z{XhBxHg$}|7r@8%kh$hUV?H5_GT}SFhX5DJOLAegzYTAM; zg-I1!)C@181GK`{2HrY&4FaX9Ac3U`Vt?wWu411H^krFHL>mW*RoU0k3Ks_+|wo)~*L12c22 zX2zZ^dL@IERWv_kKRLr%?2chzEs&xPHo(p^!fC1#FKE4ML5Z;2o`T%= zxr@LQl-2la3JQB@$y*~76AsLs3Glm8;7RR{fDcU7UeOx<$?0Z!tmj4o2IFJ2nChf- z8306~afInzS|pdt{CbO-BvF9s>X1eE?<%x!~KZ#C1N+N_?2$P<^&Z4oDn**4A}6>3{h%cXI1>qMe=vP7e2|_XzalK3fE{ zeLimy7T?}|hg4g3NT4IIC#?;Fz6OE4CYKL5u<|Hq_vU^Zf)<0jAO1;igDpkYPr}YddoSTcuUb2M$7L#%E5&oM^zDb(NSIOVtzZHaMlW#Xb z1wp!K86~eL(W_`9Tt%jF1;ZQ#Dspvl6SL2fAI}sw0cA=7%gqvP&3epkJsFT*NO){*T1;0HAcC^h zY=JUD`Vl`my7>EY@p0DtZIvA#{lC`7&ZG0fVo(rbPH{0*9G_^s#p%?s%&?UIXNz0P z`|=9gj_Z_5QQHgYmiw>Xwu#6&jBk}DBW&^-wisYo$m)wq^Htc-({ z0A2Z*wplb~u+*Jqf=-IUHACA~#mGcbXS%9AoH`7kwo}@YifZBHDg#9=T-69cjS;vwxq|=BM8N2<0P}X>x`VDghcYfruM|~#{`hi# zFgVu_{<%qVbbg%VWROk|_seLq7^FFxh0pNso<-m<24@gBcOLp*L3&AkhtvyG`qp$m z>Qc8R`xs4TcPZ`{NOy;17wx_`=>q0yW;mx%zSsU3+$q;AniT0`kRN@G%*70Te1m?D zFyzZ)SPU5Q6}H%Y$-wyWF_njP4d%%bKCa+z0e@?#1Qt~REvfCwo^cbu<|a}_QcbWD zsluxu)Qd*-;!D*FC=Qo6>_jv;*Jtdr*+Fyss6UONi`Y9LOPA^1&SG~7Uwb>V-K&19 z8Kz>t&$_QXU}H64d&i;PA7CS;iT{uWy5r?f1P%6>2Yc_>ZrI;Kqu1`zYWTOSY+jQE zwpa7EN&ip3+ktZK+wzra`B=4lFFdUO`L}ng+lTdD{d>p#8*~5u`SoYfqynl%wncJ8 zO`(R+pwp1kp2HnCSkN$kdpv-&$57sYHzJ)h-#TOa^s~y9QmITSvQ^^W;Q++H{~M11 zG)u@lZV71U%@$Ej;C}Ntx?3Jh73tlUb4368*rt;e*u4>r#Qnh+{YmepN3!NgPrN7~ zb?`;fV*#@cC0ZrwZJtCOVpk@v$}LjYqo}E_>KP3UP{`)ibsiLx8=`;BReOd%rQ*SE=#d#-byG$M3g)Z-)Za>U~0!V)hRu6X$t$)Pp& zu(LIjVkcKKYk>pe99Q_yEPWIo?GBEoas1c$;IBjYr~iq5!yo?a_v7g#r$qQU?E||c zlx%DEmyfUZmoWQOr$u)kElIR0n`GP{!ua6uRgw|i3Z^sQ>GN4!_xJl1&ticT>wbw= zptD6*KV8M6{;{Tl&!7$SR28v*_ISR3MxtvA!lybqgAmr68nJyp4KyOlj-3#TMcOR718KW@_=?5pFM4| z|GqU)`8=QB@O*YM0B0%ss=wOI(iPmYEq6gc@QKC>P*lKDsNZWOU?t{EhtCC-7@Qzt(9jVb}1B!=9z<-P7bCz1}@Zeot?R1U@CQ7`{n7_$(1=-GTP8{=2;8 z;N{f$h5=VG0&yekvn5i*+lnb>q%rVoKOe&NKL?@}L2%x`eHGW{bs|^plu#hHZvZKf zG%nGA<;~@aq_Du}(D#8Roe`N09hu{WEpUn*?w$|P`8`mJSo-l>;G__F_`-w*ttk7zqUShqEHfgwMKLVu0~lWZkj`#<`AY&)5vAAtvO}t zHwZS|$qAP8qjBQ_B)09;!}&@dj1Brj!=9>U#`(*>@<&99V|>o(w+K*I+L53<|jx=QhouG^YCJaW02NV^iL+a1sxt_;65t;P_p zVPM!-&akiiVOKae^g4wHFN!cM=`( zt_ll}qCN_PvibbiVzqcr{q4qO7h^G*9(MSp71|*ZwlGB*R-cbE{br^oMWB13LuM<% z#|ha%vNNGbEg$?)uTyd(E6I*}Pvq~X1eKgfou9LQjcKSGFfZ!W8s`ST_<7Q<%CpgP z@tQ|&?=}fTEdN8t`5r@LfS>;%BUY7C@qF%k<#UtYbs<<~GRF6|QZSK+;^q0 zmT&2zoGq{B`E&LIK|svtBPXG2SH2qPkkn zpCL`xp;yjr!4z;$8Ha{UY|`&C&*#m{RrBWek_w9Z%Eg@wW%H(dDluk1Rh$|MMa-YR zk;H2&!xjzjxY*CxeW`!p4}UL~%jf8+k9^I>t~W!gDj-g^f79M-leqaj%zIvb6yua< z4Y8X)GTI6&=tl=FvwEEGuR{G;b@ts8pD`)+ z+n95Cc~n`^P^HiDj1LXBO>bIBqrT&|S7GtO#ddbJTvEEW``dfYfn9G5gn((>2{Av6 z6z*I!6iz%7+wT9psxCgL1B@aWb=kxo?%O2-g$dlA<)>%2Ah(AI(gXbGMys4#zBqZT zgRad)YG5G^oG+`>Z25F~xyZOtMf1A)2n&SOh}gZ_8}>o*>mn~Xax!k6DPFY-O2b_7 zyvmfal6aOxolv^A`Cjbz&m5-@VP;7=fbiKjuL&e1*|)F|^w_jkv<-@%*!~;7TAT|LQvthdSbrBG4mYTJvA| zK9ui61iK)Zt(yOGK}x6ayEP+(1M{TeywwlFAr1^=H{P5#sDgQIQ^XGQ7ho0*f!dC0 z6RRz9mgaVzqrj!xl~j?1{s|Z-tm2u9ivlA-PC2D0cIZ0 z=%^^tip44X-l<(9166*FZgtwhYoX7H+^3qfcp6#sWTim6TSEZ-Zj>iEXD_iAo}!Po zWp+eKqE(7mq&F-Q&W6{!)ezy0lx#Q~t|0_rjkJ&$VFwqiu&UCM7AYr7I+Ry|RO3v8 zbfF;}lCTnMJ8i$C*h5N+`YDi7qdg=YI;!o&*!g?etM6+&^z)E{!=GUA9aN3@zF3lj zEQn{+RkiLJ+bGOsKCbr*qYV=Mbrrd?OI&y~1gLD&va^45Zd4?;S)S8X+Wl%E=YC!; z;Q%TXle7|gzA-}T+QO$+ku2_~#mhH#oe)MfJ^=ig))AfVso2$USWd1!hU5v|u}+W( z$3%frZ2?XzR4eXosi5?2W)SxQ?;!Yl7-`2zRHN&#*Al`zwJG6yfdGU+d%sztWQNY# z--z!EUlxA?*;nM4_X7}S=Iao@&S;^Ed(aQ95KMDXl*Pr>1?71Mb({lNiLm*e1w)ZI zET5M7|3|*YHc_9^6axEAbV?tBguhqH}+`Bkz!{tiTQ%Y%g|aiop>T9jc%xPC=f@(_eT16;LNQf9592d zT_DKKCV-{tT2lz6sEOIM?cg-CEiOs)IM}Wx{uqR*2U;4!FqN;}*5|Gdak{yik#6o` ztQ0;>PB%uY0{m z9@I0OPj1zu*tlA-?s)?In;nq0lGv>VW{j7k5HIe<0kN_;L(zvx{f_|~q9-(dj1`3V z^FIT_2T8UhdQ6vV5V{CD_1k1o=V!h~ER23hL}3Ws=r$eN&q6bbo;-d;4HT-+tnILG zDW&(IR_#)+-z6(U`hZPAfTlkga7lqi=$15_dyusWulvy2nmRYuBzOU9N?Li~ESguv zZ~1clQ#H@0Ih>(THc)kHm%)!upQ4DaP`6r^pap!zqJ9lgcaWwfkT+BWQQ!$53w_pg zAd=d?X^mTrt|#Cx^b;^uiDm-W_Fg3R0P2)Lj})6HUu=>#Nzrj_+h;?P+mgDeC$)Q< zuV92_`^SCu&V)$<#H4<(Arkd*F}1!XV|Bf;B*=*c;uQCOy^}v4<7u{&0^L-~S4m$F zR-ZoAPf`dd;a{8Pk3HhdI<@loizRSuJcbM+)wHJ0ceC{U)he zH7I2Ze>G~Mv1(eH1{3nkWFdZmroj+cnV7x`Mplw(s2;Ub-3l{OU{g{TMeT_zb0DAN zXm3s)1WeGhNvl>044@^5Z&idut6HEc?oWWx#~YhBN5#ms4Y2*UXH}-+H-$-$}`H;-qIS4X#h90rr9iVGMDyE!D#&LZQ9s(@DetrXNl*>bJTCKRpK za*=DCv8d9OdW(5;ENEo*PL!qWEm+_mVfrdd;+=GzV#1d(w9s_|@umm&}CwthjS)NEES3-EPMp^5aa0yWVb@f+DPp zFBB!8HZj@}it4byF^5GuKB;COKq%*518V?dB<^%Qm@jWP{&KG+Sb0fXoPSf^7Z5RviC*F4h5`S z8YYg|Ro#3M(D|6)HlNMrn2`AvZ^yP=<<`UJ|(4oE7J`brhT(;B8f=^s2@vWtIm#5V;+=I0a9;aK-nSs6)0bZ#@ zcg<%10q~+xS(Q0H@Z>`{_0RFq$PYT4#?~Q`mXDOEhR?<3Q4Mrrbdl#P&V;|-)CXuK zsFp8Je&Nhro!F(?C9a&|Lnpw@k5u0mD|b5(9OLU^?smXH!3@&4+%0xieR|D$on3b) zoD33?sbuGi=g8XLNP(zvj0 z*R4au>7C@ABSrUF8rSwsy>-YqgPR^rGd7)va4PDayT!$M3fk!Kc zGCKCkb>xjTniMfPk8g%{Ezr|de?Mo_Avpc1gDdYYY7OlBx35xP8gmyh43DAT1Qf=o zs#{VRuXf*1Ng}tydD}qVy};?*GjhhBEe&=szgvT_&Fo3@O>Nt!ZQaqr5ND|4@+dMb zjE+&xAJ@*+?;v>Bgy3C%u2EFiQ?L6VYL;bkgL)U_^^%lmzps#3&2W(OvV(RcrJ;ZO z@*AV}@?n+Y0hK)TA!ZIS~^c2p?&;)NQ%T5>H=%I5< z9iA5DTx7>qFU@d-{dBM7scJQZfynXER+Ad?oth}adR$%p@JfkBoYaZ)rQhE#@zwo@ zpWnYM&nlQMEo%QYKRw6iFWmF_JoRK@0g1eY>5UqX z$=>Lze^21zAybKl94t698{&cIMMK)4YG!E+p-#v|<7a7IG=ICw>iic}5P{<9k|(5* zFZbw4Dn1&K`?7H|=6{b7#l zkT1zqCo@?%nM6pFCe~U}t<0!%4=NzOU~I@*__ox2-At9T5&_bdqA#C>yTGt~Z5=RihBvmKQUzkdsq z)pzf||Nh0>WJbzqVGRQPd=W3yu?|G!<@$$L@2b7$P!KPu1f4`tHF^w&>O9$dPDCsw zV2wSMWHEFmDU`sO7n8v5%M305TY_>pNZxsF3dg(+7Vdg~4&|J0Tl8wltHtlh!cFpI z!H-bv9-B;t77tPg`{~Wei??szyyXICsz6HjPTo=DDp??QqUB$k4k7+PZ}BKqL=W6c zmGv3iM(HA1syFLwlX!)CXO|6-9m#O@G$q`Fq3Y#S+YCycK%F_69+p=Zr+IA=%BqML zIx*@gqL1&aCyDnJtSKWB0S%!BVIrB;ceF1FUIOR)>gDs37eBp!trFQ`t%UIJ`xkyn z3T!2P^YaU)`~2iOqLszkAl=!6iF8qK-oHC}^Zm)|7q8#EJycnpK%Mm2o1bvIoVG)K8hZ#P(Idysf$oXrpp8 zULkT3!eK+E@_tyW2K#tQ6<&hqJgPu-$*MEd-+PKzTzRLeWz}IHG%M$zA^)WLwWe(f zH{N`_e)_}7_b*?)gYyp-=L=wz58mB9^UI&^pZV9fPk%l+fPiPOp1%J1%ua4Jb${HiRkjBf~DhGwJ zF#@tG*DqBCi#Oq(*&QqGIwiHmm1aJZ<^+>mgJZ94d_s{hP!9JLdMh};yuv7F5+!Wkej{7r^C8`l$mt?t9$a&Hrk%|3 z8kWbsygn%)CvieIDhQRhKf><{e=*Fz!4Yz}nH*N;>!%0*0W0(Ei=UpqcngO!Rf6_o z-D!V;v~N_(ebi4ZhN|+kb|D9u%r1u9ptSU2H-T}WHMiNscVdbAH=DL>MM=S!)!3VF z<+0jJCfC#up+Z;RsQ`F6q1QRddob1rB@BQon(4^vk0ZKw9~XDo8so zn|oO!vG8%)_L_JqR5CHN$L8qD;wfdmr=J zUN2KNkNbZu{U|trNMZ(2uo~7to^r%TI|APiF0umFd+!E5Ra7r^@}DnHR7DU2rF<3Z zntMCFz2T_0+Zzu@NpFPzz^^{!+C<4&ot-1gteOv;_^iNVsJDR8zwDi%cwk!tugU^B zie8hUP_W*c_pan*ZMPm;34F>qapBNRIalF!Rap{Kw6w3wud_UyJ5TOxP062O8^<0# z8afy;4E~-ZDNqWPgZ*yeVNcy~a{qxILFHR2LJ$?87pxfHmYY5 zV7i8;#;;!f^dH^*;!=B9TxVZYSEP8=mqw#jD*=^$YkF19GTA}MvS&KQd*0b@JiT&g zDazHsD!=@dNeC}F^e5uz2&EMC^T+Kee~b{ZTsC5pWUUtdf8D+7cH73XApHM41bn zJIS20V}X6|>h9{Q>bk&{wki#35CZlW&iOb^z`kg-I4~ky>7hiTsSDt^6*j6ZtO}qp zr*HsmV7&$9K$qx&(j8pJHz!8_X7i)!g{;}a2yLZ{UHY98b}?5de=a-EKYo1v%c+!b zk;PGzglF@JF#`{a#lW;{FO6g}e5T{qhn&}M-#>xGDV;rQbn>URQpMR={%2YrIpS)LhbN6)olt$yw#Mf~vgB>~_(LiQ5}$EjDY( zv>u!6iwI{!>CJ!*-php^Z=w0UB#%h2xuQ#n_1!ORru+o`IK2OyNE_E{PvbqGOpDE; zCpvFrvdIb!>kWoayLA;cC~11@wyDzEvL}Szq*w{a{r4 z!PI!g;Yz%!2U~6eySR*_&-naC%#t+#QEoSqQS|`Zp*Pjzk8hs;_&w1SAK!d{+Iz4& z5!lZs6T-#C`$idI!L&vwj#}%^GOX0}K;Hrmlhj>D^ z_zdv*y_k>ktYDP5JKI|3PG4Hw=_a1`B3$k@Rz}B09`e|jm*mSZS>_H_9Se-_%Ib2# z?V#Kpr?&#Ts}dtkg_vKypo)VNe&FjC&wTFhk+AmYpm`wyOikwRlle71%+_(?{Al9z z|DcdJHy9Y-GMtFEx(GY&n>38HQE+~11fPjA%9;7@hJHv$KFVAEh@Cng&uLC z$Ewg%F4X5jJ=K(KtEU_5?Tvu^OsM-^s#DW<0)KYzI0P*FZmf#-?<1nUKi=5shsGerCYLjb4Fz z(r#Ib(*BqKP!@P5zRiM|@of@h3g6~|p>B&-+D; z08hU$26)o@>tTSWcibsYzhbBCId;n4H^l%?zX}69{l*yJPg>Wt7~oG`*KdXas_Xl2 zzyNDC0$8>|lBfK?Gil>0UlgQ|HT4XS;)quBwAtc+DUBr(hrNMz_il?HPU6wrp^n4yN=~d$!aWt&zIYK_apy-t3B)7-Tm{|X>fm~~YPBc? z#2kLl4^D@3`2B_7WcIeb)%Ix%m1`(65v~o!k)i1C!^y$La3U*D;rA4NPvLhMtXh-y znMi|qYYKnEgYL~u`0V=TCdIGx*(nBEz{W#pJoUvmxICF`U$mwp5w(KF$!xSe7BPLb zdib63cOSoxP*a(I@4|05TQBHYM!euRmzX|KU@49cU+`1Og8mHTujJNPqTuR2^2|*S zBgLD@dzP@(mgIaa`9nCLl5ufuSyci{uP@1^?juE|7Yq5EVQf*SGiUwky(R)3Mpctj zFZP_0G8!G+);x{KtLU#PpS{z=$oHtWg7!5v?;<+C@+|Ttyo@sRLHmtg%zxJ#h`d>N zWKhAAR~cMD{B@?k&i%#?$kDu`%PV zE$6p3-FFZK>0umr3BJ1}{M?q%E1SQwJ80@NpbHX7fZGRa2(BSyjTUFZ)^lX~JAG(R zZw+b?&A|cy`ZjeB;NF%)08nqsdRQNCRL+qfaJ9yFpagA7Ps2mefFVM zEdfGd-0~lGH^$S3C;Mmw0dSrUJ1Rm?Ju>laRq^2#)SoC)(DY>;AhwL#6hOA{>Y z9o4`}xGa`HtyME%)p9CT`1jqQT~MPt(BI#057kiSWLi*bfZ>5uNELBO!BKXr2F z+=u3+^Tzdr2?E#I<6?i+gZF#11%6E9yiQYq^8Of|9VO-|B~y=%(owY5{E~}hA+XVu zH%^7DnnO+XeMv4m>1Zk^Zdo{9dO4i=NxB4TtaEh@&2$Jmd`kkjwo<3=a#^WcQ z{_d{tqnvGT_woLd&i>y1F3NYX6Q)jjl6v#`SbjU5Bd^=p2gJcsRHXz%2CYSV&@Tg( z#-{s6)$DhdM`d&pRPi6f{=E3ptFPAY3aIwy@(Qm@;-e zhYu;mUBD-ac8R!(fw+nf&WCZU+zIA#7~aJ&bLK|D-gdmbXzgudtl$X}WI6spIxMA+ zK86U!kKK`&2b!adTXt*W98h7Aot3i}=;nTv0TVl z;i|tXKK?z_=En#lMA9Lvp*f8b(!6ER{Lk0)f8Q7_vuV)V^m8Tc2WadbX!pMUG5~d; z)9-VFOm;jA6VG~W1CmeRxbOq0xvi~6xj2oG%9Sf3dHTiide1qNU2cDoEO&hS}Nss^Z;m-)L4rR1B zqs1Am*~q|+p^gAe{AUoJ#AwF>e-O{*^Z|G-dp3uLFp}9ETH4ym;cp-QW(O-yhrg5# ze=*&|dVr9+_cEA)^{Pi3kV#KGuxe|bcOZ8YYKfKqlDoh*3CLYJxsLU$#lcu%C*2l0 zl1Cb}oe2EVGk^5e54ti=RMA!C?xev%9yyzbo3E{^RbGzUYch@5v+h z+1-5%nNJ>dpYB7_es}*VOi#D4&R zhc8kmok#u0Pj{iaez)JF_PHc>^kfhI^!Fb>5uHcSU=I`f)FC$5e*}N_9?_tl?DzVj zvk(10;@ob3*X-`U(n&a;0pOv>UZ>Z8vcC`2psUBb+~-r8Vt?=HQyfI^(O!2CC1_7} z_xo62fA8rNYWV3R_`m{>2^#y4y1Q8LQMb281$w(YW!>{}G@d0fZ!zflX|GQ$K0#(5 zTYlQx=jrY}>hIy0x=&!fz0TuD`%j)?PhDu6VAy}mDgE6Zj`8t+w}%Cv>^)|X^!mNs z$7a_b(s`J{-Gcq@?c%VzkNWc8F0Wd@4=n(o7wSJ4MNe!_C|bH5 zD#<~P-kuUa#@Bmf-b}+frU`QOZk(VwsLixtv~<%3wtC>9&R^l2-@~2`ZnX)MNHz9! zx`06;J>7rtXtyb!wWOEsYhYgJZtqndm{o~yLPNcf%+eoid#CNL@z+|OEeDWB$=_;n zL4)50>?Z=C=upDQX~pC>aIBNbpEC9P62fKTRT|J23rxi7bo%$4Owb6=@(N{NSw`Hg ztFt9aqW_-rY*!a;E@Q9!E$0(7@cF#LkyV#%5@w(N#*>U4Y-e?n(bagq!pZ$T=V@US zHpM}FYNTy9Dm*mL90R+}!$0SSyuV1Hm{a2bxc&XA7=Zki@cdQL+Slbyrtc#OG5%qf zaa>LE;ma7$dEI!h3q%l!W(b)h@R%2@bsNzCTKm?dVbV6GlTr$LWHEV73E>`taL z3PHXdqXKo9P2}H{Mlnln?>10jH(nICV9~1k6++p9wy^|rTN?REXoJF>-49sTM@Ml z^GaCzpGl#J+qS~p59Ql?d~<_;GU?$i8!wJHaC1*Z!d6MYKvKpo(E*MsP)Qi*_$9L- z^#Ea^4N~gCe)fkPBKn7L{0Y^hrQ28qghLt8o63B5ef&8^uiJdz`vrvRE6NhD!+gmg zw(6h7bJ%QQwx$79gqI8BaG4Frb#TU=>ClgZ2^{ouksoB`{*$1TA+IX%i*+roCE zo1!L*|3!y;Ss5OnbwQ4l6g^Y%+8SL7d9%%^>BAe5Ly?1C)b2e}C3-SWQna(wKI@^- zcIW}25beabx4O%zLLj)|R^q+*BwmWGV!d=T$ww|wqg1>Uj+9NzYYIPRdIQb@vm z&>e;c^I@p$8b5cg123e4XHf8(3SRr-6Kubi@ZWFn-z)gU($O`?v4eQghr|`eFgq zf|om=@B=BH-{dDy1+U~M&;iePKFNSWt=95je29xTIKO2E#K09w5lY*znkKBc+|wLSG=@!)qGQ9Jx>uK@mJGaRAKFrf6| z<-y+Y5^ATx=aaM6C32Vev4@{C`h0<(WBEzx7r;w;z4p0}|1Nx>qtE5nY_)@axUlocO}79&`nb83HwO29u)+Zg|-Ff5DN9)yff;VQtt z?Oy+h--3UXEh?wOmz~qsIsGE%o>CYIymh{;8Ho2*2UazO4VD^D2$cD^KK@4`z?1-2 zg8+&Ge~`7AZvPKP0@?Yy@JhZQDeUQds!;^_x zM}!Q%iYYb*sO{U;4V}9hI(Ia5zM-KrS3_rxhR$jmTBEU}OIOiVZfuXu2&*W4KU@8F zsdm+5KMvMe*DDJ(7zchGdT|^7`r9eYNL#IOE_};;_$o^DjS_ubqR%Dng}w^luQ6sQ zzb3G#*|)b)=r>j`qxmvihquNUXh5R6HI_S-Nxl^I-Taxk`1VKl~t=UY86np*LmD~(l?M4TOU&Oe7)hUKGkF)cKt6QE7+E@ zcd&_N|7~nO%cEGP%W$sk7dTB%MGa9-uH^0wOSBa{hVb(sXc#|%r73LY77?sgf;BuO z)npHn(%LDisq&vmE~s??@TpHWaWCI}ytV)(RT)0HX=sI~4z1{v8uxuLKq||K^bGc) zBi;b*PFKu18F2296()~Ng%8`UGnirY*voB&DK04ppii@DpD6h<9o+<+vR29%AQx0yb z#axh6k*H7MYOW+sg5JJ34?5jPGKK|=X&aaya$jdl+Lz_9)6W2_QWih?@YuvINzRa=dBQ0I-jR!;hfB+f?iuc^3SlBLINMd>_T6x zjHFDB#cH84HVH%xI%bCMJ=pYKgAK*_8x58PUuN6b5UshAidBQ9%T{9Dio9V~rS4ay z?kg3=;vV$T1o3V?WkhKCej$p+voy`4k2n;nO@UqIMcya(dekTS_7UZ>l~8pef*HpF zM&l?nn{1qSSVq?WT2smD~& z-%8<~-nS?0b{i{d`43}AsgH4*!8nNrlS+F#vR{+Y3>u5{v&pZjO03VR zI7YMBxmE1kH<(1T*qK#qo!Np*%aGfUZl}+2)EF_ZhbD<7^5&cuX|2PyI+sSY#i;>& zpe^{p-cEwS#zOk&;X4I>^w|QH<+}d}=Q(aV{e$#veu|Uj6Asbb-+v^jkn{D~XLZ@W z^pgVLk`ZnBMSs%g(za3`@yMqLUU5aIHDyAx=bADzEsirlQ}Dx?R-WX+;BW2v$ru2q zXctgMx14e>?`yPs>rpo!*L(1@yX^av>WN}6xLvSe&fgl-y+|(>aQ94VCGnh1HYuEy z4^BqEC$ePGP*D0^jWFqq(A}!k<9*ofl{=^gUx$T`6s3<8`+BQmmv4i$hR6nx%0syb z7oIsAt)FZ}iS_He-|`~VgoxF;eM_Uio12pn$+c?wWj(;UNV2!6o8l;Q-n z76T)IDlPf#pWu9AJWrDdHhLc>-tV%WNe3@OrC37uXVm!|W{KC7!E`ad5$BC?4(DQW z-B3ejIu(_}7~-h$4O}%$qmwULF&uTsMp zk0j?fYrt;iJSy|EW?nne%FxU?%3+SgX%_t$ea6azonN!VUy~h7!b(y8JeeE=dp6iP zY5cnUH5=`m>padXaxmkc=(Y%2Ich;cM%_FPHJ8C&R}_;$_ioumIOlwx)1Y|_5Xl=b zq{heeB7~vpyPmMg8J?D`@K^A+mzNJ)iErZUFhPntY<+6MSRvNYUI@qF&wVm13v zZM{33FxY6PIP&ih(Dk=B5~{w zYsO2RntO^eKsgU?WFuj+IurN(hT`pRwnRQf}b!2qRvKiN`qYbl;j9Jq(V|$JNc+OHhqoLH8#G=aM4vHLXzUzx3K`NEQ*Vfh~ngavgFiPVytRyl%Mc26}vwTUk z9|He6uxkyw&|+k@b*l!N2)-&wUt2IAxun;I8cTG zyTj78uHr5XGqR8!o7kZ z3v7^Kx`LMm3nmULB`d|St6N}xPnmnEU>1XWAXYb8_FukOWqF!uE*d4d1X9REh%%Ib z`-ks0u;Z_MX^nwTGtL46sde23WxtHZ^N=5at&&*>uc}J3cdbJ`)w6B)>YhZi_DyBp zBl?h*E;%W(mD@01%;P0eqi>RBO8e2%m#c)U-l@Ro;7DZ5>eE&7IRjQTnj9MiiqyA8 zQL~A2$ezKyQ_eTCutAwaLUg*p)TPVsHR^UBV_70nJhdKU+8&g4bCZeYZ>xM6Pp`Fc ziKYhSZ5bs1>T^lgs$S$1kkt*7haSpmtU4yt6(V4zU2RxPD)}{NAv~Col0PgMhAH}w zq=F&Bk%;vE$0VL`2wUl(fC-^Pd&Qt8#;qC8yw z1DhAVkH-hWoE&CK8Hq{2L7#vmh1DVV2jj|@UV_;5(39N&Iutn|hYW6|e-;TyrniC& zBPcEXf&P7q;*g`It(UGyrsjVhm^`y5&9TQR3bwD}<+bOx9{PjEmj?45gGTdVOT(-6 zuqhfQeOqJ~iBPC<`|Kg0Dm1yx3b*TAs2MsY-J4ZVijFexeAqdbp!z&yes1Whv5Jd2j`xC!9LH3~G+ zeht4&oE`DInTemASi*6tyS{u)t3em6XWA-Xi$w#GKg^yjk%kB|UulgmEy!WvvVlRy zrX41{UcjNwt?WuG#*T5)Ar3ZL*+xq8+H=ZI`~pZ0M2hmhIW3zQ7mM%~ki>gprpZyK zPCrf;I(Y>ROgRu7TJX3*JUKWg+YuDdX#g|!e?P^N-ozKbYkFb=6U-`zelpVQE|=7p z)5NEduPBtA8r46-`6_xpRURXrLov~Hi=zr_t_3u4S-g)d4laj_8e~2hoh(Mm4}ML5 zi<<%I!rPyNBP6;x+S+M_%$@!nP~(<^fpOz5P1+AkEfncc~zSxSQ^(x2S}^*Gn^;D zC7wTwh=`+c=PGI=@%GhZGQ#77?#jlE(9z-+yBl^$(kUb}rBO)4kOB9H`Y`Z^gx2^0 zr<~p(@ccWGBc4a&VtK8=1r$D7lNw|(B3m;n+JHC{pD))k6i6u>0=C6r+IHwE_K95wYeFh=eV_mt7Q(X#tN>N zNKodgL;#;1UkfOp+~MsPZ7+J{JbEAI!GT z83C(1xw72$7IfZQxG4$|HlQ6j?hsRiqZ26jS%aur$t}`f>cwRgt1bx z9w_GVy=2tCORv0GAS7Y;&p2R0-U2?+SS?gt(N_FehK(V{|Lj&JfA!;{8gTuR&Z1?;DTmqrJQE;Wn zS4D<8F6fiNgv>aQnzX~39W-vO-#cQqp#T#P^FV@YEC}`*s0Bpr^L0zu3Qb@iNN}wj zv|%(lfoYG1b6Ut?#p}6}%&Iljww$P9N9NY?t!!__J)E8vbei!-&~RpI@-}iEhPXn= z%e6sSG4NZc`z-f-c90A+#bM=j^)i2$KZ_|GWnQpZu7L&dc8TWX-_{GBa8@mNNclGD z7B%T8*EI}He2@)eRK#*~GqBC0RuIFjm9=|^%QA&L&~7dwdFgAWq$-7J7b2vcJ{Q;g zS6yk|ja0ngF5$3U)YE0gY|EUVfu~H)&xs~AVRn!bamKzn+)&Et0GEMdF`zcXmaCiC zW|;w7EX#6Hr2ewjSR}xy%+S9<+@b(8C4q)@Nce~#t5RV(>9yAPB~e@fDvDLG2&R-| zDon9E`r+r`t*ydrt#}{C2Ovzco(DbbU)CkINxyy3uTDrWqerq?Czl00TpnI($*&?G zUxxY2lOW_#U<%!FSmi7_M_o&l2v?*(#r(M#Pcv~4M;kgGo^%hhjg#_DOrA^*jZ;LaG+GaV{T zrD&0{@s7>K#24Y_TN}!?dcHoEvoNP3uztyTG$FqhkgK+)vAVRTP+P2MUFUMe(jY`J z^c0s4d3U`xtgYeP8QR;_8Xhtx(rNRwsN6Ux&MiJ?Y;Da50l=;^H?+!9XLe>D)}aUZ zVoc7XwzeYsfR(s@Jr`JiC>*-PUCyH$5rj!Cj|S@{(vF3C)B{z?G!W~|l~%2Wwx{-C z`$Y;1%C;$qKZ`_~ypba@*HV)}+>rdCGFX74v-qdVWVwpYmbx{I>vTh?Le>83wuW~7c&Eol}UbYV=z8=HAS8}tYZor05*gGez_ffPTB zGDVFW83nq5L=*$e($#$O0=w1EAC>;iS4u#BEu-@IP$>alW6U*NL*FuZ-Q=y#E9+BO)UDbbxZ2qvkb|fa zLB(u_6)446A#_(KLF8UbB4RssnvmPM%62%knOywMp~cc|m$T6?7;aA&^Inl}8E+xA zk~&m3-r900!B`TtL;N+6!ZwRGD&D24DnV2}8kH%r$hTyP)gX)LmdQ!Qp1Y}77TwoS zu}YAS%$u7GS@62MMk*FC*6Q2y0^=>l6{PMWvPmUW-s$rI0}?#s#tQN%PmFiTZjc_`=v7rU$Xsgo87k zounhBBcGGbhgJ|eqK;xHfPB3+0>B#R>szAoyt7CbFu^Y+rKCYd+SU0W7N*A0AQzTy z(ty=X%GNiUOgmAk^uJFZ|K2tTn@tTy3Lr~gA!?UFkcf&`K>3Ig#HRY7AVo@kw{bn! zm|87Rq$!q#W_1k(1>0{DUA;%wn$OxjbpST%Tca|C*5h%|7d^I1!e#6{KR*8W=DVMc zU!DH={N1Y~*g{7?JpcIW<*Cj%Qt)YBHLe?ztH$KIf$P(r(rWQHfq*}y_Y6+P$kVt4 z?TID__;;9$XRs9V6d(f7Lwfn@_4A+J9-kilE2wm%dw^Z61^$JuJh44V@OJ_>Y`z^Qqd9L8Qk!s{FzFf7wWK>yy{ zbOp=k1O9^v%t#cJkQ9Cd<@8~ySK3q*f}4|8J?ZE~b{AZfE);``!YZv?7Sq~VIjAUa z93HBolub*6ylqadnlT^>u0%R!K-*vWqB*%PG5{8oe(f7)9rb0&y@g5%)~z)HHU)+( zPJX6J@;hLA6zOLoXf}s*y6Gh^Sz;f{!!Te)B$+q>Y9z~-FJ|$4LIt+Aa7!S4-6?W_ z&P8isDqtl$%933%J@QpjQQ#5+XTF#N#qaI>?_cxQ4gB{%ZhlSBkf+)7i%dwzq=uZ0 z3JXGfK1N^wN{pO1lY`QU(xu#)DVOH+z*FBXOJLz|&kV}5tt+g8`8JX~j#gVMRPY%Z z-11C;940z3t4Q5Z^pIL`%$rK13u~lx`6-J@vGxQmiv|3Ef7{*^#;I8wuhV-1bE=Y6 zIQ?R3x7e(`Gjzf)0pRULQ)J!@aG`-Voc5O5hD0h~pB5#(CW(jyIz;CSjM_77L!OU; zyUWuoN2!b}U0E%Dl?kQck9)~hv-X)JJsvyBiAm(`QNknjRc%zEYL^j3ef(Qs0oppZrlV`!n=bh5UYhmPgrT2vnl7b&lIiZ{*Mw0q|%UX84$=6J8|~ z^QSag%g)b2ulHE=dQSx!$#*-ueiKc3CNW;iXdoBCCw4V>(4}uk{thnQD6^XA_C;@h zSGLjLheixl>p@@sl2!h5cXwA6co|__GT`UcZ{_OkQMXI>b2N;uwjdk;GPxmhLnsgA z=#n-5-y?Yg*MAoY5;@10v2@lT4cfvp*mPX{c@kf6H!#D~)6XoY;10;hjE#k3Eb!H4#r%rshOK9f5lbE_^w(HjvT7@v(|yM*)x`^ zq7g?_S|3e!vU74-r9?6&e*}9Di1A@|5Yg*$%=XGk^iXQv%lyJ;7$s_P z3cnJ=fFv;tNHm{>+qk?PT^4?lDmS;B5-*#Z#1vzeALZ@ZLutQY)-F7TST;fUYN|(E zBXwnQ>^h?u^-Re)&g6&@MMV<^tY(U-ZC0x~CRWmQ&`k~gdX|54TLs@Ovl!`-%!MbY zFpYe6;`~f6n(-vH*6YP-rKjapuw-jLV~EbxN5bV&z1NljxyA?;+OwWFD!Ik0Xw+F| zVUnY-6Ly8+MdmT?T*lF7BrT3rDW!|8etS_lg~M|rJyX+ksieY31QA3>&k-GAvuHZ1C1Sgt0c!o>JhE9Ks%YZ_^Ie+R;v5v}5>(4KEx>vV^al z*2QEq;h20OevSiajO(y|8xtG(AX! zM$?1k?Qq#Pi?@2W)e7yNQ3VROd#d=s^3VZ8B)r@D4Gl^IrqVvMR^XlhGWD*?PZ_cM zDI=@j@mwY^-aVPoiipFCNr_Fqo@OitUuqSj4Ee8`3Cd=jh^>NcfrUnnE0(uSCEt3i ztK<$X>lHHD=t>o&uA#-?y2@v;S7rxcacNWV9_3c3{Gv1Shf(cYjL`@$(b(}$ViX#| z550@@lh~NGkqOeiaH}dN3PBi8N157jSbw7yY#e;S)y-K&F=~0~v+iL!KyOPm*I`_f zVPoZb%K;bseLl4Xy#&8BL|{P1uXb;+{)r2p`wR_ZrG3V6IJQk(4b}fwirz8R)-V{W zos=w|^bUvJ5Y#`^Y&$ne=9eGv+WDH-9>uPd7$kY~lrcLoIFa$jvWuVf@njMu ziajaez<~oVDjavu_K<6<+_qv30}%VhMy%v!xb;jXAPjQj*DNrYf`jg1cVPS$;~+2P z8o$LnNYT}6NWKj$Md2zkn)@g~p1RT4+?OVKU3}smq6G!o6P!EnRXRGEjU+OfKf_}4 zgYd90h$z%%u*dzuT)I?%cHwJ$=)izzu}m!v+?jlN;wG!jmRc2)U@E-QSv%<6+{i(c za-Q{24{N#;l+x=?;GtJJXXB!TG(T*f%`pn38?#ugHwvkSacIi*kuPacqU@Y1@HmiCpTDW<{FIOO9&M8TR&aimjzOzJd96nTWzr8^(n zi%vN;F;meQ2vjb90pSV+w32F8<08f|7&D+u;i>6SZ|KO7Pg~Y(wGTP* z#gxQV#RHJ}91!#5hcKDUBP|WU^pB*!;L72})Ax%kk()(crmM4g^kN>5KOMyvtGS{$ zsK5o@d+(reSu=2^cFtnyD+Kmen!Jp7e{2+S;Jc|z@htu>nrNq2hJ>JKxhZ{&m;iC_ zVdhaG5kr`x46Rg(wk?r6!-x!>P|1^4M!|~xTa{ButkXFq7*ll(+KAm$#jKo=FT(`Y z4l60-YO<0lrEfm@*sLz?ra7`A%Ux!9r{S4fn45kLCxlfdDm9RkCLctVIcaj+3CAA7 zkz21qlHlNga>>Q%DecIg7G~3dx%gVh3E zFu2CTBCzTdOVdcF)4R2`gu`0Zij^ekF`i^pAC(tJNG}eNl!aiL=$Sl)I&5#WZOP;s)t;yUO8{ zDXgxMo1xSNh;_43ti@Azy^?vx>?%7W=((oeubDbv9~?BUT&z~F{3cgJdzDX?G9;-3 z<C`l zxoJqIo;L0C*)7R{;fNaI9qllR#Rv6|d#)Ef{no{zQ^%<`I%1F8E=ssEK3^(c;!&Bx zwSg{YrReV(xlqSBL95ASo4hr0pYr{g4V8*vps79)yTgsehJMs)iMZV+0pM`w*P|U* zv8}E68FZ`*tC_c>>fk@xhM)H6|A4W#S{ujCuXe^(D5|QNwB$^X8?Rl4;&D(d#erH511ZXDVLA@T*m~e*x5{nh?!1ExJbfJH;cAXebht~CND5sR0EUBgxzu_K^L6?KvGU<%HbxVd0gGV!hKiARGyO4&CI+_qmbl+1?Sv9msBFU- zDu8nBK$?PB=+QdSlV}>Q=5p|so(9P(%vMyKqe1~Q(74!E%#jT&0f9nUcCLDyDi=EL2eZN~D^@{qP$-pHGFqq2PNqCS6XA*k zhEjegy{09$T5EDEZ5~vI^y-*y?l9LK-mRZjddrYd5IB|&XYUD#OtT~3cEWk3-FwWd zbP!xxO7&W2_SI_=4drJli=|%+%e%35#&s-dq_r=xL0R17Bpqy=W&OOR@;0nK$oY}x z5@#XeuWBz9pezGy1AK9MK`oIpEP=H4pt}0LFFfjLtul?O5q|v===Li6L}B&~%O?@y z#`P#?xz^+k+N-uaO1fXNyL4|t^1(^=QcJ0oR9gy-td>es$<>F`le;9T<$=E%^u+a` zcWds98bt%+k+@!0VVwqI!MoHbEv?a-xsQ%a*-@5AgUHb9(CRS=Fbw&W9b+p7c2OlNmUu`zRtRCw9Y6If8Gou6mBSC zcI{AOopr9r2_XDM2Y~SB*aGVINZv|sNEFhxU}lxDe1$C!ni95f4? z@OD#~X6dsssp%ji&GPn&IH=6EHGa7t`D`|0uS*SeU8z;%p?$Hzi`G3(*zy3=@0Fz; zQh8Z7q#r$#x?vK%R@T1x($*WqzGE;NvfPG_99uBpF1HBrDFQtn$meLX33ZY+u5krq zrOY{N-Yb1gJm5p)?7m$tE^0w?3`&GFJy1A)wnQTN7B7!z8iLtfo znl<-7=_RevKqS}06(vMd&2VO^Bw9*`$T*=V`B^!-5xRe%;6*_=jLSinAX775t(NbY zd^$q6KcyyTs>!jV$(hxp71#FPOc^nd^&DtNzAxrhOS!*Y3dQf&XVZS(=Iu}goSB%zBe3}DYEgi2AjLY6j zY#+#QB*|wn#=XNJ0D)3*C~qus@N5Ds8rdHAr7vKBeI7W{i*=lp))8aiePPoCy_7Rr z%JH*+eUHNpnVyVc>B=q7^aiVB_!N>YJhU=e*(gW{t}2i-%%1gze%5Y_>Tpyn&3?!ofHox1&KR_S zwFo2#Ncg9n6^DZ`;jNaAJ4`KebTgLl(=tG9=$Drro0bq85=JV5NdX2sgl#eCjfUf` ztu?jB=B6g-e1{}sMFgkyQ#ai~h8fNXYQwwb=rTM; z;3~0QPM(LMW9VVvC3dsblUmzyQfWD%*+BEq@-Wx7toI&nVpYB8kQ`R*K)?PoUe1mX zg;W*_ZnfnhKYK_;{HiIx^nFqGVCg8S4a{pBanaW92Z-1o#27XyK8OxC_k37wH+D%? zAa&zxxicA?_-kj&jW}l(l_yN2EiK)f#AOI*@js?sfuo;i%R^W1PGJ)XGF+v*j>}hOr7C~jdlwCIeIts77BAT^Febcnb_kjUPwrwId3P@4!$KrMEPUP zFKo+Cfx%n6y2LQUSi`S}hYOCv30%i~Trji}-)J7(X35PmN-xc1zoQ9;JvOFZ8|cO! zP}?=~gZ*w-k%D$kyACXsDspz6D^jApa^_uA-ZjeS6!c54`HL*V)R!zc!MAujh1{TH zW#q}jbLpC=lH|!Z`x@&9r)`CPW_MUoP~K|cvadjZ z-f+C<`-)$~)~!8W(>6QXy=&Ws(t`n%HB%!*;L>4G$~tf=A3)=sv(<8$CO0=d+70Tr z@AAXoJn^Tey2GD?sBDcDi z9XXP9LaBPSfLpea$eAue@sO>0cD zX$yzsXn6~~*4zM)?ehSGQFR4J66O(TK~fP{c)qoj9t3cMQF!6B#_7RWJ`|EE{V&k& zSd38t)^mhc9~Yi4TD^775@yJ$MMlFvSA(zuSFAZ~4kfBx)~*gPfJPGJLb+{UDzQ)zO#rtG?CSe>hO1S=J{;R{wP zeU_u@FTgfyh1Phc^LX(y1+7ck0JGV%0!D=ani=g{yBC`o7O3~6!fjR2sxFrO{2*JJ zq+{~NC4KF^Vh^h#QPVG|FYlf>OZ0iLeO7`d0OsCVkS4=bH(C%GJnuXoH zTE2+p^YJV~vZOf;=XrFeYUt#%&CqIdK@A)9?m7Hjsu1HmC$ERi&$DHL3}@KDr{_kKP03r$VS^r~DS;mKA?06f^2j)7w4XkGI&7rUC19gF zY;cIPMsIO7Y{>X#{6qWgmA}aqq*Y=OP9}gi|Ih#b|LGAFUciS<@gL<4b(T)9(SsCh z+chs^=2nLu-o`oX^C)u_7R^u5wZ-GXWl`qv?%g2SHtObnT6}$Dak5w~bz^Vv*Vi{T zP8ZioSrR^fM?-o{zptGI&@bxgkG_A;+_b7qE`2gG%wCjqaK1?we22UG_=$49NhcBc zeXR5Vq=(hKdci=FN>ZtBv>(h#$%@TeI~b>SPE$!1DJ%L8?SXf0!BJ|}E3|3nJHpyn!CV!omsarun8f9Q3 z5>YwT>J5^#R#z0u0%3Ih0)FYoA-PcWEO26`oanNn5%N^{vOpSgjz&rlAg{eL4f&dj zXc@w%?@NukVbNKsW~tL#mV>;xxBvzUPMIYT5l&Hxto|(6-9<5q{CN=Ub(Q6Z+dpJI zZ&R;xR5kUumFx7=!XdpXS^j8?Ti8x7;qdGC#l02Bo`))F#Tr=v}JyO4XQ3 zc6duJ4GER?XJHEcW7Q&s)W|3F@|zOX|sC zK<|b=%d`NxoFQ(i>aV@HEW6TA+B{yIrC~OC87@QT6B}NsW3$xFjhx13-~rOlcBT=V zkTrJeoq?{2Wmm}TBN8vh4#D1XbP~0D7`~ZgfzxG6hgi%=qKX9M3&ZNC-XZC!3H#To zJX?OP(QJv?-mLH!OR;_`{#bR$V1wYgx!K*L*C9z;`BfJjvQ{k3(M$!9v>0{;(iq!S zyEDZSRONj_^4p}@rig+~{X|)+`bfJW|VN1pnuY#y9KCF_umn}xzEA5_KD!`T4ibDsgC|8%S3cir50p&k#qzzA=J&D>WnqZ0j7rSu(! z(~eS#u`@*u@2N|#$$Q@~%;!Ql!*Z``M}uNpbHd zJ;y8^OzlS9GnZ;t%b|nSDx1Qrd+59qU4clFe2$mrqE^L8EgW>6z7K%GyPLI5<@puo zR;g_GQ?N;)%781bkAClQB7DapLa)j4M17{*7V0Fb=!A1T0n&Kkq*-=0)oj6eqO53S z2-oy|v$eIm|G>C!;P;~kH3S4S(F%BM=-%NF6@CTaQnPQ<4UW|}>K>yci9<)rIL(ac zAR7;1sjDCpL`)(8O3*fG0u4rj4UbO2t?V~yO+A*)`sF3A-IsjK9(3)O-TSDm)@_#x z86z`1_0p{X0s}9{i>ioK>TJ&<*F@`1-(B=}?FzX&xUbKmDBYsCbWPiDV)+h2r(wly*`$ST4w`CbGw|r<)heLt zuDU)dl^^lxMLJ@Y<1n-DC9+gWa9k&GhCX#46gurz zU_MuaglW6>$AG zcr!oLK24yCnXBEHC_Gb2)?Qkm6ZHA=?AHWCl#ok>bBribIJOedIdqR%Y6Pf_^_qgS zA3ii9wd1f$`9(nLCWfPa*z{pqjfaD#(Gu!)$#zgJ%xZ;nzN$44NUDkgn4Md#^iNti zS&L)HTh%zqe5DnYL*Sy84g zE?cTY*J)4>GGT1@K|;Qt2+3iiG8~#A0wd9O%v!;CO&GIs%rm|JIMUQqOJRqT zgW!BPflW6HkkM8;Fh+zsF>eLalgUU6(M`E=G{PJd+^pDha%w7iw^Q{Vv?}F@=5MQf z8Bed9rZ1W2^Y}cuxzWs^^cxMw?l?SSU(GlYpR}xzxP+2kLazc6iiPKZQY7F=OiVu= z>&mryg}{FnG6AX>G~ASsOUC)db?fR3BMXbA5$V{m;k`L*0^AjHxlx54V7S6{#|?#* zkM+5!91q+>KxOJ{3-&qkGwSBRp~1~J*GkVAT3I~Ya0+O_I4PA$GljqfTG3P5vx6P% z3Q=lx=a+CK?|bdd0>|yx(ne^=(oraH=CUz`)4N(Ey26P8eR-%-!+L>?4-)tGUX9jz zaf`&NuAdyX_WaPBD|~COCO~Emi#>*=B>!prR)Y@9;DaAx=0WZcW-a(_oE&ZMUTrTo z+T(l6UVaz7xwX|~9B0HjJwyXpi3Mpg$Qx>$+K4ckFmC&Fl>xQkvvCw9QA9(}KYS>) z(-9?`8F*V`j4)2mReH|{YWw5)85MXqc&LgXh48Q-HkmrCJUNzq+#~S^9RIpl*8d|S8MyX%0%0WKnolYF3Wh?R7T1j zUJ$fAlb`5LXBZJ{ah6`e0?>`cSmwn%%yXdL$)W^^p7&>YlwG318}J^m%mdo9P^~F0 z;)FKVpx+gf>jX&2@jIO);5eY$iwVd1Mdw!JZ|-Ou!nDp`&*Q}asO==hgor$3U`(D^ zYag4KAg%`FE(!wDLYE9&0Hbo_2lGr zL`5xsKAj>@D7|ki(ki|U-vSgQr}cB_!hRVboLZJ(+WIo87Z!1kWx zqkxcEfyv@q)Y~Zy4$3J-!FWxkj-LT@lJ13Oo(CZcj z;gISdzS19vN-`A9=ny*LkYh`7%itvTRUQ-As+iEh%^}PH#V1-D?K*EixtMt6cP|8 zR@!PPuY$9VUgm5sdl^Qv8iy)U4>ryo7SO?53=P|IJhR0fs^FboL}9+lqEhG@V;f0B zz zR~)VJupgdWj*y?=W({C_fIr0;htY^3XU5neHv6y@wDMS%NH%MR^IeshdlL6vQalcs97 zInw8!Ja7n2>^tKZ)5WWAOIN(%V@2~Xt%$=-U|ORoz+lpRpqRku3O#h^hw?9xAN3C= zOnF<&9WA+6Vho0NEN2B{HiaCFc4DbsPFJwkyh7p$*kN?6$booZ;KqXsOx4$_GQ8Vr z#v$zPhU}|vMyNu|@uNw>4ghz7A>e1cF}H!!y4o4*JvM&^ImS)`j+l&03gQ(`H9GN7 z@7Z^HKf-l4o{+xENv^)h?(8SGeE-R-uEexLU-GjdpJQ!m<)@EtJLHLx6w5ofr_gO9 zeNb@vjHfnE=N&S0e?Rq_v*mJ;51Rhr-rnxuNtc%;*K`BODBWo_pgqdx1vlJWN_19lw&k>SiVZeDcaDZ z)Rsf_lG(7yFnSreQldn*Iu=oR`A$+vX^Y9#FJ$dBn8s>#e)dU!&@)mfVn^YMl(!2UJ2W%X}vV@b@F}~%B zD(?W>GfTA)ih2h44I_LXCIvYIXKBHe@=O3-de; zCtR`O3{>Y)qHtcdO|XE}Bd<&*B7C4&gS1gAKV*7bSXxA7hdD=&Y06 znA_=?065FP`Tvf*5t+X~f{4+~VI zCWYx{d#Es`H&Hk_`p5UEm4FLd1|7;S^aJYu{x$hE-`+t-AVuP@hn?;J!D&DY;%o2b zVOrEtWgKk#=%LdO`RUVOZvBBVwdNgLkyTw2<|36jGb;1QAEMgzKI3V#VQoo8Ind-w zdC&lXt1~C1Zl$A)OW`qB9{ct+hg|SDix&m~14m5Yx}AmNPe{oy1TfWv0XiUomM_CO zf9fh*Tk6X*!C=Y;U#A&*_Adbf8IFv?%*h*OgA*M-pD5v{Q@~AofOZ~ryCUL0899Bg z&mBr3e;{dFIE+#VrKC}UII=GQxlRIOme?fMKT!(GX(%bN-IOat67j&#j8ar@|2vqO1y^Ofh521Tg*6$PnyN&aD>rq z1rIoI4BsRiV_kB1=aPZVl~X*^yRJ16LI$ABwUtY_lq+WyF2K09MrHn%SWEditE@t4 zR5c=RYgt@ltEpFBEPbYGK+UlG@ZWK#q0Qr{R5WGg>pOMtU3LKH)zw)$0lj=LN=|j|w2=2)d0!)_ zqllh)DR7JC1vj;qyDDwMSFD{|nW0 Jm!XO^1OWP1K@tD} literal 74377 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 diff --git a/dist/fabric.require.js b/dist/fabric.require.js index f57178466..12f674a8d 100644 --- a/dist/fabric.require.js +++ b/dist/fabric.require.js @@ -1,5 +1,5 @@ var fabric = fabric || { - version: "2.0.0-beta2" + version: "2.0.0-beta3" }; if (typeof exports !== "undefined") { @@ -33,7 +33,13 @@ fabric.fontPaths = {}; fabric.iMatrix = [ 1, 0, 0, 1, 0, 0 ]; -fabric.canvasModule = "canvas-prebuilt"; +fabric.canvasModule = "canvas"; + +fabric.perfLimitSizeTotal = 2097152; + +fabric.maxCacheSideLimit = 4096; + +fabric.minCacheSideLimit = 256; fabric.charWidthsCache = {}; @@ -385,7 +391,7 @@ fabric.CommonMethods = { callback && callback(enlivenedObjects); } } - var enlivenedObjects = [], numLoadedObjects = 0, numTotalObjects = objects.length, forceAsync = true; + var enlivenedObjects = [], numLoadedObjects = 0, numTotalObjects = objects.length; if (!numTotalObjects) { callback && callback(enlivenedObjects); return; @@ -400,7 +406,7 @@ fabric.CommonMethods = { error || (enlivenedObjects[index] = obj); reviver && reviver(o, obj, error); onLoaded(); - }, forceAsync); + }); }); }, enlivenPatterns: function(patterns, callback) { @@ -482,25 +488,6 @@ fabric.CommonMethods = { createImage: function() { return fabric.document.createElement("img"); }, - createAccessors: function(klass) { - var proto = klass.prototype, i, propName, capitalizedPropName, setterName, getterName; - for (i = proto.stateProperties.length; i--; ) { - propName = proto.stateProperties[i]; - capitalizedPropName = propName.charAt(0).toUpperCase() + propName.slice(1); - setterName = "set" + capitalizedPropName; - getterName = "get" + capitalizedPropName; - if (!proto[getterName]) { - proto[getterName] = function(property) { - return new Function('return this.get("' + property + '")'); - }(propName); - } - if (!proto[setterName]) { - proto[setterName] = function(property) { - return new Function("value", 'return this.set("' + property + '", value)'); - }(propName); - } - } - }, clipContext: function(receiver, ctx) { ctx.save(); ctx.beginPath(); @@ -587,6 +574,22 @@ fabric.CommonMethods = { } else if (fabric.charWidthsCache[fontFamily]) { delete fabric.charWidthsCache[fontFamily]; } + }, + limitDimsByArea: function(ar, maximumArea) { + var roughWidth = Math.sqrt(maximumArea * ar), perfLimitSizeY = Math.floor(maximumArea / roughWidth); + return { + x: Math.floor(roughWidth), + y: perfLimitSizeY + }; + }, + capValue: function(min, value, max) { + return Math.max(min, Math.min(value, max)); + }, + findScaleToFit: function(source, destination) { + return Math.min(destination.width / source.width, destination.height / source.height); + }, + findScaleToCover: function(source, destination) { + return Math.max(destination.width / source.width, destination.height / source.height); } }; })(typeof exports !== "undefined" ? exports : this); @@ -1385,23 +1388,24 @@ if (typeof console !== "undefined") { } (function() { + function noop() { + return false; + } function animate(options) { requestAnimFrame(function(timestamp) { options || (options = {}); - var start = timestamp || +new Date(), duration = options.duration || 500, finish = start + duration, time, onChange = options.onChange || function() {}, abort = options.abort || function() { - return false; - }, easing = options.easing || function(t, b, c, d) { + var start = timestamp || +new Date(), duration = options.duration || 500, finish = start + duration, time, onChange = options.onChange || noop, abort = options.abort || noop, onComplete = options.onComplete || noop, easing = options.easing || function(t, b, c, d) { return -c * Math.cos(t / d * (Math.PI / 2)) + c + b; }, startValue = "startValue" in options ? options.startValue : 0, endValue = "endValue" in options ? options.endValue : 100, byValue = options.byValue || endValue - startValue; options.onStart && options.onStart(); (function tick(ticktime) { - time = ticktime || +new Date(); - var currentTime = time > finish ? duration : time - start; if (abort()) { - options.onComplete && options.onComplete(); + onComplete(endValue, 1, 1); return; } - onChange(easing(currentTime, startValue, byValue, duration)); + time = ticktime || +new Date(); + var currentTime = time > finish ? duration : time - start, timePerc = currentTime / duration, current = easing(currentTime, startValue, byValue, duration), valuePerc = Math.abs((current - startValue) / byValue); + onChange(current, valuePerc, timePerc); if (time > finish) { options.onComplete && options.onComplete(); return; @@ -2058,9 +2062,9 @@ if (typeof console !== "undefined") { } fabric.gradientDefs[svgUid] = fabric.getGradientDefs(doc); fabric.cssRules[svgUid] = fabric.getCSSRules(doc); - fabric.parseElements(elements, function(instances) { + fabric.parseElements(elements, function(instances, elements) { if (callback) { - callback(instances, options); + callback(instances, options, elements, descendants); } }, clone(options), reviver, parsingOptions); }; @@ -2223,8 +2227,8 @@ if (typeof console !== "undefined") { if (!xml || !xml.documentElement) { callback && callback(null); } - fabric.parseSVGDocument(xml.documentElement, function(results, _options) { - callback && callback(results, _options); + fabric.parseSVGDocument(xml.documentElement, function(results, _options, elements, allElements) { + callback && callback(results, _options, elements, allElements); }, reviver, options); } }, @@ -2241,8 +2245,8 @@ if (typeof console !== "undefined") { doc.async = "false"; doc.loadXML(string.replace(//i, "")); } - fabric.parseSVGDocument(doc.documentElement, function(results, _options) { - callback(results, _options); + fabric.parseSVGDocument(doc.documentElement, function(results, _options, elements, allElements) { + callback(results, _options, elements, allElements); }, reviver, options); } }); @@ -2288,17 +2292,7 @@ fabric.ElementsParser.prototype.createObject = function(el, index) { }; fabric.ElementsParser.prototype._createObject = function(klass, el, index) { - if (klass.async) { - klass.fromElement(el, this.createCallback(index, el), this.options); - } else { - var obj = klass.fromElement(el, this.options); - this.resolveGradient(obj, "fill"); - this.resolveGradient(obj, "stroke"); - obj._removeTransformMatrix(); - this.reviver && this.reviver(el, obj); - this.instances[index] = obj; - this.checkIfDone(); - } + klass.fromElement(el, this.createCallback(index, el), this.options); }; fabric.ElementsParser.prototype.createCallback = function(index, el) { @@ -2307,6 +2301,9 @@ fabric.ElementsParser.prototype.createCallback = function(index, el) { _this.resolveGradient(obj, "fill"); _this.resolveGradient(obj, "stroke"); obj._removeTransformMatrix(); + if (obj instanceof fabric.Image) { + obj.parsePreserveAspectRatioAttribute(el); + } _this.reviver && _this.reviver(el, obj); _this.instances[index] = obj; _this.checkIfDone(); @@ -2329,7 +2326,7 @@ fabric.ElementsParser.prototype.checkIfDone = function() { this.instances = this.instances.filter(function(el) { return el != null; }); - this.callback(this.instances); + this.callback(this.instances, this.elements); } }; @@ -2685,7 +2682,7 @@ fabric.ElementsParser.prototype.checkIfDone = function() { return this; } }; - fabric.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*)?\)$/; + fabric.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*)?\)$/; fabric.Color.reHSLa = /^hsla?\(\s*(\d{1,3})\s*,\s*(\d{1,3}\%)\s*,\s*(\d{1,3}\%)\s*(?:\s*,\s*(\d+(?:\.\d+)?)\s*)?\)$/; fabric.Color.reHex = /^#?([0-9a-f]{8}|[0-9a-f]{6}|[0-9a-f]{4}|[0-9a-f]{3})$/i; fabric.Color.colorNameMap = { @@ -3180,6 +3177,7 @@ fabric.ElementsParser.prototype.checkIfDone = function() { fabric.StaticCanvas = fabric.util.createClass(fabric.CommonMethods, { initialize: function(el, options) { options || (options = {}); + this.renderAndResetBound = this.renderAndReset.bind(this); this._initStatic(el, options); }, backgroundColor: "", @@ -3373,14 +3371,14 @@ fabric.ElementsParser.prototype.checkIfDone = function() { return this.viewportTransform[0]; }, setViewportTransform: function(vpt) { - var activeGroup = this._activeGroup, object, ingoreVpt = false, skipAbsolute = true; + var activeGroup = this._activeGroup, object, ignoreVpt = false, skipAbsolute = true; this.viewportTransform = vpt; for (var i = 0, len = this._objects.length; i < len; i++) { object = this._objects[i]; - object.group || object.setCoords(ingoreVpt, skipAbsolute); + object.group || object.setCoords(ignoreVpt, skipAbsolute); } if (activeGroup) { - activeGroup.setCoords(ingoreVpt, skipAbsolute); + activeGroup.setCoords(ignoreVpt, skipAbsolute); } this.calcViewportBoundaries(); this.renderAll(); @@ -3456,8 +3454,19 @@ fabric.ElementsParser.prototype.checkIfDone = function() { this.renderCanvas(canvasToDrawOn, this._objects); return this; }, + renderAndReset: function() { + this.renderAll(); + this.isRendering = false; + }, + requestRenderAll: function() { + if (!this.isRendering) { + this.isRendering = true; + fabric.util.requestAnimFrame(this.renderAndResetBound); + } + return this; + }, calcViewportBoundaries: function() { - var points = {}, width = this.getWidth(), height = this.getHeight(), iVpt = invertTransform(this.viewportTransform); + var points = {}, width = this.width, height = this.height, iVpt = invertTransform(this.viewportTransform); points.tl = transformPoint({ x: 0, y: 0 @@ -3524,8 +3533,8 @@ fabric.ElementsParser.prototype.checkIfDone = function() { }, getCenter: function() { return { - top: this.getHeight() / 2, - left: this.getWidth() / 2 + top: this.height / 2, + left: this.width / 2 }; }, centerObjectH: function(object) { @@ -3734,7 +3743,8 @@ fabric.ElementsParser.prototype.checkIfDone = function() { removeFromArray(this._objects, object); this._objects.unshift(object); } - return this.renderAll && this.renderAll(); + this.renderAll && this.renderAll(); + return this; }, bringToFront: function(object) { if (!object) { @@ -3752,7 +3762,8 @@ fabric.ElementsParser.prototype.checkIfDone = function() { removeFromArray(this._objects, object); this._objects.push(object); } - return this.renderAll && this.renderAll(); + this.renderAll && this.renderAll(); + return this; }, sendBackwards: function(object, intersecting) { if (!object) { @@ -4023,7 +4034,7 @@ fabric.BaseBrush = fabric.util.createClass({ ctx.closePath(); var pathData = this.convertPointsToSVGPath(this._points).join(""); if (pathData === "M 0 0 Q 0 0 0 0 L 0 0") { - this.canvas.renderAll(); + this.canvas.requestRenderAll(); return; } var path = this.createPath(pathData); @@ -4031,7 +4042,7 @@ fabric.BaseBrush = fabric.util.createClass({ path.setCoords(); this.canvas.clearContext(this.canvas.contextTop); this._resetShadow(); - this.canvas.renderAll(); + this.canvas.requestRenderAll(); this.canvas.fire("path:created", { path: path }); @@ -4093,7 +4104,7 @@ fabric.CircleBrush = fabric.util.createClass(fabric.BaseBrush, { this.canvas.clearContext(this.canvas.contextTop); this._resetShadow(); this.canvas.renderOnAddRemove = originalRenderOnAddRemove; - this.canvas.renderAll(); + this.canvas.requestRenderAll(); }, addPoint: function(pointer) { var pointerPoint = new fabric.Point(pointer.x, pointer.y), circleRadius = fabric.util.getRandomInt(Math.max(0, this.width - 20), this.width + 20) / 2, circleColor = new fabric.Color(this.color).setAlpha(fabric.util.getRandomInt(0, 100) / 100).toRgba(); @@ -4161,7 +4172,7 @@ fabric.SprayBrush = fabric.util.createClass(fabric.BaseBrush, { this.canvas.clearContext(this.canvas.contextTop); this._resetShadow(); this.canvas.renderOnAddRemove = originalRenderOnAddRemove; - this.canvas.renderAll(); + this.canvas.requestRenderAll(); }, _getOptimizedRects: function(rects) { var uniqueRects = {}, key; @@ -4251,6 +4262,7 @@ fabric.PatternBrush = fabric.util.createClass(fabric.PencilBrush, { fabric.Canvas = fabric.util.createClass(fabric.StaticCanvas, { initialize: function(el, options) { options || (options = {}); + this.renderAndResetBound = this.renderAndReset.bind(this); this._initStatic(el, options); this._initInteractive(); this._createCacheCanvas(); @@ -4274,6 +4286,7 @@ fabric.PatternBrush = fabric.util.createClass(fabric.PencilBrush, { defaultCursor: "default", freeDrawingCursor: "crosshair", rotationCursor: "crosshair", + notAllowedCursor: "not-allowed", containerClass: "canvas-container", perPixelTargetFind: false, targetFindTolerance: 0, @@ -4860,7 +4873,11 @@ fabric.PatternBrush = fabric.util.createClass(fabric.PencilBrush, { }, _createUpperCanvas: function() { var lowerCanvasClass = this.lowerCanvasEl.className.replace(/\s*lower-canvas\s*/, ""); - this.upperCanvasEl = this._createCanvasElement(); + if (this.upperCanvasEl) { + this.upperCanvasEl.className = ""; + } else { + this.upperCanvasEl = this._createCanvasElement(); + } fabric.util.addClass(this.upperCanvasEl, "upper-canvas " + lowerCanvasClass); this.wrapperEl.appendChild(this.upperCanvasEl); this._copyCanvasStyle(this.lowerCanvasEl, this.upperCanvasEl); @@ -4878,14 +4895,14 @@ fabric.PatternBrush = fabric.util.createClass(fabric.PencilBrush, { class: this.containerClass }); fabric.util.setStyle(this.wrapperEl, { - width: this.getWidth() + "px", - height: this.getHeight() + "px", + width: this.width + "px", + height: this.height + "px", position: "relative" }); fabric.util.makeElementUnselectable(this.wrapperEl); }, _applyCanvasStyle: function(element) { - var width = this.getWidth() || element.width, height = this.getHeight() || element.height; + var width = this.width || element.width, height = this.height || element.height; fabric.util.setStyle(element, { position: "absolute", width: width + "px", @@ -4933,7 +4950,7 @@ fabric.PatternBrush = fabric.util.createClass(fabric.PencilBrush, { object.fire("selected", { e: e }); - this.renderAll(); + this.requestRenderAll(); return this; }, getActiveObject: function() { @@ -5120,7 +5137,6 @@ fabric.PatternBrush = fabric.util.createClass(fabric.PencilBrush, { if (fabric.isTouchSupported) { fabric.Canvas.prototype._setCursorFromEvent = function() {}; } - fabric.Element = fabric.Canvas; })(); (function() { @@ -5140,9 +5156,11 @@ fabric.PatternBrush = fabric.util.createClass(fabric.PencilBrush, { 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(); addListener(fabric.window, "resize", this._onResize); addListener(this.upperCanvasEl, "mousedown", this._onMouseDown); + addListener(this.upperCanvasEl, "dblclick", this._onDoubleClick); addListener(this.upperCanvasEl, "mousemove", this._onMouseMove); addListener(this.upperCanvasEl, "mouseout", this._onMouseOut); addListener(this.upperCanvasEl, "mouseenter", this._onMouseEnter); @@ -5163,6 +5181,9 @@ fabric.PatternBrush = fabric.util.createClass(fabric.PencilBrush, { } }, _bindEvents: function() { + if (this.eventsBinded) { + return; + } this._onMouseDown = this._onMouseDown.bind(this); this._onMouseMove = this._onMouseMove.bind(this); this._onMouseUp = this._onMouseUp.bind(this); @@ -5176,6 +5197,8 @@ fabric.PatternBrush = fabric.util.createClass(fabric.PencilBrush, { 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.eventsBinded = true; }, removeListeners: function() { removeListener(fabric.window, "resize", this._onResize); @@ -5185,6 +5208,7 @@ fabric.PatternBrush = fabric.util.createClass(fabric.PencilBrush, { removeListener(this.upperCanvasEl, "mouseenter", this._onMouseEnter); removeListener(this.upperCanvasEl, "wheel", this._onMouseWheel); removeListener(this.upperCanvasEl, "contextmenu", this._onContextMenu); + removeListener(this.upperCanvasEl, "doubleclick", this._onDoubleClick); removeListener(this.upperCanvasEl, "touchstart", this._onMouseDown); removeListener(this.upperCanvasEl, "touchmove", this._onMouseMove); if (typeof eventjs !== "undefined" && "remove" in eventjs) { @@ -5247,6 +5271,10 @@ fabric.PatternBrush = fabric.util.createClass(fabric.PencilBrush, { } return false; }, + _onDoubleClick: function(e) { + var target; + this._handleEvent(e, "dblclick", target); + }, _onMouseDown: function(e) { this.__onMouseDown(e); addListener(fabric.document, "touchend", this._onMouseUp, { @@ -5315,7 +5343,7 @@ fabric.PatternBrush = fabric.util.createClass(fabric.PencilBrush, { } var searchTarget = true, transform = this._currentTransform, groupSelector = this._groupSelector, isClick = !groupSelector || groupSelector.left === 0 && groupSelector.top === 0; if (transform) { - this._finalizeCurrentTransform(); + this._finalizeCurrentTransform(e); searchTarget = !transform.actionPerformed; } target = searchTarget ? this.findTarget(e, true) : transform.target; @@ -5332,7 +5360,7 @@ fabric.PatternBrush = fabric.util.createClass(fabric.PencilBrush, { this._setCursorFromEvent(e, target); this._handleEvent(e, "up", target ? target : null, LEFT_CLICK, isClick); target && (target.__corner = 0); - shouldRender && this.renderAll(); + shouldRender && this.requestRenderAll(); }, _handleEvent: function(e, eventType, targetObj, button, isClick) { var target = typeof targetObj === "undefined" ? this.findTarget(e) : targetObj, targets = this.targets || [], options = { @@ -5348,7 +5376,7 @@ fabric.PatternBrush = fabric.util.createClass(fabric.PencilBrush, { targets[i].fire("mouse" + eventType, options); } }, - _finalizeCurrentTransform: function() { + _finalizeCurrentTransform: function(e) { var transform = this._currentTransform, target = transform.target; if (target._scaling) { target._scaling = false; @@ -5357,9 +5385,12 @@ fabric.PatternBrush = fabric.util.createClass(fabric.PencilBrush, { this._restoreOriginXY(target); if (transform.actionPerformed || this.stateful && target.hasStateChanged()) { this.fire("object:modified", { - target: target + target: target, + e: e + }); + target.fire("modified", { + e: e }); - target.fire("modified"); } }, _restoreOriginXY: function(target) { @@ -5375,7 +5406,7 @@ fabric.PatternBrush = fabric.util.createClass(fabric.PencilBrush, { }, _onMouseDownInDrawingMode: function(e) { this._isCurrentlyDrawing = true; - this.discardActiveObject(e).renderAll(); + this.discardActiveObject(e).requestRenderAll(); if (this.clipTo) { fabric.util.clipContext(this, this.contextTop); } @@ -5454,7 +5485,7 @@ fabric.PatternBrush = fabric.util.createClass(fabric.PencilBrush, { } } this._handleEvent(e, "down", target ? target : null); - shouldRender && this.renderAll(); + shouldRender && this.requestRenderAll(); }, _beforeTransform: function(e, target) { this.stateful && target.saveState(); @@ -5516,7 +5547,7 @@ fabric.PatternBrush = fabric.util.createClass(fabric.PencilBrush, { transform.altKey = e[this.centeredKey]; this._beforeScaleTransform(e, transform); this._performTransformAction(e, transform, pointer); - transform.actionPerformed && this.renderAll(); + transform.actionPerformed && this.requestRenderAll(); }, _performTransformAction: function(e, transform, pointer) { var x = pointer.x, y = pointer.y, target = transform.target, action = transform.action, actionPerformed = false; @@ -5560,7 +5591,7 @@ fabric.PatternBrush = fabric.util.createClass(fabric.PencilBrush, { } }, _onScale: function(e, transform, x, y) { - if ((e[this.uniScaleKey] || this.uniScaleTransform) && !transform.target.get("lockUniScaling")) { + if (this._isUniscalePossible(e, transform.target)) { transform.currentAction = "scale"; return this._scaleObject(x, y); } else { @@ -5571,8 +5602,11 @@ fabric.PatternBrush = fabric.util.createClass(fabric.PencilBrush, { return this._scaleObject(x, y, "equally"); } }, + _isUniscalePossible: function(e, target) { + return (e[this.uniScaleKey] || this.uniScaleTransform) && !target.get("lockUniScaling"); + }, _setCursorFromEvent: function(e, target) { - if (!target || !target.selectable) { + if (!target) { this.setCursor(this.defaultCursor); return false; } @@ -5580,22 +5614,33 @@ fabric.PatternBrush = fabric.util.createClass(fabric.PencilBrush, { if (!corner) { this.setCursor(hoverCursor); } else { - this._setCornerCursor(corner, target, e); + this.setCursor(this.getCornerCursor(corner, target, e)); } - return true; }, - _setCornerCursor: function(corner, target, e) { - if (corner in cursorOffset) { - this.setCursor(this._getRotatedCornerCursor(corner, target, e)); + getCornerCursor: function(corner, target, e) { + if (this.actionIsDisabled(corner, target, e)) { + return this.notAllowedCursor; + } else if (corner in cursorOffset) { + return this._getRotatedCornerCursor(corner, target, e); } else if (corner === "mtr" && target.hasRotatingPoint) { - this.setCursor(this.rotationCursor); + return this.rotationCursor; } else { - this.setCursor(this.defaultCursor); - return false; + return this.defaultCursor; + } + }, + actionIsDisabled: function(corner, target, e) { + if (corner === "mt" || corner === "mb") { + return e[this.altActionKey] ? target.lockSkewingX : target.lockScalingY; + } else if (corner === "ml" || corner === "mr") { + return e[this.altActionKey] ? target.lockSkewingY : target.lockScalingX; + } else if (corner === "mtr") { + return target.lockRotation; + } else { + return this._isUniscalePossible(e, target) ? target.lockScalingX && target.lockScalingY : target.lockScalingX || target.lockScalingY; } }, _getRotatedCornerCursor: function(corner, target, e) { - var n = Math.round(target.getAngle() % 360 / 45); + var n = Math.round(target.angle % 360 / 45); if (n < 0) { n += 8; } @@ -5683,7 +5728,7 @@ fabric.PatternBrush = fabric.util.createClass(fabric.PencilBrush, { target: group, e: e }); - this.renderAll(); + this.requestRenderAll(); } }, _collectObjects: function() { @@ -5733,7 +5778,7 @@ fabric.PatternBrush = fabric.util.createClass(fabric.PencilBrush, { return this.__toDataURLWithMultiplier(format, quality, cropping, multiplier); }, __toDataURLWithMultiplier: function(format, quality, cropping, multiplier) { - var origWidth = this.getWidth(), origHeight = this.getHeight(), scaledWidth = (cropping.width || this.getWidth()) * multiplier, scaledHeight = (cropping.height || this.getHeight()) * multiplier, zoom = this.getZoom(), newZoom = zoom * multiplier, vp = this.viewportTransform, translateX = (vp[4] - cropping.left) * multiplier, translateY = (vp[5] - cropping.top) * multiplier, newVp = [ newZoom, 0, 0, newZoom, translateX, translateY ], originalInteractive = this.interactive; + var origWidth = this.width, origHeight = this.height, scaledWidth = (cropping.width || this.width) * multiplier, scaledHeight = (cropping.height || this.height) * multiplier, zoom = this.getZoom(), newZoom = zoom * multiplier, vp = this.viewportTransform, translateX = (vp[4] - cropping.left) * multiplier, translateY = (vp[5] - cropping.top) * multiplier, newVp = [ newZoom, 0, 0, newZoom, translateX, translateY ], originalInteractive = this.interactive; this.viewportTransform = newVp; this.interactive && (this.interactive = false); if (origWidth !== scaledWidth || origHeight !== scaledHeight) { @@ -5780,23 +5825,29 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, { return; } var serialized = typeof json === "string" ? JSON.parse(json) : fabric.util.object.clone(json); - this.clear(); - var _this = this; - this._enlivenObjects(serialized.objects, function() { + var _this = this, renderOnAddRemove = this.renderOnAddRemove; + this.renderOnAddRemove = false; + this._enlivenObjects(serialized.objects, function(enlivenedObjects) { + _this.clear(); _this._setBgOverlay(serialized, function() { + enlivenedObjects.forEach(function(obj, index) { + _this.insertAt(obj, index); + }); + _this.renderOnAddRemove = renderOnAddRemove; delete serialized.objects; delete serialized.backgroundImage; delete serialized.overlayImage; delete serialized.background; delete serialized.overlay; _this._setOptions(serialized); + _this.renderAll(); callback && callback(); }); }, reviver); return this; }, _setBgOverlay: function(serialized, callback) { - var _this = this, loaded = { + var loaded = { backgroundColor: false, overlayColor: false, backgroundImage: false, @@ -5808,7 +5859,6 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, { } var cbIfLoaded = function() { if (loaded.backgroundImage && loaded.overlayImage && loaded.backgroundColor && loaded.overlayColor) { - _this.renderAll(); callback && callback(); } }; @@ -5838,19 +5888,12 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, { } }, _enlivenObjects: function(objects, callback, reviver) { - var _this = this; if (!objects || objects.length === 0) { - callback && callback(); + callback && callback([]); return; } - var renderOnAddRemove = this.renderOnAddRemove; - this.renderOnAddRemove = false; fabric.util.enlivenObjects(objects, function(enlivenedObjects) { - enlivenedObjects.forEach(function(obj, index) { - _this.insertAt(obj, index); - }); - _this.renderOnAddRemove = renderOnAddRemove; - callback && callback(); + callback && callback(enlivenedObjects); }, null, reviver); }, _toDataURL: function(format, callback) { @@ -5873,8 +5916,8 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, { }, cloneWithoutData: function(callback) { var el = fabric.document.createElement("canvas"); - el.width = this.getWidth(); - el.height = this.getHeight(); + el.width = this.width; + el.height = this.height; var clone = new fabric.Canvas(el); clone.clipTo = this.clipTo; if (this.backgroundImage) { @@ -5892,7 +5935,7 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, { (function(global) { "use strict"; - var fabric = global.fabric || (global.fabric = {}), extend = fabric.util.object.extend, clone = fabric.util.object.clone, toFixed = fabric.util.toFixed, capitalize = fabric.util.string.capitalize, degreesToRadians = fabric.util.degreesToRadians, supportsLineDash = fabric.StaticCanvas.supports("setLineDash"), objectCaching = !fabric.isLikelyNode; + var fabric = global.fabric || (global.fabric = {}), extend = fabric.util.object.extend, clone = fabric.util.object.clone, toFixed = fabric.util.toFixed, capitalize = fabric.util.string.capitalize, degreesToRadians = fabric.util.degreesToRadians, supportsLineDash = fabric.StaticCanvas.supports("setLineDash"), objectCaching = !fabric.isLikelyNode, ALIASING_LIMIT = 2; if (fabric.Object) { return; } @@ -5965,17 +6008,13 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, { statefullCache: false, noScaleCache: true, dirty: true, - needsItsOwnCache: false, - stateProperties: ("top left width height scaleX scaleY flipX flipY originX originY transformMatrix " + "stroke strokeWidth strokeDashArray strokeLineCap strokeLineJoin strokeMiterLimit " + "angle opacity fill fillRule globalCompositeOperation shadow clipTo visible backgroundColor " + "skewX skewY").split(" "), - cacheProperties: ("fill stroke strokeWidth strokeDashArray width height stroke strokeWidth strokeDashArray" + " strokeLineCap strokeLineJoin strokeMiterLimit fillRule backgroundColor").split(" "), + stateProperties: ("top left width height scaleX scaleY flipX flipY originX originY transformMatrix " + "stroke strokeWidth strokeDashArray strokeLineCap strokeLineJoin strokeMiterLimit " + "angle opacity fill globalCompositeOperation shadow clipTo visible backgroundColor " + "skewX skewY fillRule").split(" "), + cacheProperties: ("fill stroke strokeWidth strokeDashArray width height" + " strokeLineCap strokeLineJoin strokeMiterLimit backgroundColor").split(" "), initialize: function(options) { options = options || {}; if (options) { this.setOptions(options); } - if (this.objectCaching) { - this._createCacheCanvas(); - } }, _createCacheCanvas: function() { this._cacheProperties = {}; @@ -5983,11 +6022,27 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, { this._cacheContext = this._cacheCanvas.getContext("2d"); this._updateCacheCanvas(); }, + _limitCacheSize: function(dims) { + var perfLimitSizeTotal = fabric.perfLimitSizeTotal, maximumSide = fabric.cacheSideLimit, width = dims.width, height = dims.height, ar = width / height, limitedDims = fabric.util.limitDimsByArea(ar, perfLimitSizeTotal, maximumSide), capValue = fabric.util.capValue, max = fabric.maxCacheSideLimit, min = fabric.minCacheSideLimit, x = capValue(min, limitedDims.x, max), y = capValue(min, limitedDims.y, max); + if (width > x) { + dims.zoomX /= width / x; + dims.width = x; + } else if (width < min) { + dims.width = min; + } + if (height > y) { + dims.zoomY /= height / y; + dims.height = y; + } else if (height < min) { + dims.height = min; + } + return dims; + }, _getCacheCanvasDimensions: function() { var zoom = this.canvas && this.canvas.getZoom() || 1, objectScale = this.getObjectScaling(), dim = this._getNonTransformedDimensions(), retina = this.canvas && this.canvas._isRetinaScaling() ? fabric.devicePixelRatio : 1, zoomX = objectScale.scaleX * zoom * retina, zoomY = objectScale.scaleY * zoom * retina, width = dim.x * zoomX, height = dim.y * zoomY; return { - width: width + 2, - height: height + 2, + width: width + ALIASING_LIMIT, + height: height + ALIASING_LIMIT, zoomX: zoomX, zoomY: zoomY }; @@ -5995,18 +6050,33 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, { _updateCacheCanvas: function() { if (this.noScaleCache && this.canvas && this.canvas._currentTransform) { var action = this.canvas._currentTransform.action; - if (action.slice(0, 5) === "scale") { + if (action.slice && action.slice(0, 5) === "scale") { return false; } } - var dims = this._getCacheCanvasDimensions(), width = dims.width, height = dims.height, zoomX = dims.zoomX, zoomY = dims.zoomY; - if (width !== this.cacheWidth || height !== this.cacheHeight) { - this._cacheCanvas.width = Math.ceil(width); - this._cacheCanvas.height = Math.ceil(height); - this._cacheContext.translate(width / 2, height / 2); - this._cacheContext.scale(zoomX, zoomY); + var dims = this._limitCacheSize(this._getCacheCanvasDimensions()), minCacheSize = fabric.minCacheSideLimit, width = dims.width, height = dims.height, zoomX = dims.zoomX, zoomY = dims.zoomY, dimensionsChanged = width !== this.cacheWidth || height !== this.cacheHeight, zoomChanged = this.zoomX !== zoomX || this.zoomY !== zoomY, shouldRedraw = dimensionsChanged || zoomChanged, additionalWidth = 0, additionalHeight = 0, shouldResizeCanvas = false; + if (dimensionsChanged) { + var canvasWidth = this._cacheCanvas.width, canvasHeight = this._cacheCanvas.height, sizeGrowing = width > canvasWidth || height > canvasHeight, sizeShrinking = (width < canvasWidth * .9 || height < canvasHeight * .9) && canvasWidth > minCacheSize && canvasHeight > minCacheSize; + shouldResizeCanvas = sizeGrowing || sizeShrinking; + if (sizeGrowing) { + additionalWidth = width * .1 & ~1; + additionalHeight = height * .1 & ~1; + } + } + if (shouldRedraw) { + if (shouldResizeCanvas) { + this._cacheCanvas.width = Math.max(Math.ceil(width) + additionalWidth, minCacheSize); + this._cacheCanvas.height = Math.max(Math.ceil(height) + additionalHeight, minCacheSize); + this.cacheTranslationX = (width + additionalWidth) / 2; + this.cacheTranslationY = (height + additionalHeight) / 2; + } else { + this._cacheContext.setTransform(1, 0, 0, 1, 0, 0); + this._cacheContext.clearRect(0, 0, this._cacheCanvas.width, this._cacheCanvas.height); + } this.cacheWidth = width; this.cacheHeight = height; + this._cacheContext.translate(this.cacheTranslationX, this.cacheTranslationY); + this._cacheContext.scale(zoomX, zoomY); this.zoomX = zoomX; this.zoomY = zoomY; return true; @@ -6050,7 +6120,7 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, { strokeMiterLimit: toFixed(this.strokeMiterLimit, NUM_FRACTION_DIGITS), scaleX: toFixed(this.scaleX, NUM_FRACTION_DIGITS), scaleY: toFixed(this.scaleY, NUM_FRACTION_DIGITS), - angle: toFixed(this.getAngle(), NUM_FRACTION_DIGITS), + angle: toFixed(this.angle, NUM_FRACTION_DIGITS), flipX: this.flipX, flipY: this.flipY, opacity: toFixed(this.opacity, NUM_FRACTION_DIGITS), @@ -6131,7 +6201,7 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, { } this.dirty = true; } - if (this.group && this.stateProperties.indexOf(key) > -1) { + if (this.group && this.stateProperties.indexOf(key) > -1 && this.group.isOnACache()) { this.group.set("dirty", true); } if (key === "width" || key === "height") { @@ -6146,8 +6216,11 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, { } return fabric.iMatrix.concat(); }, + isNotVisible: function() { + return this.opacity === 0 || this.width === 0 && this.height === 0 || !this.visible; + }, render: function(ctx) { - if (this.width === 0 && this.height === 0 || !this.visible) { + if (this.isNotVisible()) { return; } if (this.canvas && this.canvas.skipOffscreen && !this.group && !this.isOnScreen()) { @@ -6176,6 +6249,7 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, { } this.drawCacheOnCanvas(ctx); } else { + this.dirty = false; this.drawObject(ctx); if (this.objectCaching && this.statefullCache) { this.saveState({ @@ -6186,11 +6260,15 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, { this.clipTo && ctx.restore(); ctx.restore(); }, + needsItsOwnCache: function() { + return false; + }, shouldCache: function() { - return this.objectCaching && (!this.group || this.needsItsOwnCache || !this.group.isCaching()); + this.ownCaching = this.objectCaching && (!this.group || this.needsItsOwnCache() || !this.group.isOnACache()); + return this.ownCaching; }, willDrawShadow: function() { - return !!this.shadow; + return !!this.shadow && (this.shadow.offsetX !== 0 || this.shadow.offsetY !== 0); }, drawObject: function(ctx) { this._renderBackground(ctx); @@ -6200,14 +6278,17 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, { }, drawCacheOnCanvas: function(ctx) { ctx.scale(1 / this.zoomX, 1 / this.zoomY); - ctx.drawImage(this._cacheCanvas, -this.cacheWidth / 2, -this.cacheHeight / 2); + ctx.drawImage(this._cacheCanvas, -this.cacheTranslationX, -this.cacheTranslationY); }, isCacheDirty: function(skipCanvas) { - if (!skipCanvas && this._updateCacheCanvas()) { + if (this.isNotVisible()) { + return false; + } + if (this._cacheCanvas && !skipCanvas && this._updateCacheCanvas()) { return true; } else { if (this.dirty || this.statefullCache && this.hasStateChanged("cacheProperties")) { - if (!skipCanvas) { + if (this._cacheCanvas && !skipCanvas) { var width = this.cacheWidth / this.zoomX; var height = this.cacheHeight / this.zoomY; this._cacheContext.clearRect(-width / 2, -height / 2, width, height); @@ -6261,8 +6342,10 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, { } }, _renderControls: function(ctx, styleOverride) { - var vpt = this.getViewportTransform(), matrix = this.calcTransformMatrix(), options; + var vpt = this.getViewportTransform(), matrix = this.calcTransformMatrix(), options, drawBorders, drawControls; styleOverride = styleOverride || {}; + drawBorders = typeof styleOverride.hasBorders !== "undefined" ? styleOverride.hasBorders : this.hasBorders; + drawControls = typeof styleOverride.hasControls !== "undefined" ? styleOverride.hasControls : this.hasControls; matrix = fabric.util.multiplyTransformMatrices(vpt, matrix); options = fabric.util.qrDecompose(matrix); ctx.save(); @@ -6273,12 +6356,12 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, { } if (this.group && this.group === this.canvas.getActiveGroup()) { ctx.rotate(degreesToRadians(options.angle)); - (this.hasBorders || styleOverride.hasBorders) && this.drawBordersInGroup(ctx, options, styleOverride); + drawBorders && this.drawBordersInGroup(ctx, options, styleOverride); } else { ctx.rotate(degreesToRadians(this.angle)); - (this.hasBorders || styleOverride.hasBorders) && this.drawBorders(ctx, styleOverride); + drawBorders && this.drawBorders(ctx, styleOverride); } - (this.hasControls || styleOverride.hasControls) && this.drawControls(ctx, styleOverride); + drawControls && this.drawControls(ctx, styleOverride); ctx.restore(); }, _setShadow: function(ctx) { @@ -6362,10 +6445,12 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, { this.setPositionByOrigin(center, "center", "center"); }, clone: function(callback, propertiesToInclude) { + var objectForm = this.toObject(propertiesToInclude); if (this.constructor.fromObject) { - return this.constructor.fromObject(this.toObject(propertiesToInclude), callback); + this.constructor.fromObject(objectForm, callback); + } else { + fabric.Object._fromObject("Object", objectForm, callback); } - return new fabric.Object(this.toObject(propertiesToInclude)); }, cloneAsImage: function(callback, options) { var dataUrl = this.toDataURL(options); @@ -6392,12 +6477,12 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, { canvas.backgroundColor = "#fff"; } var origParams = { - active: this.get("active"), - left: this.getLeft(), - top: this.getTop() + active: this.active, + left: this.left, + top: this.top }; this.set("active", false); - this.setPositionByOrigin(new fabric.Point(canvas.getWidth() / 2, canvas.getHeight() / 2), "center", "center"); + this.setPositionByOrigin(new fabric.Point(canvas.width / 2, canvas.height / 2), "center", "center"); var originalCanvas = this.canvas; canvas.add(this); var data = canvas.toDataURL(options); @@ -6502,29 +6587,23 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, { } } }); - fabric.util.createAccessors(fabric.Object); + fabric.util.createAccessors && fabric.util.createAccessors(fabric.Object); fabric.Object.prototype.rotate = fabric.Object.prototype.setAngle; extend(fabric.Object.prototype, fabric.Observable); fabric.Object.NUM_FRACTION_DIGITS = 2; - fabric.Object._fromObject = function(className, object, callback, forceAsync, extraParam) { + fabric.Object._fromObject = function(className, object, callback, extraParam) { var klass = fabric[className]; object = clone(object, true); - if (forceAsync) { - fabric.util.enlivenPatterns([ object.fill, object.stroke ], function(patterns) { - if (typeof patterns[0] !== "undefined") { - object.fill = patterns[0]; - } - if (typeof patterns[1] !== "undefined") { - object.stroke = patterns[1]; - } - var instance = extraParam ? new klass(object[extraParam], object) : new klass(object); - callback && callback(instance); - }); - } else { + fabric.util.enlivenPatterns([ object.fill, object.stroke ], function(patterns) { + if (typeof patterns[0] !== "undefined") { + object.fill = patterns[0]; + } + if (typeof patterns[1] !== "undefined") { + object.stroke = patterns[1]; + } var instance = extraParam ? new klass(object[extraParam], object) : new klass(object); callback && callback(instance); - return instance; - } + }); }; fabric.Object.__uid = 0; })(typeof exports !== "undefined" ? exports : this); @@ -6612,7 +6691,7 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, { this.set("top", position.y); }, adjustPosition: function(to) { - var angle = degreesToRadians(this.angle), hypotFull = this.getWidth(), xFull = Math.cos(angle) * hypotFull, yFull = Math.sin(angle) * hypotFull, offsetFrom, offsetTo; + var angle = degreesToRadians(this.angle), hypotFull = this.getScaledWidth(), xFull = Math.cos(angle) * hypotFull, yFull = Math.sin(angle) * hypotFull, offsetFrom, offsetTo; if (typeof this.originX === "string") { offsetFrom = originXOffset[this.originX]; } else { @@ -6775,10 +6854,10 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, { var coords = this.getCoords(absolute, calculate); return fabric.util.makeBoundingBoxFromPoints(coords); }, - getWidth: function() { + getScaledWidth: function() { return this._getTransformedDimensions().x; }, - getHeight: function() { + getScaledHeight: function() { return this._getTransformedDimensions().y; }, _constrainScale: function(value) { @@ -6803,11 +6882,11 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, { return this.setCoords(); }, scaleToWidth: function(value) { - var boundingRectFactor = this.getBoundingRect().width / this.getWidth(); + var boundingRectFactor = this.getBoundingRect().width / this.getScaledWidth(); return this.scale(value / this.width / boundingRectFactor); }, scaleToHeight: function(value) { - var boundingRectFactor = this.getBoundingRect().height / this.getHeight(); + var boundingRectFactor = this.getBoundingRect().height / this.getScaledHeight(); return this.scale(value / this.height / boundingRectFactor); }, calcCoords: function(absolute) { @@ -6983,7 +7062,7 @@ fabric.util.object.extend(fabric.Object.prototype, { return this.id ? 'id="' + this.id + '" ' : ""; }, getSvgTransform: function() { - var angle = this.getAngle(), skewX = this.getSkewX() % 360, skewY = this.getSkewY() % 360, center = this.getCenterPoint(), NUM_FRACTION_DIGITS = fabric.Object.NUM_FRACTION_DIGITS, translatePart = "translate(" + toFixed(center.x, NUM_FRACTION_DIGITS) + " " + toFixed(center.y, NUM_FRACTION_DIGITS) + ")", anglePart = angle !== 0 ? " rotate(" + toFixed(angle, NUM_FRACTION_DIGITS) + ")" : "", scalePart = this.scaleX === 1 && this.scaleY === 1 ? "" : " scale(" + toFixed(this.scaleX, NUM_FRACTION_DIGITS) + " " + toFixed(this.scaleY, NUM_FRACTION_DIGITS) + ")", skewXPart = skewX !== 0 ? " skewX(" + toFixed(skewX, NUM_FRACTION_DIGITS) + ")" : "", skewYPart = skewY !== 0 ? " skewY(" + toFixed(skewY, NUM_FRACTION_DIGITS) + ")" : "", flipXPart = this.flipX ? " matrix(-1 0 0 1 0 0) " : "", flipYPart = this.flipY ? " matrix(1 0 0 -1 0 0)" : ""; + var angle = this.angle, skewX = this.skewX % 360, skewY = this.skewY % 360, center = this.getCenterPoint(), NUM_FRACTION_DIGITS = fabric.Object.NUM_FRACTION_DIGITS, translatePart = "translate(" + toFixed(center.x, NUM_FRACTION_DIGITS) + " " + toFixed(center.y, NUM_FRACTION_DIGITS) + ")", anglePart = angle !== 0 ? " rotate(" + toFixed(angle, NUM_FRACTION_DIGITS) + ")" : "", scalePart = this.scaleX === 1 && this.scaleY === 1 ? "" : " scale(" + toFixed(this.scaleX, NUM_FRACTION_DIGITS) + " " + toFixed(this.scaleY, NUM_FRACTION_DIGITS) + ")", skewXPart = skewX !== 0 ? " skewX(" + toFixed(skewX, NUM_FRACTION_DIGITS) + ")" : "", skewYPart = skewY !== 0 ? " skewY(" + toFixed(skewY, NUM_FRACTION_DIGITS) + ")" : "", flipXPart = this.flipX ? " matrix(-1 0 0 1 0 0) " : "", flipYPart = this.flipY ? " matrix(1 0 0 -1 0 0)" : ""; return [ translatePart, anglePart, scalePart, flipXPart, flipYPart, skewXPart, skewYPart ].join(""); }, getSvgTransformMatrix: function() { @@ -7020,40 +7099,40 @@ fabric.util.object.extend(fabric.Object.prototype, { extend(origin[destination], tmpObj, deep); } function _isEqual(origValue, currentValue, firstPass) { - if (!fabric.isLikelyNode && origValue instanceof Element) { - return origValue === currentValue; - } else if (origValue instanceof Array) { + if (origValue === currentValue) { + return true; + } else if (Array.isArray(origValue)) { if (origValue.length !== currentValue.length) { return false; } for (var i = 0, len = origValue.length; i < len; i++) { - if (origValue[i] !== currentValue[i]) { + if (!_isEqual(origValue[i], currentValue[i])) { return false; } } return true; } else if (origValue && typeof origValue === "object") { - if (!firstPass && Object.keys(origValue).length !== Object.keys(currentValue).length) { + var keys = Object.keys(origValue), key; + if (!firstPass && keys.length !== Object.keys(currentValue).length) { return false; } - for (var key in origValue) { + for (var i = 0, len = keys.length; i < len; i++) { + key = keys[i]; if (!_isEqual(origValue[key], currentValue[key])) { return false; } } return true; - } else { - return origValue === currentValue; } } fabric.util.object.extend(fabric.Object.prototype, { hasStateChanged: function(propertySet) { propertySet = propertySet || originalSet; - propertySet = "_" + propertySet; - if (!Object.keys(this[propertySet]).length) { + var dashedPropertySet = "_" + propertySet; + if (Object.keys(this[dashedPropertySet]).length < this[propertySet].length) { return true; } - return !_isEqual(this[propertySet], this, true); + return !_isEqual(this[dashedPropertySet], this, true); }, saveState: function(options) { var propertySet = options && options.propertySet || originalSet, destination = "_" + propertySet; @@ -7148,66 +7227,66 @@ fabric.util.object.extend(fabric.Object.prototype, { ctx.restore(); return this; }, - drawBorders: function(ctx, bordersStyle) { - bordersStyle = bordersStyle || {}; - var wh = this._calculateCurrentDimensions(), strokeWidth = 1 / this.borderScaleFactor, width = wh.x + strokeWidth, height = wh.y + strokeWidth; + drawBorders: function(ctx, styleOverride) { + styleOverride = styleOverride || {}; + var wh = this._calculateCurrentDimensions(), strokeWidth = 1 / this.borderScaleFactor, width = wh.x + strokeWidth, height = wh.y + strokeWidth, drawRotatingPoint = typeof styleOverride.hasRotatingPoint !== "undefined" ? styleOverride.hasRotatingPoint : this.hasRotatingPoint, hasControls = typeof styleOverride.hasControls !== "undefined" ? styleOverride.hasControls : this.hasControls, rotatingPointOffset = typeof styleOverride.rotatingPointOffset !== "undefined" ? styleOverride.rotatingPointOffset : this.rotatingPointOffset; ctx.save(); - ctx.strokeStyle = bordersStyle.borderColor || this.borderColor; - this._setLineDash(ctx, bordersStyle.borderDashArray || this.borderDashArray, null); + ctx.strokeStyle = styleOverride.borderColor || this.borderColor; + this._setLineDash(ctx, styleOverride.borderDashArray || this.borderDashArray, null); ctx.strokeRect(-width / 2, -height / 2, width, height); - if (bordersStyle.hasRotatingPoint || this.hasRotatingPoint && this.isControlVisible("mtr") && !this.get("lockRotation") && this.hasControls) { + if (drawRotatingPoint && this.isControlVisible("mtr") && hasControls) { var rotateHeight = -height / 2; ctx.beginPath(); ctx.moveTo(0, rotateHeight); - ctx.lineTo(0, rotateHeight - this.rotatingPointOffset); + ctx.lineTo(0, rotateHeight - rotatingPointOffset); ctx.closePath(); ctx.stroke(); } ctx.restore(); return this; }, - drawBordersInGroup: function(ctx, options, bordersStyle) { - bordersStyle = bordersStyle || {}; + drawBordersInGroup: function(ctx, options, styleOverride) { + styleOverride = styleOverride || {}; var p = this._getNonTransformedDimensions(), matrix = fabric.util.customTransformMatrix(options.scaleX, options.scaleY, options.skewX), wh = fabric.util.transformPoint(p, matrix), strokeWidth = 1 / this.borderScaleFactor, width = wh.x + strokeWidth, height = wh.y + strokeWidth; ctx.save(); - this._setLineDash(ctx, bordersStyle.borderDashArray || this.borderDashArray, null); - ctx.strokeStyle = bordersStyle.borderColor || this.borderColor; + this._setLineDash(ctx, styleOverride.borderDashArray || this.borderDashArray, null); + ctx.strokeStyle = styleOverride.borderColor || this.borderColor; ctx.strokeRect(-width / 2, -height / 2, width, height); ctx.restore(); return this; }, - drawControls: function(ctx, controlsStyle) { - controlsStyle = controlsStyle || {}; - var wh = this._calculateCurrentDimensions(), width = wh.x, height = wh.y, scaleOffset = controlsStyle.cornerSize || this.cornerSize, left = -(width + scaleOffset) / 2, top = -(height + scaleOffset) / 2, methodName = controlsStyle.transparentCorners || this.transparentCorners ? "stroke" : "fill"; + drawControls: function(ctx, styleOverride) { + styleOverride = styleOverride || {}; + var wh = this._calculateCurrentDimensions(), width = wh.x, height = wh.y, scaleOffset = styleOverride.cornerSize || this.cornerSize, left = -(width + scaleOffset) / 2, top = -(height + scaleOffset) / 2, transparentCorners = typeof styleOverride.transparentCorners !== "undefined" ? styleOverride.transparentCorners : this.transparentCorners, hasRotatingPoint = typeof styleOverride.hasRotatingPoint !== "undefined" ? styleOverride.hasRotatingPoint : this.hasRotatingPoint, methodName = transparentCorners ? "stroke" : "fill"; ctx.save(); - ctx.strokeStyle = ctx.fillStyle = controlsStyle.cornerColor || this.cornerColor; + ctx.strokeStyle = ctx.fillStyle = styleOverride.cornerColor || this.cornerColor; if (!this.transparentCorners) { - ctx.strokeStyle = controlsStyle.cornerStrokeColor || this.cornerStrokeColor; + ctx.strokeStyle = styleOverride.cornerStrokeColor || this.cornerStrokeColor; } - this._setLineDash(ctx, controlsStyle.cornerDashArray || this.cornerDashArray, null); - this._drawControl("tl", ctx, methodName, left, top, controlsStyle); - this._drawControl("tr", ctx, methodName, left + width, top, controlsStyle); - this._drawControl("bl", ctx, methodName, left, top + height, controlsStyle); - this._drawControl("br", ctx, methodName, left + width, top + height, controlsStyle); + this._setLineDash(ctx, styleOverride.cornerDashArray || this.cornerDashArray, null); + this._drawControl("tl", ctx, methodName, left, top, styleOverride); + this._drawControl("tr", ctx, methodName, left + width, top, styleOverride); + this._drawControl("bl", ctx, methodName, left, top + height, styleOverride); + this._drawControl("br", ctx, methodName, left + width, top + height, styleOverride); if (!this.get("lockUniScaling")) { - this._drawControl("mt", ctx, methodName, left + width / 2, top, controlsStyle); - this._drawControl("mb", ctx, methodName, left + width / 2, top + height, controlsStyle); - this._drawControl("mr", ctx, methodName, left + width, top + height / 2, controlsStyle); - this._drawControl("ml", ctx, methodName, left, top + height / 2, controlsStyle); + this._drawControl("mt", ctx, methodName, left + width / 2, top, styleOverride); + this._drawControl("mb", ctx, methodName, left + width / 2, top + height, styleOverride); + this._drawControl("mr", ctx, methodName, left + width, top + height / 2, styleOverride); + this._drawControl("ml", ctx, methodName, left, top + height / 2, styleOverride); } - if (controlsStyle.hasRotatingPoint || this.hasRotatingPoint) { - this._drawControl("mtr", ctx, methodName, left + width / 2, top - this.rotatingPointOffset, controlsStyle); + if (hasRotatingPoint) { + this._drawControl("mtr", ctx, methodName, left + width / 2, top - this.rotatingPointOffset, styleOverride); } ctx.restore(); return this; }, - _drawControl: function(control, ctx, methodName, left, top, controlStyle) { - controlStyle = controlStyle || {}; + _drawControl: function(control, ctx, methodName, left, top, styleOverride) { + styleOverride = styleOverride || {}; if (!this.isControlVisible(control)) { return; } var size = this.cornerSize, stroke = !this.transparentCorners && this.cornerStrokeColor; - switch (controlStyle.cornerStyle || this.cornerStyle) { + switch (styleOverride.cornerStyle || this.cornerStyle) { case "circle": ctx.beginPath(); ctx.arc(left + size / 2, top + size / 2, size / 2, 0, 2 * Math.PI, false); @@ -7264,12 +7343,12 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, { callbacks = callbacks || {}; var empty = function() {}, onComplete = callbacks.onComplete || empty, onChange = callbacks.onChange || empty, _this = this; fabric.util.animate({ - startValue: object.get("left"), + startValue: object.left, endValue: this.getCenter().left, duration: this.FX_DURATION, onChange: function(value) { object.set("left", value); - _this.renderAll(); + _this.requestRenderAll(); onChange(); }, onComplete: function() { @@ -7283,12 +7362,12 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, { callbacks = callbacks || {}; var empty = function() {}, onComplete = callbacks.onComplete || empty, onChange = callbacks.onChange || empty, _this = this; fabric.util.animate({ - startValue: object.get("top"), + startValue: object.top, endValue: this.getCenter().top, duration: this.FX_DURATION, onChange: function(value) { object.set("top", value); - _this.renderAll(); + _this.requestRenderAll(); onChange(); }, onComplete: function() { @@ -7302,7 +7381,7 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, { callbacks = callbacks || {}; var empty = function() {}, onComplete = callbacks.onComplete || empty, onChange = callbacks.onChange || empty, _this = this; fabric.util.animate({ - startValue: object.get("opacity"), + startValue: object.opacity, endValue: 0, duration: this.FX_DURATION, onStart: function() { @@ -7310,7 +7389,7 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, { }, onChange: function(value) { object.set("opacity", value); - _this.renderAll(); + _this.requestRenderAll(); onChange(); }, onComplete: function() { @@ -7368,7 +7447,7 @@ fabric.util.object.extend(fabric.Object.prototype, { abort: options.abort && function() { return options.abort.call(_this); }, - onChange: function(value) { + onChange: function(value, valueProgress, timeProgress) { if (propPair) { _this[propPair[0]][propPair[1]] = value; } else { @@ -7377,14 +7456,14 @@ fabric.util.object.extend(fabric.Object.prototype, { if (skipCallbacks) { return; } - options.onChange && options.onChange(); + options.onChange && options.onChange(value, valueProgress, timeProgress); }, - onComplete: function() { + onComplete: function(value, valueProgress, timeProgress) { if (skipCallbacks) { return; } _this.setCoords(); - options.onComplete && options.onComplete(); + options.onComplete && options.onComplete(value, valueProgress, timeProgress); } }); } @@ -7512,25 +7591,21 @@ fabric.util.object.extend(fabric.Object.prototype, { } }); fabric.Line.ATTRIBUTE_NAMES = fabric.SHARED_ATTRIBUTES.concat("x1 y1 x2 y2".split(" ")); - fabric.Line.fromElement = function(element, options) { + fabric.Line.fromElement = function(element, callback, options) { options = options || {}; var parsedAttributes = fabric.parseAttributes(element, fabric.Line.ATTRIBUTE_NAMES), points = [ parsedAttributes.x1 || 0, parsedAttributes.y1 || 0, parsedAttributes.x2 || 0, parsedAttributes.y2 || 0 ]; options.originX = "left"; options.originY = "top"; - return new fabric.Line(points, extend(parsedAttributes, options)); + callback(new fabric.Line(points, extend(parsedAttributes, options))); }; - fabric.Line.fromObject = function(object, callback, forceAsync) { + fabric.Line.fromObject = function(object, callback) { function _callback(instance) { delete instance.points; callback && callback(instance); } var options = clone(object, true); options.points = [ object.x1, object.y1, object.x2, object.y2 ]; - var line = fabric.Object._fromObject("Line", options, _callback, forceAsync, "points"); - if (line) { - delete line.points; - } - return line; + fabric.Object._fromObject("Line", options, _callback, "points"); }; function makeEdgeToOriginGetter(propertyNames, originValues) { var origin = propertyNames.origin, axis1 = propertyNames.axis1, axis2 = propertyNames.axis2, dimension = propertyNames.dimension, nearest = originValues.nearest, center = originValues.center, farthest = originValues.farthest; @@ -7606,7 +7681,7 @@ fabric.util.object.extend(fabric.Object.prototype, { } }); fabric.Circle.ATTRIBUTE_NAMES = fabric.SHARED_ATTRIBUTES.concat("cx cy r".split(" ")); - fabric.Circle.fromElement = function(element, options) { + fabric.Circle.fromElement = function(element, callback, options) { options || (options = {}); var parsedAttributes = fabric.parseAttributes(element, fabric.Circle.ATTRIBUTE_NAMES); if (!isValidRadius(parsedAttributes)) { @@ -7616,13 +7691,13 @@ fabric.util.object.extend(fabric.Object.prototype, { parsedAttributes.top = (parsedAttributes.top || 0) - parsedAttributes.radius; parsedAttributes.originX = "left"; parsedAttributes.originY = "top"; - return new fabric.Circle(extend(parsedAttributes, options)); + callback(new fabric.Circle(extend(parsedAttributes, options))); }; function isValidRadius(attributes) { return "radius" in attributes && attributes.radius >= 0; } - fabric.Circle.fromObject = function(object, callback, forceAsync) { - return fabric.Object._fromObject("Circle", object, callback, forceAsync); + fabric.Circle.fromObject = function(object, callback) { + return fabric.Object._fromObject("Circle", object, callback); }; })(typeof exports !== "undefined" ? exports : this); @@ -7663,8 +7738,8 @@ fabric.util.object.extend(fabric.Object.prototype, { return reviver ? reviver(markup.join("")) : markup.join(""); } }); - fabric.Triangle.fromObject = function(object, callback, forceAsync) { - return fabric.Object._fromObject("Triangle", object, callback, forceAsync); + fabric.Triangle.fromObject = function(object, callback) { + return fabric.Object._fromObject("Triangle", object, callback); }; })(typeof exports !== "undefined" ? exports : this); @@ -7727,17 +7802,17 @@ fabric.util.object.extend(fabric.Object.prototype, { } }); fabric.Ellipse.ATTRIBUTE_NAMES = fabric.SHARED_ATTRIBUTES.concat("cx cy rx ry".split(" ")); - fabric.Ellipse.fromElement = function(element, options) { + fabric.Ellipse.fromElement = function(element, callback, options) { options || (options = {}); var parsedAttributes = fabric.parseAttributes(element, fabric.Ellipse.ATTRIBUTE_NAMES); parsedAttributes.left = (parsedAttributes.left || 0) - parsedAttributes.rx; parsedAttributes.top = (parsedAttributes.top || 0) - parsedAttributes.ry; parsedAttributes.originX = "left"; parsedAttributes.originY = "top"; - return new fabric.Ellipse(extend(parsedAttributes, options)); + callback(new fabric.Ellipse(extend(parsedAttributes, options))); }; - fabric.Ellipse.fromObject = function(object, callback, forceAsync) { - return fabric.Object._fromObject("Ellipse", object, callback, forceAsync); + fabric.Ellipse.fromObject = function(object, callback) { + return fabric.Object._fromObject("Ellipse", object, callback); }; })(typeof exports !== "undefined" ? exports : this); @@ -7808,9 +7883,9 @@ fabric.util.object.extend(fabric.Object.prototype, { } }); fabric.Rect.ATTRIBUTE_NAMES = fabric.SHARED_ATTRIBUTES.concat("x y rx ry width height".split(" ")); - fabric.Rect.fromElement = function(element, options) { + fabric.Rect.fromElement = function(element, callback, options) { if (!element) { - return null; + return callback(null); } options = options || {}; var parsedAttributes = fabric.parseAttributes(element, fabric.Rect.ATTRIBUTE_NAMES); @@ -7820,10 +7895,10 @@ fabric.util.object.extend(fabric.Object.prototype, { parsedAttributes.originY = "top"; var rect = new fabric.Rect(extend(options ? fabric.util.object.clone(options) : {}, parsedAttributes)); rect.visible = rect.visible && rect.width > 0 && rect.height > 0; - return rect; + callback(rect); }; - fabric.Rect.fromObject = function(object, callback, forceAsync) { - return fabric.Object._fromObject("Rect", object, callback, forceAsync); + fabric.Rect.fromObject = function(object, callback) { + return fabric.Object._fromObject("Rect", object, callback); }; })(typeof exports !== "undefined" ? exports : this); @@ -7912,16 +7987,16 @@ fabric.util.object.extend(fabric.Object.prototype, { } }); fabric.Polyline.ATTRIBUTE_NAMES = fabric.SHARED_ATTRIBUTES.concat(); - fabric.Polyline.fromElement = function(element, options) { + fabric.Polyline.fromElement = function(element, callback, options) { if (!element) { - return null; + return callback(null); } options || (options = {}); var points = fabric.parsePointsAttribute(element.getAttribute("points")), parsedAttributes = fabric.parseAttributes(element, fabric.Polyline.ATTRIBUTE_NAMES); - return new fabric.Polyline(points, fabric.util.object.extend(parsedAttributes, options)); + callback(new fabric.Polyline(points, fabric.util.object.extend(parsedAttributes, options))); }; - fabric.Polyline.fromObject = function(object, callback, forceAsync) { - return fabric.Object._fromObject("Polyline", object, callback, forceAsync, "points"); + fabric.Polyline.fromObject = function(object, callback) { + return fabric.Object._fromObject("Polyline", object, callback, "points"); }; })(typeof exports !== "undefined" ? exports : this); @@ -7948,16 +8023,16 @@ fabric.util.object.extend(fabric.Object.prototype, { } }); fabric.Polygon.ATTRIBUTE_NAMES = fabric.SHARED_ATTRIBUTES.concat(); - fabric.Polygon.fromElement = function(element, options) { + fabric.Polygon.fromElement = function(element, callback, options) { if (!element) { - return null; + return callback(null); } options || (options = {}); var points = fabric.parsePointsAttribute(element.getAttribute("points")), parsedAttributes = fabric.parseAttributes(element, fabric.Polygon.ATTRIBUTE_NAMES); - return new fabric.Polygon(points, extend(parsedAttributes, options)); + callback(new fabric.Polygon(points, extend(parsedAttributes, options))); }; - fabric.Polygon.fromObject = function(object, callback, forceAsync) { - return fabric.Object._fromObject("Polygon", object, callback, forceAsync, "points"); + fabric.Polygon.fromObject = function(object, callback) { + return fabric.Object._fromObject("Polygon", object, callback, "points"); }; })(typeof exports !== "undefined" ? exports : this); @@ -7981,19 +8056,20 @@ fabric.util.object.extend(fabric.Object.prototype, { fabric.warn("fabric.Path is already defined"); return; } + var stateProperties = fabric.Object.prototype.stateProperties.concat(); + stateProperties.push("path"); var cacheProperties = fabric.Object.prototype.cacheProperties.concat(); - cacheProperties.push("path"); + cacheProperties.push("path", "fillRule"); fabric.Path = fabric.util.createClass(fabric.Object, { type: "path", path: null, minX: 0, minY: 0, cacheProperties: cacheProperties, + stateProperties: stateProperties, initialize: function(path, options) { options = options || {}; - if (options) { - this.setOptions(options); - } + this.callSuper("initialize", options); if (!path) { path = []; } @@ -8006,9 +8082,6 @@ fabric.util.object.extend(fabric.Object.prototype, { this.path = this._parsePath(); } this._setPositionDimensions(options); - if (this.objectCaching) { - this._createCacheCanvas(); - } }, _setPositionDimensions: function(options) { var calcDim = this._parseDimensions(); @@ -8460,17 +8533,27 @@ fabric.util.object.extend(fabric.Object.prototype, { return o; } }); - fabric.Path.fromObject = function(object, callback, forceAsync) { - return fabric.Object._fromObject("Path", object, callback, forceAsync, "path"); + fabric.Path.fromObject = function(object, callback) { + if (typeof object.path === "string") { + var pathUrl = object.path; + fabric.loadSVGFromURL(pathUrl, function(elements) { + var path = elements[0]; + delete object.path; + path.setOptions(object); + path.setSourcePath(pathUrl); + callback && callback(path); + }); + } else { + fabric.Object._fromObject("Path", object, callback, "path"); + } }; fabric.Path.ATTRIBUTE_NAMES = fabric.SHARED_ATTRIBUTES.concat([ "d" ]); fabric.Path.fromElement = function(element, callback, options) { var parsedAttributes = fabric.parseAttributes(element, fabric.Path.ATTRIBUTE_NAMES); parsedAttributes.originX = "left"; parsedAttributes.originY = "top"; - callback && callback(new fabric.Path(parsedAttributes.d, extend(parsedAttributes, options))); + callback(new fabric.Path(parsedAttributes.d, extend(parsedAttributes, options))); }; - fabric.Path.async = true; })(typeof exports !== "undefined" ? exports : this); (function(global) { @@ -8479,18 +8562,12 @@ fabric.util.object.extend(fabric.Object.prototype, { if (fabric.Group) { return; } - var _lockProperties = { - lockMovementX: true, - lockMovementY: true, - lockRotation: true, - lockScalingX: true, - lockScalingY: true, - lockUniScaling: true - }; fabric.Group = fabric.util.createClass(fabric.Object, fabric.Collection, { type: "group", strokeWidth: 0, subTargetCheck: false, + cacheProperties: [], + useSetOnGroup: false, initialize: function(objects, options, isAlreadyGrouped) { options = options || {}; this._objects = []; @@ -8530,7 +8607,7 @@ fabric.util.object.extend(fabric.Object.prototype, { _updateObjectCoords: function(object, center) { object.__origHasControls = object.hasControls; object.hasControls = false; - var objectLeft = object.getLeft(), objectTop = object.getTop(), ignoreZoom = true, skipAbsolute = true; + var objectLeft = object.left, objectTop = object.top, ignoreZoom = true, skipAbsolute = true; object.set({ left: objectLeft - center.x, top: objectTop - center.y @@ -8580,26 +8657,14 @@ fabric.util.object.extend(fabric.Object.prototype, { delete object.group; object.set("active", false); }, - delegatedProperties: { - fill: true, - stroke: true, - strokeWidth: true, - fontFamily: true, - fontWeight: true, - fontSize: true, - fontStyle: true, - lineHeight: true, - textDecoration: true, - textAlign: true, - backgroundColor: true - }, _set: function(key, value) { var i = this._objects.length; - if (this.delegatedProperties[key] || key === "canvas") { + if (key === "canvas") { while (i--) { this._objects[i].set(key, value); } - } else { + } + if (this.useSetOnGroup) { while (i--) { this._objects[i].setOnGroup(key, value); } @@ -8641,21 +8706,21 @@ fabric.util.object.extend(fabric.Object.prototype, { this._transformDone = false; }, shouldCache: function() { - var parentCache = this.objectCaching && (!this.group || this.needsItsOwnCache || !this.group.isCaching()); - this.caching = parentCache; - if (parentCache) { + var ownCache = this.objectCaching && (!this.group || this.needsItsOwnCache() || !this.group.isOnACache()); + this.ownCaching = ownCache; + if (ownCache) { for (var i = 0, len = this._objects.length; i < len; i++) { if (this._objects[i].willDrawShadow()) { - this.caching = false; + this.ownCaching = false; return false; } } } - return parentCache; + return ownCache; }, willDrawShadow: function() { if (this.shadow) { - return true; + return this.callSuper("willDrawShadow"); } for (var i = 0, len = this._objects.length; i < len; i++) { if (this._objects[i].willDrawShadow()) { @@ -8664,8 +8729,8 @@ fabric.util.object.extend(fabric.Object.prototype, { } return false; }, - isCaching: function() { - return this.caching || this.group && this.group.isCaching(); + isOnACache: function() { + return this.ownCaching || this.group && this.group.isOnACache(); }, drawObject: function(ctx) { for (var i = 0, len = this._objects.length; i < len; i++) { @@ -8681,8 +8746,10 @@ fabric.util.object.extend(fabric.Object.prototype, { } for (var i = 0, len = this._objects.length; i < len; i++) { if (this._objects[i].isCacheDirty(true)) { - var dim = this._getNonTransformedDimensions(); - this._cacheContext.clearRect(-dim.x / 2, -dim.y / 2, dim.x, dim.y); + if (this._cacheCanvas) { + var x = this.cacheWidth / this.zoomX, y = this.cacheHeight / this.zoomY; + this._cacheContext.clearRect(-x / 2, -y / 2, x, y); + } return true; } } @@ -8700,9 +8767,6 @@ fabric.util.object.extend(fabric.Object.prototype, { ctx.restore(); }, _renderObject: function(object, ctx) { - if (!object.visible) { - return; - } var originalHasRotatingPoint = object.hasRotatingPoint; object.hasRotatingPoint = false; object.render(ctx); @@ -8787,25 +8851,6 @@ fabric.util.object.extend(fabric.Object.prototype, { } markup.push("\n"); return reviver ? reviver(markup.join("")) : markup.join(""); - }, - get: function(prop) { - if (prop in _lockProperties) { - if (this[prop]) { - return this[prop]; - } else { - for (var i = 0, len = this._objects.length; i < len; i++) { - if (this._objects[i][prop]) { - return true; - } - } - return false; - } - } else { - if (prop in this.delegatedProperties) { - return this._objects[0] && this._objects[0].get(prop); - } - return this[prop]; - } } }); fabric.Group.fromObject = function(object, callback) { @@ -8814,7 +8859,6 @@ fabric.util.object.extend(fabric.Object.prototype, { callback && callback(new fabric.Group(enlivenedObjects, object, true)); }); }; - fabric.Group.async = true; })(typeof exports !== "undefined" ? exports : this); (function(global) { @@ -8828,13 +8872,10 @@ fabric.util.object.extend(fabric.Object.prototype, { return; } var stateProperties = fabric.Object.prototype.stateProperties.concat(); - stateProperties.push("alignX", "alignY", "meetOrSlice"); + stateProperties.push("cropX", "cropY"); fabric.Image = fabric.util.createClass(fabric.Object, { type: "image", crossOrigin: "", - alignX: "none", - alignY: "none", - meetOrSlice: "meet", strokeWidth: 0, _lastScaleX: 1, _lastScaleY: 1, @@ -8844,6 +8885,8 @@ fabric.util.object.extend(fabric.Object.prototype, { stateProperties: stateProperties, objectCaching: false, cacheKey: "", + cropX: 0, + cropY: 0, initialize: function(element, options) { options || (options = {}); this.filters = []; @@ -8910,7 +8953,7 @@ fabric.util.object.extend(fabric.Object.prototype, { filters.push(filterObj.toObject()); } }); - var object = extend(this.callSuper("toObject", [ "crossOrigin", "alignX", "alignY", "meetOrSlice" ].concat(propertiesToInclude)), { + var object = extend(this.callSuper("toObject", [ "crossOrigin", "cropX", "cropY" ].concat(propertiesToInclude)), { src: this.getSrc(), filters: filters }); @@ -8922,11 +8965,8 @@ fabric.util.object.extend(fabric.Object.prototype, { return object; }, toSVG: function(reviver) { - var markup = this._createBaseSVGMarkup(), x = -this.width / 2, y = -this.height / 2, preserveAspectRatio = "none", filtered = true; - if (this.alignX !== "none" && this.alignY !== "none") { - preserveAspectRatio = "x" + this.alignX + "Y" + this.alignY + " " + this.meetOrSlice; - } - markup.push('\n', "\n"); + var markup = this._createBaseSVGMarkup(), x = -this.width / 2, y = -this.height / 2, filtered = true; + markup.push('\n', "\n"); if (this.stroke || this.strokeDashArray) { var origFill = this.fill; this.fill = null; @@ -9026,52 +9066,20 @@ fabric.util.object.extend(fabric.Object.prototype, { return this; }, _render: function(ctx) { - var x = -this.width / 2, y = -this.height / 2, imageMargins = this._findMargins(), elementToDraw; - if (this.meetOrSlice === "slice") { - ctx.beginPath(); - ctx.rect(x, y, this.width, this.height); - ctx.clip(); - } + var x = -this.width / 2, y = -this.height / 2, elementToDraw; if (this.isMoving === false && this.resizeFilter && this._needsResize()) { this._lastScaleX = this.scaleX; this._lastScaleY = this.scaleY; this.applyResizeFilters(); } elementToDraw = this._element; - elementToDraw && ctx.drawImage(elementToDraw, x + imageMargins.marginX, y + imageMargins.marginY, imageMargins.width, imageMargins.height); + elementToDraw && ctx.drawImage(elementToDraw, this.cropX, this.cropY, this.width, this.height, x, y, this.width, this.height); this._stroke(ctx); this._renderStroke(ctx); }, _needsResize: function() { return this.scaleX !== this._lastScaleX || this.scaleY !== this._lastScaleY; }, - _findMargins: function() { - var width = this.width, height = this.height, scales, scale, marginX = 0, marginY = 0; - if (this.alignX !== "none" || this.alignY !== "none") { - scales = [ this.width / this._element.width, this.height / this._element.height ]; - scale = this.meetOrSlice === "meet" ? Math.min.apply(null, scales) : Math.max.apply(null, scales); - width = this._element.width * scale; - height = this._element.height * scale; - if (this.alignX === "Mid") { - marginX = (this.width - width) / 2; - } - if (this.alignX === "Max") { - marginX = this.width - width; - } - if (this.alignY === "Mid") { - marginY = (this.height - height) / 2; - } - if (this.alignY === "Max") { - marginY = this.height - height; - } - } - return { - width: width, - height: height, - marginX: marginX, - marginY: marginY - }; - }, _resetWidthHeight: function() { var element = this.getElement(); this.set("width", element.width); @@ -9101,6 +9109,54 @@ fabric.util.object.extend(fabric.Object.prototype, { _setWidthHeight: function(options) { this.width = "width" in options ? options.width : this.getElement() ? this.getElement().width || 0 : 0; this.height = "height" in options ? options.height : this.getElement() ? this.getElement().height || 0 : 0; + }, + parsePreserveAspectRatioAttribute: function() { + if (!this.preserveAspectRatio) { + return; + } + var pAR = fabric.util.parsePreserveAspectRatioAttribute(this.preserveAspectRatio), width = this._element.width, height = this._element.height, scale, pWidth = this.width, pHeight = this.height, parsedAttributes = { + width: pWidth, + height: pHeight + }; + if (pAR && (pAR.alignX !== "none" || pAR.alignY !== "none")) { + if (pAR.meetOrSlice === "meet") { + this.width = width; + this.height = height; + this.scaleX = this.scaleY = scale = fabric.util.findScaleToFit(this._element, parsedAttributes); + if (pAR.alignX === "Mid") { + this.left += (pWidth - width * scale) / 2; + } + if (pAR.alignX === "Max") { + this.left += pWidth - width * scale; + } + if (pAR.alignY === "Mid") { + this.top += (pHeight - height * scale) / 2; + } + if (pAR.alignY === "Max") { + this.top += pHeight - height * scale; + } + } + if (pAR.meetOrSlice === "slice") { + this.scaleX = this.scaleY = scale = fabric.util.findScaleToCover(this._element, parsedAttributes); + this.width = pWidth / scale; + this.height = pHeight / scale; + if (pAR.alignX === "Mid") { + this.cropX = (width - this.width) / 2; + } + if (pAR.alignX === "Max") { + this.cropX = width - this.width; + } + if (pAR.alignY === "Mid") { + this.cropY = (height - this.height) / 2; + } + if (pAR.alignY === "Max") { + this.cropY = height - this.height; + } + } + } else { + this.scaleX = pWidth / width; + this.scaleY = pHeight / height; + } } }); fabric.Image.CSS_CANVAS = "canvas-img"; @@ -9128,20 +9184,14 @@ fabric.util.object.extend(fabric.Object.prototype, { }; fabric.Image.ATTRIBUTE_NAMES = fabric.SHARED_ATTRIBUTES.concat("x y width height preserveAspectRatio xlink:href crossOrigin".split(" ")); fabric.Image.fromElement = function(element, callback, options) { - var parsedAttributes = fabric.parseAttributes(element, fabric.Image.ATTRIBUTE_NAMES), preserveAR; - if (parsedAttributes.preserveAspectRatio) { - preserveAR = fabric.util.parsePreserveAspectRatioAttribute(parsedAttributes.preserveAspectRatio); - extend(parsedAttributes, preserveAR); - } + var parsedAttributes = fabric.parseAttributes(element, fabric.Image.ATTRIBUTE_NAMES); fabric.Image.fromURL(parsedAttributes["xlink:href"], callback, extend(options ? fabric.util.object.clone(options) : {}, parsedAttributes)); }; - fabric.Image.async = true; - fabric.Image.pngCompression = 1; })(typeof exports !== "undefined" ? exports : this); fabric.util.object.extend(fabric.Object.prototype, { _getAngleValueForStraighten: function() { - var angle = this.getAngle() % 360; + var angle = this.angle % 360; if (angle > 0) { return Math.round((angle - 1) / 90) * 90; } @@ -9467,8 +9517,8 @@ fabric.Image.filters.BaseFilter = fabric.util.createClass({ } var attributeLocations = this.getAttributeLocations(gl, program); var uniformLocations = this.getUniformLocations(gl, program) || {}; - uniformLocations.uWidth = gl.getUniformLocation(program, "uWidth"); - uniformLocations.uHeight = gl.getUniformLocation(program, "uHeight"); + uniformLocations.uStepW = gl.getUniformLocation(program, "uStepW"); + uniformLocations.uStepH = gl.getUniformLocation(program, "uStepH"); return { program: program, attributeLocations: attributeLocations, @@ -9837,7 +9887,7 @@ fabric.Image.filters.BaseFilter.fromObject = function(object, callback) { var fabric = global.fabric || (global.fabric = {}), extend = fabric.util.object.extend, filters = fabric.Image.filters, createClass = fabric.util.createClass; filters.Noise = createClass(filters.BaseFilter, { type: "Noise", - fragmentSource: "precision highp float;\n" + "uniform sampler2D uTexture;\n" + "uniform float uHeight;\n" + "uniform float uNoise;\n" + "uniform float uSeed;\n" + "varying vec2 vTexCoord;\n" + "float rand(vec2 co, float seed, float vScale) {\n" + "return fract(sin(dot(co.xy * vScale ,vec2(12.9898 , 78.233))) * 43758.5453 * (seed + 0.01) / 2.0);\n" + "}\n" + "void main() {\n" + "vec4 color = texture2D(uTexture, vTexCoord);\n" + "color.rgb += (0.5 - rand(vTexCoord, uSeed, uHeight / 10.0)) * uNoise;\n" + "gl_FragColor = color;\n" + "}", + fragmentSource: "precision highp float;\n" + "uniform sampler2D uTexture;\n" + "uniform float uStepH;\n" + "uniform float uNoise;\n" + "uniform float uSeed;\n" + "varying vec2 vTexCoord;\n" + "float rand(vec2 co, float seed, float vScale) {\n" + "return fract(sin(dot(co.xy * vScale ,vec2(12.9898 , 78.233))) * 43758.5453 * (seed + 0.01) / 2.0);\n" + "}\n" + "void main() {\n" + "vec4 color = texture2D(uTexture, vTexCoord);\n" + "color.rgb += (0.5 - rand(vTexCoord, uSeed, 0.1 / uStepH)) * uNoise;\n" + "gl_FragColor = color;\n" + "}", mainParameter: "noise", noise: 0, applyTo2d: function(options) { @@ -9908,8 +9958,8 @@ fabric.Image.filters.BaseFilter.fromObject = function(object, callback) { getUniformLocations: function(gl, program) { return { uBlocksize: gl.getUniformLocation(program, "uBlocksize"), - uWidth: gl.getUniformLocation(program, "uWidth"), - uHeight: gl.getUniformLocation(program, "uHeight") + uStepW: gl.getUniformLocation(program, "uStepW"), + uStepH: gl.getUniformLocation(program, "uStepH") }; }, sendUniformData: function(gl, uniformLocations) { @@ -10099,6 +10149,7 @@ fabric.Image.filters.BaseFilter.fromObject = function(object, callback) { }, toObject: function() { return { + type: this.type, color: this.color, mode: this.mode, alpha: this.alpha @@ -10628,7 +10679,7 @@ fabric.Image.filters.BaseFilter.fromObject = function(object, callback) { return true; }, styleHas: function(property, lineIndex) { - if (!this.styles) { + if (!this.styles || !property || property === "") { return false; } if (typeof lineIndex !== "undefined" && !this.styles[lineIndex]) { @@ -10646,6 +10697,60 @@ fabric.Image.filters.BaseFilter.fromObject = function(object, callback) { } return false; }, + cleanStyle: function(property) { + if (!this.styles || !property || property === "") { + return false; + } + var obj = this.styles, stylesCount = 0, letterCount, foundStyle = false, style, canBeSwapped = true, graphemeCount = 0; + for (var p1 in obj) { + letterCount = 0; + for (var p2 in obj[p1]) { + stylesCount++; + if (!foundStyle) { + style = obj[p1][p2][property]; + foundStyle = true; + } else if (obj[p1][p2][property] !== style) { + canBeSwapped = false; + } + if (obj[p1][p2][property] === this[property]) { + delete obj[p1][p2][property]; + } + if (Object.keys(obj[p1][p2]).length !== 0) { + letterCount++; + } else { + delete obj[p1][p2]; + } + } + if (letterCount === 0) { + delete obj[p1]; + } + } + for (var i = 0; i < this._textLines.length; i++) { + graphemeCount += this._textLines[i].length; + } + if (canBeSwapped && stylesCount === graphemeCount) { + this[property] = style; + this.removeStyle(property); + } + }, + removeStyle: function(property) { + if (!this.styles || !property || property === "") { + return; + } + var obj = this.styles, line, lineNum, charNum; + for (lineNum in obj) { + var line = obj[lineNum]; + for (charNum in line) { + delete line[charNum][property]; + if (Object.keys(line[charNum]).length === 0) { + delete line[charNum]; + } + } + if (Object.keys(line).length === 0) { + delete obj[lineNum]; + } + } + }, _extendStyles: function(index, styles) { var loc = this.get2DCursorLocation(index); if (!this._getLineStyle(loc.lineIndex)) { @@ -11156,9 +11261,9 @@ fabric.Image.filters.BaseFilter.fromObject = function(object, callback) { }); fabric.Text.ATTRIBUTE_NAMES = fabric.SHARED_ATTRIBUTES.concat("x y dx dy font-family font-style font-weight font-size text-decoration text-anchor".split(" ")); fabric.Text.DEFAULT_SVG_FONT_SIZE = 16; - fabric.Text.fromElement = function(element, options) { + fabric.Text.fromElement = function(element, callback, options) { if (!element) { - return null; + return callback(null); } var parsedAttributes = fabric.parseAttributes(element, fabric.Text.ATTRIBUTE_NAMES); options = fabric.util.object.extend(options ? clone(options) : {}, parsedAttributes); @@ -11200,25 +11305,25 @@ fabric.Image.filters.BaseFilter.fromObject = function(object, callback) { textContent = element.textContent; } textContent = textContent.replace(/^\s+|\s+$|\n+/g, "").replace(/\s+/g, " "); - var text = new fabric.Text(textContent, options), textHeightScaleFactor = text.getHeight() / text.height, lineHeightDiff = (text.height + text.strokeWidth) * text.lineHeight - text.height, scaledDiff = lineHeightDiff * textHeightScaleFactor, textHeight = text.getHeight() + scaledDiff, offX = 0; + var text = new fabric.Text(textContent, options), textHeightScaleFactor = text.getScaledHeight() / text.height, lineHeightDiff = (text.height + text.strokeWidth) * text.lineHeight - text.height, scaledDiff = lineHeightDiff * textHeightScaleFactor, textHeight = text.getScaledHeight() + scaledDiff, offX = 0; if (text.originX === "center") { - offX = text.getWidth() / 2; + offX = text.getScaledWidth() / 2; } if (text.originX === "right") { - offX = text.getWidth(); + offX = text.getScaledWidth(); } text.set({ - left: text.getLeft() - offX, - top: text.getTop() - (textHeight - text.fontSize * (.18 + text._fontSizeFraction)) / text.lineHeight + left: text.left - offX, + top: text.top - (textHeight - text.fontSize * (.18 + text._fontSizeFraction)) / text.lineHeight }); text.originX = "left"; text.originY = "top"; - return text; + callback(text); }; - fabric.Text.fromObject = function(object, callback, forceAsync) { - return fabric.Object._fromObject("Text", object, callback, forceAsync, "text"); + fabric.Text.fromObject = function(object, callback) { + return fabric.Object._fromObject("Text", object, callback, "text"); }; - fabric.util.createAccessors(fabric.Text); + fabric.util.createAccessors && fabric.util.createAccessors(fabric.Text); })(typeof exports !== "undefined" ? exports : this); (function() { @@ -11298,7 +11403,7 @@ fabric.Image.filters.BaseFilter.fromObject = function(object, callback) { return this; }, initDimensions: function() { - this.abortCursorAnimation(); + this.isEditing && this.initDelayedCursor(); this.clearContextTop(); this.callSuper("initDimensions"); }, @@ -11458,7 +11563,7 @@ fabric.Image.filters.BaseFilter.fromObject = function(object, callback) { }; } }); - fabric.IText.fromObject = function(object, callback, forceAsync) { + fabric.IText.fromObject = function(object, callback) { parseDecoration(object); if (object.styles) { for (var i in object.styles) { @@ -11467,7 +11572,7 @@ fabric.Image.filters.BaseFilter.fromObject = function(object, callback) { } } } - return fabric.Object._fromObject("IText", object, callback, forceAsync, "text"); + fabric.Object._fromObject("IText", object, callback, "text"); }; })(); @@ -11690,7 +11795,7 @@ fabric.Image.filters.BaseFilter.fromObject = function(object, callback) { target: this }); this.initMouseMoveHandler(); - this.canvas.renderAll(); + this.canvas.requestRenderAll(); return this; }, exitEditingOnOthers: function(canvas) { @@ -12083,9 +12188,6 @@ fabric.util.object.extend(fabric.IText.prototype, { if (this.isTripleClick(newPointer, options.e)) { this.fire("tripleclick", options); this._stopEvent(options.e); - } else if (this.isDoubleClick(newPointer)) { - this.fire("dblclick", options); - this._stopEvent(options.e); } this.__lastLastClickTime = this.__lastClickTime; this.__lastClickTime = this.__newClickTime; @@ -12093,9 +12195,6 @@ fabric.util.object.extend(fabric.IText.prototype, { this.__lastIsEditing = this.isEditing; this.__lastSelected = this.selected; }, - isDoubleClick: function(newPointer) { - return this.__newClickTime - this.__lastClickTime < 500 && this.__lastPointer.x === newPointer.x && this.__lastPointer.y === newPointer.y && this.__lastIsEditing; - }, isTripleClick: function(newPointer) { return this.__newClickTime - this.__lastClickTime < 500 && this.__lastClickTime - this.__lastLastClickTime < 500 && this.__lastPointer.x === newPointer.x && this.__lastPointer.y === newPointer.y; }, @@ -12109,7 +12208,7 @@ fabric.util.object.extend(fabric.IText.prototype, { this.initClicks(); }, initClicks: function() { - this.on("dblclick", function(options) { + this.on("mousedblclick", function(options) { this.selectWord(this.getSelectionStartFromPointer(options.e)); }); this.on("tripleclick", function(options) { @@ -12217,6 +12316,7 @@ fabric.util.object.extend(fabric.IText.prototype, { this.hiddenTextarea.setAttribute("autocorrect", "off"); this.hiddenTextarea.setAttribute("autocomplete", "off"); this.hiddenTextarea.setAttribute("spellcheck", "false"); + this.hiddenTextarea.setAttribute("data-fabric-hiddentextarea", ""); var style = this._calcTextareaPosition(); this.hiddenTextarea.style.cssText = "white-space: nowrap; position: absolute; top: " + style.top + "; left: " + style.left + "; z-index: -999; opacity: 0; width: 1px; height: 1px; font-size: 1px;" + " line-height: 1px; paddingーtop: " + style.fontSize + ";"; fabric.document.body.appendChild(this.hiddenTextarea); @@ -12234,7 +12334,7 @@ fabric.util.object.extend(fabric.IText.prototype, { this._clickHandlerInitialized = true; } }, - _keysMap: { + keysMap: { 9: "exitEditing", 27: "exitEditing", 33: "moveCursorUp", @@ -12246,11 +12346,11 @@ fabric.util.object.extend(fabric.IText.prototype, { 39: "moveCursorRight", 40: "moveCursorDown" }, - _ctrlKeysMapUp: { + ctrlKeysMapUp: { 67: "copy", 88: "cut" }, - _ctrlKeysMapDown: { + ctrlKeysMapDown: { 65: "selectAll" }, onClick: function() { @@ -12260,10 +12360,10 @@ fabric.util.object.extend(fabric.IText.prototype, { if (!this.isEditing || this.inCompositionMode) { return; } - if (e.keyCode in this._keysMap) { - this[this._keysMap[e.keyCode]](e); - } else if (e.keyCode in this._ctrlKeysMapDown && (e.ctrlKey || e.metaKey)) { - this[this._ctrlKeysMapDown[e.keyCode]](e); + if (e.keyCode in this.keysMap) { + this[this.keysMap[e.keyCode]](e); + } else if (e.keyCode in this.ctrlKeysMapDown && (e.ctrlKey || e.metaKey)) { + this[this.ctrlKeysMapDown[e.keyCode]](e); } else { return; } @@ -12273,7 +12373,7 @@ fabric.util.object.extend(fabric.IText.prototype, { this.clearContextTop(); this.renderCursorOrSelection(); } else { - this.canvas && this.canvas.renderAll(); + this.canvas && this.canvas.requestRenderAll(); } }, onKeyUp: function(e) { @@ -12281,14 +12381,14 @@ fabric.util.object.extend(fabric.IText.prototype, { this._copyDone = false; return; } - if (e.keyCode in this._ctrlKeysMapUp && (e.ctrlKey || e.metaKey)) { - this[this._ctrlKeysMapUp[e.keyCode]](e); + if (e.keyCode in this.ctrlKeysMapUp && (e.ctrlKey || e.metaKey)) { + this[this.ctrlKeysMapUp[e.keyCode]](e); } else { return; } e.stopImmediatePropagation(); e.preventDefault(); - this.canvas && this.canvas.renderAll(); + this.canvas && this.canvas.requestRenderAll(); }, onInput: function(e) { var fromPaste = this.fromPaste; @@ -12306,7 +12406,7 @@ fabric.util.object.extend(fabric.IText.prototype, { this.canvas.fire("text:changed", { target: this }); - this.canvas.renderAll(); + this.canvas.requestRenderAll(); } } if (this.selectionStart !== this.selectionEnd) { @@ -12339,7 +12439,7 @@ fabric.util.object.extend(fabric.IText.prototype, { this.canvas.fire("text:changed", { target: this }); - this.canvas.renderAll(); + this.canvas.requestRenderAll(); } }, onCompositionStart: function() { @@ -12552,7 +12652,7 @@ fabric.util.object.extend(fabric.IText.prototype, { this.set("dirty", true); this.setSelectionEnd(this.selectionStart); this._removeExtraneousStyles(); - this.canvas && this.canvas.renderAll(); + this.canvas && this.canvas.requestRenderAll(); this.setCoords(); this.fire("changed"); this.canvas && this.canvas.fire("text:changed", { @@ -12696,12 +12796,10 @@ fabric.util.object.extend(fabric.IText.prototype, { minWidth: 20, dynamicMinWidth: 2, __cachedLines: null, - lockScalingY: true, lockScalingFlip: true, noScaleCache: false, initialize: function(text, options) { this.callSuper("initialize", text, options); - this.setControlsVisibility(fabric.Textbox.getTextboxControlVisibility()); this.ctx = this.objectCaching ? this._cacheContext : fabric.util.createCanvasElement().getContext("2d"); this._dimensionAffectingProps.push("width"); }, @@ -12709,7 +12807,7 @@ fabric.util.object.extend(fabric.IText.prototype, { if (this.__skipDimension) { return; } - this.initDelayedCursor(); + this.isEditing && this.initDelayedCursor(); this.clearContextTop(); this._clearCache(); this.dynamicMinWidth = 0; @@ -12849,13 +12947,6 @@ fabric.util.object.extend(fabric.IText.prototype, { newText.graphemeLines = graphemeLines; return newText; }, - setOnGroup: function(key, value) { - if (key === "scaleX") { - this.set("scaleX", Math.abs(1 / value)); - this.set("width", this.get("width") * value / (typeof this.__oldScaleX === "undefined" ? 1 : this.__oldScaleX)); - this.__oldScaleX = value; - } - }, getMinWidth: function() { return Math.max(this.minWidth, this.dynamicMinWidth); }, @@ -12863,21 +12954,8 @@ fabric.util.object.extend(fabric.IText.prototype, { return this.callSuper("toObject", [ "minWidth" ].concat(propertiesToInclude)); } }); - fabric.Textbox.fromObject = function(object, callback, forceAsync) { - return fabric.Object._fromObject("Textbox", object, callback, forceAsync, "text"); - }; - fabric.Textbox.getTextboxControlVisibility = function() { - return { - tl: false, - tr: false, - br: false, - bl: false, - ml: true, - mt: false, - mr: true, - mb: false, - mtr: true - }; + fabric.Textbox.fromObject = function(object, callback) { + return fabric.Object._fromObject("Textbox", object, callback, "text"); }; })(typeof exports !== "undefined" ? exports : this); @@ -12885,8 +12963,9 @@ fabric.util.object.extend(fabric.IText.prototype, { var setObjectScaleOverridden = fabric.Canvas.prototype._setObjectScale; fabric.Canvas.prototype._setObjectScale = function(localMouse, transform, lockScalingX, lockScalingY, by, lockScalingFlip, _dim) { var t = transform.target; - if (t instanceof fabric.Textbox) { - var w = t.width * (localMouse.x / transform.scaleX / (t.width + t.strokeWidth)); + if (by === "x" && t instanceof fabric.Textbox) { + var tw = t._getTransformedDimensions().x; + var w = t.width * (localMouse.x / tw); if (w >= t.getMinWidth()) { t.set("width", w); return true; @@ -12895,17 +12974,6 @@ fabric.util.object.extend(fabric.IText.prototype, { return setObjectScaleOverridden.call(fabric.Canvas.prototype, localMouse, transform, lockScalingX, lockScalingY, by, lockScalingFlip, _dim); } }; - fabric.Group.prototype._refreshControlsVisibility = function() { - if (typeof fabric.Textbox === "undefined") { - return; - } - for (var i = this._objects.length; i--; ) { - if (this._objects[i] instanceof fabric.Textbox) { - this.setControlsVisibility(fabric.Textbox.getTextboxControlVisibility()); - return; - } - } - }; fabric.util.object.extend(fabric.Textbox.prototype, { _removeExtraneousStyles: function() { for (var prop in this._styleMap) { @@ -13077,4 +13145,4 @@ if (typeof define === "function" && define.amd) { define([], function() { return fabric; }); -} +} \ No newline at end of file diff --git a/package.json b/package.json index 62b178b0a..f72922196 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "name": "fabric", "description": "Object model for HTML5 canvas, and SVG-to-canvas parser. Backed by jsdom and node-canvas.", "homepage": "http://fabricjs.com/", - "version": "2.0.0-beta.2", + "version": "2.0.0-beta.3", "author": "Juriy Zaytsev ", "contributors": [ {