diff --git a/CHANGELOG.md b/CHANGELOG.md index e6fa1d04..4f80ad66 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,20 @@ +**Version 1.6.1** + +- Fix: image with broken element throwing error on toObject() [#2878](https://github.com/kangax/fabric.js/pull/2878) +- Fix: Warning on trying to set proprietary browser version of ctxImageSmoothingEnabled [#2880](https://github.com/kangax/fabric.js/pull/2880) +- Fix: Fixed Svg import regression on color and drawing polylines [#2887](https://github.com/kangax/fabric.js/pull/2887) +- Fix: Fixed animation ease that starts and stop at same value [#2888](https://github.com/kangax/fabric.js/pull/2888) +- Fix: Allow a not stateful canvas to fire object:modified at end of transform. [#2890](https://github.com/kangax/fabric.js/pull/2890) +- Fix: Made event handler removal safer. Removing firing events will not cause errors. [#2883](https://github.com/kangax/fabric.js/pull/2883) +- Fix: Proper handling of perPixelTargetFind and multi selections [#2894](https://github.com/kangax/fabric.js/pull/2894) +- Fix: Do not clear contextTop on drawingMode, to allow drawing over animations [#2895](https://github.com/kangax/fabric.js/pull/2895) +- Change the dependencies to optional. Allow npm to continue installing if nodecanvas installation fail.[#2901](https://github.com/kangax/fabric.js/pull/2901) +- Fix: Check again the target on mouseup [#2902](https://github.com/kangax/fabric.js/pull/2902) +- Fix: On perPixelTargetFind detect corners only if target is active [#2903](https://github.com/kangax/fabric.js/pull/2903) +- Improvement: Add canvas mouseout event listener [#2907](https://github.com/kangax/fabric.js/pull/2907) +- Improvement: Make small object draggable easier [#2907](https://github.com/kangax/fabric.js/pull/2907) +- Improvement: Use sendToBack, bringToFront, bringForward, sendBackwards for multiple selections [#2908](https://github.com/kangax/fabric.js/pull/2908) + **Version 1.6.0** - Fix rendering of activeGroup objects while preserveObjectStacking is active. [ regression from [#2083](https://github.com/kangax/fabric.js/pull/2083) ] diff --git a/HEADER.js b/HEADER.js index 5376fd25..53fcfd16 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: "1.6.0" }; +var fabric = fabric || { version: "1.6.1" }; if (typeof exports !== 'undefined') { exports.fabric = fabric; } diff --git a/ISSUE_TEMPLATE.md b/ISSUE_TEMPLATE.md index fcc15adb..ac72aa0d 100644 --- a/ISSUE_TEMPLATE.md +++ b/ISSUE_TEMPLATE.md @@ -24,7 +24,7 @@ Remove the template from below and provide thoughtful commentary *and code sampl ## Version -1.6.0 +1.6.1 ## Test Case http://jsfiddle.net/fabricjs/Da7SP/ diff --git a/dist/fabric.js b/dist/fabric.js index 1528cbc5..31705dff 100644 --- a/dist/fabric.js +++ b/dist/fabric.js @@ -1,7 +1,7 @@ -/* build: `node build.js modules=ALL exclude=gestures,json minifier=uglifyjs` */ +/* build: `node build.js modules=ALL exclude=json,gestures minifier=uglifyjs` */ /*! Fabric.js Copyright 2008-2015, Printio (Juriy Zaytsev, Maxim Chernyak) */ -var fabric = fabric || { version: "1.6.0-rc.1" }; +var fabric = fabric || { version: "1.6.1" }; if (typeof exports !== 'undefined') { exports.fabric = fabric; } @@ -185,8 +185,8 @@ fabric.devicePixelRatio = fabric.window.devicePixelRatio || /** * @namespace fabric.Observable - * @tutorial {@link http://fabricjs.com/fabric-intro-part-2/#events} - * @see {@link http://fabricjs.com/events/|Events demo} + * @tutorial {@link http://fabricjs.com/fabric-intro-part-2#events} + * @see {@link http://fabricjs.com/events|Events demo} */ fabric.Observable = { observe: observe, @@ -5148,7 +5148,7 @@ fabric.ElementsParser.prototype.checkIfDone = function() { /** * Gradient class * @class fabric.Gradient - * @tutorial {@link http://fabricjs.com/fabric-intro-part-2/#gradients} + * @tutorial {@link http://fabricjs.com/fabric-intro-part-2#gradients} * @see {@link fabric.Gradient#initialize} for constructor definition */ fabric.Gradient = fabric.util.createClass(/** @lends fabric.Gradient.prototype */ { @@ -5499,8 +5499,8 @@ fabric.ElementsParser.prototype.checkIfDone = function() { /** * Pattern class * @class fabric.Pattern - * @see {@link http://fabricjs.com/patterns/|Pattern demo} - * @see {@link http://fabricjs.com/dynamic-patterns/|DynamicPattern demo} + * @see {@link http://fabricjs.com/patterns|Pattern demo} + * @see {@link http://fabricjs.com/dynamic-patterns|DynamicPattern demo} * @see {@link fabric.Pattern#initialize} for constructor definition */ fabric.Pattern = fabric.util.createClass(/** @lends fabric.Pattern.prototype */ { @@ -5680,7 +5680,7 @@ fabric.Pattern = fabric.util.createClass(/** @lends fabric.Pattern.prototype */ /** * Shadow class * @class fabric.Shadow - * @see {@link http://fabricjs.com/shadows/|Shadow demo} + * @see {@link http://fabricjs.com/shadows|Shadow demo} * @see {@link fabric.Shadow#initialize} for constructor definition */ fabric.Shadow = fabric.util.createClass(/** @lends fabric.Shadow.prototype */ { @@ -5872,7 +5872,7 @@ fabric.Pattern = fabric.util.createClass(/** @lends fabric.Pattern.prototype */ * @class fabric.StaticCanvas * @mixes fabric.Collection * @mixes fabric.Observable - * @see {@link http://fabricjs.com/static_canvas/|StaticCanvas demo} + * @see {@link http://fabricjs.com/static_canvas|StaticCanvas demo} * @see {@link fabric.StaticCanvas#initialize} for constructor definition * @fires before:render * @fires after:render @@ -7040,7 +7040,7 @@ fabric.Pattern = fabric.util.createClass(/** @lends fabric.Pattern.prototype */ * @param {String} [options.height] desired height of svg with or without units * @param {Function} [reviver] Method for further parsing of svg elements, called after each fabric object converted into svg representation. * @return {String} SVG string - * @tutorial {@link http://fabricjs.com/fabric-intro-part-3/#serialization} + * @tutorial {@link http://fabricjs.com/fabric-intro-part-3#serialization} * @see {@link http://jsfiddle.net/fabricjs/jQ3ZZ/|jsFiddle demo} * @example Normal SVG output * var svg = canvas.toSVG(); @@ -7199,47 +7199,97 @@ fabric.Pattern = fabric.util.createClass(/** @lends fabric.Pattern.prototype */ /* _TO_SVG_END_ */ /** - * Moves an object to the bottom of the stack of drawn objects + * Moves an object or the objects of a multiple selection + * to the bottom of the stack of drawn objects * @param {fabric.Object} object Object to send to back * @return {fabric.Canvas} thisArg * @chainable */ sendToBack: function (object) { - removeFromArray(this._objects, object); - this._objects.unshift(object); + if (!object) { + return this; + } + var activeGroup = this.getActiveGroup ? this.getActiveGroup() : null, + i, obj, objs; + if (object === activeGroup) { + objs = activeGroup._objects; + for (i = objs.length; i--;) { + obj = objs[i]; + removeFromArray(this._objects, obj); + this._objects.unshift(obj); + } + } + else { + removeFromArray(this._objects, object); + this._objects.unshift(object); + } return this.renderAll && this.renderAll(); }, /** - * Moves an object to the top of the stack of drawn objects + * Moves an object or the objects of a multiple selection + * to the top of the stack of drawn objects * @param {fabric.Object} object Object to send * @return {fabric.Canvas} thisArg * @chainable */ bringToFront: function (object) { - removeFromArray(this._objects, object); - this._objects.push(object); + if (!object) { + return this; + } + var activeGroup = this.getActiveGroup ? this.getActiveGroup() : null, + i, obj, objs; + if (object === activeGroup) { + objs = activeGroup._objects; + for (i = 0; i < objs.length; i++) { + obj = objs[i]; + removeFromArray(this._objects, obj); + this._objects.push(obj); + } + } + else { + removeFromArray(this._objects, object); + this._objects.push(object); + } return this.renderAll && this.renderAll(); }, /** - * Moves an object down in stack of drawn objects + * Moves an object or a selection down in stack of drawn objects * @param {fabric.Object} object Object to send * @param {Boolean} [intersecting] If `true`, send object behind next lower intersecting object * @return {fabric.Canvas} thisArg * @chainable */ sendBackwards: function (object, intersecting) { - var idx = this._objects.indexOf(object); - - // if object is not on the bottom of stack - if (idx !== 0) { - var newIdx = this._findNewLowerIndex(object, idx, intersecting); - - removeFromArray(this._objects, object); - this._objects.splice(newIdx, 0, object); - this.renderAll && this.renderAll(); + if (!object) { + return this; } + var activeGroup = this.getActiveGroup ? this.getActiveGroup() : null, + i, obj, idx, newIdx, objs; + + if (object === activeGroup) { + objs = activeGroup._objects; + for (i = 0; i < objs.length; i++) { + obj = objs[i]; + idx = this._objects.indexOf(obj); + if (idx !== 0) { + newIdx = idx - 1; + removeFromArray(this._objects, obj); + this._objects.splice(newIdx, 0, obj); + } + } + } + else { + idx = this._objects.indexOf(object); + if (idx !== 0) { + // if object is not on the bottom of stack + newIdx = this._findNewLowerIndex(object, idx, intersecting); + removeFromArray(this._objects, object); + this._objects.splice(newIdx, 0, object); + } + } + this.renderAll && this.renderAll(); return this; }, @@ -7273,23 +7323,41 @@ fabric.Pattern = fabric.util.createClass(/** @lends fabric.Pattern.prototype */ }, /** - * Moves an object up in stack of drawn objects + * Moves an object or a selection up in stack of drawn objects * @param {fabric.Object} object Object to send * @param {Boolean} [intersecting] If `true`, send object in front of next upper intersecting object * @return {fabric.Canvas} thisArg * @chainable */ bringForward: function (object, intersecting) { - var idx = this._objects.indexOf(object); - - // if object is not on top of stack (last item in an array) - if (idx !== this._objects.length - 1) { - var newIdx = this._findNewUpperIndex(object, idx, intersecting); - - removeFromArray(this._objects, object); - this._objects.splice(newIdx, 0, object); - this.renderAll && this.renderAll(); + if (!object) { + return this; } + var activeGroup = this.getActiveGroup ? this.getActiveGroup() : null, + i, obj, idx, newIdx, objs; + + if (object === activeGroup) { + objs = activeGroup._objects; + for (i = objs.length; i--;) { + obj = objs[i]; + idx = this._objects.indexOf(obj); + if (idx !== this._objects.length - 1) { + newIdx = idx + 1; + removeFromArray(this._objects, obj); + this._objects.splice(newIdx, 0, obj); + } + } + } + else { + idx = this._objects.indexOf(object); + if (idx !== this._objects.length - 1) { + // if object is not on top of stack (last item in an array) + newIdx = this._findNewUpperIndex(object, idx, intersecting); + removeFromArray(this._objects, object); + this._objects.splice(newIdx, 0, object); + } + } + this.renderAll && this.renderAll(); return this; }, @@ -7419,7 +7487,7 @@ fabric.Pattern = fabric.util.createClass(/** @lends fabric.Pattern.prototype */ * @function * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output * @return {String} JSON string - * @tutorial {@link http://fabricjs.com/fabric-intro-part-3/#serialization} + * @tutorial {@link http://fabricjs.com/fabric-intro-part-3#serialization} * @see {@link http://jsfiddle.net/fabricjs/pec86/|jsFiddle demo} * @example JSON without additional properties * var json = canvas.toJSON(); @@ -7437,7 +7505,7 @@ fabric.Pattern = fabric.util.createClass(/** @lends fabric.Pattern.prototype */ /** * BaseBrush class * @class fabric.BaseBrush - * @see {@link http://fabricjs.com/freedrawing/|Freedrawing demo} + * @see {@link http://fabricjs.com/freedrawing|Freedrawing demo} */ fabric.BaseBrush = fabric.util.createClass(/** @lends fabric.BaseBrush.prototype */ { @@ -8162,7 +8230,7 @@ fabric.PatternBrush = fabric.util.createClass(fabric.PencilBrush, /** @lends fab * Canvas class * @class fabric.Canvas * @extends fabric.StaticCanvas - * @tutorial {@link http://fabricjs.com/fabric-intro-part-1/#canvas} + * @tutorial {@link http://fabricjs.com/fabric-intro-part-1#canvas} * @see {@link fabric.Canvas#initialize} for constructor definition * * @fires object:modified @@ -8333,7 +8401,7 @@ fabric.PatternBrush = fabric.util.createClass(fabric.PencilBrush, /** @lends fab * When true, mouse events on canvas (mousedown/mousemove/mouseup) result in free drawing. * After mousedown, mousemove creates a shape, * and then mouseup finalizes it and adds an instance of `fabric.Path` onto canvas. - * @tutorial {@link http://fabricjs.com/fabric-intro-part-4/#free_drawing} + * @tutorial {@link http://fabricjs.com/fabric-intro-part-4#free_drawing} * @type Boolean * @default */ @@ -8454,20 +8522,27 @@ fabric.PatternBrush = fabric.util.createClass(fabric.PencilBrush, /** @lends fab */ isTargetTransparent: function (target, x, y) { var hasBorders = target.hasBorders, - transparentCorners = target.transparentCorners; + transparentCorners = target.transparentCorners, + ctx = this.contextCache, + shouldTransform = target.group && target.group === this.getActiveGroup(); target.hasBorders = target.transparentCorners = false; - target.render(this.contextCache); - target._renderControls(this.contextCache); + if (shouldTransform) { + ctx.save(); + ctx.transform.apply(ctx, target.group.calcTransformMatrix()); + } + target.render(ctx); + target.active && target._renderControls(ctx); target.hasBorders = hasBorders; target.transparentCorners = transparentCorners; var isTransparent = fabric.util.isTransparent( - this.contextCache, x, y, this.targetFindTolerance); + ctx, x, y, this.targetFindTolerance); + shouldTransform && ctx.restore(); - this.clearContext(this.contextCache); + this.clearContext(ctx); return isTransparent; }, @@ -9059,7 +9134,7 @@ fabric.PatternBrush = fabric.util.createClass(fabric.PencilBrush, /** @lends fab // first check current group (if one exists) var activeGroup = this.getActiveGroup(); - if (activeGroup && !skipGroup && this.containsPoint(e, activeGroup)) { + if (!skipGroup && this._checkTarget(e, activeGroup, this.getPointer(e, true))) { return activeGroup; } @@ -9479,6 +9554,7 @@ fabric.PatternBrush = fabric.util.createClass(fabric.PencilBrush, /** @lends fab } /** + * @ignore * @class fabric.Element * @alias fabric.Canvas * @deprecated Use {@link fabric.Canvas} instead. @@ -9534,6 +9610,7 @@ fabric.PatternBrush = fabric.util.createClass(fabric.PencilBrush, /** @lends fab addListener(this.upperCanvasEl, 'mousedown', this._onMouseDown); addListener(this.upperCanvasEl, 'mousemove', this._onMouseMove); addListener(this.upperCanvasEl, 'mousewheel', this._onMouseWheel); + addListener(this.upperCanvasEl, 'mouseout', this._onMouseOut); // touch events addListener(this.upperCanvasEl, 'touchstart', this._onMouseDown); @@ -9562,6 +9639,7 @@ fabric.PatternBrush = fabric.util.createClass(fabric.PencilBrush, /** @lends fab this._onLongPress = this._onLongPress.bind(this); this._onOrientationChange = this._onOrientationChange.bind(this); this._onMouseWheel = this._onMouseWheel.bind(this); + this._onMouseOut = this._onMouseOut.bind(this); }, /** @@ -9573,6 +9651,7 @@ fabric.PatternBrush = fabric.util.createClass(fabric.PencilBrush, /** @lends fab removeListener(this.upperCanvasEl, 'mousedown', this._onMouseDown); removeListener(this.upperCanvasEl, 'mousemove', this._onMouseMove); removeListener(this.upperCanvasEl, 'mousewheel', this._onMouseWheel); + removeListener(this.upperCanvasEl, 'mouseout', this._onMouseOut); removeListener(this.upperCanvasEl, 'touchstart', this._onMouseDown); removeListener(this.upperCanvasEl, 'touchmove', this._onMouseMove); @@ -9613,6 +9692,17 @@ fabric.PatternBrush = fabric.util.createClass(fabric.PencilBrush, /** @lends fab this.__onMouseWheel && this.__onMouseWheel(e, self); }, + /** + * @private + * @param {Event} e Event object fired on mousedown + */ + _onMouseOut: function(e) { + var target = this._hoveredTarget; + this.fire('mouse:out', { target: target, e: e }); + this._hoveredTarget = null; + target && target.fire('mouseout', { e: e }); + }, + /** * @private * @param {Event} [e] Event object fired on Event.js orientation change @@ -9739,21 +9829,20 @@ fabric.PatternBrush = fabric.util.createClass(fabric.PencilBrush, /** @lends fab * @param {Event} e Event object fired on mouseup */ __onMouseUp: function (e) { - var target; + var target, searchTarget = true, transform = this._currentTransform; if (this.isDrawingMode && this._isCurrentlyDrawing) { this._onMouseUpInDrawingMode(e); return; } - if (this._currentTransform) { + if (transform) { this._finalizeCurrentTransform(); - target = this._currentTransform.target; - } - else { - target = this.findTarget(e, true); + searchTarget = !transform.actionPerformed; } + target = searchTarget ? this.findTarget(e, true) : transform.target; + var shouldRender = this._shouldRender(target, this.getPointer(e)); this._maybeGroupObjects(e); @@ -9770,11 +9859,12 @@ fabric.PatternBrush = fabric.util.createClass(fabric.PencilBrush, /** @lends fab _handleCursorAndEvent: function(e, target) { this._setCursorFromEvent(e, target); + // Can't find any reason, disabling for now // TODO: why are we doing this? - var _this = this; + /* var _this = this; setTimeout(function () { _this._setCursorFromEvent(e, target); - }, 50); + }, 50); */ this.fire('mouse:up', { target: target, e: e }); target && target.fire('mouseup', { e: e }); @@ -9925,9 +10015,16 @@ fabric.PatternBrush = fabric.util.createClass(fabric.PencilBrush, /** @lends fab target = this.getActiveGroup(); } - if (target && target.selectable && (target.__corner || !shouldGroup)) { - this._beforeTransform(e, target); - this._setupCurrentTransform(e, target); + if (target) { + if (target.selectable && (target.__corner || !shouldGroup)) { + this._beforeTransform(e, target); + this._setupCurrentTransform(e, target); + } + + if (target !== this.getActiveGroup() && target !== this.getActiveObject()) { + this.deactivateAll(); + this.setActiveObject(target, e); + } } // we must renderAll so that active image is placed on the top canvas shouldRender && this.renderAll(); @@ -9947,10 +10044,6 @@ fabric.PatternBrush = fabric.util.createClass(fabric.PencilBrush, /** @lends fab this.onBeforeScaleRotate(target); } - if (target !== this.getActiveGroup() && target !== this.getActiveObject()) { - this.deactivateAll(); - this.setActiveObject(target, e); - } }, /** @@ -10666,7 +10759,7 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, /** @lends fabric.Stati * @param {Function} [reviver] Method for further parsing of JSON elements, called after each fabric object created. * @return {fabric.Canvas} instance * @chainable - * @tutorial {@link http://fabricjs.com/fabric-intro-part-3/#deserialization} + * @tutorial {@link http://fabricjs.com/fabric-intro-part-3#deserialization} */ loadFromDatalessJSON: function (json, callback, reviver) { return this.loadFromJSON(json, callback, reviver); @@ -10682,7 +10775,7 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, /** @lends fabric.Stati * @param {Function} [reviver] Method for further parsing of JSON elements, called after each fabric object created. * @return {fabric.Canvas} instance * @chainable - * @tutorial {@link http://fabricjs.com/fabric-intro-part-3/#deserialization} + * @tutorial {@link http://fabricjs.com/fabric-intro-part-3#deserialization} * @see {@link http://jsfiddle.net/fabricjs/fmgXt/|jsFiddle demo} * @example loadFromJSON * canvas.loadFromJSON(json, canvas.renderAll.bind(canvas)); @@ -10888,7 +10981,7 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, /** @lends fabric.Stati /** * Root object class from which all 2d shape classes inherit from * @class fabric.Object - * @tutorial {@link http://fabricjs.com/fabric-intro-part-1/#objects} + * @tutorial {@link http://fabricjs.com/fabric-intro-part-1#objects} * @see {@link fabric.Object#initialize} for constructor definition * * @fires added @@ -10903,6 +10996,8 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, /** @lends fabric.Stati * * @fires mousedown * @fires mouseup + * @fires mouseover + * @fires mouseout */ fabric.Object = fabric.util.createClass(/** @lends fabric.Object.prototype */ { @@ -13868,7 +13963,7 @@ fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prot * @param {String|Object} property Property to animate (if string) or properties to animate (if object) * @param {Number|Object} value Value to animate property to (if string was given first) or options object * @return {fabric.Object} thisArg - * @tutorial {@link http://fabricjs.com/fabric-intro-part-2/#animation} + * @tutorial {@link http://fabricjs.com/fabric-intro-part-2#animation} * @chainable * * As object — multiple properties @@ -15591,7 +15686,7 @@ fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prot * Path class * @class fabric.Path * @extends fabric.Object - * @tutorial {@link http://fabricjs.com/fabric-intro-part-1/#path_and_pathgroup} + * @tutorial {@link http://fabricjs.com/fabric-intro-part-1#path_and_pathgroup} * @see {@link fabric.Path#initialize} for constructor definition */ fabric.Path = fabric.util.createClass(fabric.Object, /** @lends fabric.Path.prototype */ { @@ -16543,7 +16638,7 @@ fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prot * Path group class * @class fabric.PathGroup * @extends fabric.Path - * @tutorial {@link http://fabricjs.com/fabric-intro-part-1/#path_and_pathgroup} + * @tutorial {@link http://fabricjs.com/fabric-intro-part-1#path_and_pathgroup} * @see {@link fabric.PathGroup#initialize} for constructor definition */ fabric.PathGroup = fabric.util.createClass(fabric.Path, /** @lends fabric.PathGroup.prototype */ { @@ -16833,7 +16928,7 @@ fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prot * @class fabric.Group * @extends fabric.Object * @mixes fabric.Collection - * @tutorial {@link http://fabricjs.com/fabric-intro-part-3/#groups} + * @tutorial {@link http://fabricjs.com/fabric-intro-part-3#groups} * @see {@link fabric.Group#initialize} for constructor definition */ fabric.Group = fabric.util.createClass(fabric.Object, fabric.Collection, /** @lends fabric.Group.prototype */ { @@ -17360,7 +17455,7 @@ fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prot * Image class * @class fabric.Image * @extends fabric.Object - * @tutorial {@link http://fabricjs.com/fabric-intro-part-1/#images} + * @tutorial {@link http://fabricjs.com/fabric-intro-part-1#images} * @see {@link fabric.Image#initialize} for constructor definition */ fabric.Image = fabric.util.createClass(fabric.Object, /** @lends fabric.Image.prototype */ { @@ -18064,8 +18159,8 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, /** @lends fabric.Stati /** * @namespace fabric.Image.filters * @memberOf fabric.Image - * @tutorial {@link http://fabricjs.com/fabric-intro-part-2/#image_filters} - * @see {@link http://fabricjs.com/image-filters/|ImageFilters demo} + * @tutorial {@link http://fabricjs.com/fabric-intro-part-2#image_filters} + * @see {@link http://fabricjs.com/image-filters|ImageFilters demo} */ fabric.Image.filters = fabric.Image.filters || { }; @@ -18135,7 +18230,7 @@ fabric.Image.filters.BaseFilter = fabric.util.createClass(/** @lends fabric.Imag * @memberOf fabric.Image.filters * @extends fabric.Image.filters.BaseFilter * @see {@link fabric.Image.filters.Brightness#initialize} for constructor definition - * @see {@link http://fabricjs.com/image-filters/|ImageFilters demo} + * @see {@link http://fabricjs.com/image-filters|ImageFilters demo} * @example * var filter = new fabric.Image.filters.Brightness({ * brightness: 200 @@ -18219,7 +18314,7 @@ fabric.Image.filters.BaseFilter = fabric.util.createClass(/** @lends fabric.Imag * @memberOf fabric.Image.filters * @extends fabric.Image.filters.BaseFilter * @see {@link fabric.Image.filters.Convolute#initialize} for constructor definition - * @see {@link http://fabricjs.com/image-filters/|ImageFilters demo} + * @see {@link http://fabricjs.com/image-filters|ImageFilters demo} * @example Sharpen filter * var filter = new fabric.Image.filters.Convolute({ * matrix: [ 0, -1, 0, @@ -18377,7 +18472,7 @@ fabric.Image.filters.BaseFilter = fabric.util.createClass(/** @lends fabric.Imag * @memberOf fabric.Image.filters * @extends fabric.Image.filters.BaseFilter * @see {@link fabric.Image.filters.GradientTransparency#initialize} for constructor definition - * @see {@link http://fabricjs.com/image-filters/|ImageFilters demo} + * @see {@link http://fabricjs.com/image-filters|ImageFilters demo} * @example * var filter = new fabric.Image.filters.GradientTransparency({ * threshold: 200 @@ -18458,7 +18553,7 @@ fabric.Image.filters.BaseFilter = fabric.util.createClass(/** @lends fabric.Imag * @class fabric.Image.filters.Grayscale * @memberOf fabric.Image.filters * @extends fabric.Image.filters.BaseFilter - * @see {@link http://fabricjs.com/image-filters/|ImageFilters demo} + * @see {@link http://fabricjs.com/image-filters|ImageFilters demo} * @example * var filter = new fabric.Image.filters.Grayscale(); * object.filters.push(filter); @@ -18521,7 +18616,7 @@ fabric.Image.filters.BaseFilter = fabric.util.createClass(/** @lends fabric.Imag * @class fabric.Image.filters.Invert * @memberOf fabric.Image.filters * @extends fabric.Image.filters.BaseFilter - * @see {@link http://fabricjs.com/image-filters/|ImageFilters demo} + * @see {@link http://fabricjs.com/image-filters|ImageFilters demo} * @example * var filter = new fabric.Image.filters.Invert(); * object.filters.push(filter); @@ -18689,7 +18784,7 @@ fabric.Image.filters.BaseFilter = fabric.util.createClass(/** @lends fabric.Imag * @memberOf fabric.Image.filters * @extends fabric.Image.filters.BaseFilter * @see {@link fabric.Image.filters.Noise#initialize} for constructor definition - * @see {@link http://fabricjs.com/image-filters/|ImageFilters demo} + * @see {@link http://fabricjs.com/image-filters|ImageFilters demo} * @example * var filter = new fabric.Image.filters.Noise({ * noise: 700 @@ -18776,7 +18871,7 @@ fabric.Image.filters.BaseFilter = fabric.util.createClass(/** @lends fabric.Imag * @memberOf fabric.Image.filters * @extends fabric.Image.filters.BaseFilter * @see {@link fabric.Image.filters.Pixelate#initialize} for constructor definition - * @see {@link http://fabricjs.com/image-filters/|ImageFilters demo} + * @see {@link http://fabricjs.com/image-filters|ImageFilters demo} * @example * var filter = new fabric.Image.filters.Pixelate({ * blocksize: 8 @@ -18888,7 +18983,7 @@ fabric.Image.filters.BaseFilter = fabric.util.createClass(/** @lends fabric.Imag * @memberOf fabric.Image.filters * @extends fabric.Image.filters.BaseFilter * @see {@link fabric.Image.filters.RemoveWhite#initialize} for constructor definition - * @see {@link http://fabricjs.com/image-filters/|ImageFilters demo} + * @see {@link http://fabricjs.com/image-filters|ImageFilters demo} * @example * var filter = new fabric.Image.filters.RemoveWhite({ * threshold: 40, @@ -18988,7 +19083,7 @@ fabric.Image.filters.BaseFilter = fabric.util.createClass(/** @lends fabric.Imag * @class fabric.Image.filters.Sepia * @memberOf fabric.Image.filters * @extends fabric.Image.filters.BaseFilter - * @see {@link http://fabricjs.com/image-filters/|ImageFilters demo} + * @see {@link http://fabricjs.com/image-filters|ImageFilters demo} * @example * var filter = new fabric.Image.filters.Sepia(); * object.filters.push(filter); @@ -19048,7 +19143,7 @@ fabric.Image.filters.BaseFilter = fabric.util.createClass(/** @lends fabric.Imag * @class fabric.Image.filters.Sepia2 * @memberOf fabric.Image.filters * @extends fabric.Image.filters.BaseFilter - * @see {@link http://fabricjs.com/image-filters/|ImageFilters demo} + * @see {@link http://fabricjs.com/image-filters|ImageFilters demo} * @example * var filter = new fabric.Image.filters.Sepia2(); * object.filters.push(filter); @@ -19114,7 +19209,7 @@ fabric.Image.filters.BaseFilter = fabric.util.createClass(/** @lends fabric.Imag * @memberOf fabric.Image.filters * @extends fabric.Image.filters.BaseFilter * @see {@link fabric.Image.filters.Tint#initialize} for constructor definition - * @see {@link http://fabricjs.com/image-filters/|ImageFilters demo} + * @see {@link http://fabricjs.com/image-filters|ImageFilters demo} * @example Tint filter with hex color and opacity * var filter = new fabric.Image.filters.Tint({ * color: '#3513B0', @@ -19467,7 +19562,7 @@ fabric.Image.filters.BaseFilter = fabric.util.createClass(/** @lends fabric.Imag * @class fabric.Image.filters.Resize * @memberOf fabric.Image.filters * @extends fabric.Image.filters.BaseFilter - * @see {@link http://fabricjs.com/image-filters/|ImageFilters demo} + * @see {@link http://fabricjs.com/image-filters|ImageFilters demo} * @example * var filter = new fabric.Image.filters.Resize(); * object.filters.push(filter); @@ -19812,7 +19907,7 @@ fabric.Image.filters.BaseFilter = fabric.util.createClass(/** @lends fabric.Imag * @class fabric.Text * @extends fabric.Object * @return {fabric.Text} thisArg - * @tutorial {@link http://fabricjs.com/fabric-intro-part-2/#text} + * @tutorial {@link http://fabricjs.com/fabric-intro-part-2#text} * @see {@link fabric.Text#initialize} for constructor definition */ fabric.Text = fabric.util.createClass(fabric.Object, /** @lends fabric.Text.prototype */ { diff --git a/dist/fabric.min.js b/dist/fabric.min.js index b749434a..27a14cde 100644 --- a/dist/fabric.min.js +++ b/dist/fabric.min.js @@ -1,12 +1,11 @@ -var fabric=fabric||{version:"1.6.0-rc.1"};"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(""),fabric.window=fabric.document.createWindow?fabric.document.createWindow():fabric.document.parentWindow),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.devicePixelRatio=fabric.window.devicePixelRatio||fabric.window.webkitDevicePixelRatio||fabric.window.mozDevicePixelRatio||1,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;n>r;r++)i[r]&&i[r].call(this,e||{});return this.__eventListeners[t]=i.filter(function(t){return t!==!1}),this}}}fabric.Observable={observe:e,stopObserving:i,fire:r,on:e,off:i,trigger:r}}(),fabric.Collection={add:function(){this._objects.push.apply(this._objects,arguments);for(var t=0,e=arguments.length;e>t;t++)this._onObjectAdded(arguments[t]);return this.renderOnAddRemove&&this.renderAll(),this},insertAt:function(t,e,i){var r=this.getObjects();return i?r[e]=t:r.splice(e,0,t),this._onObjectAdded(t),this.renderOnAddRemove&&this.renderAll(),this},remove:function(){for(var t,e=this.getObjects(),i=0,r=arguments.length;r>i;i++)t=e.indexOf(arguments[i]),-1!==t&&(e.splice(t,1),this._onObjectRemoved(arguments[i]));return this.renderOnAddRemove&&this.renderAll(),this},forEachObject:function(t,e){for(var i=this.getObjects(),r=i.length;r--;)t.call(e,i[r],r,i);return this},getObjects:function(t){return"undefined"==typeof t?this._objects:this._objects.filter(function(e){return e.type===t})},item:function(t){return this.getObjects()[t]},isEmpty:function(){return 0===this.getObjects().length},size:function(){return this.getObjects().length},contains:function(t){return this.getObjects().indexOf(t)>-1},complexity:function(){return this.getObjects().reduce(function(t,e){return t+=e.complexity?e.complexity():0},0)}},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-1!==i&&t.splice(i,1),t},getRandomInt:function(t,e){return Math.floor(Math.random()*(e-t+1))+t},degreesToRadians:function(t){return t*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;for(var i=e.split("."),r=i.length,n=t||fabric.window,s=0;r>s;++s)n=n[i[s]];return n},loadImage:function(t,e,i,r){if(!t)return void(e&&e.call(i,t));var n=fabric.util.createImage();n.onload=function(){e&&e.call(i,n),n=n.onload=n.onerror=null},n.onerror=function(){fabric.log("Error loading "+n.src),e&&e.call(i,null,!0),n=n.onload=n.onerror=null},0!==t.indexOf("data")&&r&&(n.crossOrigin=r),n.src=t},enlivenObjects:function(t,e,i,r){function n(){++o===a&&e&&e(s)}t=t||[];var s=[],o=0,a=t.length;return a?void t.forEach(function(t,e){if(!t||!t.type)return void n();var o=fabric.util.getKlass(t.type,i);o.async?o.fromObject(t,function(i,o){o||(s[e]=i,r&&r(t,s[e])),n()}):(s[e]=o.fromObject(t),r&&r(t,s[e]),n())}):void(e&&e(s))},groupSVGElements:function(t,e,i){var r;return r=new fabric.PathGroup(t,e),"undefined"!=typeof i&&r.setSourcePath(i),r},populateWithProperties:function(t,e,i){if(i&&"[object Array]"===Object.prototype.toString.call(i))for(var r=0,n=i.length;n>r;r++)i[r]in t&&(e[i[r]]=t[i[r]])},drawDashedLine:function(t,r,n,s,o,a){var h=s-r,c=o-n,l=e(h*h+c*c),u=i(c,h),f=a.length,d=0,g=!0;for(t.save(),t.translate(r,n),t.moveTo(0,0),t.rotate(u),r=0;l>r;)r+=a[d++%f],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.getContext||"undefined"==typeof G_vmlCanvasManager||G_vmlCanvasManager.initElement(t),t},createImage:function(){return fabric.isLikelyNode?new(require("canvas").Image):fabric.document.createElement("img")},createAccessors:function(t){for(var e=t.prototype,i=e.stateProperties.length;i--;){var r=e.stateProperties[i],n=r.charAt(0).toUpperCase()+r.slice(1),s="set"+n,o="get"+n;e[o]||(e[o]=function(t){return new Function('return this.get("'+t+'")')}(r)),e[s]||(e[s]=function(t){return new Function("value",'return this.set("'+t+'", value)')}(r))}},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);for(var n=!0,s=t.getImageData(e,i,2*r||1,2*r||1),o=3,a=s.data.length;a>o;o+=4){var h=s.data[o];if(n=0>=h,n===!1)break}return s=null,n},parsePreserveAspectRatioAttribute:function(t){var e,i="meet",r="Mid",n="Mid",s=t.split(" ");return s&&s.length&&(i=s.pop(),"meet"!==i&&"slice"!==i?(e=i,i="meet"):s.length&&(e=s.pop())),r="none"!==e?e.slice(1,4):"none",n="none"!==e?e.slice(5,8):"none",{meetOrSlice:i,alignX:r,alignY:n}}}}("undefined"!=typeof exports?exports:this),function(){function t(t,r,s,o,h,c,l){var u=a.call(arguments);if(n[u])return n[u];var f=Math.PI,d=l*f/180,g=Math.sin(d),p=Math.cos(d),v=0,m=0;s=Math.abs(s),o=Math.abs(o);var b=-p*t*.5-g*r*.5,y=-p*r*.5+g*t*.5,_=s*s,x=o*o,S=y*y,C=b*b,w=_*x-_*S-x*C,O=0;if(0>w){var T=Math.sqrt(1-w/(_*x));s*=T,o*=T}else O=(h===c?-1:1)*Math.sqrt(w/(_*S+x*C));var k=O*s*y/o,j=-O*o*b/s,A=p*k-g*j+.5*t,P=g*k+p*j+.5*r,M=i(1,0,(b-k)/s,(y-j)/o),L=i((b-k)/s,(y-j)/o,(-b-k)/s,(-y-j)/o);0===c&&L>0?L-=2*f:1===c&&0>L&&(L+=2*f);for(var D=Math.ceil(Math.abs(L/f*2)),E=[],I=L/D,R=8/3*Math.sin(I/4)*Math.sin(I/4)/Math.sin(I/2),F=M+I,B=0;D>B;B++)E[B]=e(M,F,p,g,s,o,A,P,R,v,m),v=E[B][4],m=E[B][5],M=F,F+=I;return n[u]=E,E}function e(t,e,i,r,n,o,h,c,l,u,f){var d=a.call(arguments);if(s[d])return s[d];var g=Math.cos(t),p=Math.sin(t),v=Math.cos(e),m=Math.sin(e),b=i*n*v-r*o*m+h,y=r*n*v+i*o*m+c,_=u+l*(-i*n*p-r*o*g),x=f+l*(-r*n*p+i*o*g),S=b+l*(i*n*m+r*o*v),C=y+l*(r*n*m-i*o*v);return s[d]=[_,x,S,C,b,y],s[d]}function i(t,e,i,r){var n=Math.atan2(e,t),s=Math.atan2(r,i);return s>=n?s-n:2*Math.PI-(n-s)}function 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,y=Math.sqrt,_=Math.min,x=Math.max,S=Math.abs,C=[],w=[[],[]];f=6*t-12*i+6*n,u=-3*t+9*i-9*n+3*h,d=3*i-3*t;for(var O=0;2>O;++O)if(O>0&&(f=6*e-12*r+6*s,u=-3*e+9*r-9*s+3*c,d=3*r-3*e),S(u)<1e-12){if(S(f)<1e-12)continue;g=-d/f,g>0&&1>g&&C.push(g)}else m=f*f-4*d*u,0>m||(b=y(m),p=(-f+b)/(2*u),p>0&&1>p&&C.push(p),v=(-f-b)/(2*u),v>0&&1>v&&C.push(v));for(var T,k,j,A=C.length,P=A;A--;)g=C[A],j=1-g,T=j*j*j*t+3*j*j*g*i+3*j*g*g*n+g*g*g*h,w[0][A]=T,k=j*j*j*e+3*j*j*g*r+3*j*g*g*s+g*g*g*c,w[1][A]=k;w[0][P]=t,w[1][P]=e,w[0][P+1]=h,w[1][P+1]=c;var M=[{x:_.apply(null,w[0]),y:_.apply(null,w[1])},{x:x.apply(null,w[0]),y:x.apply(null,w[1])}];return o[l]=M,M}var n={},s={},o={},a=Array.prototype.join;fabric.util.drawArc=function(e,i,r,n){for(var s=n[0],o=n[1],a=n[2],h=n[3],c=n[4],l=n[5],u=n[6],f=[[],[],[],[]],d=t(l-i,u-r,s,o,h,c,a),g=0,p=d.length;p>g;g++)f[g][0]=d[g][0]+i,f[g][1]=d[g][1]+r,f[g][2]=d[g][2]+i,f[g][3]=d[g][3]+r,f[g][4]=d[g][4]+i,f[g][5]=d[g][5]+r,e.bezierCurveTo.apply(e,f[g])},fabric.util.getBoundsOfArc=function(e,i,n,s,o,a,h,c,l){for(var u=0,f=0,d=[],g=[],p=t(c-e,l-i,n,s,a,h,o),v=[[],[]],m=0,b=p.length;b>m;m++)d=r(u,f,p[m][0],p[m][1],p[m][2],p[m][3],p[m][4],p[m][5]),v[0].x=d[0].x+e,v[0].y=d[0].y+i,v[1].x=d[1].x+e,v[1].y=d[1].y+i,g.push(v[0]),g.push(v[1]),u=p[m][4],f=p[m][5];return g},fabric.util.getBoundsOfCurve=r}(),function(){function t(t,e){for(var i=s.call(arguments,2),r=[],n=0,o=t.length;o>n;n++)r[n]=i.length?t[n][e].apply(t[n],i):t[n][e].call(t[n]);return r}function e(t,e){return n(t,e,function(t,e){return t>=e})}function i(t,e){return n(t,e,function(t,e){return e>t})}function r(t,e){for(var i=t.length;i--;)t[i]=e;return t}function n(t,e,i){if(t&&0!==t.length){var r=t.length-1,n=e?t[r][e]:t[r];if(e)for(;r--;)i(t[r][e],n)&&(n=t[r][e]);else for(;r--;)i(t[r],n)&&(n=t[r]);return n}}var s=Array.prototype.slice;Array.prototype.indexOf||(Array.prototype.indexOf=function(t){if(void 0===this||null===this)throw new TypeError;var e=Object(this),i=e.length>>>0;if(0===i)return-1;var r=0;if(arguments.length>0&&(r=Number(arguments[1]),r!==r?r=0:0!==r&&r!==Number.POSITIVE_INFINITY&&r!==Number.NEGATIVE_INFINITY&&(r=(r>0||-1)*Math.floor(Math.abs(r)))),r>=i)return-1;for(var n=r>=0?r:Math.max(i-Math.abs(r),0);i>n;n++)if(n in e&&e[n]===t)return n;return-1}),Array.prototype.forEach||(Array.prototype.forEach=function(t,e){for(var i=0,r=this.length>>>0;r>i;i++)i in this&&t.call(e,this[i],i,this)}),Array.prototype.map||(Array.prototype.map=function(t,e){for(var i=[],r=0,n=this.length>>>0;n>r;r++)r in this&&(i[r]=t.call(e,this[r],r,this));return i}),Array.prototype.every||(Array.prototype.every=function(t,e){for(var i=0,r=this.length>>>0;r>i;i++)if(i in this&&!t.call(e,this[i],i,this))return!1;return!0}),Array.prototype.some||(Array.prototype.some=function(t,e){for(var i=0,r=this.length>>>0;r>i;i++)if(i in this&&t.call(e,this[i],i,this))return!0;return!1}),Array.prototype.filter||(Array.prototype.filter=function(t,e){for(var i,r=[],n=0,s=this.length>>>0;s>n;n++)n in this&&(i=this[n],t.call(e,i,n,this)&&r.push(i));return r}),Array.prototype.reduce||(Array.prototype.reduce=function(t){var e,i=this.length>>>0,r=0;if(arguments.length>1)e=arguments[1];else for(;;){if(r in this){e=this[r++];break}if(++r>=i)throw new TypeError}for(;i>r;r++)r in this&&(e=t.call(null,e,this[r],r,this));return e}),fabric.util.array={fill:r,invoke:t,min:i,max:e}}(),function(){function t(t,e){for(var i in e)t[i]=e[i];return t}function e(e){return t({},e)}fabric.util.object={extend:t,clone:e}}(),function(){function t(t){return t.replace(/-+(.)?/g,function(t,e){return e?e.toUpperCase():""})}function e(t,e){return t.charAt(0).toUpperCase()+(e?t.slice(1):t.slice(1).toLowerCase())}function i(t){return t.replace(/&/g,"&").replace(/"/g,""").replace(/'/g,"'").replace(//g,">")}String.prototype.trim||(String.prototype.trim=function(){return this.replace(/^[\s\xA0]+/,"").replace(/[\s\xA0]+$/,"")}),fabric.util.string={camelize:t,capitalize:e,escapeXml:i}}(),function(){var t=Array.prototype.slice,e=Function.prototype.apply,i=function(){};Function.prototype.bind||(Function.prototype.bind=function(r){var n,s=this,o=t.call(arguments,1);return n=o.length?function(){return e.call(s,this instanceof i?this:r,o.concat(t.call(arguments)))}:function(){return e.call(s,this instanceof i?this:r,arguments)},i.prototype=this.prototype,n.prototype=new i,n})}(),function(){function t(){}function e(t){var e=this.constructor.superclass.prototype[t];return arguments.length>1?e.apply(this,r.call(arguments,1)):e.call(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;c>h;h++)o(i,a[h],s);return i.prototype.initialize||(i.prototype.initialize=n),i.prototype.constructor=i,i.prototype.callSuper=e,i}var r=Array.prototype.slice,n=function(){},s=function(){for(var t in{toString:1})if("toString"===t)return!1;return!0}(),o=function(t,e,i){for(var r in e)t.prototype[r]=r in t.prototype&&"function"==typeof t.prototype[r]&&(e[r]+"").indexOf("callSuper")>-1?function(t){return function(){var r=this.constructor.superclass;this.constructor.superclass=i;var n=e[t].apply(this,arguments);return this.constructor.superclass=r,"initialize"!==t?n:void 0}}(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;n>i;i++)if(e=typeof t[r[i]],!/^(?:function|object|unknown)$/.test(e))return!1;return!0}function e(t,e){return{handler:e,wrappedHandler:i(t,e)}}function i(t,e){return function(i){e.call(o(t),i||fabric.window.event)}}function r(t,e){return function(i){if(p[t]&&p[t][e])for(var r=p[t][e],n=0,s=r.length;s>n;n++)r[n].call(this,i||fabric.window.event)}}function n(t){t||(t=fabric.window.event);var e=t.target||(typeof t.srcElement!==h?t.srcElement:null),i=fabric.util.getScrollLeftTop(e);return{x:v(t)+i.left,y:m(t)+i.top}}function s(t,e,i){var r="touchend"===t.type?"changedTouches":"touches";return t[r]&&t[r][0]?t[r][0][e]-(t[r][0][e]-t[r][0][i])||t[i]:t[i]}var o,a,h="unknown",c=function(){var t=0;return function(e){return e.__uniqueID||(e.__uniqueID="uniqueID__"+t++)}}();!function(){var t={};o=function(e){return t[e]},a=function(e,i){t[e]=i}}();var l,u,f=t(fabric.document.documentElement,"addEventListener","removeEventListener")&&t(fabric.window,"addEventListener","removeEventListener"),d=t(fabric.document.documentElement,"attachEvent","detachEvent")&&t(fabric.window,"attachEvent","detachEvent"),g={},p={};f?(l=function(t,e,i){t.addEventListener(e,i,!1)},u=function(t,e,i){t.removeEventListener(e,i,!1)}):d?(l=function(t,i,r){var n=c(t);a(n,t),g[n]||(g[n]={}),g[n][i]||(g[n][i]=[]);var s=e(n,r);g[n][i].push(s),t.attachEvent("on"+i,s.wrappedHandler)},u=function(t,e,i){var r,n=c(t);if(g[n]&&g[n][e])for(var s=0,o=g[n][e].length;o>s;s++)r=g[n][e][s],r&&r.handler===i&&(t.detachEvent("on"+e,r.wrappedHandler),g[n][e][s]=null)}):(l=function(t,e,i){var n=c(t);if(p[n]||(p[n]={}),!p[n][e]){p[n][e]=[];var s=t["on"+e];s&&p[n][e].push(s),t["on"+e]=r(n,e)}p[n][e].push(i)},u=function(t,e,i){var r=c(t);if(p[r]&&p[r][e])for(var n=p[r][e],s=0,o=n.length;o>s;s++)n[s]===i&&n.splice(s,1)}),fabric.util.addListener=l,fabric.util.removeListener=u;var v=function(t){return typeof t.clientX!==h?t.clientX:0},m=function(t){return typeof t.clientY!==h?t.clientY:0};fabric.isTouchSupported&&(v=function(t){return s(t,"pageX","clientX")},m=function(t){return s(t,"pageY","clientY")}),fabric.util.getPointer=n,fabric.util.object.extend(fabric.util,fabric.Observable)}(),function(){function t(t,e){var i=t.style;if(!i)return t;if("string"==typeof e)return t.style.cssText+=";"+e,e.indexOf("opacity")>-1?s(t,e.match(/opacity:\s*(\d?\.?\d*)/)[1]):t;for(var r in e)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&&-1===(" "+t.className+" ").indexOf(" "+e+" ")&&(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(l(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(c){}o||(h=function(t){for(var e=new Array(t.length),i=t.length;i--;)e[i]=t[i];return e});var l;l=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=l}(),function(){function t(t,e){return t+(/\?/.test(t)?"&":"?")+e}function e(){}function i(i,n){n||(n={});var s,o=n.method?n.method.toUpperCase():"GET",a=n.onComplete||function(){},h=r();return h.onreadystatechange=function(){4===h.readyState&&(a(h),h.onreadystatechange=e)},"GET"===o&&(s=null,"string"==typeof n.parameters&&(i=t(i,n.parameters))),h.open(o,i,!0),("POST"===o||"PUT"===o)&&h.setRequestHeader("Content-Type","application/x-www-form-urlencoded"),h.send(s),h}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(r){}}();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 d(i){r=i||+new Date;var u=r>o?s:r-n;return h()?void(t.onComplete&&t.onComplete()):(a(c(u,l,f,s)),r>o?void(t.onComplete&&t.onComplete()):void e(d))}(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,r){return tt?i/2*t*t*t+e:i/2*((t-=2)*t*t+2)+e}function n(t,e,i,r){return i*(t/=r)*t*t*t+e}function s(t,e,i,r){return-i*((t=t/r-1)*t*t*t-1)+e}function o(t,e,i,r){return t/=r/2,1>t?i/2*t*t*t*t+e:-i/2*((t-=2)*t*t*t-2)+e}function a(t,e,i,r){return i*(t/=r)*t*t*t*t+e}function h(t,e,i,r){return i*((t=t/r-1)*t*t*t*t+1)+e}function c(t,e,i,r){return t/=r/2,1>t?i/2*t*t*t*t*t+e:i/2*((t-=2)*t*t*t*t+2)+e}function l(t,e,i,r){return-i*Math.cos(t/r*(Math.PI/2))+i+e}function u(t,e,i,r){return i*Math.sin(t/r*(Math.PI/2))+e}function f(t,e,i,r){return-i/2*(Math.cos(Math.PI*t/r)-1)+e}function d(t,e,i,r){return 0===t?e:i*Math.pow(2,10*(t/r-1))+e}function g(t,e,i,r){return t===r?e+i:i*(-Math.pow(2,-10*t/r)+1)+e}function p(t,e,i,r){return 0===t?e:t===r?e+i:(t/=r/2,1>t?i/2*Math.pow(2,10*(t-1))+e:i/2*(-Math.pow(2,-10*--t)+2)+e)}function v(t,e,i,r){return-i*(Math.sqrt(1-(t/=r)*t)-1)+e}function m(t,e,i,r){return i*Math.sqrt(1-(t=t/r-1)*t)+e}function b(t,e,i,r){return t/=r/2,1>t?-i/2*(Math.sqrt(1-t*t)-1)+e:i/2*(Math.sqrt(1-(t-=2)*t)+1)+e}function y(i,r,n,s){var o=1.70158,a=0,h=n;if(0===i)return r;if(i/=s,1===i)return r+n;a||(a=.3*s);var c=t(h,n,a,o);return-e(c,i,s)+r}function _(e,i,r,n){var s=1.70158,o=0,a=r;if(0===e)return i;if(e/=n,1===e)return i+r;o||(o=.3*n);var h=t(a,r,o,s);return h.a*Math.pow(2,-10*e)*Math.sin(2*(e*n-h.s)*Math.PI/h.p)+h.c+i}function x(i,r,n,s){var o=1.70158,a=0,h=n;if(0===i)return r;if(i/=s/2,2===i)return r+n;a||(a=.3*s*1.5);var c=t(h,n,a,o);return 1>i?-.5*e(c,i,s)+r:c.a*Math.pow(2,-10*(i-=1))*Math.sin(2*(i*s-c.s)*Math.PI/c.p)*.5+c.c+r}function S(t,e,i,r,n){return void 0===n&&(n=1.70158),i*(t/=r)*t*((n+1)*t-n)+e}function C(t,e,i,r,n){return void 0===n&&(n=1.70158),i*((t=t/r-1)*t*((n+1)*t+n)+1)+e}function w(t,e,i,r,n){return void 0===n&&(n=1.70158),t/=r/2,1>t?i/2*t*t*(((n*=1.525)+1)*t-n)+e:i/2*((t-=2)*t*(((n*=1.525)+1)*t+n)+2)+e}function O(t,e,i,r){return i-T(r-t,0,i,r)+e}function T(t,e,i,r){return(t/=r)<1/2.75?7.5625*i*t*t+e:2/2.75>t?i*(7.5625*(t-=1.5/2.75)*t+.75)+e:2.5/2.75>t?i*(7.5625*(t-=2.25/2.75)*t+.9375)+e:i*(7.5625*(t-=2.625/2.75)*t+.984375)+e}function k(t,e,i,r){return r/2>t?.5*O(2*t,0,i,r)+e:.5*T(2*t-r,0,i,r)+.5*i+e}fabric.util.ease={easeInQuad:function(t,e,i,r){return i*(t/=r)*t+e},easeOutQuad:function(t,e,i,r){return-i*(t/=r)*(t-2)+e},easeInOutQuad:function(t,e,i,r){return t/=r/2,1>t?i/2*t*t+e:-i/2*(--t*(t-2)-1)+e},easeInCubic:function(t,e,i,r){return i*(t/=r)*t*t+e},easeOutCubic:i,easeInOutCubic:r,easeInQuart:n,easeOutQuart:s,easeInOutQuart:o,easeInQuint:a,easeOutQuint:h,easeInOutQuint:c,easeInSine:l,easeOutSine:u,easeInOutSine:f,easeInExpo:d,easeOutExpo:g,easeInOutExpo:p,easeInCirc:v,easeOutCirc:m,easeInOutCirc:b,easeInElastic:y,easeOutElastic:_,easeInOutElastic:x,easeInBack:S,easeOutBack:C,easeInOutBack:w,easeInBounce:O,easeOutBounce:T,easeInOutBounce:k}}(),function(t){"use strict";function e(t){return t in T?T[t]:t}function i(t,e,i,r){var n,s="[object Array]"===Object.prototype.toString.call(e);return"fill"!==t&&"stroke"!==t||"none"!==e?"strokeDashArray"===t?e=e.replace(/,/g," ").split(/\s+/).map(function(t){return parseFloat(t)}):"transformMatrix"===t?e=i&&i.transformMatrix?x(i.transformMatrix,p.parseTransformAttribute(e)):p.parseTransformAttribute(e):"visible"===t?(e="none"===e||"hidden"===e?!1:!0,i&&i.visible===!1&&(e=!1)):"originX"===t?e="start"===e?"left":"end"===e?"right":"center":n=s?e.map(_):_(e,r):e="",!s&&isNaN(n)?e:n}function r(t){for(var e in k)if("undefined"!=typeof t[k[e]]&&""!==t[e]){if("undefined"==typeof t[e]){if(!p.Object.prototype[e])continue;t[e]=p.Object.prototype[e]}if(0!==t[e].indexOf("url(")){var i=new p.Color(t[e]);t[e]=i.setAlpha(y(i.getAlpha()*t[k[e]],2)).toRgba()}}return t}function n(t,r){var n,s;t.replace(/;\s*$/,"").split(";").forEach(function(t){var o=t.split(":");n=e(o[0].trim().toLowerCase()),s=i(n,o[1].trim()),r[n]=s})}function s(t,r){var n,s;for(var o in t)"undefined"!=typeof t[o]&&(n=e(o.toLowerCase()),s=i(n,t[o]),r[n]=s)}function o(t,e){var i={};for(var r in p.cssRules[e])if(a(t,r.split(" ")))for(var n in p.cssRules[e][r])i[n]=p.cssRules[e][r][n];return i}function a(t,e){var i,r=!0;return i=c(t,e.pop()),i&&e.length&&(r=h(t,e)),i&&r&&0===e.length}function h(t,e){for(var i,r=!0;t.parentNode&&1===t.parentNode.nodeType&&e.length;)r&&(i=e.pop()),t=t.parentNode,r=c(t,i);return 0===e.length}function c(t,e){var i,r=t.nodeName,n=t.getAttribute("class"),s=t.getAttribute("id");if(i=new RegExp("^"+r,"i"),e=e.replace(i,""),s&&e.length&&(i=new RegExp("#"+s+"(?![a-zA-Z\\-]+)","i"),e=e.replace(i,"")),n&&e.length){n=n.split(" ");for(var o=n.length;o--;)i=new RegExp("\\."+n[o]+"(?![a-zA-Z\\-]+)","i"),e=e.replace(i,"")}return 0===e.length}function l(t,e){var i;if(t.getElementById&&(i=t.getElementById(e)),i)return i;var r,n,s=t.getElementsByTagName("*");for(n=0;ns;s++)n=o.item(s),m.setAttribute(n.nodeName,n.nodeValue);for(;null!=g.firstChild;)m.appendChild(g.firstChild);g=m}for(s=0,o=h.attributes,a=o.length;a>s;s++)n=o.item(s),"x"!==n.nodeName&&"y"!==n.nodeName&&"xlink:href"!==n.nodeName&&("transform"===n.nodeName?p=n.nodeValue+" "+p:g.setAttribute(n.nodeName,n.nodeValue));g.setAttribute("transform",p),g.setAttribute("instantiated_by_use","1"),g.removeAttribute("id"),r=h.parentNode,r.replaceChild(g,h),e.length===v&&i++}}function f(t){var e,i,r,n,s=t.getAttribute("viewBox"),o=1,a=1,h=0,c=0,l=t.getAttribute("width"),u=t.getAttribute("height"),f=t.getAttribute("x")||0,d=t.getAttribute("y")||0,g=t.getAttribute("preserveAspectRatio")||"",v=!s||!C.test(t.tagName)||!(s=s.match(j)),m=!l||!u||"100%"===l||"100%"===u,b=v&&m,y={},x="";if(y.width=0,y.height=0,y.toBeParsed=b,b)return y;if(v)return y.width=_(l),y.height=_(u),y;if(h=-parseFloat(s[1]),c=-parseFloat(s[2]),e=parseFloat(s[3]),i=parseFloat(s[4]),m?(y.width=e,y.height=i):(y.width=_(l),y.height=_(u),o=y.width/e,a=y.height/i),g=p.util.parsePreserveAspectRatioAttribute(g),"none"!==g.alignX&&(a=o=o>a?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.tagName){for(n=t.ownerDocument.createElement("g");null!=t.firstChild;)n.appendChild(t.firstChild);t.appendChild(n)}else n=t,r=n.getAttribute("transform")+r;return n.setAttribute("transform",r),y}function d(t){var e=t.objects,i=t.options;return e=e.map(function(t){return p[m(t.type)].fromObject(t)}),{objects:e,options:i}}function g(t,e,i){e[i]&&e[i].toSVG&&t.push(' \n',' \n \n')}var p=t.fabric||(t.fabric={}),v=p.util.object.extend,m=p.util.string.capitalize,b=p.util.object.clone,y=p.util.toFixed,_=p.util.parseUnit,x=p.util.multiplyTransformMatrices,S=/^(path|circle|polygon|polyline|ellipse|rect|line|image|text)$/i,C=/^(symbol|image|marker|pattern|view|svg)$/i,w=/^(?:pattern|defs|symbol|metadata)$/i,O=/^(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"},k={stroke:"strokeOpacity",fill:"fillOpacity"};p.cssRules={},p.gradientDefs={},p.parseTransformAttribute=function(){function t(t,e){var i=e[0],r=3===e.length?e[1]:0,n=3===e.length?e[2]:0;t[0]=Math.cos(i),t[1]=Math.sin(i),t[2]=-Math.sin(i),t[3]=Math.cos(i),t[4]=r-(t[0]*r+t[2]*n),t[5]=n-(t[1]*r+t[3]*n)}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){t[2]=Math.tan(p.util.degreesToRadians(e[0]))}function r(t,e){t[1]=Math.tan(p.util.degreesToRadians(e[0]))}function n(t,e){t[4]=e[0],2===e.length&&(t[5]=e[1])}var s=[1,0,0,1,0,0],o=p.reNum,a="(?:\\s+,?\\s*|,\\s*)",h="(?:(skewX)\\s*\\(\\s*("+o+")\\s*\\))",c="(?:(skewY)\\s*\\(\\s*("+o+")\\s*\\))",l="(?:(rotate)\\s*\\(\\s*("+o+")(?:"+a+"("+o+")"+a+"("+o+"))?\\s*\\))",u="(?:(scale)\\s*\\(\\s*("+o+")(?:"+a+"("+o+"))?\\s*\\))",f="(?:(translate)\\s*\\(\\s*("+o+")(?:"+a+"("+o+"))?\\s*\\))",d="(?:(matrix)\\s*\\(\\s*("+o+")"+a+"("+o+")"+a+"("+o+")"+a+"("+o+")"+a+"("+o+")"+a+"("+o+")\\s*\\))",g="(?:"+d+"|"+f+"|"+u+"|"+l+"|"+h+"|"+c+")",v="(?:"+g+"(?:"+a+"*"+g+")*)",m="^\\s*(?:"+v+"?)\\s*$",b=new RegExp(m),y=new RegExp(g,"g"); - -return function(o){var a=s.concat(),h=[];if(!o||o&&!b.test(o))return a;o.replace(y,function(o){var c=new RegExp(g).exec(o).filter(function(t){return""!==t&&null!=t}),l=c[1],u=c.slice(2).map(parseFloat);switch(l){case"translate":n(a,u);break;case"rotate":u[0]=p.util.degreesToRadians(u[0]),t(a,u);break;case"scale":e(a,u);break;case"skewX":i(a,u);break;case"skewY":r(a,u);break;case"matrix":a=u}h.push(a.concat()),a=s.concat()});for(var c=h[0];h.length>1;)h.shift(),c=p.util.multiplyTransformMatrices(c,h[0]);return c}}();var j=new RegExp("^\\s*("+p.reNum+"+)\\s*,?\\s*("+p.reNum+"+)\\s*,?\\s*("+p.reNum+"+)\\s*,?\\s*("+p.reNum+"+)\\s*$");p.parseSVGDocument=function(){function t(t,e){for(;t&&(t=t.parentNode);)if(e.test(t.nodeName)&&!t.getAttribute("instantiated_by_use"))return!0;return!1}return function(e,i,r){if(e){u(e);var n=new Date,s=p.Object.__uid++,o=f(e),a=p.util.toArray(e.getElementsByTagName("*"));if(o.svgUid=s,0===a.length&&p.isLikelyNode){a=e.selectNodes('//*[name(.)!="svg"]');for(var h=[],c=0,l=a.length;l>c;c++)h[c]=a[c];a=h}var d=a.filter(function(e){return f(e),S.test(e.tagName)&&!t(e,w)});if(!d||d&&!d.length)return void(i&&i([],{}));p.gradientDefs[s]=p.getGradientDefs(e),p.cssRules[s]=p.getCSSRules(e),p.parseElements(d,function(t){p.documentParsingTime=new Date-n,i&&i(t,o)},b(o),r)}}}();var A={has:function(t,e){e(!1)},get:function(){},set:function(){}},P=new RegExp("(normal|italic)?\\s*(normal|small-caps)?\\s*(normal|bold|bolder|lighter|100|200|300|400|500|600|700|800|900)?\\s*("+p.reNum+"(?:px|cm|mm|em|pt|pc|in)*)(?:\\/(normal|"+p.reNum+"))?\\s+(.*)");v(p,{parseFontDeclaration:function(t,e){var i=t.match(P);if(i){var r=i[1],n=i[3],s=i[4],o=i[5],a=i[6];r&&(e.fontStyle=r),n&&(e.fontWeight=isNaN(parseFloat(n))?n:parseFloat(n)),s&&(e.fontSize=_(s)),a&&(e.fontFamily=a),o&&(e.lineHeight="normal"===o?1:o)}},getGradientDefs:function(t){var e,i,r,n,s=t.getElementsByTagName("linearGradient"),o=t.getElementsByTagName("radialGradient"),a=0,h=[],c={},l={};for(h.length=s.length+o.length,i=s.length;i--;)h[a++]=s[i];for(i=o.length;i--;)h[a++]=o[i];for(;a--;)e=h[a],n=e.getAttribute("xlink:href"),r=e.getAttribute("id"),n&&(l[r]=n.substr(1)),c[r]=e;for(r in l){var u=c[l[r]].cloneNode(!0);for(e=c[r];u.firstChild;)e.appendChild(u.firstChild)}return c},parseAttributes:function(t,n,s){if(t){var a,h,c={};"undefined"==typeof s&&(s=t.getAttribute("svgUid")),t.parentNode&&O.test(t.parentNode.nodeName)&&(c=p.parseAttributes(t.parentNode,n,s)),h=c&&c.fontSize||t.getAttribute("font-size")||p.Text.DEFAULT_SVG_FONT_SIZE;var l=n.reduce(function(r,n){return a=t.getAttribute(n),a&&(n=e(n),a=i(n,a,c,h),r[n]=a),r},{});return l=v(l,v(o(t,s),p.parseStyleAttribute(t))),l.font&&p.parseFontDeclaration(l.font,l),r(v(c,l))}},parseElements:function(t,e,i,r){new p.ElementsParser(t,e,i,r).parse()},parseStyleAttribute:function(t){var e={},i=t.getAttribute("style");return i?("string"==typeof i?n(i,e):s(i,e),e):e},parsePointsAttribute:function(t){if(!t)return null;t=t.replace(/,/g," ").trim(),t=t.split(/\s+/);var e,i,r=[];for(e=0,i=t.length;i>e;e+=2)r.push({x:parseFloat(t[e]),y:parseFloat(t[e+1])});return r},getCSSRules:function(t){for(var r,n=t.getElementsByTagName("style"),s={},o=0,a=n.length;a>o;o++){var h=n[o].textContent||n[o].text;h=h.replace(/\/\*[\s\S]*?\*\//g,""),""!==h.trim()&&(r=h.match(/[^{]*\{[\s\S]*?\}/g),r=r.map(function(t){return t.trim()}),r.forEach(function(t){for(var r=t.match(/([\s\S]*?)\s*\{([^}]*)\}/),n={},o=r[2].trim(),a=o.replace(/;$/,"").split(/\s*;\s*/),h=0,c=a.length;c>h;h++){var l=a[h].split(/\s*:\s*/),u=e(l[0]),f=i(u,l[1],l[0]);n[u]=f}t=r[1],t.split(",").forEach(function(t){t=t.replace(/^svg/i,"").trim(),""!==t&&(s[t]=p.util.object.clone(n))})}))}return s},loadSVGFromURL:function(t,e,i){function r(r){var n=r.responseXML;n&&!n.documentElement&&p.window.ActiveXObject&&r.responseText&&(n=new ActiveXObject("Microsoft.XMLDOM"),n.async="false",n.loadXML(r.responseText.replace(//i,""))),n&&n.documentElement&&p.parseSVGDocument(n.documentElement,function(i,r){A.set(t,{objects:p.util.array.invoke(i,"toObject"),options:r}),e(i,r)},i)}t=t.replace(/^\n\s*/,"").trim(),A.has(t,function(i){i?A.get(t,function(t){var i=d(t);e(i.objects,i.options)}):new p.util.request(t,{method:"get",onComplete:r})})},loadSVGFromString:function(t,e,i){t=t.trim();var r;if("undefined"!=typeof DOMParser){var n=new DOMParser;n&&n.parseFromString&&(r=n.parseFromString(t,"text/xml"))}else p.window.ActiveXObject&&(r=new ActiveXObject("Microsoft.XMLDOM"),r.async="false",r.loadXML(t.replace(//i,"")));p.parseSVGDocument(r.documentElement,function(t,i){e(t,i)},i)},createSVGFontFacesMarkup:function(t){for(var e,i,r,n,s,o,a,h="",c={},l=p.fontPaths,u=0,f=t.length;f>u;u++)if(e=t[u],i=e.fontFamily,-1!==e.type.indexOf("text")&&!c[i]&&l[i]&&(c[i]=!0,e.styles)){r=e.styles;for(s in r){o=r[s];for(a in n)o=n[a],i=o.fontFamily,!c[i]&&l[i]&&(c[i]=!0)}}for(var d in c)h+=[" @font-face {\n"," font-family: '",d,"';\n"," src: url('",l[d],"');\n"," }\n"].join("");return h&&(h=[' \n"].join("")),h},createSVGRefElementsMarkup:function(t){var e=[];return g(e,t,"backgroundColor"),g(e,t,"overlayColor"),e.join("")}})}("undefined"!=typeof exports?exports:this),fabric.ElementsParser=function(t,e,i,r){this.elements=t,this.callback=e,this.options=i,this.reviver=r,this.svgUid=i&&i.svgUid||0},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;e>t;t++)this.elements[t].setAttribute("svgUid",this.svgUid),function(t,e){setTimeout(function(){t.createObject(t.elements[e],e)},0)}(this,t)},fabric.ElementsParser.prototype.createObject=function(t,e){var i=fabric[fabric.util.string.capitalize(t.tagName)];if(i&&i.fromElement)try{this._createObject(i,t,e)}catch(r){fabric.log(r)}else this.checkIfDone()},fabric.ElementsParser.prototype._createObject=function(t,e,i){if(t.async)t.fromElement(e,this.createCallback(i,e),this.options);else{var r=t.fromElement(e,this.options);this.resolveGradient(r,"fill"),this.resolveGradient(r,"stroke"),this.reviver&&this.reviver(e,r),this.instances[i]=r,this.checkIfDone()}},fabric.ElementsParser.prototype.createCallback=function(t,e){var i=this;return function(r){i.resolveGradient(r,"fill"),i.resolveGradient(r,"stroke"),i.reviver&&i.reviver(e,r),i.instances[t]=r,i.checkIfDone()}},fabric.ElementsParser.prototype.resolveGradient=function(t,e){var i=t.get(e);if(/^url\(/.test(i)){var r=i.slice(5,i.length-1);fabric.gradientDefs[this.svgUid][r]&&t.set(e,fabric.Gradient.fromElement(fabric.gradientDefs[this.svgUid][r],t))}},fabric.ElementsParser.prototype.checkIfDone=function(){0===--this.numElements&&(this.instances=this.instances.filter(function(t){return null!=t}),this.callback(this.instances))},function(t){"use strict";function e(t,e){this.x=t,this.y=e}var i=t.fabric||(t.fabric={});return i.Point?void i.warn("fabric.Point is already defined"):(i.Point=e,void(e.prototype={constructor:e,add:function(t){return new e(this.x+t.x,this.y+t.y)},addEquals:function(t){return this.x+=t.x,this.y+=t.y,this},scalarAdd:function(t){return new e(this.x+t,this.y+t)},scalarAddEquals:function(t){return this.x+=t,this.y+=t,this},subtract:function(t){return new e(this.x-t.x,this.y-t.y)},subtractEquals:function(t){return this.x-=t.x,this.y-=t.y,this},scalarSubtract:function(t){return new e(this.x-t,this.y-t)},scalarSubtractEquals:function(t){return this.x-=t,this.y-=t,this},multiply:function(t){return new e(this.x*t,this.y*t)},multiplyEquals:function(t){return this.x*=t,this.y*=t,this},divide:function(t){return new e(this.x/t,this.y/t)},divideEquals:function(t){return this.x/=t,this.y/=t,this},eq:function(t){return this.x===t.x&&this.y===t.y},lt:function(t){return this.xt.x&&this.y>t.y},gte:function(t){return this.x>=t.x&&this.y>=t.y},lerp:function(t,i){return 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 new e(this.x+(t.x-this.x)/2,this.y+(t.y-this.y)/2)},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){this.x=t,this.y=e},setFromPoint:function(t){this.x=t.x,this.y=t.y},swap:function(t){var e=this.x,i=this.y;this.x=t.x,this.y=t.y,t.x=e,t.y=i}}))}("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={appendPoint:function(t){this.points.push(t)},appendPoints:function(t){this.points=this.points.concat(t)}},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;l>=0&&1>=l&&u>=0&&1>=u?(o=new e("Intersection"),o.points.push(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=new e,s=r.length,o=0;s>o;o++){var a=r[o],h=r[(o+1)%s],c=e.intersectLineLine(t,i,a,h);n.appendPoints(c.points)}return n.points.length>0&&(n.status="Intersection"),n},i.Intersection.intersectPolygonPolygon=function(t,i){for(var r=new e,n=t.length,s=0;n>s;s++){var o=t[s],a=t[(s+1)%n],h=e.intersectLinePolygon(o,a,i);r.appendPoints(h.points)}return r.points.length>0&&(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 0>i&&(i+=1),i>1&&(i-=1),1/6>i?t+6*(e-t)*i:.5>i?e:2/3>i?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;return t in e.colorNameMap&&(t=e.colorNameMap[t]),"transparent"===t?void this.setSource([255,255,255,0]):(i=e.sourceFromHex(t),i||(i=e.sourceFromRgb(t)),i||(i=e.sourceFromHsl(t)),void(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+(i>e?6:0);break;case e:n=(i-t)/c+2;break;case i:n=(t-e)/c+4}n/=6}return[Math.round(360*n),Math.round(100*s),Math.round(100*o)]},getSource:function(){return this._source},setSource:function(t){this._source=t},toRgb:function(){var t=this.getSource();return"rgb("+t[0]+","+t[1]+","+t[2]+")"},toRgba:function(){var t=this.getSource();return"rgba("+t[0]+","+t[1]+","+t[2]+","+t[3]+")"},toHsl:function(){var t=this.getSource(),e=this._rgbToHsl(t[0],t[1],t[2]);return"hsl("+e[0]+","+e[1]+"%,"+e[2]+"%)"},toHsla:function(){var t=this.getSource(),e=this._rgbToHsl(t[0],t[1],t[2]);return"hsla("+e[0]+","+e[1]+"%,"+e[2]+"%,"+t[3]+")"},toHex:function(){var t,e,i,r=this.getSource();return t=r[0].toString(16),t=1===t.length?"0"+t:t,e=r[1].toString(16),e=1===e.length?"0"+e:e,i=r[2].toString(16),i=1===i.length?"0"+i:i,t.toUpperCase()+e.toUpperCase()+i.toUpperCase()},getAlpha:function(){return this.getSource()[3]},setAlpha:function(t){var e=this.getSource();return e[3]=t,this.setSource(e),this},toGrayscale:function(){var t=this.getSource(),e=parseInt((.3*t[0]+.59*t[1]+.11*t[2]).toFixed(0),10),i=t[3];return this.setSource([e,e,e,i]),this},toBlackWhite:function(t){var e=this.getSource(),i=(.3*e[0]+.59*e[1]+.11*e[2]).toFixed(0),r=e[3];return t=t||127,i=Number(i)a;a++)i.push(Math.round(s[a]*(1-n)+o[a]*n));return i[3]=r,this.setSource(i),this}},r.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*)?\)$/,r.Color.reHSLa=/^hsla?\(\s*(\d{1,3})\s*,\s*(\d{1,3}\%)\s*,\s*(\d{1,3}\%)\s*(?:\s*,\s*(\d+(?:\.\d+)?)\s*)?\)$/,r.Color.reHex=/^#?([0-9a-f]{6}|[0-9a-f]{3})$/i,r.Color.colorNameMap={aqua:"#00FFFF",black:"#000000",blue:"#0000FF",fuchsia:"#FF00FF",gray:"#808080",green:"#008000",lime:"#00FF00",maroon:"#800000",navy:"#000080",olive:"#808000",orange:"#FFA500",purple:"#800080",red:"#FF0000",silver:"#C0C0C0",teal:"#008080",white:"#FFFFFF",yellow:"#FFFF00"},r.Color.fromRgb=function(t){return e.fromSource(e.sourceFromRgb(t))},r.Color.sourceFromRgb=function(t){var i=t.match(e.reRGBa);if(i){var r=parseInt(i[1],10)/(/%$/.test(i[1])?100:1)*(/%$/.test(i[1])?255:1),n=parseInt(i[2],10)/(/%$/.test(i[2])?100:1)*(/%$/.test(i[2])?255:1),s=parseInt(i[3],10)/(/%$/.test(i[3])?100:1)*(/%$/.test(i[3])?255:1);return[parseInt(r,10),parseInt(n,10),parseInt(s,10),i[4]?parseFloat(i[4]):1]}},r.Color.fromRgba=e.fromRgb,r.Color.fromHsl=function(t){return e.fromSource(e.sourceFromHsl(t))},r.Color.sourceFromHsl=function(t){var r=t.match(e.reHSLa);if(r){var n,s,o,a=(parseFloat(r[1])%360+360)%360/360,h=parseFloat(r[2])/(/%$/.test(r[2])?100:1),c=parseFloat(r[3])/(/%$/.test(r[3])?100:1);if(0===h)n=s=o=c;else{var l=.5>=c?c*(h+1):c+h-c*h,u=2*c-l;n=i(u,l,a+1/3),s=i(u,l,a),o=i(u,l,a-1/3)}return[Math.round(255*n),Math.round(255*s),Math.round(255*o),r[4]?parseFloat(r[4]):1]}},r.Color.fromHsla=e.fromHsl,r.Color.fromHex=function(t){return e.fromSource(e.sourceFromHex(t))},r.Color.sourceFromHex=function(t){if(t.match(e.reHex)){var i=t.slice(t.indexOf("#")+1),r=3===i.length,n=r?i.charAt(0)+i.charAt(0):i.substring(0,2),s=r?i.charAt(1)+i.charAt(1):i.substring(2,4),o=r?i.charAt(2)+i.charAt(2):i.substring(4,6);return[parseInt(n,16),parseInt(s,16),parseInt(o,16),1]}},void(r.Color.fromSource=function(t){var i=new e;return i.setSource(t),i}))}("undefined"!=typeof exports?exports:this),function(){function t(t){var e,i,r,n=t.getAttribute("style"),s=t.getAttribute("offset")||0;if(s=parseFloat(s)/(/%$/.test(s)?100:1),s=0>s?0:s>1?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)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}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:e,color:i.toRgb(),opacity:i.getAlpha()})}return this},toObject:function(){return{type:this.type,coords:this.coords,colorStops:this.colorStops,offsetX:this.offsetX,offsetY:this.offsetY,gradientTransform:this.gradientTransform?this.gradientTransform.concat():this.gradientTransform}},toSVG:function(t){var e,i,r=fabric.util.object.clone(this.coords);if(this.colorStops.sort(function(t,e){return t.offset-e.offset}),!t.group||"path-group"!==t.group.type)for(var n in r)"x1"===n||"x2"===n||"r2"===n?r[n]+=this.offsetX-t.width/2:("y1"===n||"y2"===n)&&(r[n]+=this.offsetY-t.height/2);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']);for(var s=0;s\n');return e.push("linear"===this.type?"\n":"\n"),e.join("")},toLive:function(t,e){var i,r,n=fabric.util.object.clone(this.coords);if(this.type){if(e.group&&"path-group"===e.group.type)for(r in n)"x1"===r||"x2"===r?n[r]+=-this.offsetX+e.width/2:("y1"===r||"y2"===r)&&(n[r]+=-this.offsetY+e.height/2);"linear"===this.type?i=t.createLinearGradient(n.x1,n.y1,n.x2,n.y2):"radial"===this.type&&(i=t.createRadialGradient(n.x1,n.y1,n.r1,n.x2,n.y2,n.r2));for(var s=0,o=this.colorStops.length;o>s;s++){var a=this.colorStops[s].color,h=this.colorStops[s].opacity,c=this.colorStops[s].offset;"undefined"!=typeof h&&(a=new fabric.Color(a).setAlpha(h).toRgba()),i.addColorStop(parseFloat(c),a)}return i}}}),fabric.util.object.extend(fabric.Gradient,{fromElement:function(n,s){var o,a=n.getElementsByTagName("stop"),h="linearGradient"===n.nodeName?"linear":"radial",c=n.getAttribute("gradientUnits")||"objectBoundingBox",l=n.getAttribute("gradientTransform"),u=[],f={};"linear"===h?f=e(n):"radial"===h&&(f=i(n));for(var d=a.length;d--;)u.push(t(a[d]));o=r(s,f,c);var g=new fabric.Gradient({type:h,coords:f,colorStops:u,offsetX:-s.left,offsetY:-s.top});return(l||""!==o)&&(g.gradientTransform=fabric.parseTransformAttribute((l||"")+o)),g},forObject:function(t,e){return e||(e={}),r(t,e.coords,"userSpaceOnUse"),new fabric.Gradient(e)}})}(),fabric.Pattern=fabric.util.createClass({repeat:"repeat",offsetX:0,offsetY:0,initialize:function(t){if(t||(t={}),this.id=fabric.Object.__uid++,t.source)if("string"==typeof t.source)if("undefined"!=typeof fabric.util.getFunctionBody(t.source))this.source=new Function(fabric.util.getFunctionBody(t.source));else{var e=this;this.source=fabric.util.createImage(),fabric.util.loadImage(t.source,function(t){e.source=t})}else this.source=t.source;t.repeat&&(this.repeat=t.repeat),t.offsetX&&(this.offsetX=t.offsetX),t.offsetY&&(this.offsetY=t.offsetY)},toObject:function(){var t;return"function"==typeof this.source?t=String(this.source):"string"==typeof this.source.src?t=this.source.src:"object"==typeof this.source&&this.source.toDataURL&&(t=this.source.toDataURL()),{source:t,repeat:this.repeat,offsetX:this.offsetX,offsetY:this.offsetY}},toSVG:function(t){var e="function"==typeof this.source?this.source():this.source,i=e.width/t.getWidth(),r=e.height/t.getHeight(),n=this.offsetX/t.getWidth(),s=this.offsetY/t.getHeight(),o="";return("repeat-x"===this.repeat||"no-repeat"===this.repeat)&&(r=1),("repeat-y"===this.repeat||"no-repeat"===this.repeat)&&(i=1),e.src?o=e.src:e.toDataURL&&(o=e.toDataURL()),'\n\n\n'},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 \n \n \n \n \n \n \n \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=new Error("Could not initialize `canvas` element");fabric.StaticCanvas=fabric.util.createClass({initialize:function(t,e){e||(e={}),this._initStatic(t,e)},backgroundColor:"",backgroundImage:null,overlayColor:"",overlayImage:null,includeDefaultValues:!0,stateful:!0,renderOnAddRemove:!0,clipTo:null,controlsAboveOverlay:!1,allowTouchScrolling:!1,imageSmoothingEnabled:!0,preserveObjectStacking:!1,viewportTransform:[1,0,0,1,0,0],onBeforeScaleRotate:function(){},enableRetinaScaling:!0,_initStatic:function(t,e){this._objects=[],this._createLowerCanvas(t),this._initOptions(e),this._setImageSmoothing(),this.interactive||this._initRetinaScaling(),e.overlayImage&&this.setOverlayImage(e.overlayImage,this.renderAll.bind(this)),e.backgroundImage&&this.setBackgroundImage(e.backgroundImage,this.renderAll.bind(this)),e.backgroundColor&&this.setBackgroundColor(e.backgroundColor,this.renderAll.bind(this)),e.overlayColor&&this.setOverlayColor(e.overlayColor,this.renderAll.bind(this)),this.calcOffset()},_isRetinaScaling:function(){return 1!==fabric.devicePixelRatio&&this.enableRetinaScaling},_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){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){if(e&&e.source){var r=this;fabric.util.loadImage(e.source,function(n){r[t]=new fabric.Pattern({source:n,repeat:e.repeat,offsetX:e.offsetX,offsetY:e.offsetY}),i&&i()})}else this[t]=e,i&&i();return this},_createCanvasElement:function(){var t=fabric.document.createElement("canvas");if(t.style||(t.style={}),!t)throw n;return this._initCanvasElement(t),t},_initCanvasElement:function(t){if(fabric.util.createCanvasElement(t),"undefined"==typeof t.getContext)throw n},_initOptions:function(t){for(var e in t)this[e]=t[e];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(),this._initCanvasElement(this.lowerCanvasEl),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 Math.sqrt(this.viewportTransform[0]*this.viewportTransform[3])},setViewportTransform:function(t){var e=this.getActiveGroup();this.viewportTransform=t,this.renderAll();for(var i=0,r=this._objects.length;r>i;i++)this._objects[i].setCoords();return e&&e.setCoords(),this},zoomToPoint:function(t,e){var i=t;t=fabric.util.transformPoint(t,fabric.util.invertTransform(this.viewportTransform)),this.viewportTransform[0]=e,this.viewportTransform[3]=e;var r=fabric.util.transformPoint(t,this.viewportTransform);this.viewportTransform[4]+=i.x-r.x,this.viewportTransform[5]+=i.y-r.y,this.renderAll();for(var n=0,s=this._objects.length;s>n;n++)this._objects[n].setCoords();return this},setZoom:function(t){return this.zoomToPoint(new fabric.Point(0,0),t),this},absolutePan:function(t){this.viewportTransform[4]=-t.x,this.viewportTransform[5]=-t.y,this.renderAll();for(var e=0,i=this._objects.length;i>e;e++)this._objects[e].setCoords();return this},relativePan:function(t){return this.absolutePan(new fabric.Point(-t.x-this.viewportTransform[4],-t.y-this.viewportTransform[5]))},getElement:function(){return this.lowerCanvasEl},getActiveObject:function(){return null},getActiveGroup:function(){return null},_onObjectAdded:function(t){this.stateful&&t.setupState(),t._set("canvas",this),t.setCoords(),this.fire("object:added",{target:t}),t.fire("added")},_onObjectRemoved:function(t){this.getActiveObject()===t&&(this.fire("before:selection:cleared",{target:t}),this._discardActiveObject(),this.fire("selection:cleared")),this.fire("object:removed",{target:t}),t.fire("removed")},clearContext:function(t){return t.clearRect(0,0,this.width,this.height),this},getContext:function(){return this.contextContainer},clear:function(){return this._objects.length=0,this.discardActiveGroup&&this.discardActiveGroup(),this.discardActiveObject&&this.discardActiveObject(),this.clearContext(this.contextContainer),this.contextTop&&this.clearContext(this.contextTop),this.fire("canvas:cleared"),this.renderAll(),this},_chooseObjectsToRender:function(){var t,e=this.getActiveGroup(),i=[],r=[];if(e&&!this.preserveObjectStacking){for(var n=0,s=this._objects.length;s>n;n++)t=this._objects[n],e.contains(t)?r.push(t):i.push(t);e._set("_objects",r)}else i=this._objects;return i},renderAll:function(){var t,e=this.contextContainer;return this.contextTop&&this.selection&&!this._groupSelector&&!this.isDrawingMode&&this.clearContext(this.contextTop),this.clearContext(e),this.fire("before:render"),this.clipTo&&fabric.util.clipContext(this,e),this._renderBackground(e),e.save(),t=this._chooseObjectsToRender(),e.transform.apply(e,this.viewportTransform),this._renderObjects(e,t),this.preserveObjectStacking||this._renderObjects(e,[this.getActiveGroup()]),e.restore(),!this.controlsAboveOverlay&&this.interactive&&this.drawControls(e),this.clipTo&&e.restore(),this._renderOverlay(e),this.controlsAboveOverlay&&this.interactive&&this.drawControls(e),this.fire("after:render"),this},_renderObjects:function(t,e){for(var i=0,r=e.length;r>i;++i)e[i]&&e[i].render(t)},_renderBackgroundOrOverlay:function(t,e){var i=this[e+"Color"];i&&(t.fillStyle=i.toLive?i.toLive(t):i,t.fillRect(i.offsetX||0,i.offsetY||0,this.width,this.height)),i=this[e+"Image"],i&&i.render(t)},_renderBackground:function(t){this._renderBackgroundOrOverlay(t,"background")},_renderOverlay:function(t){this._renderBackgroundOrOverlay(t,"overlay")},renderTop:function(){var t=this.contextTop||this.contextContainer;return this.clearContext(t),this.selection&&this._groupSelector&&this._drawSelection(),this.fire("after:render"),this},getCenter:function(){return{top:this.getHeight()/2,left:this.getWidth()/2}},centerObjectH:function(t){return this._centerObject(t,new fabric.Point(this.getCenter().left,t.getCenterPoint().y)),this.renderAll(),this},centerObjectV:function(t){return this._centerObject(t,new fabric.Point(t.getCenterPoint().x,this.getCenter().top)),this.renderAll(),this},centerObject:function(t){var e=this.getCenter();return this._centerObject(t,new fabric.Point(e.left,e.top)),this.renderAll(),this},_centerObject:function(t,e){return t.setPositionByOrigin(e,"center","center"),this},toDatalessJSON:function(t){return this.toDatalessObject(t)},toObject:function(t){return this._toObjectMethod("toObject",t)},toDatalessObject:function(t){return this._toObjectMethod("toDatalessObject",t)},_toObjectMethod:function(e,i){var r={objects:this._toObjects(e,i)};return t(r,this.__serializeBgOverlay()),fabric.util.populateWithProperties(this,r,i),r},_toObjects:function(t,e){return this.getObjects().map(function(i){ -return this._toObject(i,t,e)},this)},_toObject:function(t,e,i){var r;this.includeDefaultValues||(r=t.includeDefaultValues,t.includeDefaultValues=!1);var n=this._realizeGroupTransformOnObject(t),s=t[e](i);return this.includeDefaultValues||(t.includeDefaultValues=r),this._unwindGroupTransformOnObject(t,n),s},_realizeGroupTransformOnObject:function(t){var e=["angle","flipX","flipY","height","left","scaleX","scaleY","top","width"];if(t.group&&t.group===this.getActiveGroup()){var i={};return e.forEach(function(e){i[e]=t[e]}),this.getActiveGroup().realizeTransform(t),i}return null},_unwindGroupTransformOnObject:function(t,e){e&&t.set(e)},__serializeBgOverlay:function(){var t={background:this.backgroundColor&&this.backgroundColor.toObject?this.backgroundColor.toObject():this.backgroundColor};return this.overlayColor&&(t.overlay=this.overlayColor.toObject?this.overlayColor.toObject():this.overlayColor),this.backgroundImage&&(t.backgroundImage=this.backgroundImage.toObject()),this.overlayImage&&(t.overlayImage=this.overlayImage.toObject()),t},svgViewportTransformation:!0,toSVG:function(t,e){t||(t={});var i=[];return this._setSVGPreamble(i,t),this._setSVGHeader(i,t),this._setSVGBgOverlayColor(i,"backgroundColor"),this._setSVGBgOverlayImage(i,"backgroundImage"),this._setSVGObjects(i,e),this._setSVGBgOverlayColor(i,"overlayColor"),this._setSVGBgOverlayImage(i,"overlayImage"),i.push(""),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","",fabric.createSVGFontFacesMarkup(this.getObjects()),fabric.createSVGRefElementsMarkup(this),"\n")},_setSVGObjects:function(t,e){for(var i=0,r=this.getObjects(),n=r.length;n>i;i++){var s=r[i],o=this._realizeGroupTransformOnObject(s);t.push(s.toSVG(e)),this._unwindGroupTransformOnObject(s,o)}},_setSVGBgOverlayImage:function(t,e){this[e]&&this[e].toSVG&&t.push(this[e].toSVG())},_setSVGBgOverlayColor:function(t,e){this[e]&&this[e].source?t.push('\n"):this[e]&&"overlayColor"===e&&t.push('\n")},sendToBack:function(t){return i(this._objects,t),this._objects.unshift(t),this.renderAll&&this.renderAll()},bringToFront:function(t){return i(this._objects,t),this._objects.push(t),this.renderAll&&this.renderAll()},sendBackwards:function(t,e){var r=this._objects.indexOf(t);if(0!==r){var n=this._findNewLowerIndex(t,r,e);i(this._objects,t),this._objects.splice(n,0,t),this.renderAll&&this.renderAll()}return this},_findNewLowerIndex:function(t,e,i){var r;if(i){r=e;for(var n=e-1;n>=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){var r=this._objects.indexOf(t);if(r!==this._objects.length-1){var n=this._findNewUpperIndex(t,r,e);i(this._objects,t),this._objects.splice(n,0,t),this.renderAll&&this.renderAll()}return 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(r){}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;t.shadowColor=this.shadow.color,t.shadowBlur=this.shadow.blur,t.shadowOffsetX=this.shadow.offsetX,t.shadowOffsetY=this.shadow.offsetY}},_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;s>n;n++){var o=i.midPointFrom(r);t.quadraticCurveTo(i.x,i.y,o.x,o.y),i=this._points[n],r=this._points[n+1]}t.lineTo(i.x,i.y),t.stroke(),t.restore()},convertPointsToSVGPath:function(t){var e=[],i=new fabric.Point(t[0].x,t[0].y),r=new fabric.Point(t[1].x,t[1].y);e.push("M ",t[0].x," ",t[0].y," ");for(var n=1,s=t.length;s>n;n++){var o=i.midPointFrom(r);e.push("Q ",i.x," ",i.y," ",o.x," ",o.y," "),i=new fabric.Point(t[n].x,t[n].y),n+1i;i++){var n=this.points[i],s=new fabric.Circle({radius:n.radius,left:n.x,top:n.y,originX:"center",originY:"center",fill:n.fill});this.shadow&&s.setShadow(this.shadow),e.push(s)}var o=new fabric.Group(e,{originX:"center",originY:"center"});o.canvas=this.canvas,this.canvas.add(o),this.canvas.fire("path:created",{path:o}),this.canvas.clearContext(this.canvas.contextTop),this._resetShadow(),this.canvas.renderOnAddRemove=t,this.canvas.renderAll()},addPoint:function(t){var e=new fabric.Point(t.x,t.y),i=fabric.util.getRandomInt(Math.max(0,this.width-20),this.width+20)/2,r=new fabric.Color(this.color).setAlpha(fabric.util.getRandomInt(0,100)/100).toRgba();return e.radius=i,e.fill=r,this.points.push(e),e}}),fabric.SprayBrush=fabric.util.createClass(fabric.BaseBrush,{width:10,density:20,dotWidth:1,dotWidthVariance:1,randomOpacity:!1,optimizeOverlapping:!0,initialize:function(t){this.canvas=t,this.sprayChunks=[]},onMouseDown:function(t){this.sprayChunks.length=0,this.canvas.clearContext(this.canvas.contextTop),this._setShadow(),this.addSprayChunk(t),this.render()},onMouseMove:function(t){this.addSprayChunk(t),this.render()},onMouseUp:function(){var t=this.canvas.renderOnAddRemove;this.canvas.renderOnAddRemove=!1;for(var e=[],i=0,r=this.sprayChunks.length;r>i;i++)for(var n=this.sprayChunks[i],s=0,o=n.length;o>s;s++){var a=new fabric.Rect({width:n[s].width,height:n[s].width,left:n[s].x+1,top:n[s].y+1,originX:"center",originY:"center",fill:this.color});this.shadow&&a.setShadow(this.shadow),e.push(a)}this.optimizeOverlapping&&(e=this._getOptimizedRects(e));var h=new fabric.Group(e,{originX:"center",originY:"center"});h.canvas=this.canvas,this.canvas.add(h),this.canvas.fire("path:created",{path:h}),this.canvas.clearContext(this.canvas.contextTop),this._resetShadow(),this.canvas.renderOnAddRemove=t,this.canvas.renderAll()},_getOptimizedRects:function(t){for(var e,i={},r=0,n=t.length;n>r;r++)e=t[r].left+""+t[r].top,i[e]||(i[e]=t[r]);var s=[];for(e in i)s.push(i[e]);return s},render:function(){var t=this.canvas.contextTop;t.fillStyle=this.color;var e=this.canvas.viewportTransform;t.save(),t.transform(e[0],e[1],e[2],e[3],e[4],e[5]);for(var i=0,r=this.sprayChunkPoints.length;r>i;i++){var n=this.sprayChunkPoints[i];"undefined"!=typeof n.opacity&&(t.globalAlpha=n.opacity),t.fillRect(n.x,n.y,n.width,n.width)}t.restore()},addSprayChunk:function(t){this.sprayChunkPoints=[];for(var e,i,r,n=this.width/2,s=0;s0?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],2>=l?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&&0>=c&&c=l&&li.padding?t.x<0?t.x+=i.padding:t.x-=i.padding:t.x=0,n(t.y)>i.padding?t.y<0?t.y+=i.padding:t.y-=i.padding: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);return 0>a&&(a=360+a),n.target.angle=a%360,!0},setCursor:function(t){this.upperCanvasEl.style.cursor=t},_resetObjectTransform:function(t){t.scaleX=1,t.scaleY=1,t.skewX=0,t.skewY=0,t.setAngle(0)},_drawSelection:function(){var t=this.contextTop,e=this._groupSelector,i=e.left,r=e.top,o=n(i),a=n(r);if(t.fillStyle=this.selectionColor,t.fillRect(e.ex-(i>0?0:-i),e.ey-(r>0?0:-r),o,a),t.lineWidth=this.selectionLineWidth,t.strokeStyle=this.selectionBorderColor,this.selectionDashArray.length>1){var h=e.ex+s-(i>0?0:o),c=e.ey+s-(r>0?0:a);t.beginPath(),fabric.util.drawDashedLine(t,h,c,h+o,c,this.selectionDashArray),fabric.util.drawDashedLine(t,h,c+a-1,h+o,c+a-1,this.selectionDashArray),fabric.util.drawDashedLine(t,h,c,h,c+a,this.selectionDashArray),fabric.util.drawDashedLine(t,h+o-1,c,h+o-1,c+a,this.selectionDashArray),t.closePath(),t.stroke()}else t.strokeRect(e.ex+s-(i>0?0:o),e.ey+s-(r>0?0:a),o,a)},_isLastRenderedObject:function(t){return this.controlsAboveOverlay&&this.lastRenderedObjectWithControlsAboveOverlay&&this.lastRenderedObjectWithControlsAboveOverlay.visible&&this.containsPoint(t,this.lastRenderedObjectWithControlsAboveOverlay)&&this.lastRenderedObjectWithControlsAboveOverlay._findTargetCorner(this.getPointer(t,!0))},findTarget:function(t,e){if(!this.skipTargetFind){if(this._isLastRenderedObject(t))return this.lastRenderedObjectWithControlsAboveOverlay;var i=this.getActiveGroup();if(i&&!e&&this.containsPoint(t,i))return i;var r=this._searchPossibleTargets(t,e);return this._fireOverOutEvents(r,t),r}},_fireOverOutEvents:function(t,e){t?this._hoveredTarget!==t&&(this._hoveredTarget&&(this.fire("mouse:out",{target:this._hoveredTarget,e:e}),this._hoveredTarget.fire("mouseout")),this.fire("mouse:over",{target:t,e:e}),t.fire("mouseover"),this._hoveredTarget=t):this._hoveredTarget&&(this.fire("mouse:out",{target:this._hoveredTarget,e:e}),this._hoveredTarget.fire("mouseout"),this._hoveredTarget=null)},_checkTarget:function(t,e,i){if(e&&e.visible&&e.evented&&this.containsPoint(t,e)){if(!this.perPixelTargetFind&&!e.perPixelTargetFind||e.isEditing)return!0;var r=this.isTargetTransparent(e,i.x,i.y);if(!r)return!0}},_searchPossibleTargets:function(t,e){for(var i,r=this.getPointer(t,!0),n=this._objects.length;n--;)if((!this._objects[n].group||e)&&this._checkTarget(t,this._objects[n],r)){this.relatedTarget=this._objects[n],i=this._objects[n];break}return i},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=fabric.util.transformPoint(s,fabric.util.invertTransform(this.viewportTransform))),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}),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){this._activeObject&&this._activeObject.set("active",!1),this._activeObject=t,t.set("active",!0)},setActiveObject:function(t,e){return this._setActiveObject(t),this.renderAll(),this.fire("object:selected",{target:t,e:e}),t.fire("selected",{e:e}),this},getActiveObject:function(){return this._activeObject},_discardActiveObject:function(){this._activeObject&&this._activeObject.set("active",!1),this._activeObject=null},discardActiveObject:function(t){return this._discardActiveObject(),this.renderAll(),this.fire("selection:cleared",{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){return this._discardActiveGroup(),this.fire("selection:cleared",{e:t}),this},deactivateAll:function(){for(var t=this.getObjects(),e=0,i=t.length;i>e;e++)t[e].set("active",!1);return this._discardActiveGroup(),this._discardActiveObject(),this},deactivateAllWithDispatch:function(t){var e=this.getActiveGroup()||this.getActiveObject();return e&&this.fire("before:selection:cleared",{target:e,e:t}),this.deactivateAll(),e&&this.fire("selection:cleared",{e:t}),this},dispose:function(){this.callSuper("dispose");var t=this.wrapperEl;return this.removeListeners(),t.removeChild(this.upperCanvasEl),t.removeChild(this.lowerCanvasEl),delete this.upperCanvasEl,t.parentNode&&t.parentNode.replaceChild(this.lowerCanvasEl,this.wrapperEl),delete this.wrapperEl,this},drawControls:function(t){var e=this.getActiveGroup();e?e._renderControls(t):this._drawObjectsControls(t)},_drawObjectsControls:function(t){for(var e=0,i=this._objects.length;i>e;++e)this._objects[e]&&this._objects[e].active&&(this._objects[e]._renderControls(t),this.lastRenderedObjectWithControlsAboveOverlay=this._objects[e])}});for(var o in fabric.StaticCanvas)"prototype"!==o&&(fabric.Canvas[o]=fabric.StaticCanvas[o]);fabric.isTouchSupported&&(fabric.Canvas.prototype._setCursorFromEvent=function(){}),fabric.Element=fabric.Canvas}(),function(){var t={mt:0,tr:1,mr:2,br:3,mb:4,bl:5,ml:6,tl:7},e=fabric.util.addListener,i=fabric.util.removeListener;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._bindEvents(),e(fabric.window,"resize",this._onResize),e(this.upperCanvasEl,"mousedown",this._onMouseDown),e(this.upperCanvasEl,"mousemove",this._onMouseMove),e(this.upperCanvasEl,"mousewheel",this._onMouseWheel),e(this.upperCanvasEl,"touchstart",this._onMouseDown),e(this.upperCanvasEl,"touchmove",this._onMouseMove),"undefined"!=typeof eventjs&&"add"in eventjs&&(eventjs.add(this.upperCanvasEl,"gesture",this._onGesture),eventjs.add(this.upperCanvasEl,"drag",this._onDrag),eventjs.add(this.upperCanvasEl,"orientation",this._onOrientationChange),eventjs.add(this.upperCanvasEl,"shake",this._onShake),eventjs.add(this.upperCanvasEl,"longpress",this._onLongPress))},_bindEvents:function(){this._onMouseDown=this._onMouseDown.bind(this),this._onMouseMove=this._onMouseMove.bind(this),this._onMouseUp=this._onMouseUp.bind(this),this._onResize=this._onResize.bind(this),this._onGesture=this._onGesture.bind(this),this._onDrag=this._onDrag.bind(this),this._onShake=this._onShake.bind(this),this._onLongPress=this._onLongPress.bind(this),this._onOrientationChange=this._onOrientationChange.bind(this),this._onMouseWheel=this._onMouseWheel.bind(this)},removeListeners:function(){i(fabric.window,"resize",this._onResize),i(this.upperCanvasEl,"mousedown",this._onMouseDown),i(this.upperCanvasEl,"mousemove",this._onMouseMove),i(this.upperCanvasEl,"mousewheel",this._onMouseWheel),i(this.upperCanvasEl,"touchstart",this._onMouseDown),i(this.upperCanvasEl,"touchmove",this._onMouseMove),"undefined"!=typeof eventjs&&"remove"in eventjs&&(eventjs.remove(this.upperCanvasEl,"gesture",this._onGesture),eventjs.remove(this.upperCanvasEl,"drag",this._onDrag),eventjs.remove(this.upperCanvasEl,"orientation",this._onOrientationChange),eventjs.remove(this.upperCanvasEl,"shake",this._onShake),eventjs.remove(this.upperCanvasEl,"longpress",this._onLongPress))},_onGesture:function(t,e){this.__onTransformGesture&&this.__onTransformGesture(t,e)},_onDrag:function(t,e){this.__onDrag&&this.__onDrag(t,e)},_onMouseWheel:function(t,e){this.__onMouseWheel&&this.__onMouseWheel(t,e)},_onOrientationChange:function(t,e){this.__onOrientationChange&&this.__onOrientationChange(t,e)},_onShake:function(t,e){this.__onShake&&this.__onShake(t,e)},_onLongPress:function(t,e){this.__onLongPress&&this.__onLongPress(t,e)},_onMouseDown:function(t){this.__onMouseDown(t),e(fabric.document,"touchend",this._onMouseUp),e(fabric.document,"touchmove",this._onMouseMove),i(this.upperCanvasEl,"mousemove",this._onMouseMove),i(this.upperCanvasEl,"touchmove",this._onMouseMove),"touchstart"===t.type?i(this.upperCanvasEl,"mousedown",this._onMouseDown):(e(fabric.document,"mouseup",this._onMouseUp),e(fabric.document,"mousemove",this._onMouseMove))},_onMouseUp:function(t){if(this.__onMouseUp(t),i(fabric.document,"mouseup",this._onMouseUp),i(fabric.document,"touchend",this._onMouseUp),i(fabric.document,"mousemove",this._onMouseMove),i(fabric.document,"touchmove",this._onMouseMove),e(this.upperCanvasEl,"mousemove",this._onMouseMove),e(this.upperCanvasEl,"touchmove",this._onMouseMove),"touchend"===t.type){var r=this;setTimeout(function(){e(r.upperCanvasEl,"mousedown",r._onMouseDown)},400)}},_onMouseMove:function(t){!this.allowTouchScrolling&&t.preventDefault&&t.preventDefault(),this.__onMouseMove(t)},_onResize:function(){this.calcOffset()},_shouldRender:function(t,e){var i=this.getActiveGroup()||this.getActiveObject();return!!(t&&(t.isMoving||t!==i)||!t&&i||!t&&!i&&!this._groupSelector||e&&this._previousPointer&&this.selection&&(e.x!==this._previousPointer.x||e.y!==this._previousPointer.y))},__onMouseUp:function(t){var e;if(this.isDrawingMode&&this._isCurrentlyDrawing)return void this._onMouseUpInDrawingMode(t);this._currentTransform?(this._finalizeCurrentTransform(),e=this._currentTransform.target):e=this.findTarget(t,!0);var i=this._shouldRender(e,this.getPointer(t));this._maybeGroupObjects(t),e&&(e.isMoving=!1),i&&this.renderAll(),this._handleCursorAndEvent(t,e)},_handleCursorAndEvent:function(t,e){this._setCursorFromEvent(t,e);var i=this;setTimeout(function(){i._setCursorFromEvent(t,e)},50),this.fire("mouse:up",{target:e,e:t}),e&&e.fire("mouseup",{e:t})},_finalizeCurrentTransform:function(){var t=this._currentTransform,e=t.target;e._scaling&&(e._scaling=!1),e.setCoords(),this._restoreOriginXY(e),(t.actionPerformed||this.stateful&&e.hasStateChanged())&&(this.fire("object:modified",{target:e}),e.fire("modified"))},_restoreOriginXY:function(t){if(this._previousOriginX&&this._previousOriginY){var e=t.translateToOriginPoint(t.getCenterPoint(),this._previousOriginX,this._previousOriginY); - -t.originX=this._previousOriginX,t.originY=this._previousOriginY,t.left=e.x,t.top=e.y,this._previousOriginX=null,this._previousOriginY=null}},_onMouseDownInDrawingMode:function(t){this._isCurrentlyDrawing=!0,this.discardActiveObject(t).renderAll(),this.clipTo&&fabric.util.clipContext(this,this.contextTop);var e=fabric.util.invertTransform(this.viewportTransform),i=fabric.util.transformPoint(this.getPointer(t,!0),e);this.freeDrawingBrush.onMouseDown(i),this.fire("mouse:down",{e:t});var r=this.findTarget(t);"undefined"!=typeof r&&r.fire("mousedown",{e:t,target:r})},_onMouseMoveInDrawingMode:function(t){if(this._isCurrentlyDrawing){var e=fabric.util.invertTransform(this.viewportTransform),i=fabric.util.transformPoint(this.getPointer(t,!0),e);this.freeDrawingBrush.onMouseMove(i)}this.setCursor(this.freeDrawingCursor),this.fire("mouse:move",{e:t});var r=this.findTarget(t);"undefined"!=typeof r&&r.fire("mousemove",{e:t,target:r})},_onMouseUpInDrawingMode:function(t){this._isCurrentlyDrawing=!1,this.clipTo&&this.contextTop.restore(),this.freeDrawingBrush.onMouseUp(),this.fire("mouse:up",{e:t});var e=this.findTarget(t);"undefined"!=typeof e&&e.fire("mouseup",{e:t,target:e})},__onMouseDown:function(t){var e="which"in t?1===t.which:0===t.button;if(e||fabric.isTouchSupported){if(this.isDrawingMode)return void this._onMouseDownInDrawingMode(t);if(!this._currentTransform){var i=this.findTarget(t),r=this.getPointer(t,!0);this._previousPointer=r;var n=this._shouldRender(i,r),s=this._shouldGroup(t,i);this._shouldClearSelection(t,i)?this._clearSelection(t,i,r):s&&(this._handleGrouping(t,i),i=this.getActiveGroup()),i&&i.selectable&&(i.__corner||!s)&&(this._beforeTransform(t,i),this._setupCurrentTransform(t,i)),n&&this.renderAll(),this.fire("mouse:down",{target:i,e:t}),i&&i.fire("mousedown",{e:t})}}},_beforeTransform:function(t,e){this.stateful&&e.saveState(),e._findTargetCorner(this.getPointer(t))&&this.onBeforeScaleRotate(e),e!==this.getActiveGroup()&&e!==this.getActiveObject()&&(this.deactivateAll(),this.setActiveObject(e,t))},_clearSelection:function(t,e,i){this.deactivateAllWithDispatch(t),e&&e.selectable?this.setActiveObject(e,t):this.selection&&(this._groupSelector={ex:i.x,ey:i.y,top:0,left:0})},_setOriginToCenter:function(t){this._previousOriginX=this._currentTransform.target.originX,this._previousOriginY=this._currentTransform.target.originY;var e=t.getCenterPoint();t.originX="center",t.originY="center",t.left=e.x,t.top=e.y,this._currentTransform.left=t.left,this._currentTransform.top=t.top},_setCenterToOrigin:function(t){var e=t.translateToOriginPoint(t.getCenterPoint(),this._previousOriginX,this._previousOriginY);t.originX=this._previousOriginX,t.originY=this._previousOriginY,t.left=e.x,t.top=e.y,this._previousOriginX=null,this._previousOriginY=null},__onMouseMove:function(t){var e,i;if(this.isDrawingMode)return void this._onMouseMoveInDrawingMode(t);if(!("undefined"!=typeof t.touches&&t.touches.length>1)){var r=this._groupSelector;r?(i=this.getPointer(t,!0),r.left=i.x-r.ex,r.top=i.y-r.ey,this.renderTop()):this._currentTransform?this._transformObject(t):(e=this.findTarget(t),!e||e&&!e.selectable?this.setCursor(this.defaultCursor):this._setCursorFromEvent(t,e)),this.fire("mouse:move",{target:e,e:t}),e&&e.fire("mousemove",{e:t})}},_transformObject:function(t){var e=this.getPointer(t),i=this._currentTransform;i.reset=!1,i.target.isMoving=!0,this._beforeScaleTransform(t,i),this._performTransformAction(t,i,e),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))&&this._fire("moving",s,t),this.setCursor(this.moveCursor)),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.shiftKey&&!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=this.getActiveGroup(),r=e._findTargetCorner&&(!i||!i.contains(e))&&e._findTargetCorner(this.getPointer(t,!0));return r?this._setCornerCursor(r,e,t):this.setCursor(e.hoverCursor||this.hoverCursor),!0},_setCornerCursor:function(e,i,r){if(e in t)this.setCursor(this._getRotatedCornerCursor(e,i,r));else{if("mtr"!==e||!i.hasRotatingPoint)return this.setCursor(this.defaultCursor),!1;this.setCursor(this.rotationCursor)}},_getRotatedCornerCursor:function(e,i,r){var n=Math.round(i.getAngle()%360/45);return 0>n&&(n+=8),n+=t[e],r.shiftKey&&t[e]%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.shiftKey&&e&&e.selectable&&(this.getActiveGroup()||i&&i!==e)&&this.selection},_handleGrouping:function(t,e){(e!==this.getActiveGroup()||(e=this.findTarget(t,!0),e&&!e.isType("group")))&&(this.getActiveGroup()?this._updateActiveGroup(e,t):this._createActiveGroup(e,t),this._activeGroup&&this._activeGroup.saveCoords())},_updateActiveGroup:function(t,e){var i=this.getActiveGroup();if(i.contains(t)){if(i.removeWithUpdate(t),t.set("active",!1),1===i.size())return this.discardActiveGroup(e),void this.setActiveObject(i.item(0))}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),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),e.saveCoords(),this.fire("selection:created",{target:e}),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}})}(),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,top:t.top,width:t.width,height:t.height};return this._isRetinaScaling()&&(r*=fabric.devicePixelRatio),1!==r?this.__toDataURLWithMultiplier(e,i,n,r):this.__toDataURL(e,i,n)},__toDataURL:function(t,e,i){this.renderAll();var r=this.contextContainer.canvas,n=this.__getCroppedCanvas(r,i);"jpg"===t&&(t="jpeg");var s=fabric.StaticCanvas.supports("toDataURLWithQuality")?(n||r).toDataURL("image/"+t,e):(n||r).toDataURL("image/"+t);return n&&(n=null),s},__getCroppedCanvas:function(t,e){var i,r,n="left"in e||"top"in e||"width"in e||"height"in e;return n&&(i=fabric.util.createCanvasElement(),r=i.getContext("2d"),i.width=e.width||this.width,i.height=e.height||this.height,r.drawImage(t,-e.left||0,-e.top||0)),i},__toDataURLWithMultiplier:function(t,e,i,r){var n=this.getWidth(),s=this.getHeight(),o=n*r,a=s*r,h=this.getActiveObject(),c=this.getActiveGroup(),l=this.contextContainer;r>1&&this.setDimensions({width:o,height:a}),l.save(),l.scale(r/fabric.devicePixelRatio,r/fabric.devicePixelRatio),i.left&&(i.left*=r),i.top&&(i.top*=r),i.width?i.width*=r:1>r&&(i.width=o),i.height?i.height*=r:1>r&&(i.height=a),c?this._tempRemoveBordersControlsFromGroup(c):h&&this.deactivateAll&&this.deactivateAll();var u=this.__toDataURL(t,e,i);return this.width=n,this.height=s,this.setDimensions({width:n,height:s}),c?this._restoreBordersControlsOnGroup(c):h&&this.setActiveObject&&this.setActiveObject(h),this.contextTop&&this.clearContext(this.contextTop),this.renderAll(),u},toDataURLWithMultiplier:function(t,e,i){return this.toDataURL({format:t,multiplier:e,quality:i})},_tempRemoveBordersControlsFromGroup:function(t){t.origHasControls=t.hasControls,t.origBorderColor=t.borderColor,t.hasControls=!0,t.borderColor="rgba(0,0,0,0)",t.forEachObject(function(t){t.origBorderColor=t.borderColor,t.borderColor="rgba(0,0,0,0)"})},_restoreBordersControlsOnGroup:function(t){t.hideControls=t.origHideControls,t.borderColor=t.origBorderColor,t.forEachObject(function(t){t.borderColor=t.origBorderColor,delete t.origBorderColor})}}),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):t;this.clear();var n=this;return this._enlivenObjects(r.objects,function(){n._setBgOverlay(r,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),n()},__setBgOverlay:function(t,e,i,r){var n=this;return e?void("backgroundImage"===t||"overlayImage"===t?fabric.Image.fromObject(e,function(e){n[t]=e,i[t]=!0,r&&r()}):this["set"+fabric.util.string.capitalize(t,!0)](e,function(){i[t]=!0,r&&r()})):void(i[t]=!0)},_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,!0)}),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.toFixed,n=e.util.string.capitalize,s=e.util.degreesToRadians,o=e.StaticCanvas.supports("setLineDash");e.Object||(e.Object=e.util.createClass({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:12,transparentCorners:!0,hoverCursor:null,padding:0,borderColor:"rgba(102,153,255,0.75)",cornerColor:"rgba(102,153,255,0.5)",centeredScaling:!1,centeredRotation:!0,fill:"rgb(0,0,0)",fillRule:"nonzero",globalCompositeOperation:"source-over",backgroundColor:"",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,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 alignX alignY meetOrSlice skewX skewY".split(" "),initialize:function(t){t&&this.setOptions(t)},_initGradient:function(t){!t.fill||!t.fill.colorStops||t.fill instanceof e.Gradient||this.set("fill",new e.Gradient(t.fill)),!t.stroke||!t.stroke.colorStops||t.stroke instanceof e.Gradient||this.set("stroke",new e.Gradient(t.stroke))},_initPattern:function(t){!t.fill||!t.fill.source||t.fill instanceof e.Pattern||this.set("fill",new e.Pattern(t.fill)),!t.stroke||!t.stroke.source||t.stroke instanceof e.Pattern||this.set("stroke",new e.Pattern(t.stroke))},_initClipping:function(t){if(t.clipTo&&"string"==typeof t.clipTo){var i=e.util.getFunctionBody(t.clipTo);"undefined"!=typeof i&&(this.clipTo=new Function("ctx",i))}},setOptions:function(t){for(var e in t)this.set(e,t[e]);this._initGradient(t),this._initPattern(t),this._initClipping(t)},transform:function(t,e){this.group&&this.canvas.preserveObjectStacking&&this.group===this.canvas._activeGroup&&this.group.transform(t);var i=e?this._getLeftTopCoords():this.getCenterPoint();t.translate(i.x,i.y),t.rotate(s(this.angle)),t.scale(this.scaleX*(this.flipX?-1:1),this.scaleY*(this.flipY?-1:1)),t.transform(1,0,Math.tan(s(this.skewX)),1,0,0),t.transform(1,Math.tan(s(this.skewY)),0,1,0,0)},toObject:function(t){var i=e.Object.NUM_FRACTION_DIGITS,n={type:this.type,originX:this.originX,originY:this.originY,left:r(this.left,i),top:r(this.top,i),width:r(this.width,i),height:r(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:r(this.strokeWidth,i),strokeDashArray:this.strokeDashArray?this.strokeDashArray.concat():this.strokeDashArray,strokeLineCap:this.strokeLineCap,strokeLineJoin:this.strokeLineJoin,strokeMiterLimit:r(this.strokeMiterLimit,i),scaleX:r(this.scaleX,i),scaleY:r(this.scaleY,i),angle:r(this.getAngle(),i),flipX:this.flipX,flipY:this.flipY,opacity:r(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():this.transformMatrix,skewX:r(this.skewX,i),skewY:r(this.skewY,i)};return this.includeDefaultValues||(n=this._removeDefaultValues(n)),e.util.populateWithProperties(this,n,t),n},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"#"},get:function(t){return this[t]},_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,i){var n="scaleX"===t||"scaleY"===t;return n&&(i=this._constrainScale(i)),"scaleX"===t&&0>i?(this.flipX=!this.flipX,i*=-1):"scaleY"===t&&0>i?(this.flipY=!this.flipY,i*=-1):"width"===t||"height"===t?this.minScaleLimit=r(Math.min(.1,1/Math.max(this.width,this.height)),2):"shadow"!==t||!i||i instanceof e.Shadow||(i=new e.Shadow(i)),this[t]=i,this},setOnGroup:function(){},toggle:function(t){var e=this.get(t);return"boolean"==typeof e&&this.set(t,!e),this},setSourcePath:function(t){return this.sourcePath=t,this},getViewportTransform:function(){return this.canvas&&this.canvas.viewportTransform?this.canvas.viewportTransform:[1,0,0,1,0,0]},render:function(t,i){0===this.width&&0===this.height||!this.visible||(t.save(),this._setupCompositeOperation(t),i||this.transform(t),this._setStrokeStyles(t),this._setFillStyles(t),this.transformMatrix&&t.transform.apply(t,this.transformMatrix),this._setOpacity(t),this._setShadow(t),this.clipTo&&e.util.clipContext(this,t),this._render(t,i),this.clipTo&&t.restore(),t.restore())},_setOpacity:function(t){this.group&&this.group._setOpacity(t),t.globalAlpha*=this.opacity},_setStrokeStyles:function(t){this.stroke&&(t.lineWidth=this.strokeWidth,t.lineCap=this.strokeLineCap,t.lineJoin=this.strokeLineJoin,t.miterLimit=this.strokeMiterLimit,t.strokeStyle=this.stroke.toLive?this.stroke.toLive(t,this):this.stroke)},_setFillStyles:function(t){this.fill&&(t.fillStyle=this.fill.toLive?this.fill.toLive(t,this):this.fill)},_renderControls:function(t,i){if(!(!this.active||i||this.group&&this.group!==this.canvas.getActiveGroup())){var r,n=this.getViewportTransform(),o=this.calcTransformMatrix();o=e.util.multiplyTransformMatrices(n,o),r=e.util.qrDecompose(o),t.save(),t.translate(r.translateX,r.translateY),this.group&&this.group===this.canvas.getActiveGroup()?(t.rotate(s(r.angle)),this.drawBordersInGroup(t,r)):(t.rotate(s(this.angle)),this.drawBorders(t)),this.drawControls(t),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;this.canvas&&this.canvas._isRetinaScaling()&&(i*=e.devicePixelRatio,r*=e.devicePixelRatio),t.shadowColor=this.shadow.color,t.shadowBlur=this.shadow.blur*(i+r)*(this.scaleX+this.scaleY)/4,t.shadowOffsetX=this.shadow.offsetX*i*this.scaleX,t.shadowOffsetY=this.shadow.offsetY*r*this.scaleY}},_removeShadow:function(t){this.shadow&&(t.shadowColor="",t.shadowBlur=t.shadowOffsetX=t.shadowOffsetY=0)},_renderFill:function(t){if(this.fill){if(t.save(),this.fill.gradientTransform){var e=this.fill.gradientTransform;t.transform.apply(t,e)}this.fill.toLive&&t.translate(-this.width/2+this.fill.offsetX||0,-this.height/2+this.fill.offsetY||0),"evenodd"===this.fillRule?t.fill("evenodd"):t.fill(),t.restore()}},_renderStroke:function(t){if(this.stroke&&0!==this.strokeWidth){if(this.shadow&&!this.shadow.affectStroke&&this._removeShadow(t),t.save(),this.strokeDashArray)1&this.strokeDashArray.length&&this.strokeDashArray.push.apply(this.strokeDashArray,this.strokeDashArray),o?(t.setLineDash(this.strokeDashArray),this._stroke&&this._stroke(t)):this._renderDashedStroke&&this._renderDashedStroke(t),t.stroke();else{if(this.stroke.gradientTransform){var e=this.stroke.gradientTransform;t.transform.apply(t,e)}this._stroke?this._stroke(t):t.stroke()}t.restore()}},clone:function(t,i){return this.constructor.fromObject?this.constructor.fromObject(this.toObject(i),t):new e.Object(this.toObject(i))},cloneAsImage:function(t){var i=this.toDataURL();return e.util.loadImage(i,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);"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(i.width/2,i.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 0},toJSON:function(t){return this.toObject(t)},setGradient:function(t,i){i||(i={});var r={colorStops:[]};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),i.gradientTransform&&(r.gradientTransform=i.gradientTransform);for(var n in i.colorStops){var s=new e.Color(i.colorStops[n]);r.colorStops.push({offset:n,color:s.toRgb(),opacity:s.getAlpha()})}return 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.centerObjectH(this),this},centerV:function(){return this.canvas.centerObjectV(this),this},center:function(){return this.canvas.centerObject(this),this},remove:function(){return 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,e.util.degreesToRadians(-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.__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=t.x,c=t.y,l=e[s]-e[r],u=i[o]-i[n];return(l||u)&&(a=this._getTransformedDimensions(),h=t.x+l*a.x,c=t.y+u*a.y),new fabric.Point(h,c)},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=i&&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=t(this.angle),n=this.getWidth(),s=Math.cos(r)*n,o=Math.sin(r)*n;this.left+=s*(e[i]-e[this.originX]),this.top+=o*(e[i]-e[this.originX]),this.setCoords(),this.originX=i},_setOriginToCenter:function(){this._originalOriginX=this.originX,this._originalOriginY=this.originY;var t=this.getCenterPoint();this.originX="center",this.originY="center",this.left=t.x,this.top=t.y},_resetOrigin:function(){var t=this.translateToOriginPoint(this.getCenterPoint(),this._originalOriginX,this._originalOriginY);this.originX=this._originalOriginX,this.originY=this._originalOriginY,this.left=t.x,this.top=t.y,this._originalOriginX=null,this._originalOriginY=null},_getLeftTopCoords:function(){return this.translateToOriginPoint(this.getCenterPoint(),"left","top")}})}(),function(){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,intersectsWithRect:function(e,i){var r=t(this.oCoords),n=fabric.Intersection.intersectPolygonRectangle(r,e,i);return"Intersection"===n.status},intersectsWithObject:function(e){var i=fabric.Intersection.intersectPolygonPolygon(t(this.oCoords),t(e.oCoords));return"Intersection"===i.status},isContainedWithinObject:function(t){var e=t.getBoundingRect(),i=new fabric.Point(e.left,e.top),r=new fabric.Point(e.left+e.width,e.top+e.height);return this.isContainedWithinRect(i,r)},isContainedWithinRect:function(t,e){var i=this.getBoundingRect();return i.left>=t.x&&i.left+i.width<=e.x&&i.top>=t.y&&i.top+i.height<=e.y},containsPoint:function(t){var e=this._getImageLines(this.oCoords),i=this._findCrossPoints(t,e);return 0!==i&&i%2===1},_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,c=0;for(var l in e)if(h=e[l],!(h.o.y=t.y&&h.d.y>=t.y||(h.o.x===h.d.x&&h.o.x>=t.x?(o=h.o.x,a=t.y):(i=0,r=(h.d.y-h.o.y)/(h.d.x-h.o.x),n=t.y-i*t.x,s=h.o.y-r*h.o.x,o=-(n-s)/(i-r),a=n+i*o),o>=t.x&&(c+=1),2!==c)))break;return c},getBoundingRectWidth:function(){return this.getBoundingRect().width},getBoundingRectHeight:function(){return this.getBoundingRect().height},getBoundingRect:function(){return this.oCoords||this.setCoords(),fabric.util.makeBoundingBoxFromPoints([this.oCoords.tl,this.oCoords.tr,this.oCoords.br,this.oCoords.bl])},getWidth:function(){return this._getTransformedDimensions().x},getHeight:function(){return this._getTransformedDimensions().y},_constrainScale:function(t){return Math.abs(t)t?-this.minScaleLimit:this.minScaleLimit:t},scale:function(t){return t=this._constrainScale(t),0>t&&(this.flipX=!this.flipX,this.flipY=!this.flipY,t*=-1),this.scaleX=t,this.scaleY=t,this.setCoords(),this},scaleToWidth:function(t){var e=this.getBoundingRect().width/this.getWidth();return this.scale(t/this.width/e)},scaleToHeight:function(t){var e=this.getBoundingRect().height/this.getHeight();return this.scale(t/this.height/e)},setCoords:function(){var t=e(this.angle),i=this.getViewportTransform(),r=this._calculateCurrentDimensions(),n=r.x,s=r.y;0>n&&(n=Math.abs(n));var o=Math.sin(t),a=Math.cos(t),h=n>0?Math.atan(s/n):0,c=n/Math.cos(h)/2,l=Math.cos(h+t)*c,u=Math.sin(h+t)*c,f=fabric.util.transformPoint(this.getCenterPoint(),i),d=new fabric.Point(f.x-l,f.y-u),g=new fabric.Point(d.x+n*a,d.y+n*o),p=new fabric.Point(d.x-s*o,d.y+s*a),v=new fabric.Point(f.x+l,f.y+u),m=new fabric.Point((d.x+p.x)/2,(d.y+p.y)/2),b=new fabric.Point((g.x+d.x)/2,(g.y+d.y)/2),y=new fabric.Point((v.x+g.x)/2,(v.y+g.y)/2),_=new fabric.Point((v.x+p.x)/2,(v.y+p.y)/2),x=new fabric.Point(b.x+o*this.rotatingPointOffset,b.y-a*this.rotatingPointOffset);return this.oCoords={tl:d,tr:g,br:v,bl:p,ml:m,mt:b,mr:y,mb:_,mtr:x},this._setCornerCoords&&this._setCornerCoords(),this},_calcRotateMatrix:function(){if(this.angle){var t=e(this.angle),i=Math.cos(t),r=Math.sin(t);return[i,r,-r,i,0,0]}return[1,0,0,1,0,0]},calcTransformMatrix:function(){var t=this.getCenterPoint(),e=[1,0,0,1,t.x,t.y],r=this._calcRotateMatrix(),n=this._calcDimensionsTransformMatrix(this.skewX,this.skewY,!0),s=this.group?this.group.calcTransformMatrix():[1,0,0,1,0,0];return s=i(s,e),s=i(s,r),s=i(s,n)},_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)}})}(),fabric.util.object.extend(fabric.Object.prototype,{sendToBack:function(){return this.group?fabric.StaticCanvas.prototype.sendToBack.call(this.group,this):this.canvas.sendToBack(this),this},bringToFront:function(){return this.group?fabric.StaticCanvas.prototype.bringToFront.call(this.group,this):this.canvas.bringToFront(this),this},sendBackwards:function(t){return this.group?fabric.StaticCanvas.prototype.sendBackwards.call(this.group,this,t):this.canvas.sendBackwards(this,t),this},bringForward:function(t){return this.group?fabric.StaticCanvas.prototype.bringForward.call(this.group,this,t):this.canvas.bringForward(this,t),this},moveTo:function(t){return this.group?fabric.StaticCanvas.prototype.moveTo.call(this.group,this,t):this.canvas.moveTo(this,t),this}}),fabric.util.object.extend(fabric.Object.prototype,{getSvgStyles:function(t){var e=this.fill?this.fill.toLive?"url(#SVGID_"+this.fill.id+")":this.fill:"none",i=this.fillRule,r=this.stroke?this.stroke.toLive?"url(#SVGID_"+this.stroke.id+")":this.stroke:"none",n=this.strokeWidth?this.strokeWidth:"0",s=this.strokeDashArray?this.strokeDashArray.join(" "):"none",o=this.strokeLineCap?this.strokeLineCap:"butt",a=this.strokeLineJoin?this.strokeLineJoin:"miter",h=this.strokeMiterLimit?this.strokeMiterLimit:"4",c="undefined"!=typeof this.opacity?this.opacity:"1",l=this.visible?"":" visibility: hidden;",u=t?"":this.getSvgFilter();return["stroke: ",r,"; ","stroke-width: ",n,"; ","stroke-dasharray: ",s,"; ","stroke-linecap: ",o,"; ","stroke-linejoin: ",a,"; ","stroke-miterlimit: ",h,"; ","fill: ",e,"; ","fill-rule: ",i,"; ","opacity: ",c,";",u,l].join("")},getSvgFilter:function(){return this.shadow?"filter: url(#SVGID_"+this.shadow.id+");":""},getSvgTransform:function(){if(this.group&&"path-group"===this.group.type)return"";var t=fabric.util.toFixed,e=this.getAngle(),i=this.getSkewX()%360,r=this.getSkewY()%360,n=this.getCenterPoint(),s=fabric.Object.NUM_FRACTION_DIGITS,o="path-group"===this.type?"":"translate("+t(n.x,s)+" "+t(n.y,s)+")",a=0!==e?" rotate("+t(e,s)+")":"",h=1===this.scaleX&&1===this.scaleY?"":" scale("+t(this.scaleX,s)+" "+t(this.scaleY,s)+")",c=0!==i?" skewX("+t(i,s)+")":"",l=0!==r?" skewY("+t(r,s)+")":"",u="path-group"===this.type?this.width:0,f=this.flipX?" matrix(-1 0 0 1 "+u+" 0) ":"",d="path-group"===this.type?this.height:0,g=this.flipY?" matrix(1 0 0 -1 0 "+d+")":"";return[o,a,h,f,g,c,l].join("")},getSvgTransformMatrix:function(){return this.transformMatrix?" matrix("+this.transformMatrix.join(" ")+") ":""},_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}}),fabric.util.object.extend(fabric.Object.prototype,{hasStateChanged:function(){return this.stateProperties.some(function(t){return this.get(t)!==this.originalState[t]},this)},saveState:function(t){return this.stateProperties.forEach(function(t){this.originalState[t]=this.get(t)},this),t&&t.stateProperties&&t.stateProperties.forEach(function(t){this.originalState[t]=this.get(t)},this),this},setupState:function(){return this.originalState={},this.saveState(),this}}),function(){var t=fabric.util.degreesToRadians,e=function(){return"undefined"!=typeof G_vmlCanvasManager};fabric.util.object.extend(fabric.Object.prototype,{_controlsVisibility:null,_findTargetCorner:function(t){if(!this.hasControls||!this.active)return!1;var e,i,r=t.x,n=t.y;this.__corner=0;for(var s in this.oCoords)if(this.isControlVisible(s)&&("mtr"!==s||this.hasRotatingPoint)&&(!this.get("lockUniScaling")||"mt"!==s&&"mr"!==s&&"mb"!==s&&"ml"!==s)&&(i=this._getImageLines(this.oCoords[s].corner),e=this._findCrossPoints({ -x:r,y:n},i),0!==e&&e%2===1))return this.__corner=s,s;return!1},_setCornerCoords:function(){var e,i,r=this.oCoords,n=t(45-this.angle),s=.707106*this.cornerSize,o=s*Math.cos(n),a=s*Math.sin(n);for(var h in r)e=r[h].x,i=r[h].y,r[h].corner={tl:{x:e-a,y:i-o},tr:{x:e+o,y:i-a},bl:{x:e-o,y:i+a},br:{x:e+a,y:i+o}}},_getNonTransformedDimensions:function(){var t=this.strokeWidth,e=this.width,i=this.height,r=!0,n=!0;return"line"===this.type&&"butt"===this.strokeLineCap&&(n=e,r=i),n&&(i+=0>i?-t:t),r&&(e+=0>e?-t:t),{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;ir;r++)t=i[r],e=r!==n-1,this._animate(t,arguments[0][t],arguments[1],e)}else this._animate.apply(this,arguments);return this},_animate:function(t,e,i,r){var n,s=this;e=e.toString(),i=i?fabric.util.object.clone(i):{},~t.indexOf(".")&&(n=t.split("."));var o=n?this.get(n[0])[n[1]]:this.get(t);"from"in i||(i.from=o),e=~e.indexOf("=")?o+parseFloat(e.replace("=","")):parseFloat(e),fabric.util.animate({startValue:i.from,endValue:e,byValue:i.by,easing:i.easing,duration:i.duration,abort:i.abort&&function(){return i.abort.call(s)},onChange:function(e){n?s[n[0]][n[1]]=e:s.set(t,e),r||i.onChange&&i.onChange()},onComplete:function(){r||(s.setCoords(),i.onComplete&&i.onComplete())}})}}),function(t){"use strict";function e(t,e){var i=t.origin,r=t.axis1,n=t.axis2,s=t.dimension,o=e.nearest,a=e.center,h=e.farthest;return function(){switch(this.get(i)){case o:return Math.min(this.get(r),this.get(n));case a:return Math.min(this.get(r),this.get(n))+.5*this.get(s);case h:return Math.max(this.get(r),this.get(n))}}}var i=t.fabric||(t.fabric={}),r=i.util.object.extend,n={x1:1,x2:1,y1:1,y2:1},s=i.StaticCanvas.supports("setLineDash");return i.Line?void i.warn("fabric.Line is already defined"):(i.Line=i.util.createClass(i.Object,{type:"line",x1:0,y1:0,x2:0,y2:0,initialize:function(t,e){e=e||{},t||(t=[0,0,0,0]),this.callSuper("initialize",e),this.set("x1",t[0]),this.set("y1",t[1]),this.set("x2",t[2]),this.set("y2",t[3]),this._setWidthHeight(e)},_setWidthHeight:function(t){t||(t={}),this.width=Math.abs(this.x2-this.x1),this.height=Math.abs(this.y2-this.y1),this.left="left"in t?t.left:this._getLeftToOriginX(),this.top="top"in t?t.top:this._getTopToOriginY()},_set:function(t,e){return this.callSuper("_set",t,e),"undefined"!=typeof n[t]&&this._setWidthHeight(),this},_getLeftToOriginX:e({origin:"originX",axis1:"x1",axis2:"x2",dimension:"width"},{nearest:"left",center:"center",farthest:"right"}),_getTopToOriginY:e({origin:"originY",axis1:"y1",axis2:"y2",dimension:"height"},{nearest:"top",center:"center",farthest:"bottom"}),_render:function(t,e){if(t.beginPath(),e){var i=this.getCenterPoint();t.translate(i.x-this.strokeWidth/2,i.y-this.strokeWidth/2)}if(!this.strokeDashArray||this.strokeDashArray&&s){var r=this.calcLinePoints();t.moveTo(r.x1,r.y1),t.lineTo(r.x2,r.y2)}t.lineWidth=this.strokeWidth;var n=t.strokeStyle;t.strokeStyle=this.stroke||t.fillStyle,this.stroke&&this._renderStroke(t),t.strokeStyle=n},_renderDashedStroke:function(t){var e=this.calcLinePoints();t.beginPath(),i.util.drawDashedLine(t,e.x1,e.y1,e.x2,e.y2,this.strokeDashArray),t.closePath()},toObject:function(t){return r(this.callSuper("toObject",t),this.calcLinePoints())},calcLinePoints:function(){var t=this.x1<=this.x2?-1:1,e=this.y1<=this.y2?-1:1,i=t*this.width*.5,r=e*this.height*.5,n=t*this.width*-.5,s=e*this.height*-.5;return{x1:i,x2:n,y1:r,y2:s}},toSVG:function(t){var e=this._createBaseSVGMarkup(),i={x1:this.x1,x2:this.x2,y1:this.y1,y2:this.y2};return this.group&&"path-group"===this.group.type||(i=this.calcLinePoints()),e.push("\n'),t?t(e.join("")):e.join("")},complexity:function(){return 1}}),i.Line.ATTRIBUTE_NAMES=i.SHARED_ATTRIBUTES.concat("x1 y1 x2 y2".split(" ")),i.Line.fromElement=function(t,e){var n=i.parseAttributes(t,i.Line.ATTRIBUTE_NAMES),s=[n.x1||0,n.y1||0,n.x2||0,n.y2||0];return new i.Line(s,r(n,e))},void(i.Line.fromObject=function(t){var e=[t.x1,t.y1,t.x2,t.y2];return new i.Line(e,t)}))}("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;return i.Circle?void i.warn("fabric.Circle is already defined."):(i.Circle=i.util.createClass(i.Object,{type:"circle",radius:0,startAngle:0,endAngle:2*r,initialize:function(t){t=t||{},this.callSuper("initialize",t),this.set("radius",t.radius||0),this.startAngle=t.startAngle||this.startAngle,this.endAngle=t.endAngle||this.endAngle},_set:function(t,e){return this.callSuper("_set",t,e),"radius"===t&&this.setRadius(e),this},toObject:function(t){return n(this.callSuper("toObject",t),{radius:this.get("radius"),startAngle:this.startAngle,endAngle:this.endAngle})},toSVG:function(t){var e=this._createBaseSVGMarkup(),i=0,n=0,s=(this.endAngle-this.startAngle)%(2*r);if(0===s)this.group&&"path-group"===this.group.type&&(i=this.left+this.radius,n=this.top+this.radius),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,e){t.beginPath(),t.arc(e?this.left+this.radius:0,e?this.top+this.radius: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)},complexity:function(){return 1}}),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");s.left=s.left||0,s.top=s.top||0;var o=new i.Circle(n(s,r));return o.left-=o.radius,o.top-=o.radius,o},void(i.Circle.fromObject=function(t){return new i.Circle(t)}))}("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){t=t||{},this.callSuper("initialize",t),this.set("width",t.width||100).set("height",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("")},complexity:function(){return 1}}),void(e.Triangle.fromObject=function(t){return new e.Triangle(t)}))}("undefined"!=typeof exports?exports:this),function(t){"use strict";var e=t.fabric||(t.fabric={}),i=2*Math.PI,r=e.util.object.extend;return e.Ellipse?void e.warn("fabric.Ellipse is already defined."):(e.Ellipse=e.util.createClass(e.Object,{type:"ellipse",rx:0,ry:0,initialize:function(t){t=t||{},this.callSuper("initialize",t),this.set("rx",t.rx||0),this.set("ry",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 r(this.callSuper("toObject",t),{rx:this.get("rx"),ry:this.get("ry")})},toSVG:function(t){var e=this._createBaseSVGMarkup(),i=0,r=0;return this.group&&"path-group"===this.group.type&&(i=this.left+this.rx,r=this.top+this.ry),e.push("\n'),t?t(e.join("")):e.join("")},_render:function(t,e){t.beginPath(),t.save(),t.transform(1,0,0,this.ry/this.rx,0,0),t.arc(e?this.left+this.rx:0,e?(this.top+this.ry)*this.rx/this.ry:0,this.rx,0,i,!1),t.restore(),this._renderFill(t),this._renderStroke(t)},complexity:function(){return 1}}),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);n.left=n.left||0,n.top=n.top||0;var s=new e.Ellipse(r(n,i));return s.top-=s.ry,s.left-=s.rx,s},void(e.Ellipse.fromObject=function(t){return new e.Ellipse(t)}))}("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","x","y"),e.Rect=e.util.createClass(e.Object,{stateProperties:r,type:"rect",rx:0,ry:0,strokeDashArray:null,initialize:function(t){t=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,e){if(1===this.width&&1===this.height)return void t.fillRect(-.5,-.5,1,1);var i=this.rx?Math.min(this.rx,this.width/2):0,r=this.ry?Math.min(this.ry,this.height/2):0,n=this.width,s=this.height,o=e?this.left:-this.width/2,a=e?this.top:-this.height/2,h=0!==i||0!==r,c=.4477152502;t.beginPath(),t.moveTo(o+i,a),t.lineTo(o+n-i,a),h&&t.bezierCurveTo(o+n-c*i,a,o+n,a+c*r,o+n,a+r),t.lineTo(o+n,a+s-r),h&&t.bezierCurveTo(o+n,a+s-c*r,o+n-c*i,a+s,o+n-i,a+s),t.lineTo(o+i,a+s),h&&t.bezierCurveTo(o+c*i,a+s,o,a+s-c*r,o,a+s-r),t.lineTo(o,a+r),h&&t.bezierCurveTo(o,a+c*r,o+c*i,a,o+i,a),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){var e=i(this.callSuper("toObject",t),{rx:this.get("rx")||0,ry:this.get("ry")||0});return this.includeDefaultValues||this._removeDefaultValues(e),e},toSVG:function(t){var e=this._createBaseSVGMarkup(),i=this.left,r=this.top;return this.group&&"path-group"===this.group.type||(i=-this.width/2,r=-this.height/2),e.push("\n'),t?t(e.join("")):e.join("")},complexity:function(){return 1}}),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;var s=new e.Rect(i(r?e.util.object.clone(r):{},n));return s.visible=s.width>0&&s.height>0,s},e.Rect.fromObject=function(t){return new e.Rect(t)}}("undefined"!=typeof exports?exports:this),function(t){"use strict";var e=t.fabric||(t.fabric={});return e.Polyline?void e.warn("fabric.Polyline is already defined"):(e.Polyline=e.util.createClass(e.Object,{type:"polyline",points:null,minX:0,minY:0,initialize:function(t,i){return e.Polygon.prototype.initialize.call(this,t,i)},_calcDimensions:function(){return e.Polygon.prototype._calcDimensions.call(this)},_applyPointOffset:function(){return e.Polygon.prototype._applyPointOffset.call(this)},toObject:function(t){return e.Polygon.prototype.toObject.call(this,t)},toSVG:function(t){return e.Polygon.prototype.toSVG.call(this,t)},_render:function(t,i){e.Polygon.prototype.commonRender.call(this,t,i)&&(this._renderFill(t),this._renderStroke(t))},_renderDashedStroke:function(t){var i,r;t.beginPath();for(var n=0,s=this.points.length;s>n;n++)i=this.points[n],r=this.points[n+1]||i,e.util.drawDashedLine(t,i.x,i.y,r.x,r.y,this.strokeDashArray)},complexity:function(){return this.get("points").length}}),e.Polyline.ATTRIBUTE_NAMES=e.SHARED_ATTRIBUTES.concat(),e.Polyline.fromElement=function(t,i){if(!t)return null;i||(i={});var r=e.parsePointsAttribute(t.getAttribute("points")),n=e.parseAttributes(t,e.Polyline.ATTRIBUTE_NAMES);return new e.Polyline(r,e.util.object.extend(n,i))},void(e.Polyline.fromObject=function(t){var i=t.points;return new e.Polyline(i,t,!0)}))}("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;return e.Polygon?void e.warn("fabric.Polygon is already defined"):(e.Polygon=e.util.createClass(e.Object,{type:"polygon",points:null,minX:0,minY:0,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=[],r=this._createBaseSVGMarkup(),n=0,o=this.points.length;o>n;n++)i.push(s(this.points[n].x,2),",",s(this.points[n].y,2)," ");return this.group&&"path-group"===this.group.type||(e=" translate("+-this.pathOffset.x+", "+-this.pathOffset.y+") "),r.push("<",this.type," ",'points="',i.join(""),'" style="',this.getSvgStyles(),'" transform="',this.getSvgTransform(),e," ",this.getSvgTransformMatrix(),'"/>\n'),t?t(r.join("")):r.join("")},_render:function(t,e){this.commonRender(t,e)&&(this._renderFill(t),(this.stroke||this.strokeDashArray)&&(t.closePath(),this._renderStroke(t)))},commonRender:function(t,e){var i,r=this.points.length;if(!r||isNaN(this.points[r-1].y))return!1;e||t.translate(-this.pathOffset.x,-this.pathOffset.y),t.beginPath(),t.moveTo(this.points[0].x,this.points[0].y);for(var n=0;r>n;n++)i=this.points[n],t.lineTo(i.x,i.y);return!0},_renderDashedStroke:function(t){e.Polyline.prototype._renderDashedStroke.call(this,t),t.closePath()},complexity:function(){return this.points.length}}),e.Polygon.ATTRIBUTE_NAMES=e.SHARED_ATTRIBUTES.concat(),e.Polygon.fromElement=function(t,r){if(!t)return null;r||(r={});var n=e.parsePointsAttribute(t.getAttribute("points")),s=e.parseAttributes(t,e.Polygon.ATTRIBUTE_NAMES);return new e.Polygon(n,i(s,r))},void(e.Polygon.fromObject=function(t){return new e.Polygon(t.points,t,!0)}))}("undefined"!=typeof exports?exports:this),function(t){"use strict";var e=t.fabric||(t.fabric={}),i=e.util.array.min,r=e.util.array.max,n=e.util.object.extend,s=Object.prototype.toString,o=e.util.drawArc,a={m:2,l:2,h:1,v:1,c:6,s:4,q:4,t:2,a:7},h={m:"l",M:"L"};return e.Path?void e.warn("fabric.Path is already defined"):(e.Path=e.util.createClass(e.Object,{type:"path",path:null,minX:0,minY:0,initialize:function(t,e){e=e||{},this.setOptions(e),t||(t=[]);var i="[object Array]"===s.call(t);this.path=i?t:t.match&&t.match(/[mzlhvcsqta][^mzlhvcsqta]*/gi),this.path&&(i||(this.path=this._parsePath()),this._setPositionDimensions(e),e.sourcePath&&this.setSourcePath(e.sourcePath))},_setPositionDimensions:function(t){var e=this._parseDimensions();this.minX=e.left,this.minY=e.top,this.width=e.width,this.height=e.height,"undefined"==typeof t.left&&(this.left=e.left+("center"===this.originX?this.width/2:"right"===this.originX?this.width:0)),"undefined"==typeof t.top&&(this.top=e.top+("center"===this.originY?this.height/2:"bottom"===this.originY?this.height:0)),this.pathOffset=this.pathOffset||{x:this.minX+this.width/2,y:this.minY+this.height/2}},_render:function(t){var e,i,r,n=null,s=0,a=0,h=0,c=0,l=0,u=0,f=-this.pathOffset.x,d=-this.pathOffset.y;this.group&&"path-group"===this.group.type&&(f=0,d=0),t.beginPath();for(var g=0,p=this.path.length;p>g;++g){switch(e=this.path[g],e[0]){case"l":h+=e[1],c+=e[2],t.lineTo(h+f,c+d);break;case"L":h=e[1],c=e[2],t.lineTo(h+f,c+d);break;case"h":h+=e[1],t.lineTo(h+f,c+d);break;case"H":h=e[1],t.lineTo(h+f,c+d);break;case"v":c+=e[1],t.lineTo(h+f,c+d);break;case"V":c=e[1],t.lineTo(h+f,c+d);break;case"m":h+=e[1],c+=e[2],s=h,a=c,t.moveTo(h+f,c+d);break;case"M":h=e[1],c=e[2],s=h,a=c,t.moveTo(h+f,c+d);break;case"c":i=h+e[5],r=c+e[6],l=h+e[3],u=c+e[4],t.bezierCurveTo(h+e[1]+f,c+e[2]+d,l+f,u+d,i+f,r+d),h=i,c=r;break;case"C":h=e[5],c=e[6],l=e[3],u=e[4],t.bezierCurveTo(e[1]+f,e[2]+d,l+f,u+d,h+f,c+d);break;case"s":i=h+e[3],r=c+e[4],null===n[0].match(/[CcSs]/)?(l=h,u=c):(l=2*h-l,u=2*c-u),t.bezierCurveTo(l+f,u+d,h+e[1]+f,c+e[2]+d,i+f,r+d),l=h+e[1],u=c+e[2],h=i,c=r;break;case"S":i=e[3],r=e[4],null===n[0].match(/[CcSs]/)?(l=h,u=c):(l=2*h-l,u=2*c-u),t.bezierCurveTo(l+f,u+d,e[1]+f,e[2]+d,i+f,r+d),h=i,c=r,l=e[1],u=e[2];break;case"q":i=h+e[3],r=c+e[4],l=h+e[1],u=c+e[2],t.quadraticCurveTo(l+f,u+d,i+f,r+d),h=i,c=r;break;case"Q":i=e[3],r=e[4],t.quadraticCurveTo(e[1]+f,e[2]+d,i+f,r+d),h=i,c=r,l=e[1],u=e[2];break;case"t":i=h+e[1],r=c+e[2],null===n[0].match(/[QqTt]/)?(l=h,u=c):(l=2*h-l,u=2*c-u),t.quadraticCurveTo(l+f,u+d,i+f,r+d),h=i,c=r;break;case"T":i=e[1],r=e[2],null===n[0].match(/[QqTt]/)?(l=h,u=c):(l=2*h-l,u=2*c-u),t.quadraticCurveTo(l+f,u+d,i+f,r+d),h=i,c=r;break;case"a":o(t,h+f,c+d,[e[1],e[2],e[3],e[4],e[5],e[6]+h+f,e[7]+c+d]),h+=e[6],c+=e[7];break;case"A":o(t,h+f,c+d,[e[1],e[2],e[3],e[4],e[5],e[6]+f,e[7]+d]),h=e[6],c=e[7];break;case"z":case"Z":h=s,c=a,t.closePath()}n=e}this._renderFill(t),this._renderStroke(t)},toString:function(){return"#"},toObject:function(t){var e=n(this.callSuper("toObject",t),{path:this.path.map(function(t){return t.slice()}),pathOffset:this.pathOffset});return this.sourcePath&&(e.sourcePath=this.sourcePath),this.transformMatrix&&(e.transformMatrix=this.transformMatrix),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;s>n;n++)e.push(this.path[n].join(" "));var o=e.join(" ");return this.group&&"path-group"===this.group.type||(r=" translate("+-this.pathOffset.x+", "+-this.pathOffset.y+") "),i.push("\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;u>l;l++){for(t=this.path[l],r=t.slice(1).trim(),o.length=0;i=c.exec(r);)o.push(i[0]);n=[t.charAt(0)];for(var f=0,d=o.length;d>f;f++)e=parseFloat(o[f]),isNaN(e)||n.push(e);var g=n[0],p=a[g.toLowerCase()],v=h[g]||g;if(n.length-1>p)for(var m=1,b=n.length;b>m;m+=p)s.push([g].concat(n.slice(m,m+p))),g=v;else s.push(n)}return s},_parseDimensions:function(){for(var t,n,s,o,a=[],h=[],c=null,l=0,u=0,f=0,d=0,g=0,p=0,v=0,m=this.path.length;m>v;++v){switch(t=this.path[v],t[0]){case"l":f+=t[1],d+=t[2],o=[];break;case"L":f=t[1],d=t[2],o=[];break;case"h":f+=t[1],o=[];break;case"H":f=t[1],o=[];break;case"v":d+=t[1],o=[];break;case"V":d=t[1],o=[];break;case"m":f+=t[1],d+=t[2],l=f,u=d,o=[];break;case"M":f=t[1],d=t[2],l=f,u=d,o=[];break;case"c":n=f+t[5],s=d+t[6],g=f+t[3],p=d+t[4],o=e.util.getBoundsOfCurve(f,d,f+t[1],d+t[2],g,p,n,s),f=n,d=s;break;case"C":f=t[5],d=t[6],g=t[3],p=t[4],o=e.util.getBoundsOfCurve(f,d,t[1],t[2],g,p,f,d);break;case"s":n=f+t[3],s=d+t[4],null===c[0].match(/[CcSs]/)?(g=f,p=d):(g=2*f-g,p=2*d-p),o=e.util.getBoundsOfCurve(f,d,g,p,f+t[1],d+t[2],n,s),g=f+t[1],p=d+t[2],f=n,d=s;break;case"S":n=t[3],s=t[4],null===c[0].match(/[CcSs]/)?(g=f,p=d):(g=2*f-g,p=2*d-p),o=e.util.getBoundsOfCurve(f,d,g,p,t[1],t[2],n,s),f=n,d=s,g=t[1],p=t[2];break;case"q":n=f+t[3],s=d+t[4],g=f+t[1],p=d+t[2],o=e.util.getBoundsOfCurve(f,d,g,p,g,p,n,s),f=n,d=s;break;case"Q":g=t[1],p=t[2],o=e.util.getBoundsOfCurve(f,d,g,p,g,p,t[3],t[4]),f=t[3],d=t[4];break;case"t":n=f+t[1],s=d+t[2],null===c[0].match(/[QqTt]/)?(g=f,p=d):(g=2*f-g,p=2*d-p),o=e.util.getBoundsOfCurve(f,d,g,p,g,p,n,s),f=n,d=s;break;case"T":n=t[1],s=t[2],null===c[0].match(/[QqTt]/)?(g=f,p=d):(g=2*f-g,p=2*d-p),o=e.util.getBoundsOfCurve(f,d,g,p,g,p,n,s),f=n,d=s;break;case"a":o=e.util.getBoundsOfArc(f,d,t[1],t[2],t[3],t[4],t[5],t[6]+f,t[7]+d),f+=t[6],d+=t[7];break;case"A":o=e.util.getBoundsOfArc(f,d,t[1],t[2],t[3],t[4],t[5],t[6],t[7]),f=t[6],d=t[7];break;case"z":case"Z":f=l,d=u}c=t,o.forEach(function(t){a.push(t.x),h.push(t.y)}),a.push(f),h.push(d)}var b=i(a)||0,y=i(h)||0,_=r(a)||0,x=r(h)||0,S=_-b,C=x-y,w={left:b,top:y,width:S,height:C};return w}}),e.Path.fromObject=function(t,i){"string"==typeof t.path?e.loadSVGFromURL(t.path,function(r){var n=r[0],s=t.path;delete t.path,e.util.object.extend(n,t),n.setSourcePath(s),i(n)}):i(new e.Path(t.path,t))},e.Path.ATTRIBUTE_NAMES=e.SHARED_ATTRIBUTES.concat(["d"]),e.Path.fromElement=function(t,i,r){var s=e.parseAttributes(t,e.Path.ATTRIBUTE_NAMES);i&&i(new e.Path(s.d,n(s,r)))},void(e.Path.async=!0))}("undefined"!=typeof exports?exports:this),function(t){"use strict";var e=t.fabric||(t.fabric={}),i=e.util.object.extend,r=e.util.array.invoke,n=e.Object.prototype.toObject;return e.PathGroup?void e.warn("fabric.PathGroup is already defined"):(e.PathGroup=e.util.createClass(e.Path,{type:"path-group",fill:"",initialize:function(t,e){e=e||{},this.paths=t||[];for(var i=this.paths.length;i--;)this.paths[i].group=this;e.toBeParsed&&(this.parseDimensionsFromPaths(e),delete e.toBeParsed),this.setOptions(e),this.setCoords(),e.sourcePath&&this.setSourcePath(e.sourcePath)},parseDimensionsFromPaths:function(t){for(var i,r,n,s,o,a,h=[],c=[],l=this.paths.length;l--;){n=this.paths[l],s=n.height+n.strokeWidth,o=n.width+n.strokeWidth,i=[{x:n.left,y:n.top},{x:n.left+o,y:n.top},{x:n.left,y:n.top+s},{x:n.left+o,y:n.top+s}],a=this.paths[l].transformMatrix;for(var u=0;ui;++i)this.paths[i].render(t,!0);this.clipTo&&t.restore(),t.restore()}},_set:function(t,e){if("fill"===t&&e&&this.isSameColor())for(var i=this.paths.length;i--;)this.paths[i]._set(t,e);return this.callSuper("_set",t,e)},toObject:function(t){var e=i(n.call(this,t),{paths:r(this.getObjects(),"toObject",t)});return this.sourcePath&&(e.sourcePath=this.sourcePath),e},toDatalessObject:function(t){var e=this.toObject(t);return this.sourcePath&&(e.paths=this.sourcePath),e},toSVG:function(t){var e=this.getObjects(),i=this.getPointByOrigin("left","top"),r="translate("+i.x+" "+i.y+")",n=this._createBaseSVGMarkup();n.push("\n");for(var s=0,o=e.length;o>s;s++)n.push(" ",e[s].toSVG(t));return n.push("\n"),t?t(n.join("")):n.join("")},toString:function(){return"#"},isSameColor:function(){var t=this.getObjects()[0].get("fill")||"";return"string"!=typeof t?!1:(t=t.toLowerCase(),this.getObjects().every(function(e){var i=e.get("fill")||"";return"string"==typeof i&&i.toLowerCase()===t}))},complexity:function(){return this.paths.reduce(function(t,e){return t+(e&&e.complexity?e.complexity():0)},0)},getObjects:function(){return this.paths}}),e.PathGroup.fromObject=function(t,i){"string"==typeof t.paths?e.loadSVGFromURL(t.paths,function(r){var n=t.paths;delete t.paths;var s=e.util.groupSVGElements(r,t,n);i(s)}):e.util.enlivenObjects(t.paths,function(r){delete t.paths,i(new e.PathGroup(r,t))})},void(e.PathGroup.async=!0))}("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.array.invoke;if(!e.Group){var o={lockMovementX:!0,lockMovementY:!0,lockRotation:!0,lockScalingX:!0,lockScalingY:!0,lockUniScaling:!0};e.Group=e.util.createClass(e.Object,e.Collection,{type:"group",strokeWidth:0,initialize:function(t,e,i){e=e||{},this._objects=[],i&&this.callSuper("initialize",e),this._objects=t||[];for(var r=this._objects.length;r--;)this._objects[r].group=this;this.originalState={},e.originX&&(this.originX=e.originX),e.originY&&(this.originY=e.originY),i?this._updateObjectsCoords(!0):(this._calcBounds(),this._updateObjectsCoords(),this.callSuper("initialize",e)),this.setCoords(),this.saveCoords()},_updateObjectsCoords:function(t){for(var e=this._objects.length;e--;)this._updateObjectCoords(this._objects[e],t)},_updateObjectCoords:function(t,e){if(t.__origHasControls=t.hasControls,t.hasControls=!1,!e){var i=t.getLeft(),r=t.getTop(),n=this.getCenterPoint();t.set({originalLeft:i,originalTop:r,left:i-n.x,top:r-n.y}),t.setCoords()}},toString:function(){return"#"},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},_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},_onObjectAdded:function(t){t.group=this,t._set("canvas",this.canvas)},_onObjectRemoved:function(t){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){return i(this.callSuper("toObject",t),{objects:s(this._objects,"toObject",t)})},render:function(t){if(this.visible){t.save(),this.transformMatrix&&t.transform.apply(t,this.transformMatrix),this.transform(t),this._setShadow(t),this.clipTo&&e.util.clipContext(this,t);for(var i=0,r=this._objects.length;r>i;i++)this._renderObject(this._objects[i],t);this.clipTo&&t.restore(),t.restore()}},_renderControls:function(t,e){this.callSuper("_renderControls",t,e);for(var i=0,r=this._objects.length;r>i;i++)this._objects[i]._renderControls(t)},_renderObject:function(t,e){if(t.visible){var i=t.hasRotatingPoint;t.hasRotatingPoint=!1,t.render(e),t.hasRotatingPoint=i}},_restoreObjectsState:function(){return this._objects.forEach(this._restoreObjectState,this), -this},realizeTransform:function(t){var i=t.calcTransformMatrix(),r=e.util.qrDecompose(i),n=new e.Point(r.translateX,r.translateY);return t.scaleX=r.scaleX,t.scaleY=r.scaleY,t.skewX=r.skewX,t.skewY=r.skewY,t.angle=r.angle,t.flipX=!1,t.flipY=!1,t.setPositionByOrigin(n,"center","center"),t},_restoreObjectState:function(t){return this.realizeTransform(t),t.setCoords(),t.hasControls=t.__origHasControls,delete t.__origHasControls,t.set("active",!1),delete t.group,this},destroy:function(){return this._restoreObjectsState()},saveCoords:function(){return this._originalLeft=this.get("left"),this._originalTop=this.get("top"),this},hasMoved:function(){return this._originalLeft!==this.get("left")||this._originalTop!==this.get("top")},setObjectsCoords:function(){return this.forEachObject(function(t){t.setCoords()}),this},_calcBounds:function(t){for(var e,i,r,n=[],s=[],o=["tr","br","bl","tl"],a=0,h=this._objects.length,c=o.length;h>a;++a)for(e=this._objects[a],e.setCoords(),r=0;c>r;r++)i=o[r],n.push(e.oCoords[i].x),s.push(e.oCoords[i].y);this.set(this._getBounds(n,s,t))},_getBounds:function(t,i,s){var o=e.util.invertTransform(this.getViewportTransform()),a=e.util.transformPoint(new e.Point(r(t),r(i)),o),h=e.util.transformPoint(new e.Point(n(t),n(i)),o),c={width:h.x-a.x||0,height:h.y-a.y||0};return s||(c.left=a.x||0,c.top=a.y||0,"center"===this.originX&&(c.left+=c.width/2),"right"===this.originX&&(c.left+=c.width),"center"===this.originY&&(c.top+=c.height/2),"bottom"===this.originY&&(c.top+=c.height)),c},toSVG:function(t){var e=this._createBaseSVGMarkup();e.push('\n');for(var i=0,r=this._objects.length;r>i;i++)e.push(" ",this._objects[i].toSVG(t));return e.push("\n"),t?t(e.join("")):e.join("")},get:function(t){if(t in o){if(this[t])return this[t];for(var e=0,i=this._objects.length;i>e;e++)if(this._objects[e][t])return!0;return!1}return t in this.delegatedProperties?this._objects[0]&&this._objects[0].get(t):this[t]}}),e.Group.fromObject=function(t,i){e.util.enlivenObjects(t.objects,function(r){delete t.objects,i&&i(new e.Group(r,t,!0))})},e.Group.async=!0}}("undefined"!=typeof exports?exports:this),function(t){"use strict";var e=fabric.util.object.extend;return t.fabric||(t.fabric={}),t.fabric.Image?void fabric.warn("fabric.Image is already defined."):(fabric.Image=fabric.util.createClass(fabric.Object,{type:"image",crossOrigin:"",alignX:"none",alignY:"none",meetOrSlice:"meet",strokeWidth:0,_lastScaleX:1,_lastScaleY:1,initialize:function(t,e){e||(e={}),this.filters=[],this.resizeFilters=[],this.callSuper("initialize",e),this._initElement(t,e)},getElement:function(){return this._element},setElement:function(t,e,i){return this._element=t,this._originalElement=t,this._initConfig(i),0!==this.filters.length?this.applyFilters(e):e&&e(),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){t.save(),this._setStrokeStyles(t),t.beginPath(),t.strokeRect(-this.width/2,-this.height/2,this.width,this.height),t.closePath(),t.restore()},_renderDashedStroke:function(t){var e=-this.width/2,i=-this.height/2,r=this.width,n=this.height;t.save(),this._setStrokeStyles(t),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=[],r=this._originalElement;this.filters.forEach(function(t){t&&i.push(t.toObject())});var n=e(this.callSuper("toObject",t),{src:r?r.src||r._src:"",filters:i,crossOrigin:this.crossOrigin,alignX:this.alignX,alignY:this.alignY,meetOrSlice:this.meetOrSlice});return this.resizeFilters.length>0&&(n.resizeFilters=this.resizeFilters.map(function(t){return t&&t.toObject()})),this.includeDefaultValues||this._removeDefaultValues(n),n},toSVG:function(t){var e=this._createBaseSVGMarkup(),i=-this.width/2,r=-this.height/2,n="none";if(this.group&&"path-group"===this.group.type&&(i=this.left,r=this.top),"none"!==this.alignX&&"none"!==this.alignY&&(n="x"+this.alignX+"Y"+this.alignY+" "+this.meetOrSlice),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(){return this.getElement()?this.getElement().src||this.getElement()._src:void 0},setSrc:function(t,e,i){fabric.util.loadImage(t,function(t){return this.setElement(t,e,i)},this,i&&i.crossOrigin)},toString:function(){return'#'},clone:function(t,e){this.constructor.fromObject(this.toObject(e),t)},applyFilters:function(t,e,i,r){if(e=e||this.filters,i=i||this._originalElement){var n=i,s=fabric.util.createCanvasElement(),o=fabric.util.createImage(),a=this;return s.width=n.width,s.height=n.height,s.getContext("2d").drawImage(n,0,0,n.width,n.height),0===e.length?(this._element=i,t&&t(),s):(e.forEach(function(t){t&&t.applyTo(s,t.scaleX||a.scaleX,t.scaleY||a.scaleY),!r&&t&&"Resize"===t.type&&(a.width*=t.scaleX,a.height*=t.scaleY)}),o.width=s.width,o.height=s.height,fabric.isLikelyNode?(o.src=s.toBuffer(void 0,fabric.Image.pngCompression),a._element=o,!r&&(a._filteredEl=o),t&&t()):(o.onload=function(){a._element=o,!r&&(a._filteredEl=o),t&&t(),o.onload=s=n=null},o.src=s.toDataURL("image/png")),s)}},_render:function(t,e){var i,r,n,s=this._findMargins();i=e?this.left:-this.width/2,r=e?this.top:-this.height/2,"slice"===this.meetOrSlice&&(t.beginPath(),t.rect(i,r,this.width,this.height),t.clip()),this.isMoving===!1&&this.resizeFilters.length&&this._needsResize()?(this._lastScaleX=this.scaleX,this._lastScaleY=this.scaleY,n=this.applyFilters(null,this.resizeFilters,this._filteredEl||this._originalElement,!0)):n=this._element,n&&t.drawImage(n,i+s.marginX,r+s.marginY,s.width,s.height),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),null,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},complexity:function(){return 1}}),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){fabric.Image.prototype._initFilters.call(t,t.filters,function(r){t.filters=r||[],fabric.Image.prototype._initFilters.call(t,t.resizeFilters,function(r){t.resizeFilters=r||[];var n=new fabric.Image(i,t);e&&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".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,void(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}}),fabric.Image.filters=fabric.Image.filters||{},fabric.Image.filters.BaseFilter=fabric.util.createClass({type:"BaseFilter",initialize:function(t){t&&this.setOptions(t)},setOptions:function(t){for(var e in t)this[e]=t[e]},toObject:function(){return{type:this.type}},toJSON:function(){return this.toObject()}}),function(t){"use strict";var e=t.fabric||(t.fabric={}),i=e.util.object.extend;e.Image.filters.Brightness=e.util.createClass(e.Image.filters.BaseFilter,{type:"Brightness",initialize:function(t){t=t||{},this.brightness=t.brightness||0},applyTo:function(t){for(var e=t.getContext("2d"),i=e.getImageData(0,0,t.width,t.height),r=i.data,n=this.brightness,s=0,o=r.length;o>s;s+=4)r[s]+=n,r[s+1]+=n,r[s+2]+=n;e.putImageData(i,0,0)},toObject:function(){return i(this.callSuper("toObject"),{brightness:this.brightness})}}),e.Image.filters.Brightness.fromObject=function(t){return new e.Image.filters.Brightness(t)}}("undefined"!=typeof exports?exports:this),function(t){"use strict";var e=t.fabric||(t.fabric={}),i=e.util.object.extend;e.Image.filters.Convolute=e.util.createClass(e.Image.filters.BaseFilter,{type:"Convolute",initialize:function(t){t=t||{},this.opaque=t.opaque,this.matrix=t.matrix||[0,0,0,0,1,0,0,0,0]},applyTo:function(t){for(var e,i,r,n,s,o,a,h,c,l=this.matrix,u=t.getContext("2d"),f=u.getImageData(0,0,t.width,t.height),d=Math.round(Math.sqrt(l.length)),g=Math.floor(d/2),p=f.data,v=f.width,m=f.height,b=u.createImageData(v,m),y=b.data,_=this.opaque?1:0,x=0;m>x;x++)for(var S=0;v>S;S++){s=4*(x*v+S),e=0,i=0,r=0,n=0;for(var C=0;d>C;C++)for(var w=0;d>w;w++)a=x+C-g,o=S+w-g,0>a||a>m||0>o||o>v||(h=4*(a*v+o),c=l[C*d+w],e+=p[h]*c,i+=p[h+1]*c,r+=p[h+2]*c,n+=p[h+3]*c);y[s]=e,y[s+1]=i,y[s+2]=r,y[s+3]=n+_*(255-n)}u.putImageData(b,0,0)},toObject:function(){return i(this.callSuper("toObject"),{opaque:this.opaque,matrix:this.matrix})}}),e.Image.filters.Convolute.fromObject=function(t){return new e.Image.filters.Convolute(t)}}("undefined"!=typeof exports?exports:this),function(t){"use strict";var e=t.fabric||(t.fabric={}),i=e.util.object.extend;e.Image.filters.GradientTransparency=e.util.createClass(e.Image.filters.BaseFilter,{type:"GradientTransparency",initialize:function(t){t=t||{},this.threshold=t.threshold||100},applyTo:function(t){for(var e=t.getContext("2d"),i=e.getImageData(0,0,t.width,t.height),r=i.data,n=this.threshold,s=r.length,o=0,a=r.length;a>o;o+=4)r[o+3]=n+255*(s-o)/s;e.putImageData(i,0,0)},toObject:function(){return i(this.callSuper("toObject"),{threshold:this.threshold})}}),e.Image.filters.GradientTransparency.fromObject=function(t){return new e.Image.filters.GradientTransparency(t)}}("undefined"!=typeof exports?exports:this),function(t){"use strict";var e=t.fabric||(t.fabric={});e.Image.filters.Grayscale=e.util.createClass(e.Image.filters.BaseFilter,{type:"Grayscale",applyTo:function(t){for(var e,i=t.getContext("2d"),r=i.getImageData(0,0,t.width,t.height),n=r.data,s=r.width*r.height*4,o=0;s>o;)e=(n[o]+n[o+1]+n[o+2])/3,n[o]=e,n[o+1]=e,n[o+2]=e,o+=4;i.putImageData(r,0,0)}}),e.Image.filters.Grayscale.fromObject=function(){return new e.Image.filters.Grayscale}}("undefined"!=typeof exports?exports:this),function(t){"use strict";var e=t.fabric||(t.fabric={});e.Image.filters.Invert=e.util.createClass(e.Image.filters.BaseFilter,{type:"Invert",applyTo:function(t){var e,i=t.getContext("2d"),r=i.getImageData(0,0,t.width,t.height),n=r.data,s=n.length;for(e=0;s>e;e+=4)n[e]=255-n[e],n[e+1]=255-n[e+1],n[e+2]=255-n[e+2];i.putImageData(r,0,0)}}),e.Image.filters.Invert.fromObject=function(){return new e.Image.filters.Invert}}("undefined"!=typeof exports?exports:this),function(t){"use strict";var e=t.fabric||(t.fabric={}),i=e.util.object.extend;e.Image.filters.Mask=e.util.createClass(e.Image.filters.BaseFilter,{type:"Mask",initialize:function(t){t=t||{},this.mask=t.mask,this.channel=[0,1,2,3].indexOf(t.channel)>-1?t.channel:0},applyTo:function(t){if(this.mask){var i,r=t.getContext("2d"),n=r.getImageData(0,0,t.width,t.height),s=n.data,o=this.mask.getElement(),a=e.util.createCanvasElement(),h=this.channel,c=n.width*n.height*4;a.width=t.width,a.height=t.height,a.getContext("2d").drawImage(o,0,0,t.width,t.height);var l=a.getContext("2d").getImageData(0,0,t.width,t.height),u=l.data;for(i=0;c>i;i+=4)s[i+3]=u[i+h];r.putImageData(n,0,0)}},toObject:function(){return i(this.callSuper("toObject"),{mask:this.mask.toObject(),channel:this.channel})}}),e.Image.filters.Mask.fromObject=function(t,i){e.util.loadImage(t.mask.src,function(r){t.mask=new e.Image(r,t.mask),i&&i(new e.Image.filters.Mask(t))})},e.Image.filters.Mask.async=!0}("undefined"!=typeof exports?exports:this),function(t){"use strict";var e=t.fabric||(t.fabric={}),i=e.util.object.extend;e.Image.filters.Noise=e.util.createClass(e.Image.filters.BaseFilter,{type:"Noise",initialize:function(t){t=t||{},this.noise=t.noise||0},applyTo:function(t){for(var e,i=t.getContext("2d"),r=i.getImageData(0,0,t.width,t.height),n=r.data,s=this.noise,o=0,a=n.length;a>o;o+=4)e=(.5-Math.random())*s,n[o]+=e,n[o+1]+=e,n[o+2]+=e;i.putImageData(r,0,0)},toObject:function(){return i(this.callSuper("toObject"),{noise:this.noise})}}),e.Image.filters.Noise.fromObject=function(t){return new e.Image.filters.Noise(t)}}("undefined"!=typeof exports?exports:this),function(t){"use strict";var e=t.fabric||(t.fabric={}),i=e.util.object.extend;e.Image.filters.Pixelate=e.util.createClass(e.Image.filters.BaseFilter,{type:"Pixelate",initialize:function(t){t=t||{},this.blocksize=t.blocksize||4},applyTo:function(t){var e,i,r,n,s,o,a,h=t.getContext("2d"),c=h.getImageData(0,0,t.width,t.height),l=c.data,u=c.height,f=c.width;for(i=0;u>i;i+=this.blocksize)for(r=0;f>r;r+=this.blocksize){e=4*i*f+4*r,n=l[e],s=l[e+1],o=l[e+2],a=l[e+3];for(var d=i,g=i+this.blocksize;g>d;d++)for(var p=r,v=r+this.blocksize;v>p;p++)e=4*d*f+4*p,l[e]=n,l[e+1]=s,l[e+2]=o,l[e+3]=a}h.putImageData(c,0,0)},toObject:function(){return i(this.callSuper("toObject"),{blocksize:this.blocksize})}}),e.Image.filters.Pixelate.fromObject=function(t){return new e.Image.filters.Pixelate(t)}}("undefined"!=typeof exports?exports:this),function(t){"use strict";var e=t.fabric||(t.fabric={}),i=e.util.object.extend;e.Image.filters.RemoveWhite=e.util.createClass(e.Image.filters.BaseFilter,{type:"RemoveWhite",initialize:function(t){t=t||{},this.threshold=t.threshold||30,this.distance=t.distance||20},applyTo:function(t){for(var e,i,r,n=t.getContext("2d"),s=n.getImageData(0,0,t.width,t.height),o=s.data,a=this.threshold,h=this.distance,c=255-a,l=Math.abs,u=0,f=o.length;f>u;u+=4)e=o[u],i=o[u+1],r=o[u+2],e>c&&i>c&&r>c&&l(e-i)e;e+=4)i=.3*s[e]+.59*s[e+1]+.11*s[e+2],s[e]=i+100,s[e+1]=i+50,s[e+2]=i+255;r.putImageData(n,0,0)}}),e.Image.filters.Sepia.fromObject=function(){return new e.Image.filters.Sepia}}("undefined"!=typeof exports?exports:this),function(t){"use strict";var e=t.fabric||(t.fabric={});e.Image.filters.Sepia2=e.util.createClass(e.Image.filters.BaseFilter,{type:"Sepia2",applyTo:function(t){var e,i,r,n,s=t.getContext("2d"),o=s.getImageData(0,0,t.width,t.height),a=o.data,h=a.length;for(e=0;h>e;e+=4)i=a[e],r=a[e+1],n=a[e+2],a[e]=(.393*i+.769*r+.189*n)/1.351,a[e+1]=(.349*i+.686*r+.168*n)/1.203,a[e+2]=(.272*i+.534*r+.131*n)/2.14;s.putImageData(o,0,0)}}),e.Image.filters.Sepia2.fromObject=function(){return new e.Image.filters.Sepia2}}("undefined"!=typeof exports?exports:this),function(t){"use strict";var e=t.fabric||(t.fabric={}),i=e.util.object.extend;e.Image.filters.Tint=e.util.createClass(e.Image.filters.BaseFilter,{type:"Tint",initialize:function(t){t=t||{},this.color=t.color||"#000000",this.opacity="undefined"!=typeof t.opacity?t.opacity:new e.Color(this.color).getAlpha()},applyTo:function(t){var i,r,n,s,o,a,h,c,l,u=t.getContext("2d"),f=u.getImageData(0,0,t.width,t.height),d=f.data,g=d.length;for(l=new e.Color(this.color).getSource(),r=l[0]*this.opacity,n=l[1]*this.opacity,s=l[2]*this.opacity,c=1-this.opacity,i=0;g>i;i+=4)o=d[i],a=d[i+1],h=d[i+2],d[i]=r+o*c,d[i+1]=n+a*c,d[i+2]=s+h*c;u.putImageData(f,0,0)},toObject:function(){return i(this.callSuper("toObject"),{color:this.color,opacity:this.opacity})}}),e.Image.filters.Tint.fromObject=function(t){return new e.Image.filters.Tint(t)}}("undefined"!=typeof exports?exports:this),function(t){"use strict";var e=t.fabric||(t.fabric={}),i=e.util.object.extend;e.Image.filters.Multiply=e.util.createClass(e.Image.filters.BaseFilter,{type:"Multiply",initialize:function(t){t=t||{},this.color=t.color||"#000000"},applyTo:function(t){var i,r,n=t.getContext("2d"),s=n.getImageData(0,0,t.width,t.height),o=s.data,a=o.length;for(r=new e.Color(this.color).getSource(),i=0;a>i;i+=4)o[i]*=r[0]/255,o[i+1]*=r[1]/255,o[i+2]*=r[2]/255;n.putImageData(s,0,0)},toObject:function(){return i(this.callSuper("toObject"),{color:this.color})}}),e.Image.filters.Multiply.fromObject=function(t){return new e.Image.filters.Multiply(t)}}("undefined"!=typeof exports?exports:this),function(t){"use strict";var e=t.fabric;e.Image.filters.Blend=e.util.createClass({type:"Blend",initialize:function(t){t=t||{},this.color=t.color||"#000",this.image=t.image||!1,this.mode=t.mode||"multiply",this.alpha=t.alpha||1},applyTo:function(t){var i,r,n,s,o,a,h,c,l,u,f=t.getContext("2d"),d=f.getImageData(0,0,t.width,t.height),g=d.data,p=!1;if(this.image){p=!0;var v=e.util.createCanvasElement();v.width=this.image.width,v.height=this.image.height;var m=new e.StaticCanvas(v);m.add(this.image);var b=m.getContext("2d");u=b.getImageData(0,0,m.width,m.height).data}else u=new e.Color(this.color).getSource(),i=u[0]*this.alpha,r=u[1]*this.alpha,n=u[2]*this.alpha;for(var y=0,_=g.length;_>y;y+=4)switch(s=g[y],o=g[y+1],a=g[y+2],p&&(i=u[y]*this.alpha,r=u[y+1]*this.alpha,n=u[y+2]*this.alpha),this.mode){case"multiply":g[y]=s*i/255,g[y+1]=o*r/255,g[y+2]=a*n/255;break;case"screen":g[y]=1-(1-s)*(1-i),g[y+1]=1-(1-o)*(1-r),g[y+2]=1-(1-a)*(1-n);break;case"add":g[y]=Math.min(255,s+i),g[y+1]=Math.min(255,o+r),g[y+2]=Math.min(255,a+n);break;case"diff":case"difference":g[y]=Math.abs(s-i),g[y+1]=Math.abs(o-r),g[y+2]=Math.abs(a-n);break;case"subtract":h=s-i,c=o-r,l=a-n,g[y]=0>h?0:h,g[y+1]=0>c?0:c,g[y+2]=0>l?0:l;break;case"darken":g[y]=Math.min(s,i),g[y+1]=Math.min(o,r),g[y+2]=Math.min(a,n);break;case"lighten":g[y]=Math.max(s,i),g[y+1]=Math.max(o,r),g[y+2]=Math.max(a,n)}f.putImageData(d,0,0)},toObject:function(){return{color:this.color,image:this.image,mode:this.mode,alpha:this.alpha}}}),e.Image.filters.Blend.fromObject=function(t){return new e.Image.filters.Blend(t)}}("undefined"!=typeof exports?exports:this),function(t){"use strict";var e=t.fabric||(t.fabric={}),i=Math.pow,r=Math.floor,n=Math.sqrt,s=Math.abs,o=Math.max,a=Math.round,h=Math.sin,c=Math.ceil;e.Image.filters.Resize=e.util.createClass(e.Image.filters.BaseFilter,{type:"Resize",resizeType:"hermite",scaleX:0,scaleY:0,lanczosLobes:3,applyTo:function(t,e,i){this.rcpScaleX=1/e,this.rcpScaleY=1/i;var r,n=t.width,s=t.height,o=a(n*e),h=a(s*i);"sliceHack"===this.resizeType&&(r=this.sliceByTwo(t,n,s,o,h)),"hermite"===this.resizeType&&(r=this.hermiteFastResize(t,n,s,o,h)),"bilinear"===this.resizeType&&(r=this.bilinearFiltering(t,n,s,o,h)),"lanczos"===this.resizeType&&(r=this.lanczosResize(t,n,s,o,h)),t.width=o,t.height=h,t.getContext("2d").putImageData(r,0,0)},sliceByTwo:function(t,i,n,s,a){var h,c=t.getContext("2d"),l=.5,u=.5,f=1,d=1,g=!1,p=!1,v=i,m=n,b=e.util.createCanvasElement(),y=b.getContext("2d");for(s=r(s),a=r(a),b.width=o(s,i),b.height=o(a,n),s>i&&(l=2,f=-1),a>n&&(u=2,d=-1),h=c.getImageData(0,0,i,n),t.width=o(s,i),t.height=o(a,n),c.putImageData(h,0,0);!g||!p;)i=v,n=m,s*ft)return 0;if(e*=Math.PI,s(e)<1e-16)return 1;var i=e/t;return h(e)*h(i)/e/i}}function f(t){var h,c,u,d,g,j,A,P,M,L,D;for(T.x=(t+.5)*y,k.x=r(T.x),h=0;l>h;h++){for(T.y=(h+.5)*_,k.y=r(T.y),g=0,j=0,A=0,P=0,M=0,c=k.x-C;c<=k.x+C;c++)if(!(0>c||c>=e)){L=r(1e3*s(c-T.x)),O[L]||(O[L]={});for(var E=k.y-w;E<=k.y+w;E++)0>E||E>=o||(D=r(1e3*s(E-T.y)),O[L][D]||(O[L][D]=b(n(i(L*x,2)+i(D*S,2))/1e3)),u=O[L][D],u>0&&(d=4*(E*e+c),g+=u,j+=u*v[d],A+=u*v[d+1],P+=u*v[d+2],M+=u*v[d+3]))}d=4*(h*a+t),m[d]=j/g,m[d+1]=A/g,m[d+2]=P/g,m[d+3]=M/g}return++tf;f++)for(d=0;n>d;d++)for(l=r(_*d),u=r(x*f),g=_*d-l,p=x*f-u,b=4*(u*e+l),v=0;4>v;v++)o=O[b+v],a=O[b+4+v],h=O[b+C+v],c=O[b+C+4+v],m=o*(1-g)*(1-p)+a*g*(1-p)+h*p*(1-g)+c*g*p,k[y++]=m;return T},hermiteFastResize:function(t,e,i,o,a){for(var h=this.rcpScaleX,l=this.rcpScaleY,u=c(h/2),f=c(l/2),d=t.getContext("2d"),g=d.getImageData(0,0,e,i),p=g.data,v=d.getImageData(0,0,o,a),m=v.data,b=0;a>b;b++)for(var y=0;o>y;y++){for(var _=4*(y+b*o),x=0,S=0,C=0,w=0,O=0,T=0,k=0,j=(b+.5)*l,A=r(b*l);(b+1)*l>A;A++)for(var P=s(j-(A+.5))/f,M=(y+.5)*h,L=P*P,D=r(y*h);(y+1)*h>D;D++){var E=s(M-(D+.5))/u,I=n(L+E*E);I>1&&-1>I||(x=2*I*I*I-3*I*I+1,x>0&&(E=4*(D+A*e),k+=x*p[E+3],C+=x,p[E+3]<255&&(x=x*p[E+3]/250),w+=x*p[E],O+=x*p[E+1],T+=x*p[E+2],S+=x))}m[_]=w/S,m[_+1]=O/S,m[_+2]=T/S,m[_+3]=k/C}return v},toObject:function(){return{type:this.type,scaleX:this.scaleX,scaleY:this.scaleY,resizeType:this.resizeType,lanczosLobes:this.lanczosLobes}}}),e.Image.filters.Resize.fromObject=function(t){return new e.Image.filters.Resize(t)}}("undefined"!=typeof exports?exports:this),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.StaticCanvas.supports("setLineDash"),o=e.Object.NUM_FRACTION_DIGITS;if(e.Text)return void e.warn("fabric.Text is already defined");var a=e.Object.prototype.stateProperties.concat();a.push("fontFamily","fontWeight","fontSize","text","textDecoration","textAlign","fontStyle","lineHeight","textBackgroundColor"),e.Text=e.util.createClass(e.Object,{_dimensionAffectingProps:{fontSize:!0,fontWeight:!0,fontFamily:!0,fontStyle:!0,lineHeight:!0,stroke:!0,strokeWidth:!0,text:!0,textAlign:!0},_reNewline:/\r?\n/,_reSpacesAndTabs:/[ \t\r]+/g,type:"text",fontSize:40,fontWeight:"normal",fontFamily:"Times New Roman",textDecoration:"",textAlign:"left",fontStyle:"",lineHeight:1.16,textBackgroundColor:"",stateProperties:a,stroke:null,shadow:null,_fontSizeFraction:.25,_fontSizeMult:1.13,initialize:function(t,e){e=e||{},this.text=t,this.__skipDimension=!0,this.setOptions(e),this.__skipDimension=!1,this._initDimensions()},_initDimensions:function(t){this.__skipDimension||(t||(t=e.util.createCanvasElement().getContext("2d"),this._setTextStyles(t)),this._textLines=this._splitTextIntoLines(),this._clearCache(),this._cacheLinesWidth="justify"!==this.textAlign,this.width=this._getTextWidth(t),this._cacheLinesWidth=!0,this.height=this._getTextHeight(t))},toString:function(){return"#'},_render:function(t){this.clipTo&&e.util.clipContext(this,t),this._setOpacity(t),this._setShadow(t),this._setupCompositeOperation(t),this._renderTextBackground(t),this._setStrokeStyles(t),this._setFillStyles(t),this._renderText(t),this._renderTextDecoration(t),this.clipTo&&t.restore()},_renderText:function(t){this._translateForTextAlign(t),this._renderTextFill(t),this._renderTextStroke(t),this._translateForTextAlign(t,!0)},_translateForTextAlign:function(t,e){if("left"!==this.textAlign&&"justify"!==this.textAlign){var i=e?-1:1;t.translate("center"===this.textAlign?i*this.width/2:i*this.width,0)}},_setTextStyles:function(t){t.textBaseline="alphabetic",this.skipTextAlign||(t.textAlign=this.textAlign),t.font=this._getFontDeclaration()},_getTextHeight:function(){return this._textLines.length*this._getHeightOfLine()},_getTextWidth:function(t){for(var e=this._getLineWidth(t,0),i=1,r=this._textLines.length;r>i;i++){var n=this._getLineWidth(t,i);n>e&&(e=n)}return e},_renderChars:function(t,e,i,r,n){var s=t.slice(0,-4);if(this[s].toLive){var o=-this.width/2+this[s].offsetX||0,a=-this.height/2+this[s].offsetY||0;e.save(),e.translate(o,a),r-=o,n-=a}e[t](i,r,n),this[s].toLive&&e.restore()},_renderTextLine:function(t,e,i,r,n,s){n-=this.fontSize*this._fontSizeFraction;var o=this._getLineWidth(e,s);if("justify"!==this.textAlign||this.width0?u/f:0,g=0,p=0,v=h.length;v>p;p++){for(;" "===i[c]&&ci;i++){var n=this._getHeightOfLine(t,i),s=n/this.lineHeight;this._renderTextLine("fillText",t,this._textLines[i],this._getLeftOffset(),this._getTopOffset()+e+s,i),e+=n}},_renderTextStroke:function(t){if(this.stroke&&0!==this.strokeWidth||!this.isEmptyStyles()){var e=0;this.shadow&&!this.shadow.affectStroke&&this._removeShadow(t),t.save(),this.strokeDashArray&&(1&this.strokeDashArray.length&&this.strokeDashArray.push.apply(this.strokeDashArray,this.strokeDashArray),s&&t.setLineDash(this.strokeDashArray)),t.beginPath();for(var i=0,r=this._textLines.length;r>i;i++){var n=this._getHeightOfLine(t,i),o=n/this.lineHeight;this._renderTextLine("strokeText",t,this._textLines[i],this._getLeftOffset(),this._getTopOffset()+e+o,i),e+=n}t.closePath(),t.restore()}},_getHeightOfLine:function(){return this.fontSize*this._fontSizeMult*this.lineHeight},_renderTextBackground:function(t){this._renderTextBoxBackground(t),this._renderTextLinesBackground(t)},_renderTextBoxBackground:function(t){this.backgroundColor&&(t.fillStyle=this.backgroundColor,t.fillRect(this._getLeftOffset(),this._getTopOffset(),this.width,this.height),this._removeShadow(t))},_renderTextLinesBackground:function(t){if(this.textBackgroundColor){var e,i,r,n=0;t.fillStyle=this.textBackgroundColor;for(var s=0,o=this._textLines.length;o>s;s++)e=this._getHeightOfLine(t,s),""!==this._textLines[s]&&(i="justify"===this.textAlign?this.width:this._getLineWidth(t,s),r=this._getLineLeftOffset(i),t.fillRect(this._getLeftOffset()+r,this._getTopOffset()+n,i,e/this.lineHeight)),n+=e;this._removeShadow(t)}},_getLineLeftOffset:function(t){return"center"===this.textAlign?(this.width-t)/2:"right"===this.textAlign?this.width-t:0},_clearCache:function(){this.__lineWidths=[],this.__lineHeights=[]},_shouldClearCache:function(){var t=!1;if(this._forceClearCache)return this._forceClearCache=!1,!0;for(var e in this._dimensionAffectingProps)this["__"+e]!==this[e]&&(this["__"+e]=this[e],t=!0);return t},_getLineWidth:function(t,e){if(this.__lineWidths[e])return this.__lineWidths[e];var i,r,n=this._textLines[e];return""===n?i=0:"justify"===this.textAlign&&this._cacheLinesWidth?(r=n.split(/\s+/),i=r.length>1?this.width:t.measureText(n).width):i=t.measureText(n).width,this._cacheLinesWidth&&(this.__lineWidths[e]=i),i},_renderTextDecoration:function(t){function e(e){var n,s,o,a,h,c,l,u=0;for(n=0,s=r._textLines.length;s>n;n++){for(h=r._getLineWidth(t,n),c=r._getLineLeftOffset(h),l=r._getHeightOfLine(t,n),o=0,a=e.length;a>o;o++)t.fillRect(r._getLeftOffset()+c,u+(r._fontSizeMult-1+e[o])*r.fontSize-i,h,r.fontSize/15);u+=l}}if(this.textDecoration){var i=this.height/2,r=this,n=[];this.textDecoration.indexOf("underline")>-1&&n.push(.85),this.textDecoration.indexOf("line-through")>-1&&n.push(.43),this.textDecoration.indexOf("overline")>-1&&n.push(-.12),n.length>0&&e(n)}},_getFontDeclaration:function(){return[e.isLikelyNode?this.fontWeight:this.fontStyle,e.isLikelyNode?this.fontStyle:this.fontWeight,this.fontSize+"px",e.isLikelyNode?'"'+this.fontFamily+'"':this.fontFamily].join(" ")},render:function(t,e){this.visible&&(t.save(),this._setTextStyles(t),this._shouldClearCache()&&this._initDimensions(t),e||this.transform(t),this.transformMatrix&&t.transform.apply(t,this.transformMatrix),this.group&&"path-group"===this.group.type&&t.translate(this.left,this.top),this._render(t),t.restore())},_splitTextIntoLines:function(){return this.text.split(this._reNewline)},toObject:function(t){var e=i(this.callSuper("toObject",t),{text:this.text,fontSize:this.fontSize,fontWeight:this.fontWeight,fontFamily:this.fontFamily,fontStyle:this.fontStyle,lineHeight:this.lineHeight,textDecoration:this.textDecoration,textAlign:this.textAlign,textBackgroundColor:this.textBackgroundColor});return this.includeDefaultValues||this._removeDefaultValues(e),e},toSVG:function(t){var e=this._createBaseSVGMarkup(),i=this._getSVGLeftTopOffsets(this.ctx),r=this._getSVGTextAndBg(i.textTop,i.textLeft);return this._wrapSVGTextAndBg(e,r),t?t(e.join("")):e.join("")},_getSVGLeftTopOffsets:function(t){var e=this._getHeightOfLine(t,0),i=-this.width/2,r=0;return{textLeft:i+(this.group&&"path-group"===this.group.type?this.left:0),textTop:r+(this.group&&"path-group"===this.group.type?-this.top:0),lineTop:e}},_wrapSVGTextAndBg:function(t,e){var i=!0,r=this.getSvgFilter(),n=""===r?"":' style="'+r+'"';t.push(' \n",e.textBgRects.join("")," \n',e.textSpans.join("")," \n"," \n"); - -},_getSVGTextAndBg:function(t,e){var i=[],r=[],n=0;this._setSVGBg(r);for(var s=0,o=this._textLines.length;o>s;s++)this.textBackgroundColor&&this._setSVGTextLineBg(r,s,e,t,n),this._setSVGTextLineText(s,i,n,e,t,r),n+=this._getHeightOfLine(this.ctx,s);return{textSpans:i,textBgRects:r}},_setSVGTextLineText:function(t,i,r,s,a){var h=this.fontSize*(this._fontSizeMult-this._fontSizeFraction)-a+r-this.height/2;return"justify"===this.textAlign?void this._setSVGTextLineJustifed(t,i,h,s):void i.push(' ",e.util.string.escapeXml(this._textLines[t]),"\n")},_setSVGTextLineJustifed:function(t,i,r,s){var a=e.util.createCanvasElement().getContext("2d");this._setTextStyles(a);var h,c,l=this._textLines[t],u=l.split(/\s+/),f=this._getWidthOfWords(a,l),d=this.width-f,g=u.length-1,p=g>0?d/g:0,v=this._getFillAttributes(this.fill);for(s+=this._getLineLeftOffset(this._getLineWidth(a,t)),t=0,c=u.length;c>t;t++)h=u[t],i.push(' ",e.util.string.escapeXml(h),"\n"),s+=this._getWidthOfWords(a,h)+p},_setSVGTextLineBg:function(t,e,i,r,s){t.push(" \n')},_setSVGBg:function(t){this.backgroundColor&&t.push(" \n')},_getFillAttributes:function(t){var i=t&&"string"==typeof t?new e.Color(t):"";return i&&i.getSource()&&1!==i.getAlpha()?'opacity="'+i.getAlpha()+'" fill="'+i.setAlpha(1).toRgb()+'"':'fill="'+t+'"'},_set:function(t,e){this.callSuper("_set",t,e),t in this._dimensionAffectingProps&&(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,i){if(!t)return null;var r=e.parseAttributes(t,e.Text.ATTRIBUTE_NAMES);i=e.util.object.extend(i?e.util.object.clone(i):{},r),i.top=i.top||0,i.left=i.left||0,"dx"in r&&(i.left+=r.dx),"dy"in r&&(i.top+=r.dy),"fontSize"in i||(i.fontSize=e.Text.DEFAULT_SVG_FONT_SIZE),i.originX||(i.originX="left");var n="";"textContent"in t?n=t.textContent:"firstChild"in t&&null!==t.firstChild&&"data"in t.firstChild&&null!==t.firstChild.data&&(n=t.firstChild.data),n=n.replace(/^\s+|\s+$|\n+/g,"").replace(/\s+/g," ");var s=new e.Text(n,i),o=0;return"left"===s.originX&&(o=s.getWidth()/2),"right"===s.originX&&(o=-s.getWidth()/2),s.set({left:s.getLeft()+o,top:s.getTop()-s.getHeight()/2+s.fontSize*(.18+s._fontSizeFraction)}),s},e.Text.fromObject=function(t){return new e.Text(t.text,r(t))},e.util.createAccessors(e.Text)}("undefined"!=typeof exports?exports:this),function(){var t=fabric.util.object.clone;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,styles:null,caching:!0,_reSpace:/\s|\n/,_currentCursorOpacity:0,_selectionDirection:null,_abortCursorAnimation:!1,_charWidthsCache:{},__widthOfSpace:[],initialize:function(t,e){this.styles=e?e.styles||{}:{},this.callSuper("initialize",t,e),this.initBehavior()},_clearCache:function(){this.callSuper("_clearCache"),this.__widthOfSpace=[]},isEmptyStyles:function(){if(!this.styles)return!0;var t=this.styles;for(var e in t)for(var i in t[e])for(var r in t[e][i])return!1;return!0},setSelectionStart:function(t){t=Math.max(t,0),this.selectionStart!==t&&(this.fire("selection:changed"),this.canvas&&this.canvas.fire("text:selection:changed",{target:this}),this.selectionStart=t),this._updateTextarea()},setSelectionEnd:function(t){t=Math.min(t,this.text.length),this.selectionEnd!==t&&(this.fire("selection:changed"),this.canvas&&this.canvas.fire("text:selection:changed",{target:this}),this.selectionEnd=t),this._updateTextarea()},getSelectionStyles:function(t,e){if(2===arguments.length){for(var i=[],r=t;e>r;r++)i.push(this.getSelectionStyles(r));return i}var n=this.get2DCursorLocation(t),s=this._getStyleDeclaration(n.lineIndex,n.charIndex);return s||{}},setSelectionStyles:function(t){if(this.selectionStart===this.selectionEnd)this._extendStyles(this.selectionStart,t);else for(var e=this.selectionStart;ei;i++){if(t<=this._textLines[i].length)return{lineIndex:i,charIndex:t};t-=this._textLines[i].length+1}return{lineIndex:i-1,charIndex:this._textLines[i-1].length=a;a++){var h=this._getLineLeftOffset(this._getLineWidth(i,a))||0,c=this._getHeightOfLine(this.ctx,a),l=0,u=this._textLines[a];if(a===s)for(var f=0,d=u.length;d>f;f++)f>=r.charIndex&&(a!==o||fs&&o>a)l+=this._getLineWidth(i,a)||5;else if(a===o)for(var g=0,p=n.charIndex;p>g;g++)l+=this._getWidthOfChar(i,u[g],a,g);i.fillRect(e.left+h,e.top+e.topOffset,l,c),e.topOffset+=c}},_renderChars:function(t,e,i,r,n,s,o){if(this.isEmptyStyles())return this._renderCharsFast(t,e,i,r,n);o=o||0,this.skipTextAlign=!0,r-="center"===this.textAlign?this.width/2:"right"===this.textAlign?this.width:0;var a,h,c=this._getHeightOfLine(e,s),l=this._getLineLeftOffset(this._getLineWidth(e,s)),u="";r+=l||0,e.save(),n-=c/this.lineHeight*this._fontSizeFraction;for(var f=o,d=i.length+o;d>=f;f++)a=a||this.getCurrentCharStyle(s,f),h=this.getCurrentCharStyle(s,f+1),(this._hasStyleChanged(a,h)||f===d)&&(this._renderChar(t,e,s,f-1,u,r,n,c),u="",a=h),u+=i[f-o];e.restore()},_renderCharsFast:function(t,e,i,r,n){this.skipTextAlign=!1,"fillText"===t&&this.fill&&this.callSuper("_renderChars",t,e,i,r,n),"strokeText"===t&&(this.stroke&&this.strokeWidth>0||this.skipFillStrokeCheck)&&this.callSuper("_renderChars",t,e,i,r,n)},_renderChar:function(t,e,i,r,n,s,o,a){var h,c,l,u,f,d,g=this._getStyleDeclaration(i,r);g?(c=this._getHeightOfChar(e,n,i,r),u=g.stroke,l=g.fill,d=g.textDecoration):c=this.fontSize,u=(u||this.stroke)&&"strokeText"===t,l=(l||this.fill)&&"fillText"===t,g&&e.save(),h=this._applyCharStylesGetWidth(e,n,i,r,g||{}),d=d||this.textDecoration,g&&g.textBackgroundColor&&this._removeShadow(e),l&&e.fillText(n,s,o),u&&e.strokeText(n,s,o),(d||""!==d)&&(f=this._fontSizeFraction*a/this.lineHeight,this._renderCharDecoration(e,d,s,o,f,h,c)),g&&e.restore(),e.translate(h,0)},_hasStyleChanged:function(t,e){return t.fill!==e.fill||t.fontSize!==e.fontSize||t.textBackgroundColor!==e.textBackgroundColor||t.textDecoration!==e.textDecoration||t.fontFamily!==e.fontFamily||t.fontWeight!==e.fontWeight||t.fontStyle!==e.fontStyle||t.stroke!==e.stroke||t.strokeWidth!==e.strokeWidth},_renderCharDecoration:function(t,e,i,r,n,s,o){if(e){var a,h,c=o/15,l={underline:r+o/10,"line-through":r-o*(this._fontSizeFraction+this._fontSizeMult-1)+c,overline:r-(this._fontSizeMult-this._fontSizeFraction)*o},u=["underline","line-through","overline"];for(a=0;a-1&&t.fillRect(i,l[h],s,c)}},_renderTextLine:function(t,e,i,r,n,s){this.isEmptyStyles()||(n+=this.fontSize*(this._fontSizeFraction+.03)),this.callSuper("_renderTextLine",t,e,i,r,n,s)},_renderTextDecoration:function(t){return this.isEmptyStyles()?this.callSuper("_renderTextDecoration",t):void 0},_renderTextLinesBackground:function(t){this.callSuper("_renderTextLinesBackground",t);for(var e,i,r,n,s,o,a=0,h=this._getLeftOffset(),c=this._getTopOffset(),l=0,u=this._textLines.length;u>l;l++)if(e=this._getHeightOfLine(t,l),n=this._textLines[l],""!==n&&this.styles&&this._getLineStyle(l)){i=this._getLineWidth(t,l),r=this._getLineLeftOffset(i);for(var f=0,d=n.length;d>f;f++)o=this._getStyleDeclaration(l,f),o&&o.textBackgroundColor&&(s=n[f],t.fillStyle=o.textBackgroundColor,t.fillRect(h+r+this._getWidthOfCharsAt(t,l,f),c+a,this._getWidthOfChar(t,s,l,f)+1,e/this.lineHeight));a+=e}else a+=e},_getCacheProp:function(t,e){return t+e.fontFamily+e.fontSize+e.fontWeight+e.fontStyle+e.shadow},_applyCharStylesGetWidth:function(e,i,r,n,s){var o,a=this._getStyleDeclaration(r,n),h=s&&t(s)||t(a);this._applyFontStyles(h);var c=this._getCacheProp(i,h);if(!a&&this._charWidthsCache[c]&&this.caching)return this._charWidthsCache[c];"string"==typeof h.shadow&&(h.shadow=new fabric.Shadow(h.shadow));var l=h.fill||this.fill;return e.fillStyle=l.toLive?l.toLive(e,this):l,h.stroke&&(e.strokeStyle=h.stroke&&h.stroke.toLive?h.stroke.toLive(e,this):h.stroke),e.lineWidth=h.strokeWidth||this.strokeWidth,e.font=this._getFontDeclaration.call(h),h.shadow&&(h.scaleX=this.scaleX,h.scaleY=this.scaleY,h.canvas=this.canvas,this._setShadow.call(h,e)),this.caching&&this._charWidthsCache[c]||(o=e.measureText(i).width,this.caching&&(this._charWidthsCache[c]=o)),this._charWidthsCache[c]},_applyFontStyles:function(t){t.fontFamily||(t.fontFamily=this.fontFamily),t.fontSize||(t.fontSize=this.fontSize),t.fontWeight||(t.fontWeight=this.fontWeight),t.fontStyle||(t.fontStyle=this.fontStyle)},_getStyleDeclaration:function(e,i,r){return r?this.styles[e]&&this.styles[e][i]?t(this.styles[e][i]):{}:this.styles[e]&&this.styles[e][i]?this.styles[e][i]:null},_setStyleDeclaration:function(t,e,i){this.styles[t][e]=i},_deleteStyleDeclaration:function(t,e){delete this.styles[t][e]},_getLineStyle:function(t){return this.styles[t]},_setLineStyle:function(t,e){this.styles[t]=e},_deleteLineStyle:function(t){delete this.styles[t]},_getWidthOfChar:function(t,e,i,r){if("justify"===this.textAlign&&this._reSpacesAndTabs.test(e))return this._getWidthOfSpace(t,i);var n=this._getStyleDeclaration(i,r,!0);this._applyFontStyles(n);var s=this._getCacheProp(e,n);if(this._charWidthsCache[s]&&this.caching)return this._charWidthsCache[s];if(t){t.save();var o=this._applyCharStylesGetWidth(t,e,i,r);return t.restore(),o}},_getHeightOfChar:function(t,e,i){var r=this._getStyleDeclaration(e,i);return r&&r.fontSize?r.fontSize:this.fontSize},_getWidthOfCharsAt:function(t,e,i){var r,n,s=0;for(r=0;i>r;r++)n=this._textLines[e][r],s+=this._getWidthOfChar(t,n,e,r);return s},_getLineWidth:function(t,e){return this.__lineWidths[e]?this.__lineWidths[e]:(this.__lineWidths[e]=this._getWidthOfCharsAt(t,e,this._textLines[e].length),this.__lineWidths[e])},_getWidthOfSpace:function(t,e){if(this.__widthOfSpace[e])return this.__widthOfSpace[e];var i=this._textLines[e],r=this._getWidthOfWords(t,i,e,0),n=this.width-r,s=i.length-i.replace(this._reSpacesAndTabs,"").length,o=n/s;return this.__widthOfSpace[e]=o,o},_getWidthOfWords:function(t,e,i,r){for(var n=0,s=0;sn;n++){var o=this._getHeightOfChar(t,e,n);o>r&&(r=o)}return this.__lineHeights[e]=r*this.lineHeight*this._fontSizeMult,this.__lineHeights[e]},_getTextHeight:function(t){for(var e=0,i=0,r=this._textLines.length;r>i;i++)e+=this._getHeightOfLine(t,i);return e},toObject:function(e){var i,r,n,s={};for(i in this.styles){n=this.styles[i],s[i]={};for(r in n)s[i][r]=t(n[r])}return fabric.util.object.extend(this.callSuper("toObject",e),{styles:s})}}),fabric.IText.fromObject=function(e){return new fabric.IText(e.text,t(e))}}(),function(){var t=fabric.util.object.clone;fabric.util.object.extend(fabric.IText.prototype,{initBehavior:function(){this.initAddedHandler(),this.initRemovedHandler(),this.initCursorSelectionHandlers(),this.initDoubleClickSimulation()},initSelectedHandler:function(){this.on("selected",function(){var t=this;setTimeout(function(){t.selected=!0},100)})},initAddedHandler:function(){var t=this;this.on("added",function(){this.canvas&&!this.canvas._hasITextHandlers&&(this.canvas._hasITextHandlers=!0,this._initCanvasHandlers()),t.canvas&&(t.canvas._iTextInstances=t.canvas._iTextInstances||[],t.canvas._iTextInstances.push(t))})},initRemovedHandler:function(){var t=this;this.on("removed",function(){t.canvas&&(t.canvas._iTextInstances=t.canvas._iTextInstances||[],fabric.util.removeFromArray(t.canvas._iTextInstances,t))})},_initCanvasHandlers:function(){var t=this;this.canvas.on("selection:cleared",function(){fabric.IText.prototype.exitEditingOnOthers(t.canvas)}),this.canvas.on("mouse:up",function(){t.canvas._iTextInstances&&t.canvas._iTextInstances.forEach(function(t){t.__isMousedown=!1})}),this.canvas.on("object:selected",function(){fabric.IText.prototype.exitEditingOnOthers(t.canvas)})},_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.canvas.clearContext(t.canvas.contextTop||t.ctx),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._currentTickState&&this._currentTickState.abort(),this._currentTickCompleteState&&this._currentTickCompleteState.abort(),clearTimeout(this._cursorTimeout1),this._currentCursorOpacity=1,this.canvas&&(this.canvas.clearContext(this.canvas.contextTop||this.ctx),this.renderCursorOrSelection()),this._cursorTimeout2&&clearTimeout(this._cursorTimeout2),this._cursorTimeout2=setTimeout(function(){e._tick()},i)},abortCursorAnimation:function(){this._currentTickState&&this._currentTickState.abort(),this._currentTickCompleteState&&this._currentTickCompleteState.abort(),clearTimeout(this._cursorTimeout1),clearTimeout(this._cursorTimeout2),this._currentCursorOpacity=0,this.canvas&&this.canvas.clearContext(this.canvas.contextTop||this.ctx)},selectAll:function(){this.setSelectionStart(0),this.setSelectionEnd(this.text.length)},getSelectedText:function(){return this.text.slice(this.selectionStart,this.selectionEnd)},findWordBoundaryLeft:function(t){var e=0,i=t-1;if(this._reSpace.test(this.text.charAt(i)))for(;this._reSpace.test(this.text.charAt(i));)e++,i--;for(;/\S/.test(this.text.charAt(i))&&i>-1;)e++,i--;return t-e},findWordBoundaryRight:function(t){var e=0,i=t;if(this._reSpace.test(this.text.charAt(i)))for(;this._reSpace.test(this.text.charAt(i));)e++,i++;for(;/\S/.test(this.text.charAt(i))&&i-1;)e++,i--;return t-e},findLineBoundaryRight:function(t){for(var e=0,i=t;!/\n/.test(this.text.charAt(i))&&ii;i++)"\n"===t[i]&&e++;return e},searchWordBoundary:function(t,e){for(var i=this._reSpace.test(this.text.charAt(t))?t-1:t,r=this.text.charAt(i),n=/[ \n\.,;!\?\-]/;!n.test(r)&&i>0&&i=t.__selectionStartOnMouseDown?(t.setSelectionStart(t.__selectionStartOnMouseDown),t.setSelectionEnd(i)):(t.setSelectionStart(i),t.setSelectionEnd(t.__selectionStartOnMouseDown))}})},_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},_updateTextarea:function(){if(this.hiddenTextarea&&!this.inCompositionMode&&(this.hiddenTextarea.value=this.text,this.hiddenTextarea.selectionStart=this.selectionStart,this.hiddenTextarea.selectionEnd=this.selectionEnd,this.selectionStart===this.selectionEnd)){var t=this._calcTextareaPosition();this.hiddenTextarea.style.left=t.x+"px",this.hiddenTextarea.style.top=t.y+"px"}},_calcTextareaPosition:function(){var t=this.text.split(""),e=this._getCursorBoundaries(t,"cursor"),i=this.get2DCursorLocation(),r=i.lineIndex,n=i.charIndex,s=this.getCurrentCharFontSize(r,n),o=0===r&&0===n?this._getLineLeftOffset(this._getLineWidth(this.ctx,r)):e.leftOffset,a=this.calcTransformMatrix(),h={x:e.left+o,y:e.top+e.topOffset+s};return this.hiddenTextarea.style.fontSize=s+"px",fabric.util.transformPoint(h,a)},_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(){return this.selected=!1,this.isEditing=!1,this.selectable=!0,this.selectionEnd=this.selectionStart,this.hiddenTextarea&&this.canvas&&this.hiddenTextarea.parentNode.removeChild(this.hiddenTextarea),this.hiddenTextarea=null,this.abortCursorAnimation(),this._restoreEditingProps(),this._currentCursorOpacity=0,this.fire("editing:exited"),this.canvas&&this.canvas.fire("text:editing:exited",{target:this}),this},_removeExtraneousStyles:function(){for(var t in this.styles)this._textLines[t]||delete this.styles[t]},_removeCharsFromTo:function(t,e){for(;e!==t;)this._removeSingleCharAndStyle(t+1),e--;this.setSelectionStart(t)},_removeSingleCharAndStyle:function(t){var e="\n"===this.text[t-1],i=e?t:t-1;this.removeStyleObject(e,i),this.text=this.text.slice(0,t-1)+this.text.slice(t),this._textLines=this._splitTextIntoLines()},insertChars:function(t,e){var i;if(this.selectionEnd-this.selectionStart>1&&(this._removeCharsFromTo(this.selectionStart,this.selectionEnd),this.setSelectionEnd(this.selectionStart)),!e&&this.isEmptyStyles())return void this.insertChar(t,!1);for(var r=0,n=t.length;n>r;r++)e&&(i=fabric.copiedTextStyle[r]),this.insertChar(t[r],n-1>r,i)},insertChar:function(t,e,i){var r="\n"===this.text[this.selectionStart];this.text=this.text.slice(0,this.selectionStart)+t+this.text.slice(this.selectionEnd),this._textLines=this._splitTextIntoLines(),this.insertStyleObjects(t,r,i),this.selectionStart+=t.length,this.selectionEnd=this.selectionStart,e||(this._updateTextarea(),this.canvas&&this.canvas.renderAll(),this.setCoords(),this.fire("changed"),this.canvas&&this.canvas.fire("text:changed",{target:this}))},insertNewlineStyleObject:function(e,i,r){this.shiftLineStyles(e,1),this.styles[e+1]||(this.styles[e+1]={});var n={},s={};if(this.styles[e]&&this.styles[e][i-1]&&(n=this.styles[e][i-1]),r)s[0]=t(n),this.styles[e+1]=s;else{for(var o in this.styles[e])parseInt(o,10)>=i&&(s[parseInt(o,10)-i]=this.styles[e][o],delete this.styles[e][o]);this.styles[e+1]=s}this._forceClearCache=!0},insertCharStyleObject:function(e,i,r){var n=this.styles[e],s=t(n);0!==i||r||(i=1);for(var o in s){var a=parseInt(o,10);a>=i&&(n[a+1]=s[a],s[a-1]||delete n[a])}this.styles[e][i]=r||t(n[i-1]),this._forceClearCache=!0},insertStyleObjects:function(t,e,i){var r=this.get2DCursorLocation(),n=r.lineIndex,s=r.charIndex;this._getLineStyle(n)||this._setLineStyle(n,{}),"\n"===t?this.insertNewlineStyleObject(n,s,e):this.insertCharStyleObject(n,s,i)},shiftLineStyles:function(e,i){var r=t(this.styles);for(var n in this.styles){var s=parseInt(n,10);s>e&&(this.styles[s+i]=r[s],r[s-i]||delete this.styles[s])}},removeStyleObject:function(t,e){var i=this.get2DCursorLocation(e),r=i.lineIndex,n=i.charIndex;this._removeStyleObject(t,i,r,n)},_getTextOnPreviousLine:function(t){return this._textLines[t-1]},_removeStyleObject:function(e,i,r,n){if(e){var s=this._getTextOnPreviousLine(i.lineIndex),o=s?s.length:0;this.styles[r-1]||(this.styles[r-1]={});for(n in this.styles[r])this.styles[r-1][parseInt(n,10)+o]=this.styles[r][n];this.shiftLineStyles(i.lineIndex,-1)}else{var a=this.styles[r];a&&delete a[n];var h=t(a);for(var c in h){var l=parseInt(c,10);l>=n&&0!==l&&(a[l-1]=h[l],delete a[l])}}},insertNewline:function(){this.insertChars("\n")}})}(),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)?(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.initSelectedHandler(),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){var e=this.canvas.getPointer(t.e);this.__mousedownX=e.x,this.__mousedownY=e.y,this.__isMousedown=!0,this.hiddenTextarea&&this.canvas&&this.canvas.wrapperEl.appendChild(this.hiddenTextarea),this.selected&&this.setCursorByClick(t.e),this.isEditing&&(this.__selectionStartOnMouseDown=this.selectionStart,this.initDelayedCursor(!0))}})},_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)&&(this.__lastSelected&&!this.__corner&&(this.enterEditing(t.e),this.initDelayedCursor(!0)),this.selected=!0)})},setCursorByClick:function(t){var e=this.getSelectionStartFromPointer(t);t.shiftKey?eh;h++){i=this._textLines[h],o+=this._getHeightOfLine(this.ctx,h)*this.scaleY;var l=this._getLineWidth(this.ctx,h),u=this._getLineLeftOffset(l);s=u*this.scaleX;for(var f=0,d=i.length;d>f;f++){if(n=s,s+=this._getWidthOfChar(this.ctx,i[f],h,this.flipX?d-f:f)*this.scaleX,!(o<=r.y||s<=r.x))return this._getNewSelectionStartFromOffset(r,n,s,a+h,d);a++}if(r.ys?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(t){var e;t&&this.canvas?e=this.canvas.getPointer(t):(this.oCoords||this.setCoords(),e=this.oCoords.tl),this.hiddenTextarea=fabric.document.createElement("textarea"),this.hiddenTextarea.setAttribute("autocapitalize","off"),this.hiddenTextarea.style.cssText="position: absolute; top: "+e.y+"px; left: "+e.x+"px; opacity: 0; width: 0px; height: 0px; z-index: -999;",this.canvas?this.canvas.lowerCanvasEl.parentNode.appendChild(this.hiddenTextarea):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.cut.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:{8:"removeChars",9:"exitEditing",27:"exitEditing",13:"insertNewline",33:"moveCursorUp",34:"moveCursorDown",35:"moveCursorRight",36:"moveCursorLeft",37:"moveCursorLeft",38:"moveCursorUp",39:"moveCursorRight",40:"moveCursorDown",46:"forwardDelete"},_ctrlKeysMap:{65:"selectAll",67:"copy",88:"cut"},onClick:function(){this.hiddenTextarea&&this.hiddenTextarea.focus()},onKeyDown:function(t){this.isEditing&&t.keyCode in this._keysMap&&(this[this._keysMap[t.keyCode]](t),t.stopImmediatePropagation(),t.preventDefault(),this.canvas&&this.canvas.renderAll())},onKeyUp:function(t){return!this.isEditing||this._copyDone?void(this._copyDone=!1):void(t.keyCode in this._ctrlKeysMap&&(t.ctrlKey||t.metaKey)&&(this[this._ctrlKeysMap[t.keyCode]](t),t.stopImmediatePropagation(),t.preventDefault(),this.canvas&&this.canvas.renderAll()))},onInput:function(t){if(this.isEditing&&!this.inCompositionMode){var e,i,r,n=this.selectionStart||0,s=this.selectionEnd||0,o=this.text.length,a=this.hiddenTextarea.value.length;a>o?(r="left"===this._selectionDirection?s:n,e=a-o,i=this.hiddenTextarea.value.slice(r,r+e)):(e=a-o+s-n,i=this.hiddenTextarea.value.slice(n,n+e)),this.insertChars(i),t.stopPropagation()}},onCompositionStart:function(){this.inCompositionMode=!0,this.prevCompositionLength=0,this.compositionStart=this.selectionStart},onCompositionEnd:function(){this.inCompositionMode=!1},onCompositionUpdate:function(t){var e=t.data;this.selectionStart=this.compositionStart,this.selectionEnd=this.selectionEnd===this.selectionStart?this.compositionStart+this.prevCompositionLength:this.selectionEnd,this.insertChars(e,!1),this.prevCompositionLength=e.length},forwardDelete:function(t){if(this.selectionStart===this.selectionEnd){if(this.selectionStart===this.text.length)return;this.moveCursorRight(t)}this.removeChars(t)},copy:function(t){if(this.selectionStart!==this.selectionEnd){var e=this.getSelectedText(),i=this._getClipboardData(t);i&&i.setData("text",e),fabric.copiedText=e,fabric.copiedTextStyle=this.getSelectionStyles(this.selectionStart,this.selectionEnd),t.stopImmediatePropagation(),t.preventDefault(),this._copyDone=!0}},paste:function(t){var e=null,i=this._getClipboardData(t),r=!0;i?(e=i.getData("text").replace(/\r/g,""),fabric.copiedTextStyle&&fabric.copiedText===e||(r=!1)):e=fabric.copiedText,e&&this.insertChars(e,r),t.stopImmediatePropagation(),t.preventDefault(); - -},cut:function(t){this.selectionStart!==this.selectionEnd&&(this.copy(t),this.removeChars(t))},_getClipboardData:function(t){return t&&t.clipboardData||fabric.window.clipboardData},getDownCursorOffset:function(t,e){var i,r,n=e?this.selectionEnd:this.selectionStart,s=this.get2DCursorLocation(n),o=s.lineIndex,a=this._textLines[o].slice(0,s.charIndex),h=this._textLines[o].slice(s.charIndex),c=this._textLines[o+1]||"";if(o===this._textLines.length-1||t.metaKey||34===t.keyCode)return this.text.length-n;var l=this._getLineWidth(this.ctx,o);r=this._getLineLeftOffset(l);for(var u=r,f=0,d=a.length;d>f;f++)i=a[f],u+=this._getWidthOfChar(this.ctx,i,o,f);var g=this._getIndexOnNextLine(s,c,u);return h.length+1+g},_getIndexOnNextLine:function(t,e,i){for(var r,n=t.lineIndex+1,s=this._getLineWidth(this.ctx,n),o=this._getLineLeftOffset(s),a=o,h=0,c=0,l=e.length;l>c;c++){var u=e[c],f=this._getWidthOfChar(this.ctx,u,n,c);if(a+=f,a>i){r=!0;var d=a-f,g=a,p=Math.abs(d-i),v=Math.abs(g-i);h=p>v?c+1:c;break}}return r||(h=e.length),h},moveCursorDown:function(t){this.abortCursorAnimation(),this._currentCursorOpacity=1;var e=this.getDownCursorOffset(t,"right"===this._selectionDirection);t.shiftKey?this.moveCursorDownWithShift(e):this.moveCursorDownWithoutShift(e),this.initDelayedCursor()},moveCursorDownWithoutShift:function(t){this._selectionDirection="right",this.setSelectionStart(this.selectionStart+t),this.setSelectionEnd(this.selectionStart)},swapSelectionPoints:function(){var t=this.selectionEnd;this.setSelectionEnd(this.selectionStart),this.setSelectionStart(t)},moveCursorDownWithShift:function(t){this.selectionEnd===this.selectionStart&&(this._selectionDirection="right"),"right"===this._selectionDirection?this.setSelectionEnd(this.selectionEnd+t):this.setSelectionStart(this.selectionStart+t),this.selectionEndthis.text.length&&this.setSelectionEnd(this.text.length)},getUpCursorOffset:function(t,e){var i=e?this.selectionEnd:this.selectionStart,r=this.get2DCursorLocation(i),n=r.lineIndex;if(0===n||t.metaKey||33===t.keyCode)return i;for(var s,o=this._textLines[n].slice(0,r.charIndex),a=this._textLines[n-1]||"",h=this._getLineWidth(this.ctx,r.lineIndex),c=this._getLineLeftOffset(h),l=c,u=0,f=o.length;f>u;u++)s=o[u],l+=this._getWidthOfChar(this.ctx,s,n,u);var d=this._getIndexOnPrevLine(r,a,l);return a.length-d+o.length},_getIndexOnPrevLine:function(t,e,i){for(var r,n=t.lineIndex-1,s=this._getLineWidth(this.ctx,n),o=this._getLineLeftOffset(s),a=o,h=0,c=0,l=e.length;l>c;c++){var u=e[c],f=this._getWidthOfChar(this.ctx,u,n,c);if(a+=f,a>i){r=!0;var d=a-f,g=a,p=Math.abs(d-i),v=Math.abs(g-i);h=p>v?c:c-1;break}}return r||(h=e.length-1),h},moveCursorUp:function(t){this.abortCursorAnimation(),this._currentCursorOpacity=1;var e=this.getUpCursorOffset(t,"right"===this._selectionDirection);t.shiftKey?this.moveCursorUpWithShift(e):this.moveCursorUpWithoutShift(e),this.initDelayedCursor()},moveCursorUpWithShift:function(t){this.selectionEnd===this.selectionStart&&(this._selectionDirection="left"),"right"===this._selectionDirection?this.setSelectionEnd(this.selectionEnd-t):this.setSelectionStart(this.selectionStart-t),this.selectionEnd=this.text.length&&this.selectionEnd>=this.text.length||(this.abortCursorAnimation(),this._currentCursorOpacity=1,t.shiftKey?this.moveCursorRightWithShift(t):this.moveCursorRightWithoutShift(t),this.initDelayedCursor())},moveCursorRightWithShift:function(t){"left"===this._selectionDirection&&this.selectionStart!==this.selectionEnd?this._moveRight(t,"selectionStart"):(this._selectionDirection="right",this._moveRight(t,"selectionEnd"))},moveCursorRightWithoutShift:function(t){this._selectionDirection="right",this.selectionStart===this.selectionEnd?(this._moveRight(t,"selectionStart"),this.setSelectionEnd(this.selectionStart)):(this.setSelectionEnd(this.selectionEnd+this.getNumNewLinesInSelectedText()),this.setSelectionStart(this.selectionEnd))},removeChars:function(t){this.selectionStart===this.selectionEnd?this._removeCharsNearCursor(t):this._removeCharsFromTo(this.selectionStart,this.selectionEnd),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.IText.prototype,{_setSVGTextLineText:function(t,e,i,r,n,s){this._getLineStyle(t)?this._setSVGTextLineChars(t,e,i,r,s):fabric.Text.prototype._setSVGTextLineText.call(this,t,e,i,r,n)},_setSVGTextLineChars:function(t,e,i,r,n){for(var s=this._textLines[t],o=0,a=this._getLineLeftOffset(this._getLineWidth(this.ctx,t))-this.width/2,h=this._getSVGLineTopOffset(t),c=this._getHeightOfLine(this.ctx,t),l=0,u=s.length;u>l;l++){var f=this._getStyleDeclaration(t,l)||{};e.push(this._createTextCharSpan(s[l],f,a,h.lineTop+h.offset,o));var d=this._getWidthOfChar(this.ctx,s[l],t,l);f.textBackgroundColor&&n.push(this._createTextCharBg(f,a,h.lineTop,c,d,o)),o+=d}},_getSVGLineTopOffset:function(t){for(var e=0,i=0,r=0;t>r;r++)e+=this._getHeightOfLine(this.ctx,r);return i=this._getHeightOfLine(this.ctx,r),{lineTop:e,offset:(this._fontSizeMult-this._fontSizeFraction)*i/(this.lineHeight*this._fontSizeMult)}},_createTextCharBg:function(i,r,n,s,o,a){return[' \n'].join("")},_createTextCharSpan:function(i,r,n,s,o){var a=this.getSvgStyles.call(fabric.util.object.extend({visible:!0,fill:this.fill,stroke:this.stroke,type:"text",getSvgFilter:fabric.Object.prototype.getSvgFilter},r));return[' ',fabric.util.string.escapeXml(i),"\n"].join("")}})}(),function(t){"use strict";var e=t.fabric||(t.fabric={}),i=e.util.object.clone;e.Textbox=e.util.createClass(e.IText,e.Observable,{type:"textbox",minWidth:20,dynamicMinWidth:0,__cachedLines:null,initialize:function(t,i){this.ctx=e.util.createCanvasElement().getContext("2d"),this.callSuper("initialize",t,i),this.set({lockUniScaling:!1,lockScalingY:!0,lockScalingFlip:!0,hasBorders:!0}),this.setControlsVisibility(e.Textbox.getTextboxControlVisibility()),this._dimensionAffectingProps.width=!0},_initDimensions:function(t){this.__skipDimension||(t||(t=e.util.createCanvasElement().getContext("2d"),this._setTextStyles(t)),this.dynamicMinWidth=0,this._textLines=this._splitTextIntoLines(),this.dynamicMinWidth>this.width&&this._set("width",this.dynamicMinWidth),this._clearCache(),this.height=this._getTextHeight(t))},_generateStyleMap:function(){for(var t=0,e=0,i=0,r={},n=0;ns;s++)n+=this._getWidthOfChar(t,e[s],i,s+r);return n},_wrapLine:function(t,e,i){for(var r=0,n=[],s="",o=e.split(" "),a="",h=0,c=" ",l=0,u=0,f=0,d=!0,g=0;g=this.width&&!d&&(n.push(s),s="",r=l,d=!0),d||(s+=c),s+=a,u=this._measureText(t,c,i,h),h++,d=!1,l>f&&(f=l);return g&&n.push(s),f>this.dynamicMinWidth&&(this.dynamicMinWidth=f),n},_splitTextIntoLines:function(){var t=this.textAlign;this.ctx.save(),this._setTextStyles(this.ctx),this.textAlign="left";var e=this._wrapText(this.ctx,this.text);return this.textAlign=t,this.ctx.restore(),this._textLines=e,this._styleMap=this._generateStyleMap(),e},setOnGroup:function(t,e){"scaleX"===t&&(this.set("scaleX",Math.abs(1/e)),this.set("width",this.get("width")*e/("undefined"==typeof this.__oldScaleX?1:this.__oldScaleX)),this.__oldScaleX=e)},get2DCursorLocation:function(t){"undefined"==typeof t&&(t=this.selectionStart);for(var e=this._textLines.length,i=0,r=0;e>r;r++){var n=this._textLines[r],s=n.length;if(i+s>=t)return{lineIndex:r,charIndex:t-i};i+=s,("\n"===this.text[i]||" "===this.text[i])&&i++}return{lineIndex:e-1,charIndex:this._textLines[e-1].length}},_getCursorBoundariesOffsets:function(t,e){for(var i=0,r=0,n=this.get2DCursorLocation(),s=this._textLines[n.lineIndex].split(""),o=this._getLineLeftOffset(this._getLineWidth(this.ctx,n.lineIndex)),a=0;a=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())};var e=fabric.util.object.clone;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]},insertCharStyleObject:function(t,e,i){var r=this._styleMap[t];t=r.line,e=r.offset+e,fabric.IText.prototype.insertCharStyleObject.apply(this,[t,e,i])},insertNewlineStyleObject:function(t,e,i){var r=this._styleMap[t];t=r.line,e=r.offset+e,fabric.IText.prototype.insertNewlineStyleObject.apply(this,[t,e,i])},shiftLineStyles:function(t,i){var r=e(this.styles),n=this._styleMap[t];t=n.line;for(var s in this.styles){var o=parseInt(s,10);o>t&&(this.styles[o+i]=r[o],r[o-i]||delete this.styles[o])}},_getTextOnPreviousLine:function(t){for(var e=this._textLines[t-1];this._styleMap[t-2]&&this._styleMap[t-2].line===this._styleMap[t-1].line;)e=this._textLines[t-2]+e,t--;return e},removeStyleObject:function(t,e){var i=this.get2DCursorLocation(e),r=this._styleMap[i.lineIndex],n=r.line,s=r.offset+i.charIndex;this._removeStyleObject(t,i,n,s)}})}(),function(){var t=fabric.IText.prototype._getNewSelectionStartFromOffset;fabric.IText.prototype._getNewSelectionStartFromOffset=function(e,i,r,n,s){n=t.call(this,e,i,r,n,s);for(var o=0,a=0,h=0;h=n));h++)("\n"===this.text[o+a]||" "===this.text[o+a])&&a++;return n-h+a}}(),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){fabric.log(t.errno===process.ECONNREFUSED?"ECONNREFUSED: connection refused to "+r.hostname+":"+r.port: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("canvas"),Image=require("canvas").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.Image.fromObject=function(t,e){fabric.util.loadImage(t.src,function(i){var r=new fabric.Image(i);r._initConfig(t),r._initFilters(t.filters,function(i){r.filters=i||[],r._initFilters(t.resizeFilters,function(t){r.resizeFilters=t||[],e&&e(r)})})})},fabric.createCanvasForNode=function(t,e,i,r){r=r||i;var n=fabric.document.createElement("canvas"),s=new Canvas(t||600,e||600,r);n.style={},n.width=s.width,n.height=s.height;var o=fabric.Canvas||fabric.StaticCanvas,a=new o(n,i);return a.contextContainer=s.getContext("2d"),a.nodeCanvas=s,a.Font=Canvas.Font,a},fabric.StaticCanvas.prototype.createPNGStream=function(){return this.nodeCanvas.createPNGStream()},fabric.StaticCanvas.prototype.createJPEGStream=function(t){return this.nodeCanvas.createJPEGStream(t)};var origSetWidth=fabric.StaticCanvas.prototype.setWidth;fabric.StaticCanvas.prototype.setWidth=function(t,e){return origSetWidth.call(this,t,e),this.nodeCanvas.width=t,this},fabric.Canvas&&(fabric.Canvas.prototype.setWidth=fabric.StaticCanvas.prototype.setWidth);var origSetHeight=fabric.StaticCanvas.prototype.setHeight;fabric.StaticCanvas.prototype.setHeight=function(t,e){return origSetHeight.call(this,t,e),this.nodeCanvas.height=t,this},fabric.Canvas&&(fabric.Canvas.prototype.setHeight=fabric.StaticCanvas.prototype.setHeight)}}(); \ No newline at end of file +var fabric=fabric||{version:"1.6.1"};if(typeof exports!=="undefined"){exports.fabric=fabric}if(typeof document!=="undefined"&&typeof window!=="undefined"){fabric.document=document;fabric.window=window;window.fabric=fabric}else{fabric.document=require("jsdom").jsdom("");if(fabric.document.createWindow){fabric.window=fabric.document.createWindow()}else{fabric.window=fabric.document.parentWindow}}fabric.isTouchSupported="ontouchstart"in fabric.document.documentElement;fabric.isLikelyNode=typeof Buffer!=="undefined"&&typeof window==="undefined";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.devicePixelRatio=fabric.window.devicePixelRatio||fabric.window.webkitDevicePixelRatio||fabric.window.mozDevicePixelRatio||1;(function(){function _removeEventListener(eventName,handler){if(!this.__eventListeners[eventName]){return}var eventListener=this.__eventListeners[eventName];if(handler){eventListener[eventListener.indexOf(handler)]=false}else{fabric.util.array.fill(eventListener,false)}}function observe(eventName,handler){if(!this.__eventListeners){this.__eventListeners={}}if(arguments.length===1){for(var prop in eventName){this.on(prop,eventName[prop])}}else{if(!this.__eventListeners[eventName]){this.__eventListeners[eventName]=[]}this.__eventListeners[eventName].push(handler)}return this}function stopObserving(eventName,handler){if(!this.__eventListeners){return}if(arguments.length===0){for(eventName in this.__eventListeners){_removeEventListener.call(this,eventName)}}else if(arguments.length===1&&typeof arguments[0]==="object"){for(var prop in eventName){_removeEventListener.call(this,prop,eventName[prop])}}else{_removeEventListener.call(this,eventName,handler)}return this}function fire(eventName,options){if(!this.__eventListeners){return}var listenersForEvent=this.__eventListeners[eventName];if(!listenersForEvent){return}for(var i=0,len=listenersForEvent.length;i-1},complexity:function(){return this.getObjects().reduce(function(memo,current){memo+=current.complexity?current.complexity():0;return memo},0)}};(function(global){var sqrt=Math.sqrt,atan2=Math.atan2,pow=Math.pow,abs=Math.abs,PiBy180=Math.PI/180;fabric.util={removeFromArray:function(array,value){var idx=array.indexOf(value);if(idx!==-1){array.splice(idx,1)}return array},getRandomInt:function(min,max){return Math.floor(Math.random()*(max-min+1))+min},degreesToRadians:function(degrees){return degrees*PiBy180},radiansToDegrees:function(radians){return radians/PiBy180},rotatePoint:function(point,origin,radians){point.subtractEquals(origin);var v=fabric.util.rotateVector(point,radians);return new fabric.Point(v.x,v.y).addEquals(origin)},rotateVector:function(vector,radians){var sin=Math.sin(radians),cos=Math.cos(radians),rx=vector.x*cos-vector.y*sin,ry=vector.x*sin+vector.y*cos;return{x:rx,y:ry}},transformPoint:function(p,t,ignoreOffset){if(ignoreOffset){return new fabric.Point(t[0]*p.x+t[2]*p.y,t[1]*p.x+t[3]*p.y)}return new fabric.Point(t[0]*p.x+t[2]*p.y+t[4],t[1]*p.x+t[3]*p.y+t[5])},makeBoundingBoxFromPoints:function(points){var xPoints=[points[0].x,points[1].x,points[2].x,points[3].x],minX=fabric.util.array.min(xPoints),maxX=fabric.util.array.max(xPoints),width=Math.abs(minX-maxX),yPoints=[points[0].y,points[1].y,points[2].y,points[3].y],minY=fabric.util.array.min(yPoints),maxY=fabric.util.array.max(yPoints),height=Math.abs(minY-maxY);return{left:minX,top:minY,width:width,height:height}},invertTransform:function(t){var a=1/(t[0]*t[3]-t[1]*t[2]),r=[a*t[3],-a*t[1],-a*t[2],a*t[0]],o=fabric.util.transformPoint({x:t[4],y:t[5]},r,true);r[4]=-o.x;r[5]=-o.y;return r},toFixed:function(number,fractionDigits){return parseFloat(Number(number).toFixed(fractionDigits))},parseUnit:function(value,fontSize){var unit=/\D{0,2}$/.exec(value),number=parseFloat(value);if(!fontSize){fontSize=fabric.Text.DEFAULT_SVG_FONT_SIZE}switch(unit[0]){case"mm":return number*fabric.DPI/25.4;case"cm":return number*fabric.DPI/2.54;case"in":return number*fabric.DPI;case"pt":return number*fabric.DPI/72;case"pc":return number*fabric.DPI/72*12;case"em":return number*fontSize;default:return number}},falseFunction:function(){return false},getKlass:function(type,namespace){type=fabric.util.string.camelize(type.charAt(0).toUpperCase()+type.slice(1));return fabric.util.resolveNamespace(namespace)[type]},resolveNamespace:function(namespace){if(!namespace){return fabric}var parts=namespace.split("."),len=parts.length,obj=global||fabric.window;for(var i=0;ix){x+=da[di++%dc];if(x>len){x=len}ctx[draw?"lineTo":"moveTo"](x,0);draw=!draw}ctx.restore()},createCanvasElement:function(canvasEl){canvasEl||(canvasEl=fabric.document.createElement("canvas"));if(!canvasEl.getContext&&typeof G_vmlCanvasManager!=="undefined"){G_vmlCanvasManager.initElement(canvasEl)}return canvasEl},createImage:function(){return fabric.isLikelyNode?new(require("canvas").Image):fabric.document.createElement("img")},createAccessors:function(klass){var proto=klass.prototype;for(var i=proto.stateProperties.length;i--;){var 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();receiver.clipTo(ctx);ctx.clip()},multiplyTransformMatrices:function(a,b,is2x2){return[a[0]*b[0]+a[2]*b[1],a[1]*b[0]+a[3]*b[1],a[0]*b[2]+a[2]*b[3],a[1]*b[2]+a[3]*b[3],is2x2?0:a[0]*b[4]+a[2]*b[5]+a[4],is2x2?0:a[1]*b[4]+a[3]*b[5]+a[5]]},qrDecompose:function(a){var angle=atan2(a[1],a[0]),denom=pow(a[0],2)+pow(a[1],2),scaleX=sqrt(denom),scaleY=(a[0]*a[3]-a[2]*a[1])/scaleX,skewX=atan2(a[0]*a[2]+a[1]*a[3],denom);return{angle:angle/PiBy180,scaleX:scaleX,scaleY:scaleY,skewX:skewX/PiBy180,skewY:0,translateX:a[4],translateY:a[5]}},customTransformMatrix:function(scaleX,scaleY,skewX){var skewMatrixX=[1,0,abs(Math.tan(skewX*PiBy180)),1],scaleMatrix=[abs(scaleX),0,0,abs(scaleY)];return fabric.util.multiplyTransformMatrices(scaleMatrix,skewMatrixX,true)},resetObjectTransform:function(target){target.scaleX=1;target.scaleY=1;target.skewX=0;target.skewY=0;target.flipX=false;target.flipY=false;target.setAngle(0)},getFunctionBody:function(fn){return(String(fn).match(/function[^{]*\{([\s\S]*)\}/)||{})[1]},isTransparent:function(ctx,x,y,tolerance){if(tolerance>0){if(x>tolerance){x-=tolerance}else{x=0}if(y>tolerance){y-=tolerance}else{y=0}}var _isTransparent=true,imageData=ctx.getImageData(x,y,tolerance*2||1,tolerance*2||1);for(var i=3,l=imageData.data.length;i0){dtheta-=2*PI}else if(sweep===1&&dtheta<0){dtheta+=2*PI}var segments=Math.ceil(Math.abs(dtheta/PI*2)),result=[],mDelta=dtheta/segments,mT=8/3*Math.sin(mDelta/4)*Math.sin(mDelta/4)/Math.sin(mDelta/2),th3=mTheta+mDelta;for(var i=0;i=ta){return tb-ta}else{return 2*Math.PI-(ta-tb)}}fabric.util.drawArc=function(ctx,fx,fy,coords){var rx=coords[0],ry=coords[1],rot=coords[2],large=coords[3],sweep=coords[4],tx=coords[5],ty=coords[6],segs=[[],[],[],[]],segsNorm=arcToSegments(tx-fx,ty-fy,rx,ry,large,sweep,rot);for(var i=0,len=segsNorm.length;i0){b=6*y0-12*y1+6*y2;a=-3*y0+9*y1-9*y2+3*y3;c=3*y1-3*y0}if(abs(a)<1e-12){if(abs(b)<1e-12){continue}t=-c/b;if(0>>0;if(len===0){return-1}var n=0;if(arguments.length>0){n=Number(arguments[1]);if(n!==n){n=0}else if(n!==0&&n!==Number.POSITIVE_INFINITY&&n!==Number.NEGATIVE_INFINITY){n=(n>0||-1)*Math.floor(Math.abs(n))}}if(n>=len){return-1}var k=n>=0?n:Math.max(len-Math.abs(n),0);for(;k>>0;i>>0;i>>0;i>>0;i>>0;i>>0,i=0,rv;if(arguments.length>1){rv=arguments[1]}else{do{if(i in this){rv=this[i++];break}if(++i>=len){throw new TypeError}}while(true)}for(;i=value2})}function min(array,byProperty){return find(array,byProperty,function(value1,value2){return value1/g,">")}fabric.util.string={camelize:camelize,capitalize:capitalize,escapeXml:escapeXml}})();(function(){var slice=Array.prototype.slice,apply=Function.prototype.apply,Dummy=function(){};if(!Function.prototype.bind){Function.prototype.bind=function(thisArg){var _this=this,args=slice.call(arguments,1),bound;if(args.length){bound=function(){return apply.call(_this,this instanceof Dummy?this:thisArg,args.concat(slice.call(arguments)))}}else{bound=function(){return apply.call(_this,this instanceof Dummy?this:thisArg,arguments)}}Dummy.prototype=this.prototype;bound.prototype=new Dummy;return bound}}})();(function(){var slice=Array.prototype.slice,emptyFunction=function(){},IS_DONTENUM_BUGGY=function(){for(var p in{toString:1}){if(p==="toString"){return false}}return true}(),addMethods=function(klass,source,parent){for(var property in source){if(property in klass.prototype&&typeof klass.prototype[property]==="function"&&(source[property]+"").indexOf("callSuper")>-1){klass.prototype[property]=function(property){return function(){var superclass=this.constructor.superclass;this.constructor.superclass=parent;var returnValue=source[property].apply(this,arguments);this.constructor.superclass=superclass;if(property!=="initialize"){return returnValue}}}(property)}else{klass.prototype[property]=source[property]}if(IS_DONTENUM_BUGGY){if(source.toString!==Object.prototype.toString){klass.prototype.toString=source.toString}if(source.valueOf!==Object.prototype.valueOf){klass.prototype.valueOf=source.valueOf}}}};function Subclass(){}function callSuper(methodName){var fn=this.constructor.superclass.prototype[methodName];return arguments.length>1?fn.apply(this,slice.call(arguments,1)):fn.call(this)}function createClass(){var parent=null,properties=slice.call(arguments,0);if(typeof properties[0]==="function"){parent=properties.shift()}function klass(){this.initialize.apply(this,arguments)}klass.superclass=parent;klass.subclasses=[];if(parent){Subclass.prototype=parent.prototype;klass.prototype=new Subclass;parent.subclasses.push(klass)}for(var i=0,length=properties.length;i-1?setOpacity(element,styles.match(/opacity:\s*(\d?\.?\d*)/)[1]):element}for(var property in styles){if(property==="opacity"){setOpacity(element,styles[property])}else{var normalizedProperty=property==="float"||property==="cssFloat"?typeof elementStyle.styleFloat==="undefined"?"cssFloat":"styleFloat":property;elementStyle[normalizedProperty]=styles[property]}}return element}var parseEl=fabric.document.createElement("div"),supportsOpacity=typeof parseEl.style.opacity==="string",supportsFilters=typeof parseEl.style.filter==="string",reOpacity=/alpha\s*\(\s*opacity\s*=\s*([^\)]+)\)/,setOpacity=function(element){return element};if(supportsOpacity){setOpacity=function(element,value){element.style.opacity=value;return element}}else if(supportsFilters){setOpacity=function(element,value){var es=element.style;if(element.currentStyle&&!element.currentStyle.hasLayout){es.zoom=1}if(reOpacity.test(es.filter)){value=value>=.9999?"":"alpha(opacity="+value*100+")";es.filter=es.filter.replace(reOpacity,value)}else{es.filter+=" alpha(opacity="+value*100+")"}return element}}fabric.util.setStyle=setStyle})();(function(){var _slice=Array.prototype.slice;function getById(id){return typeof id==="string"?fabric.document.getElementById(id):id}var sliceCanConvertNodelists,toArray=function(arrayLike){return _slice.call(arrayLike,0)};try{sliceCanConvertNodelists=toArray(fabric.document.childNodes)instanceof Array}catch(err){}if(!sliceCanConvertNodelists){toArray=function(arrayLike){var arr=new Array(arrayLike.length),i=arrayLike.length;while(i--){arr[i]=arrayLike[i]}return arr}}function makeElement(tagName,attributes){var el=fabric.document.createElement(tagName);for(var prop in attributes){if(prop==="class"){el.className=attributes[prop]}else if(prop==="for"){el.htmlFor=attributes[prop]}else{el.setAttribute(prop,attributes[prop])}}return el}function addClass(element,className){if(element&&(" "+element.className+" ").indexOf(" "+className+" ")===-1){element.className+=(element.className?" ":"")+className}}function wrapElement(element,wrapper,attributes){if(typeof wrapper==="string"){wrapper=makeElement(wrapper,attributes)}if(element.parentNode){element.parentNode.replaceChild(wrapper,element)}wrapper.appendChild(element);return wrapper}function getScrollLeftTop(element){var left=0,top=0,docElement=fabric.document.documentElement,body=fabric.document.body||{scrollLeft:0,scrollTop:0};while(element&&(element.parentNode||element.host)){element=element.parentNode||element.host;if(element===fabric.document){left=body.scrollLeft||docElement.scrollLeft||0;top=body.scrollTop||docElement.scrollTop||0}else{left+=element.scrollLeft||0;top+=element.scrollTop||0}if(element.nodeType===1&&fabric.util.getElementStyle(element,"position")==="fixed"){break}}return{left:left,top:top}}function getElementOffset(element){var docElem,doc=element&&element.ownerDocument,box={left:0,top:0},offset={left:0,top:0},scrollLeftTop,offsetAttributes={borderLeftWidth:"left",borderTopWidth:"top",paddingLeft:"left",paddingTop:"top"};if(!doc){return offset}for(var attr in offsetAttributes){offset[offsetAttributes[attr]]+=parseInt(getElementStyle(element,attr),10)||0}docElem=doc.documentElement;if(typeof element.getBoundingClientRect!=="undefined"){box=element.getBoundingClientRect()}scrollLeftTop=getScrollLeftTop(element);return{left:box.left+scrollLeftTop.left-(docElem.clientLeft||0)+offset.left,top:box.top+scrollLeftTop.top-(docElem.clientTop||0)+offset.top}}var getElementStyle;if(fabric.document.defaultView&&fabric.document.defaultView.getComputedStyle){getElementStyle=function(element,attr){var style=fabric.document.defaultView.getComputedStyle(element,null);return style?style[attr]:undefined}}else{getElementStyle=function(element,attr){var value=element.style[attr];if(!value&&element.currentStyle){value=element.currentStyle[attr]}return value}}(function(){var style=fabric.document.documentElement.style,selectProp="userSelect"in style?"userSelect":"MozUserSelect"in style?"MozUserSelect":"WebkitUserSelect"in style?"WebkitUserSelect":"KhtmlUserSelect"in style?"KhtmlUserSelect":"";function makeElementUnselectable(element){if(typeof element.onselectstart!=="undefined"){element.onselectstart=fabric.util.falseFunction}if(selectProp){element.style[selectProp]="none"}else if(typeof element.unselectable==="string"){element.unselectable="on"}return element}function makeElementSelectable(element){if(typeof element.onselectstart!=="undefined"){element.onselectstart=null}if(selectProp){element.style[selectProp]=""}else if(typeof element.unselectable==="string"){element.unselectable=""}return element}fabric.util.makeElementUnselectable=makeElementUnselectable;fabric.util.makeElementSelectable=makeElementSelectable})();(function(){function getScript(url,callback){var headEl=fabric.document.getElementsByTagName("head")[0],scriptEl=fabric.document.createElement("script"),loading=true;scriptEl.onload=scriptEl.onreadystatechange=function(e){if(loading){if(typeof this.readyState==="string"&&this.readyState!=="loaded"&&this.readyState!=="complete"){return}loading=false;callback(e||fabric.window.event);scriptEl=scriptEl.onload=scriptEl.onreadystatechange=null}};scriptEl.src=url;headEl.appendChild(scriptEl)}fabric.util.getScript=getScript})();fabric.util.getById=getById;fabric.util.toArray=toArray;fabric.util.makeElement=makeElement;fabric.util.addClass=addClass;fabric.util.wrapElement=wrapElement;fabric.util.getScrollLeftTop=getScrollLeftTop;fabric.util.getElementOffset=getElementOffset;fabric.util.getElementStyle=getElementStyle})();(function(){function addParamToUrl(url,param){return url+(/\?/.test(url)?"&":"?")+param}var makeXHR=function(){var factories=[function(){return new ActiveXObject("Microsoft.XMLHTTP")},function(){return new ActiveXObject("Msxml2.XMLHTTP")},function(){return new ActiveXObject("Msxml2.XMLHTTP.3.0")},function(){return new XMLHttpRequest}];for(var i=factories.length;i--;){try{var req=factories[i]();if(req){return factories[i]}}catch(err){}}}();function emptyFn(){}function request(url,options){options||(options={});var method=options.method?options.method.toUpperCase():"GET",onComplete=options.onComplete||function(){},xhr=makeXHR(),body;xhr.onreadystatechange=function(){if(xhr.readyState===4){onComplete(xhr);xhr.onreadystatechange=emptyFn}};if(method==="GET"){body=null; +if(typeof options.parameters==="string"){url=addParamToUrl(url,options.parameters)}}xhr.open(method,url,true);if(method==="POST"||method==="PUT"){xhr.setRequestHeader("Content-Type","application/x-www-form-urlencoded")}xhr.send(body);return xhr}fabric.util.request=request})();fabric.log=function(){};fabric.warn=function(){};if(typeof console!=="undefined"){["log","warn"].forEach(function(methodName){if(typeof console[methodName]!=="undefined"&&typeof console[methodName].apply==="function"){fabric[methodName]=function(){return console[methodName].apply(console,arguments)}}})}(function(){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){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();return}onChange(easing(currentTime,startValue,byValue,duration));if(time>finish){options.onComplete&&options.onComplete();return}requestAnimFrame(tick)})(start)})}var _requestAnimFrame=fabric.window.requestAnimationFrame||fabric.window.webkitRequestAnimationFrame||fabric.window.mozRequestAnimationFrame||fabric.window.oRequestAnimationFrame||fabric.window.msRequestAnimationFrame||function(callback){fabric.window.setTimeout(callback,1e3/60)};function requestAnimFrame(){return _requestAnimFrame.apply(fabric.window,arguments)}fabric.util.animate=animate;fabric.util.requestAnimFrame=requestAnimFrame})();(function(){function normalize(a,c,p,s){if(a1){matrices.shift();combinedMatrix=fabric.util.multiplyTransformMatrices(combinedMatrix,matrices[0])}return combinedMatrix}}();function parseStyleString(style,oStyle){var attr,value;style.replace(/;\s*$/,"").split(";").forEach(function(chunk){var pair=chunk.split(":");attr=normalizeAttr(pair[0].trim().toLowerCase());value=normalizeValue(attr,pair[1].trim());oStyle[attr]=value})}function parseStyleObject(style,oStyle){var attr,value;for(var prop in style){if(typeof style[prop]==="undefined"){continue}attr=normalizeAttr(prop.toLowerCase());value=normalizeValue(attr,style[prop]);oStyle[attr]=value}}function getGlobalStylesForElement(element,svgUid){var styles={};for(var rule in fabric.cssRules[svgUid]){if(elementMatchesRule(element,rule.split(" "))){for(var property in fabric.cssRules[svgUid][rule]){styles[property]=fabric.cssRules[svgUid][rule][property]}}}return styles}function elementMatchesRule(element,selectors){var firstMatching,parentMatching=true;firstMatching=selectorMatches(element,selectors.pop());if(firstMatching&&selectors.length){parentMatching=doesSomeParentMatch(element,selectors)}return firstMatching&&parentMatching&&selectors.length===0}function doesSomeParentMatch(element,selectors){var selector,parentMatching=true;while(element.parentNode&&element.parentNode.nodeType===1&&selectors.length){if(parentMatching){selector=selectors.pop()}element=element.parentNode;parentMatching=selectorMatches(element,selector)}return selectors.length===0}function selectorMatches(element,selector){var nodeName=element.nodeName,classNames=element.getAttribute("class"),id=element.getAttribute("id"),matcher;matcher=new RegExp("^"+nodeName,"i");selector=selector.replace(matcher,"");if(id&&selector.length){matcher=new RegExp("#"+id+"(?![a-zA-Z\\-]+)","i");selector=selector.replace(matcher,"")}if(classNames&&selector.length){classNames=classNames.split(" ");for(var i=classNames.length;i--;){matcher=new RegExp("\\."+classNames[i]+"(?![a-zA-Z\\-]+)","i");selector=selector.replace(matcher,"")}}return selector.length===0}function elementById(doc,id){var el;doc.getElementById&&(el=doc.getElementById(id));if(el){return el}var node,i,nodelist=doc.getElementsByTagName("*");for(i=0;iscaleY?scaleY:scaleX}if(scaleX===1&&scaleY===1&&minX===0&&minY===0&&x===0&&y===0){return parsedDim}if(x||y){translateMatrix=" translate("+parseUnit(x)+" "+parseUnit(y)+") "}matrix=translateMatrix+" matrix("+scaleX+" 0"+" 0 "+scaleY+" "+minX*scaleX+" "+minY*scaleY+") ";if(element.tagName==="svg"){el=element.ownerDocument.createElement("g");while(element.firstChild!=null){el.appendChild(element.firstChild)}element.appendChild(el)}else{el=element;matrix=el.getAttribute("transform")+matrix}el.setAttribute("transform",matrix);return parsedDim}fabric.parseSVGDocument=function(){function hasAncestorWithNodeName(element,nodeName){while(element&&(element=element.parentNode)){if(nodeName.test(element.nodeName)&&!element.getAttribute("instantiated_by_use")){return true}}return false}return function(doc,callback,reviver){if(!doc){return}parseUseDirectives(doc);var startTime=new Date,svgUid=fabric.Object.__uid++,options=applyViewboxTransform(doc),descendants=fabric.util.toArray(doc.getElementsByTagName("*"));options.svgUid=svgUid;if(descendants.length===0&&fabric.isLikelyNode){descendants=doc.selectNodes('//*[name(.)!="svg"]');var arr=[];for(var i=0,len=descendants.length;i\n',' \n \n')}}var reFontDeclaration=new RegExp("(normal|italic)?\\s*(normal|small-caps)?\\s*"+"(normal|bold|bolder|lighter|100|200|300|400|500|600|700|800|900)?\\s*("+fabric.reNum+"(?:px|cm|mm|em|pt|pc|in)*)(?:\\/(normal|"+fabric.reNum+"))?\\s+(.*)");extend(fabric,{parseFontDeclaration:function(value,oStyle){var match=value.match(reFontDeclaration);if(!match){return}var fontStyle=match[1],fontWeight=match[3],fontSize=match[4],lineHeight=match[5],fontFamily=match[6];if(fontStyle){oStyle.fontStyle=fontStyle}if(fontWeight){oStyle.fontWeight=isNaN(parseFloat(fontWeight))?fontWeight:parseFloat(fontWeight)}if(fontSize){oStyle.fontSize=parseUnit(fontSize)}if(fontFamily){oStyle.fontFamily=fontFamily}if(lineHeight){oStyle.lineHeight=lineHeight==="normal"?1:lineHeight}},getGradientDefs:function(doc){var linearGradientEls=doc.getElementsByTagName("linearGradient"),radialGradientEls=doc.getElementsByTagName("radialGradient"),el,i,j=0,id,xlink,elList=[],gradientDefs={},idsToXlinkMap={};elList.length=linearGradientEls.length+radialGradientEls.length;i=linearGradientEls.length;while(i--){elList[j++]=linearGradientEls[i]}i=radialGradientEls.length;while(i--){elList[j++]=radialGradientEls[i]}while(j--){el=elList[j];xlink=el.getAttribute("xlink:href");id=el.getAttribute("id");if(xlink){idsToXlinkMap[id]=xlink.substr(1)}gradientDefs[id]=el}for(id in idsToXlinkMap){var el2=gradientDefs[idsToXlinkMap[id]].cloneNode(true);el=gradientDefs[id];while(el2.firstChild){el.appendChild(el2.firstChild)}}return gradientDefs},parseAttributes:function(element,attributes,svgUid){if(!element){return}var value,parentAttributes={},fontSize;if(typeof svgUid==="undefined"){svgUid=element.getAttribute("svgUid")}if(element.parentNode&&reAllowedParents.test(element.parentNode.nodeName)){parentAttributes=fabric.parseAttributes(element.parentNode,attributes,svgUid)}fontSize=parentAttributes&&parentAttributes.fontSize||element.getAttribute("font-size")||fabric.Text.DEFAULT_SVG_FONT_SIZE;var ownAttributes=attributes.reduce(function(memo,attr){value=element.getAttribute(attr);if(value){attr=normalizeAttr(attr);value=normalizeValue(attr,value,parentAttributes,fontSize);memo[attr]=value}return memo},{});ownAttributes=extend(ownAttributes,extend(getGlobalStylesForElement(element,svgUid),fabric.parseStyleAttribute(element)));if(ownAttributes.font){fabric.parseFontDeclaration(ownAttributes.font,ownAttributes)}return _setStrokeFillOpacity(extend(parentAttributes,ownAttributes))},parseElements:function(elements,callback,options,reviver){new fabric.ElementsParser(elements,callback,options,reviver).parse()},parseStyleAttribute:function(element){var oStyle={},style=element.getAttribute("style");if(!style){return oStyle}if(typeof style==="string"){parseStyleString(style,oStyle)}else{parseStyleObject(style,oStyle)}return oStyle},parsePointsAttribute:function(points){if(!points){return null}points=points.replace(/,/g," ").trim();points=points.split(/\s+/);var parsedPoints=[],i,len;i=0;len=points.length;for(;i/i,""))}if(!xml||!xml.documentElement){return}fabric.parseSVGDocument(xml.documentElement,function(results,options){svgCache.set(url,{objects:fabric.util.array.invoke(results,"toObject"),options:options});callback(results,options)},reviver)}},loadSVGFromString:function(string,callback,reviver){string=string.trim();var doc;if(typeof DOMParser!=="undefined"){var parser=new DOMParser;if(parser&&parser.parseFromString){doc=parser.parseFromString(string,"text/xml")}}else if(fabric.window.ActiveXObject){doc=new ActiveXObject("Microsoft.XMLDOM");doc.async="false";doc.loadXML(string.replace(//i,""))}fabric.parseSVGDocument(doc.documentElement,function(results,options){callback(results,options)},reviver)},createSVGFontFacesMarkup:function(objects){var markup="",fontList={},obj,fontFamily,style,row,rowIndex,char,charIndex,fontPaths=fabric.fontPaths;for(var i=0,len=objects.length;i',"","\n"].join("")}return markup},createSVGRefElementsMarkup:function(canvas){var markup=[];_createSVGPattern(markup,canvas,"backgroundColor");_createSVGPattern(markup,canvas,"overlayColor");return markup.join("")}})})(typeof exports!=="undefined"?exports:this);fabric.ElementsParser=function(elements,callback,options,reviver){this.elements=elements;this.callback=callback;this.options=options;this.reviver=reviver;this.svgUid=options&&options.svgUid||0};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 i=0,len=this.elements.length;ithat.x&&this.y>that.y},gte:function(that){return this.x>=that.x&&this.y>=that.y},lerp:function(that,t){return new Point(this.x+(that.x-this.x)*t,this.y+(that.y-this.y)*t)},distanceFrom:function(that){var dx=this.x-that.x,dy=this.y-that.y;return Math.sqrt(dx*dx+dy*dy)},midPointFrom:function(that){return new Point(this.x+(that.x-this.x)/2,this.y+(that.y-this.y)/2)},min:function(that){return new Point(Math.min(this.x,that.x),Math.min(this.y,that.y))},max:function(that){return new Point(Math.max(this.x,that.x),Math.max(this.y,that.y))},toString:function(){return this.x+","+this.y},setXY:function(x,y){this.x=x;this.y=y},setFromPoint:function(that){this.x=that.x;this.y=that.y},swap:function(that){var x=this.x,y=this.y;this.x=that.x;this.y=that.y;that.x=x;that.y=y}}})(typeof exports!=="undefined"?exports:this);(function(global){"use strict";var fabric=global.fabric||(global.fabric={});if(fabric.Intersection){fabric.warn("fabric.Intersection is already defined");return}function Intersection(status){this.status=status;this.points=[]}fabric.Intersection=Intersection;fabric.Intersection.prototype={appendPoint:function(point){this.points.push(point)},appendPoints:function(points){this.points=this.points.concat(points)}};fabric.Intersection.intersectLineLine=function(a1,a2,b1,b2){var result,uaT=(b2.x-b1.x)*(a1.y-b1.y)-(b2.y-b1.y)*(a1.x-b1.x),ubT=(a2.x-a1.x)*(a1.y-b1.y)-(a2.y-a1.y)*(a1.x-b1.x),uB=(b2.y-b1.y)*(a2.x-a1.x)-(b2.x-b1.x)*(a2.y-a1.y);if(uB!==0){var ua=uaT/uB,ub=ubT/uB;if(0<=ua&&ua<=1&&0<=ub&&ub<=1){result=new Intersection("Intersection");result.points.push(new fabric.Point(a1.x+ua*(a2.x-a1.x),a1.y+ua*(a2.y-a1.y)))}else{result=new Intersection}}else{if(uaT===0||ubT===0){result=new Intersection("Coincident")}else{result=new Intersection("Parallel")}}return result};fabric.Intersection.intersectLinePolygon=function(a1,a2,points){var result=new Intersection,length=points.length;for(var i=0;i0){result.status="Intersection"}return result};fabric.Intersection.intersectPolygonPolygon=function(points1,points2){var result=new Intersection,length=points1.length;for(var i=0;i0){result.status="Intersection"}return result};fabric.Intersection.intersectPolygonRectangle=function(points,r1,r2){var min=r1.min(r2),max=r1.max(r2),topRight=new fabric.Point(max.x,min.y),bottomLeft=new fabric.Point(min.x,max.y),inter1=Intersection.intersectLinePolygon(min,topRight,points),inter2=Intersection.intersectLinePolygon(topRight,max,points),inter3=Intersection.intersectLinePolygon(max,bottomLeft,points),inter4=Intersection.intersectLinePolygon(bottomLeft,min,points),result=new Intersection;result.appendPoints(inter1.points);result.appendPoints(inter2.points);result.appendPoints(inter3.points);result.appendPoints(inter4.points);if(result.points.length>0){result.status="Intersection"}return result}})(typeof exports!=="undefined"?exports:this);(function(global){"use strict";var fabric=global.fabric||(global.fabric={});if(fabric.Color){fabric.warn("fabric.Color is already defined.");return}function Color(color){if(!color){this.setSource([0,0,0,1])}else{this._tryParsingColor(color)}}fabric.Color=Color;fabric.Color.prototype={_tryParsingColor:function(color){var source;if(color in Color.colorNameMap){color=Color.colorNameMap[color] +}if(color==="transparent"){this.setSource([255,255,255,0]);return}source=Color.sourceFromHex(color);if(!source){source=Color.sourceFromRgb(color)}if(!source){source=Color.sourceFromHsl(color)}if(source){this.setSource(source)}},_rgbToHsl:function(r,g,b){r/=255,g/=255,b/=255;var h,s,l,max=fabric.util.array.max([r,g,b]),min=fabric.util.array.min([r,g,b]);l=(max+min)/2;if(max===min){h=s=0}else{var d=max-min;s=l>.5?d/(2-max-min):d/(max+min);switch(max){case r:h=(g-b)/d+(g1){t-=1}if(t<1/6){return p+(q-p)*6*t}if(t<1/2){return q}if(t<2/3){return p+(q-p)*(2/3-t)*6}return p}fabric.Color.fromRgb=function(color){return Color.fromSource(Color.sourceFromRgb(color))};fabric.Color.sourceFromRgb=function(color){var match=color.match(Color.reRGBa);if(match){var r=parseInt(match[1],10)/(/%$/.test(match[1])?100:1)*(/%$/.test(match[1])?255:1),g=parseInt(match[2],10)/(/%$/.test(match[2])?100:1)*(/%$/.test(match[2])?255:1),b=parseInt(match[3],10)/(/%$/.test(match[3])?100:1)*(/%$/.test(match[3])?255:1);return[parseInt(r,10),parseInt(g,10),parseInt(b,10),match[4]?parseFloat(match[4]):1]}};fabric.Color.fromRgba=Color.fromRgb;fabric.Color.fromHsl=function(color){return Color.fromSource(Color.sourceFromHsl(color))};fabric.Color.sourceFromHsl=function(color){var match=color.match(Color.reHSLa);if(!match){return}var h=(parseFloat(match[1])%360+360)%360/360,s=parseFloat(match[2])/(/%$/.test(match[2])?100:1),l=parseFloat(match[3])/(/%$/.test(match[3])?100:1),r,g,b;if(s===0){r=g=b=l}else{var q=l<=.5?l*(s+1):l+s-l*s,p=l*2-q;r=hue2rgb(p,q,h+1/3);g=hue2rgb(p,q,h);b=hue2rgb(p,q,h-1/3)}return[Math.round(r*255),Math.round(g*255),Math.round(b*255),match[4]?parseFloat(match[4]):1]};fabric.Color.fromHsla=Color.fromHsl;fabric.Color.fromHex=function(color){return Color.fromSource(Color.sourceFromHex(color))};fabric.Color.sourceFromHex=function(color){if(color.match(Color.reHex)){var value=color.slice(color.indexOf("#")+1),isShortNotation=value.length===3,r=isShortNotation?value.charAt(0)+value.charAt(0):value.substring(0,2),g=isShortNotation?value.charAt(1)+value.charAt(1):value.substring(2,4),b=isShortNotation?value.charAt(2)+value.charAt(2):value.substring(4,6);return[parseInt(r,16),parseInt(g,16),parseInt(b,16),1]}};fabric.Color.fromSource=function(source){var oColor=new Color;oColor.setSource(source);return oColor}})(typeof exports!=="undefined"?exports:this);(function(){function getColorStop(el){var style=el.getAttribute("style"),offset=el.getAttribute("offset")||0,color,colorAlpha,opacity;offset=parseFloat(offset)/(/%$/.test(offset)?100:1);offset=offset<0?0:offset>1?1:offset;if(style){var keyValuePairs=style.split(/\s*;\s*/);if(keyValuePairs[keyValuePairs.length-1]===""){keyValuePairs.pop()}for(var i=keyValuePairs.length;i--;){var split=keyValuePairs[i].split(/\s*:\s*/),key=split[0].trim(),value=split[1].trim();if(key==="stop-color"){color=value}else if(key==="stop-opacity"){opacity=value}}}if(!color){color=el.getAttribute("stop-color")||"rgb(0,0,0)"}if(!opacity){opacity=el.getAttribute("stop-opacity")}color=new fabric.Color(color);colorAlpha=color.getAlpha();opacity=isNaN(parseFloat(opacity))?1:parseFloat(opacity);opacity*=colorAlpha;return{offset:offset,color:color.toRgb(),opacity:opacity}}function getLinearCoords(el){return{x1:el.getAttribute("x1")||0,y1:el.getAttribute("y1")||0,x2:el.getAttribute("x2")||"100%",y2:el.getAttribute("y2")||0}}function getRadialCoords(el){return{x1:el.getAttribute("fx")||el.getAttribute("cx")||"50%",y1:el.getAttribute("fy")||el.getAttribute("cy")||"50%",r1:0,x2:el.getAttribute("cx")||"50%",y2:el.getAttribute("cy")||"50%",r2:el.getAttribute("r")||"50%"}}fabric.Gradient=fabric.util.createClass({offsetX:0,offsetY:0,initialize:function(options){options||(options={});var coords={};this.id=fabric.Object.__uid++;this.type=options.type||"linear";coords={x1:options.coords.x1||0,y1:options.coords.y1||0,x2:options.coords.x2||0,y2:options.coords.y2||0};if(this.type==="radial"){coords.r1=options.coords.r1||0;coords.r2=options.coords.r2||0}this.coords=coords;this.colorStops=options.colorStops.slice();if(options.gradientTransform){this.gradientTransform=options.gradientTransform}this.offsetX=options.offsetX||this.offsetX;this.offsetY=options.offsetY||this.offsetY},addColorStop:function(colorStop){for(var position in colorStop){var color=new fabric.Color(colorStop[position]);this.colorStops.push({offset:position,color:color.toRgb(),opacity:color.getAlpha()})}return this},toObject:function(){return{type:this.type,coords:this.coords,colorStops:this.colorStops,offsetX:this.offsetX,offsetY:this.offsetY,gradientTransform:this.gradientTransform?this.gradientTransform.concat():this.gradientTransform}},toSVG:function(object){var coords=fabric.util.object.clone(this.coords),markup,commonAttributes;this.colorStops.sort(function(a,b){return a.offset-b.offset});if(!(object.group&&object.group.type==="path-group")){for(var prop in coords){if(prop==="x1"||prop==="x2"||prop==="r2"){coords[prop]+=this.offsetX-object.width/2}else if(prop==="y1"||prop==="y2"){coords[prop]+=this.offsetY-object.height/2}}}commonAttributes='id="SVGID_'+this.id+'" gradientUnits="userSpaceOnUse"';if(this.gradientTransform){commonAttributes+=' gradientTransform="matrix('+this.gradientTransform.join(" ")+')" '}if(this.type==="linear"){markup=["\n']}else if(this.type==="radial"){markup=["\n']}for(var i=0;i\n')}markup.push(this.type==="linear"?"\n":"\n");return markup.join("")},toLive:function(ctx,object){var gradient,prop,coords=fabric.util.object.clone(this.coords);if(!this.type){return}if(object.group&&object.group.type==="path-group"){for(prop in coords){if(prop==="x1"||prop==="x2"){coords[prop]+=-this.offsetX+object.width/2}else if(prop==="y1"||prop==="y2"){coords[prop]+=-this.offsetY+object.height/2}}}if(this.type==="linear"){gradient=ctx.createLinearGradient(coords.x1,coords.y1,coords.x2,coords.y2)}else if(this.type==="radial"){gradient=ctx.createRadialGradient(coords.x1,coords.y1,coords.r1,coords.x2,coords.y2,coords.r2)}for(var i=0,len=this.colorStops.length;i\n'+'\n'+"\n"},toLive:function(ctx){var source=typeof this.source==="function"?this.source():this.source;if(!source){return""}if(typeof source.src!=="undefined"){if(!source.complete){return""}if(source.naturalWidth===0||source.naturalHeight===0){return""}}return ctx.createPattern(source,this.repeat)}});(function(global){"use strict";var fabric=global.fabric||(global.fabric={}),toFixed=fabric.util.toFixed;if(fabric.Shadow){fabric.warn("fabric.Shadow is already defined.");return}fabric.Shadow=fabric.util.createClass({color:"rgb(0,0,0)",blur:0,offsetX:0,offsetY:0,affectStroke:false,includeDefaultValues:true,initialize:function(options){if(typeof options==="string"){options=this._parseShadow(options)}for(var prop in options){this[prop]=options[prop]}this.id=fabric.Object.__uid++},_parseShadow:function(shadow){var shadowStr=shadow.trim(),offsetsAndBlur=fabric.Shadow.reOffsetsAndBlur.exec(shadowStr)||[],color=shadowStr.replace(fabric.Shadow.reOffsetsAndBlur,"")||"rgb(0,0,0)";return{color:color.trim(),offsetX:parseInt(offsetsAndBlur[1],10)||0,offsetY:parseInt(offsetsAndBlur[2],10)||0,blur:parseInt(offsetsAndBlur[3],10)||0}},toString:function(){return[this.offsetX,this.offsetY,this.blur,this.color].join("px ")},toSVG:function(object){var fBoxX=40,fBoxY=40,NUM_FRACTION_DIGITS=fabric.Object.NUM_FRACTION_DIGITS,offset=fabric.util.rotateVector({x:this.offsetX,y:this.offsetY},fabric.util.degreesToRadians(-object.angle)),BLUR_BOX=20;if(object.width&&object.height){fBoxX=toFixed((Math.abs(offset.x)+this.blur)/object.width,NUM_FRACTION_DIGITS)*100+BLUR_BOX;fBoxY=toFixed((Math.abs(offset.y)+this.blur)/object.height,NUM_FRACTION_DIGITS)*100+BLUR_BOX}if(object.flipX){offset.x*=-1}if(object.flipY){offset.y*=-1}return'\n"+' \n'+' \n'+' \n'+' \n'+" \n"+" \n"+' \n'+" \n"+"\n"},toObject:function(){if(this.includeDefaultValues){return{color:this.color,blur:this.blur,offsetX:this.offsetX,offsetY:this.offsetY,affectStroke:this.affectStroke}}var obj={},proto=fabric.Shadow.prototype;["color","blur","offsetX","offsetY","affectStroke"].forEach(function(prop){if(this[prop]!==proto[prop]){obj[prop]=this[prop]}},this);return obj}});fabric.Shadow.reOffsetsAndBlur=/(?:\s|^)(-?\d+(?:px)?(?:\s?|$))?(-?\d+(?:px)?(?:\s?|$))?(\d+(?:px)?)?(?:\s?|$)(?:$|\s)/})(typeof exports!=="undefined"?exports:this);(function(){"use strict";if(fabric.StaticCanvas){fabric.warn("fabric.StaticCanvas is already defined.");return}var extend=fabric.util.object.extend,getElementOffset=fabric.util.getElementOffset,removeFromArray=fabric.util.removeFromArray,toFixed=fabric.util.toFixed,CANVAS_INIT_ERROR=new Error("Could not initialize `canvas` element");fabric.StaticCanvas=fabric.util.createClass({initialize:function(el,options){options||(options={});this._initStatic(el,options)},backgroundColor:"",backgroundImage:null,overlayColor:"",overlayImage:null,includeDefaultValues:true,stateful:true,renderOnAddRemove:true,clipTo:null,controlsAboveOverlay:false,allowTouchScrolling:false,imageSmoothingEnabled:true,preserveObjectStacking:false,viewportTransform:[1,0,0,1,0,0],onBeforeScaleRotate:function(){},enableRetinaScaling:true,_initStatic:function(el,options){this._objects=[];this._createLowerCanvas(el);this._initOptions(options);this._setImageSmoothing();if(!this.interactive){this._initRetinaScaling()}if(options.overlayImage){this.setOverlayImage(options.overlayImage,this.renderAll.bind(this))}if(options.backgroundImage){this.setBackgroundImage(options.backgroundImage,this.renderAll.bind(this))}if(options.backgroundColor){this.setBackgroundColor(options.backgroundColor,this.renderAll.bind(this))}if(options.overlayColor){this.setOverlayColor(options.overlayColor,this.renderAll.bind(this))}this.calcOffset()},_isRetinaScaling:function(){return fabric.devicePixelRatio!==1&&this.enableRetinaScaling},_initRetinaScaling:function(){if(!this._isRetinaScaling()){return}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(){this._offset=getElementOffset(this.lowerCanvasEl);return this},setOverlayImage:function(image,callback,options){return this.__setBgOverlayImage("overlayImage",image,callback,options)},setBackgroundImage:function(image,callback,options){return this.__setBgOverlayImage("backgroundImage",image,callback,options)},setOverlayColor:function(overlayColor,callback){return this.__setBgOverlayColor("overlayColor",overlayColor,callback)},setBackgroundColor:function(backgroundColor,callback){return this.__setBgOverlayColor("backgroundColor",backgroundColor,callback)},_setImageSmoothing:function(){var ctx=this.getContext();ctx.imageSmoothingEnabled=ctx.imageSmoothingEnabled||ctx.webkitImageSmoothingEnabled||ctx.mozImageSmoothingEnabled||ctx.msImageSmoothingEnabled||ctx.oImageSmoothingEnabled;ctx.imageSmoothingEnabled=this.imageSmoothingEnabled},__setBgOverlayImage:function(property,image,callback,options){if(typeof image==="string"){fabric.util.loadImage(image,function(img){this[property]=new fabric.Image(img,options);callback&&callback(img)},this,options&&options.crossOrigin)}else{options&&image.setOptions(options);this[property]=image;callback&&callback(image)}return this},__setBgOverlayColor:function(property,color,callback){if(color&&color.source){var _this=this;fabric.util.loadImage(color.source,function(img){_this[property]=new fabric.Pattern({source:img,repeat:color.repeat,offsetX:color.offsetX,offsetY:color.offsetY});callback&&callback()})}else{this[property]=color;callback&&callback()}return this},_createCanvasElement:function(){var element=fabric.document.createElement("canvas");if(!element.style){element.style={}}if(!element){throw CANVAS_INIT_ERROR}this._initCanvasElement(element);return element},_initCanvasElement:function(element){fabric.util.createCanvasElement(element);if(typeof element.getContext==="undefined"){throw CANVAS_INIT_ERROR}},_initOptions:function(options){for(var prop in options){this[prop]=options[prop]}this.width=this.width||parseInt(this.lowerCanvasEl.width,10)||0;this.height=this.height||parseInt(this.lowerCanvasEl.height,10)||0;if(!this.lowerCanvasEl.style){return}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(canvasEl){this.lowerCanvasEl=fabric.util.getById(canvasEl)||this._createCanvasElement();this._initCanvasElement(this.lowerCanvasEl);fabric.util.addClass(this.lowerCanvasEl,"lower-canvas");if(this.interactive){this._applyCanvasStyle(this.lowerCanvasEl)}this.contextContainer=this.lowerCanvasEl.getContext("2d")},getWidth:function(){return this.width},getHeight:function(){return this.height},setWidth:function(value,options){return this.setDimensions({width:value},options)},setHeight:function(value,options){return this.setDimensions({height:value},options)},setDimensions:function(dimensions,options){var cssValue;options=options||{};for(var prop in dimensions){cssValue=dimensions[prop];if(!options.cssOnly){this._setBackstoreDimension(prop,dimensions[prop]);cssValue+="px"}if(!options.backstoreOnly){this._setCssDimension(prop,cssValue)}}this._initRetinaScaling();this._setImageSmoothing();this.calcOffset();if(!options.cssOnly){this.renderAll()}return this},_setBackstoreDimension:function(prop,value){this.lowerCanvasEl[prop]=value;if(this.upperCanvasEl){this.upperCanvasEl[prop]=value}if(this.cacheCanvasEl){this.cacheCanvasEl[prop]=value}this[prop]=value;return this},_setCssDimension:function(prop,value){this.lowerCanvasEl.style[prop]=value;if(this.upperCanvasEl){this.upperCanvasEl.style[prop]=value}if(this.wrapperEl){this.wrapperEl.style[prop]=value}return this},getZoom:function(){return Math.sqrt(this.viewportTransform[0]*this.viewportTransform[3])},setViewportTransform:function(vpt){var activeGroup=this.getActiveGroup();this.viewportTransform=vpt;this.renderAll();for(var i=0,len=this._objects.length;i");return markup.join("")},_setSVGPreamble:function(markup,options){if(options.suppressPreamble){return}markup.push('\n','\n')},_setSVGHeader:function(markup,options){var width=options.width||this.width,height=options.height||this.height,vpt,viewBox='viewBox="0 0 '+this.width+" "+this.height+'" ',NUM_FRACTION_DIGITS=fabric.Object.NUM_FRACTION_DIGITS;if(options.viewBox){viewBox='viewBox="'+options.viewBox.x+" "+options.viewBox.y+" "+options.viewBox.width+" "+options.viewBox.height+'" '}else{if(this.svgViewportTransformation){vpt=this.viewportTransform;viewBox='viewBox="'+toFixed(-vpt[4]/vpt[0],NUM_FRACTION_DIGITS)+" "+toFixed(-vpt[5]/vpt[3],NUM_FRACTION_DIGITS)+" "+toFixed(this.width/vpt[0],NUM_FRACTION_DIGITS)+" "+toFixed(this.height/vpt[3],NUM_FRACTION_DIGITS)+'" '}}markup.push("\n',"Created with Fabric.js ",fabric.version,"\n","",fabric.createSVGFontFacesMarkup(this.getObjects()),fabric.createSVGRefElementsMarkup(this),"\n")},_setSVGObjects:function(markup,reviver){for(var i=0,objects=this.getObjects(),len=objects.length;i\n")}else if(this[property]&&property==="overlayColor"){markup.push('\n")}},sendToBack:function(object){if(!object){return this}var activeGroup=this.getActiveGroup?this.getActiveGroup():null,i,obj,objs;if(object===activeGroup){objs=activeGroup._objects;for(i=objs.length;i--;){obj=objs[i];removeFromArray(this._objects,obj); +this._objects.unshift(obj)}}else{removeFromArray(this._objects,object);this._objects.unshift(object)}return this.renderAll&&this.renderAll()},bringToFront:function(object){if(!object){return this}var activeGroup=this.getActiveGroup?this.getActiveGroup():null,i,obj,objs;if(object===activeGroup){objs=activeGroup._objects;for(i=0;i=0;--i){var isIntersecting=object.intersectsWithObject(this._objects[i])||object.isContainedWithinObject(this._objects[i])||this._objects[i].isContainedWithinObject(object);if(isIntersecting){newIdx=i;break}}}else{newIdx=idx-1}return newIdx},bringForward:function(object,intersecting){if(!object){return this}var activeGroup=this.getActiveGroup?this.getActiveGroup():null,i,obj,idx,newIdx,objs;if(object===activeGroup){objs=activeGroup._objects;for(i=objs.length;i--;){obj=objs[i];idx=this._objects.indexOf(obj);if(idx!==this._objects.length-1){newIdx=idx+1;removeFromArray(this._objects,obj);this._objects.splice(newIdx,0,obj)}}}else{idx=this._objects.indexOf(object);if(idx!==this._objects.length-1){newIdx=this._findNewUpperIndex(object,idx,intersecting);removeFromArray(this._objects,object);this._objects.splice(newIdx,0,object)}}this.renderAll&&this.renderAll();return this},_findNewUpperIndex:function(object,idx,intersecting){var newIdx;if(intersecting){newIdx=idx;for(var i=idx+1;i"}});extend(fabric.StaticCanvas.prototype,fabric.Observable);extend(fabric.StaticCanvas.prototype,fabric.Collection);extend(fabric.StaticCanvas.prototype,fabric.DataURLExporter);extend(fabric.StaticCanvas,{EMPTY_JSON:'{"objects": [], "background": "white"}',supports:function(methodName){var el=fabric.util.createCanvasElement();if(!el||!el.getContext){return null}var ctx=el.getContext("2d");if(!ctx){return null}switch(methodName){case"getImageData":return typeof ctx.getImageData!=="undefined";case"setLineDash":return typeof ctx.setLineDash!=="undefined";case"toDataURL":return typeof el.toDataURL!=="undefined";case"toDataURLWithQuality":try{el.toDataURL("image/jpeg",0);return true}catch(e){}return false;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(options){this.shadow=new fabric.Shadow(options);return this},_setBrushStyles:function(){var ctx=this.canvas.contextTop;ctx.strokeStyle=this.color;ctx.lineWidth=this.width;ctx.lineCap=this.strokeLineCap;ctx.lineJoin=this.strokeLineJoin;if(this.strokeDashArray&&fabric.StaticCanvas.supports("setLineDash")){ctx.setLineDash(this.strokeDashArray)}},_setShadow:function(){if(!this.shadow){return}var ctx=this.canvas.contextTop;ctx.shadowColor=this.shadow.color;ctx.shadowBlur=this.shadow.blur;ctx.shadowOffsetX=this.shadow.offsetX;ctx.shadowOffsetY=this.shadow.offsetY},_resetShadow:function(){var ctx=this.canvas.contextTop;ctx.shadowColor="";ctx.shadowBlur=ctx.shadowOffsetX=ctx.shadowOffsetY=0}});(function(){fabric.PencilBrush=fabric.util.createClass(fabric.BaseBrush,{initialize:function(canvas){this.canvas=canvas;this._points=[]},onMouseDown:function(pointer){this._prepareForDrawing(pointer);this._captureDrawingPath(pointer);this._render()},onMouseMove:function(pointer){this._captureDrawingPath(pointer);this.canvas.clearContext(this.canvas.contextTop);this._render()},onMouseUp:function(){this._finalizeAndAddPath()},_prepareForDrawing:function(pointer){var p=new fabric.Point(pointer.x,pointer.y);this._reset();this._addPoint(p);this.canvas.contextTop.moveTo(p.x,p.y)},_addPoint:function(point){this._points.push(point)},_reset:function(){this._points.length=0;this._setBrushStyles();this._setShadow()},_captureDrawingPath:function(pointer){var pointerPoint=new fabric.Point(pointer.x,pointer.y);this._addPoint(pointerPoint)},_render:function(){var ctx=this.canvas.contextTop,v=this.canvas.viewportTransform,p1=this._points[0],p2=this._points[1];ctx.save();ctx.transform(v[0],v[1],v[2],v[3],v[4],v[5]);ctx.beginPath();if(this._points.length===2&&p1.x===p2.x&&p1.y===p2.y){p1.x-=.5;p2.x+=.5}ctx.moveTo(p1.x,p1.y);for(var i=1,len=this._points.length;i0?1:-1;if(by==="y"){skew=t.target.skewY;originA="top";originB="bottom";property="originY"}origins[-1]=originA;origins[1]=originB;t.target.flipX&&(flipSign*=-1);t.target.flipY&&(flipSign*=-1);if(skew===0){t.skewSign=-corner*mouseMove*flipSign;t[property]=origins[-mouseMove]}else{skew=skew>0?1:-1;t.skewSign=skew;t[property]=origins[skew*corner*flipSign]}},_skewObject:function(x,y,by){var t=this._currentTransform,target=t.target,skewed=false,lockSkewingX=target.get("lockSkewingX"),lockSkewingY=target.get("lockSkewingY");if(lockSkewingX&&by==="x"||lockSkewingY&&by==="y"){return false}var center=target.getCenterPoint(),actualMouseByCenter=target.toLocalPoint(new fabric.Point(x,y),"center","center")[by],lastMouseByCenter=target.toLocalPoint(new fabric.Point(t.lastX,t.lastY),"center","center")[by],actualMouseByOrigin,constraintPosition,dim=target._getTransformedDimensions();this._changeSkewTransformOrigin(actualMouseByCenter-lastMouseByCenter,t,by);actualMouseByOrigin=target.toLocalPoint(new fabric.Point(x,y),t.originX,t.originY)[by],constraintPosition=target.translateToOriginPoint(center,t.originX,t.originY);skewed=this._setObjectSkew(actualMouseByOrigin,t,by,dim);t.lastX=x;t.lastY=y;target.setPositionByOrigin(constraintPosition,t.originX,t.originY);return skewed},_setObjectSkew:function(localMouse,transform,by,_dim){var target=transform.target,newValue,skewed=false,skewSign=transform.skewSign,newDim,dimNoSkew,otherBy,_otherBy,_by,newDimMouse,skewX,skewY;if(by==="x"){otherBy="y";_otherBy="Y";_by="X";skewX=0;skewY=target.skewY}else{otherBy="x";_otherBy="X";_by="Y";skewX=target.skewX;skewY=0}dimNoSkew=target._getTransformedDimensions(skewX,skewY);newDimMouse=2*Math.abs(localMouse)-dimNoSkew[by];if(newDimMouse<=2){newValue=0}else{newValue=skewSign*Math.atan(newDimMouse/target["scale"+_by]/(dimNoSkew[otherBy]/target["scale"+_otherBy]));newValue=fabric.util.radiansToDegrees(newValue)}skewed=target["skew"+_by]!==newValue;target.set("skew"+_by,newValue);if(target["skew"+_otherBy]!==0){newDim=target._getTransformedDimensions();newValue=_dim[otherBy]/newDim[otherBy]*target["scale"+_otherBy];target.set("scale"+_otherBy,newValue)}return skewed},_scaleObject:function(x,y,by){var t=this._currentTransform,target=t.target,lockScalingX=target.get("lockScalingX"),lockScalingY=target.get("lockScalingY"),lockScalingFlip=target.get("lockScalingFlip");if(lockScalingX&&lockScalingY){return false}var constraintPosition=target.translateToOriginPoint(target.getCenterPoint(),t.originX,t.originY),localMouse=target.toLocalPoint(new fabric.Point(x,y),t.originX,t.originY),dim=target._getTransformedDimensions(),scaled=false;this._setLocalMouse(localMouse,t);scaled=this._setObjectScale(localMouse,t,lockScalingX,lockScalingY,by,lockScalingFlip,dim);target.setPositionByOrigin(constraintPosition,t.originX,t.originY);return scaled},_setObjectScale:function(localMouse,transform,lockScalingX,lockScalingY,by,lockScalingFlip,_dim){var target=transform.target,forbidScalingX=false,forbidScalingY=false,scaled=false,changeX,changeY,scaleX,scaleY;scaleX=localMouse.x*target.scaleX/_dim.x;scaleY=localMouse.y*target.scaleY/_dim.y;changeX=target.scaleX!==scaleX;changeY=target.scaleY!==scaleY;if(lockScalingFlip&&scaleX<=0&&scaleXtarget.padding){if(localMouse.x<0){localMouse.x+=target.padding}else{localMouse.x-=target.padding}}else{localMouse.x=0}if(abs(localMouse.y)>target.padding){if(localMouse.y<0){localMouse.y+=target.padding}else{localMouse.y-=target.padding}}else{localMouse.y=0}},_rotateObject:function(x,y){var t=this._currentTransform;if(t.target.get("lockRotation")){return false}var lastAngle=atan2(t.ey-t.top,t.ex-t.left),curAngle=atan2(y-t.top,x-t.left),angle=radiansToDegrees(curAngle-lastAngle+t.theta);if(angle<0){angle=360+angle}t.target.angle=angle%360;return true},setCursor:function(value){this.upperCanvasEl.style.cursor=value},_resetObjectTransform:function(target){target.scaleX=1;target.scaleY=1;target.skewX=0;target.skewY=0;target.setAngle(0)},_drawSelection:function(){var ctx=this.contextTop,groupSelector=this._groupSelector,left=groupSelector.left,top=groupSelector.top,aleft=abs(left),atop=abs(top);ctx.fillStyle=this.selectionColor;ctx.fillRect(groupSelector.ex-(left>0?0:-left),groupSelector.ey-(top>0?0:-top),aleft,atop);ctx.lineWidth=this.selectionLineWidth;ctx.strokeStyle=this.selectionBorderColor;if(this.selectionDashArray.length>1){var px=groupSelector.ex+STROKE_OFFSET-(left>0?0:aleft),py=groupSelector.ey+STROKE_OFFSET-(top>0?0:atop);ctx.beginPath();fabric.util.drawDashedLine(ctx,px,py,px+aleft,py,this.selectionDashArray);fabric.util.drawDashedLine(ctx,px,py+atop-1,px+aleft,py+atop-1,this.selectionDashArray);fabric.util.drawDashedLine(ctx,px,py,px,py+atop,this.selectionDashArray);fabric.util.drawDashedLine(ctx,px+aleft-1,py,px+aleft-1,py+atop,this.selectionDashArray);ctx.closePath();ctx.stroke()}else{ctx.strokeRect(groupSelector.ex+STROKE_OFFSET-(left>0?0:aleft),groupSelector.ey+STROKE_OFFSET-(top>0?0:atop),aleft,atop)}},_isLastRenderedObject:function(e){return this.controlsAboveOverlay&&this.lastRenderedObjectWithControlsAboveOverlay&&this.lastRenderedObjectWithControlsAboveOverlay.visible&&this.containsPoint(e,this.lastRenderedObjectWithControlsAboveOverlay)&&this.lastRenderedObjectWithControlsAboveOverlay._findTargetCorner(this.getPointer(e,true))},findTarget:function(e,skipGroup){if(this.skipTargetFind){return}if(this._isLastRenderedObject(e)){return this.lastRenderedObjectWithControlsAboveOverlay}var activeGroup=this.getActiveGroup();if(!skipGroup&&this._checkTarget(e,activeGroup,this.getPointer(e,true))){return activeGroup}var target=this._searchPossibleTargets(e,skipGroup);this._fireOverOutEvents(target,e);return target},_fireOverOutEvents:function(target,e){if(target){if(this._hoveredTarget!==target){if(this._hoveredTarget){this.fire("mouse:out",{target:this._hoveredTarget,e:e});this._hoveredTarget.fire("mouseout")}this.fire("mouse:over",{target:target,e:e});target.fire("mouseover");this._hoveredTarget=target}}else if(this._hoveredTarget){this.fire("mouse:out",{target:this._hoveredTarget,e:e});this._hoveredTarget.fire("mouseout");this._hoveredTarget=null}},_checkTarget:function(e,obj,pointer){if(obj&&obj.visible&&obj.evented&&this.containsPoint(e,obj)){if((this.perPixelTargetFind||obj.perPixelTargetFind)&&!obj.isEditing){var isTransparent=this.isTargetTransparent(obj,pointer.x,pointer.y);if(!isTransparent){return true}}else{return true}}},_searchPossibleTargets:function(e,skipGroup){var target,pointer=this.getPointer(e,true),i=this._objects.length;while(i--){if((!this._objects[i].group||skipGroup)&&this._checkTarget(e,this._objects[i],pointer)){this.relatedTarget=this._objects[i];target=this._objects[i];break}}return target},getPointer:function(e,ignoreZoom,upperCanvasEl){if(!upperCanvasEl){upperCanvasEl=this.upperCanvasEl}var pointer=getPointer(e),bounds=upperCanvasEl.getBoundingClientRect(),boundsWidth=bounds.width||0,boundsHeight=bounds.height||0,cssScale;if(!boundsWidth||!boundsHeight){if("top"in bounds&&"bottom"in bounds){boundsHeight=Math.abs(bounds.top-bounds.bottom)}if("right"in bounds&&"left"in bounds){boundsWidth=Math.abs(bounds.right-bounds.left)}}this.calcOffset();pointer.x=pointer.x-this._offset.left;pointer.y=pointer.y-this._offset.top;if(!ignoreZoom){pointer=fabric.util.transformPoint(pointer,fabric.util.invertTransform(this.viewportTransform))}if(boundsWidth===0||boundsHeight===0){cssScale={width:1,height:1}}else{cssScale={width:upperCanvasEl.width/boundsWidth,height:upperCanvasEl.height/boundsHeight}}return{x:pointer.x*cssScale.width,y:pointer.y*cssScale.height}},_createUpperCanvas:function(){var lowerCanvasClass=this.lowerCanvasEl.className.replace(/\s*lower-canvas\s*/,"");this.upperCanvasEl=this._createCanvasElement();fabric.util.addClass(this.upperCanvasEl,"upper-canvas "+lowerCanvasClass);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(element){var width=this.getWidth()||element.width,height=this.getHeight()||element.height;fabric.util.setStyle(element,{position:"absolute",width:width+"px",height:height+"px",left:0,top:0});element.width=width;element.height=height;fabric.util.makeElementUnselectable(element)},_copyCanvasStyle:function(fromEl,toEl){toEl.style.cssText=fromEl.style.cssText},getSelectionContext:function(){return this.contextTop},getSelectionElement:function(){return this.upperCanvasEl},_setActiveObject:function(object){if(this._activeObject){this._activeObject.set("active",false)}this._activeObject=object;object.set("active",true)},setActiveObject:function(object,e){this._setActiveObject(object);this.renderAll();this.fire("object:selected",{target:object,e:e});object.fire("selected",{e:e});return this},getActiveObject:function(){return this._activeObject},_discardActiveObject:function(){if(this._activeObject){this._activeObject.set("active",false)}this._activeObject=null},discardActiveObject:function(e){this._discardActiveObject();this.renderAll();this.fire("selection:cleared",{e:e});return this},_setActiveGroup:function(group){this._activeGroup=group;if(group){group.set("active",true)}},setActiveGroup:function(group,e){this._setActiveGroup(group);if(group){this.fire("object:selected",{target:group,e:e});group.fire("selected",{e:e})}return this},getActiveGroup:function(){return this._activeGroup},_discardActiveGroup:function(){var g=this.getActiveGroup();if(g){g.destroy()}this.setActiveGroup(null)},discardActiveGroup:function(e){this._discardActiveGroup();this.fire("selection:cleared",{e:e});return this},deactivateAll:function(){var allObjects=this.getObjects(),i=0,len=allObjects.length;for(;i1){return}var groupSelector=this._groupSelector;if(groupSelector){pointer=this.getPointer(e,true);groupSelector.left=pointer.x-groupSelector.ex;groupSelector.top=pointer.y-groupSelector.ey;this.renderTop()}else if(!this._currentTransform){target=this.findTarget(e);if(!target||target&&!target.selectable){this.setCursor(this.defaultCursor)}else{this._setCursorFromEvent(e,target)}}else{this._transformObject(e)}this.fire("mouse:move",{target:target,e:e});target&&target.fire("mousemove",{e:e})},_transformObject:function(e){var pointer=this.getPointer(e),transform=this._currentTransform;transform.reset=false,transform.target.isMoving=true;this._beforeScaleTransform(e,transform);this._performTransformAction(e,transform,pointer);this.renderAll()},_performTransformAction:function(e,transform,pointer){var x=pointer.x,y=pointer.y,target=transform.target,action=transform.action,actionPerformed=false;if(action==="rotate"){(actionPerformed=this._rotateObject(x,y))&&this._fire("rotating",target,e)}else if(action==="scale"){(actionPerformed=this._onScale(e,transform,x,y))&&this._fire("scaling",target,e)}else if(action==="scaleX"){(actionPerformed=this._scaleObject(x,y,"x"))&&this._fire("scaling",target,e)}else if(action==="scaleY"){(actionPerformed=this._scaleObject(x,y,"y"))&&this._fire("scaling",target,e)}else if(action==="skewX"){(actionPerformed=this._skewObject(x,y,"x"))&&this._fire("skewing",target,e)}else if(action==="skewY"){(actionPerformed=this._skewObject(x,y,"y"))&&this._fire("skewing",target,e)}else{(actionPerformed=this._translateObject(x,y))&&this._fire("moving",target,e);this.setCursor(this.moveCursor)}transform.actionPerformed=actionPerformed},_fire:function(eventName,target,e){this.fire("object:"+eventName,{target:target,e:e});target.fire(eventName,{e:e})},_beforeScaleTransform:function(e,transform){if(transform.action==="scale"||transform.action==="scaleX"||transform.action==="scaleY"){var centerTransform=this._shouldCenterTransform(transform.target);if(centerTransform&&(transform.originX!=="center"||transform.originY!=="center")||!centerTransform&&transform.originX==="center"&&transform.originY==="center"){this._resetCurrentTransform();transform.reset=true}}},_onScale:function(e,transform,x,y){if((e.shiftKey||this.uniScaleTransform)&&!transform.target.get("lockUniScaling")){transform.currentAction="scale";return this._scaleObject(x,y)}else{if(!transform.reset&&transform.currentAction==="scale"){this._resetCurrentTransform()}transform.currentAction="scaleEqually";return this._scaleObject(x,y,"equally")}},_setCursorFromEvent:function(e,target){if(!target||!target.selectable){this.setCursor(this.defaultCursor);return false}else{var activeGroup=this.getActiveGroup(),corner=target._findTargetCorner&&(!activeGroup||!activeGroup.contains(target))&&target._findTargetCorner(this.getPointer(e,true));if(!corner){this.setCursor(target.hoverCursor||this.hoverCursor)}else{this._setCornerCursor(corner,target,e)}}return true},_setCornerCursor:function(corner,target,e){if(corner in cursorOffset){this.setCursor(this._getRotatedCornerCursor(corner,target,e))}else if(corner==="mtr"&&target.hasRotatingPoint){this.setCursor(this.rotationCursor)}else{this.setCursor(this.defaultCursor);return false}},_getRotatedCornerCursor:function(corner,target,e){var n=Math.round(target.getAngle()%360/45);if(n<0){n+=8}n+=cursorOffset[corner];if(e.shiftKey&&cursorOffset[corner]%2===0){n+=2}n%=8;return this.cursorMap[n]}})})();(function(){var min=Math.min,max=Math.max;fabric.util.object.extend(fabric.Canvas.prototype,{_shouldGroup:function(e,target){var activeObject=this.getActiveObject();return e.shiftKey&&target&&target.selectable&&(this.getActiveGroup()||activeObject&&activeObject!==target)&&this.selection},_handleGrouping:function(e,target){if(target===this.getActiveGroup()){target=this.findTarget(e,true);if(!target||target.isType("group")){return}}if(this.getActiveGroup()){this._updateActiveGroup(target,e)}else{this._createActiveGroup(target,e)}if(this._activeGroup){this._activeGroup.saveCoords()}},_updateActiveGroup:function(target,e){var activeGroup=this.getActiveGroup();if(activeGroup.contains(target)){activeGroup.removeWithUpdate(target);target.set("active",false);if(activeGroup.size()===1){this.discardActiveGroup(e);this.setActiveObject(activeGroup.item(0));return}}else{activeGroup.addWithUpdate(target)}this.fire("selection:created",{target:activeGroup,e:e});activeGroup.set("active",true)},_createActiveGroup:function(target,e){if(this._activeObject&&target!==this._activeObject){var group=this._createGroup(target);group.addWithUpdate();this.setActiveGroup(group);this._activeObject=null;this.fire("selection:created",{target:group,e:e})}target.set("active",true)},_createGroup:function(target){var objects=this.getObjects(),isActiveLower=objects.indexOf(this._activeObject)1){group=new fabric.Group(group.reverse(),{canvas:this});group.addWithUpdate();this.setActiveGroup(group,e);group.saveCoords();this.fire("selection:created",{target:group});this.renderAll()}},_collectObjects:function(){var group=[],currentObject,x1=this._groupSelector.ex,y1=this._groupSelector.ey,x2=x1+this._groupSelector.left,y2=y1+this._groupSelector.top,selectionX1Y1=new fabric.Point(min(x1,x2),min(y1,y2)),selectionX2Y2=new fabric.Point(max(x1,x2),max(y1,y2)),isClick=x1===x2&&y1===y2;for(var i=this._objects.length;i--;){currentObject=this._objects[i];if(!currentObject||!currentObject.selectable||!currentObject.visible){continue}if(currentObject.intersectsWithRect(selectionX1Y1,selectionX2Y2)||currentObject.isContainedWithinRect(selectionX1Y1,selectionX2Y2)||currentObject.containsPoint(selectionX1Y1)||currentObject.containsPoint(selectionX2Y2)){currentObject.set("active",true);group.push(currentObject);if(isClick){break}}}return group},_maybeGroupObjects:function(e){if(this.selection&&this._groupSelector){this._groupSelectedObjects(e)}var activeGroup=this.getActiveGroup();if(activeGroup){activeGroup.setObjectsCoords().setCoords();activeGroup.isMoving=false;this.setCursor(this.defaultCursor)}this._groupSelector=null;this._currentTransform=null}})})();fabric.util.object.extend(fabric.StaticCanvas.prototype,{toDataURL:function(options){options||(options={});var format=options.format||"png",quality=options.quality||1,multiplier=options.multiplier||1,cropping={left:options.left,top:options.top,width:options.width,height:options.height};if(this._isRetinaScaling()){multiplier*=fabric.devicePixelRatio}if(multiplier!==1){return this.__toDataURLWithMultiplier(format,quality,cropping,multiplier)}else{return this.__toDataURL(format,quality,cropping)}},__toDataURL:function(format,quality,cropping){this.renderAll();var canvasEl=this.contextContainer.canvas,croppedCanvasEl=this.__getCroppedCanvas(canvasEl,cropping);if(format==="jpg"){format="jpeg"}var data=fabric.StaticCanvas.supports("toDataURLWithQuality")?(croppedCanvasEl||canvasEl).toDataURL("image/"+format,quality):(croppedCanvasEl||canvasEl).toDataURL("image/"+format);if(croppedCanvasEl){croppedCanvasEl=null}return data},__getCroppedCanvas:function(canvasEl,cropping){var croppedCanvasEl,croppedCtx,shouldCrop="left"in cropping||"top"in cropping||"width"in cropping||"height"in cropping;if(shouldCrop){croppedCanvasEl=fabric.util.createCanvasElement();croppedCtx=croppedCanvasEl.getContext("2d");croppedCanvasEl.width=cropping.width||this.width;croppedCanvasEl.height=cropping.height||this.height;croppedCtx.drawImage(canvasEl,-cropping.left||0,-cropping.top||0)}return croppedCanvasEl},__toDataURLWithMultiplier:function(format,quality,cropping,multiplier){var origWidth=this.getWidth(),origHeight=this.getHeight(),scaledWidth=origWidth*multiplier,scaledHeight=origHeight*multiplier,activeObject=this.getActiveObject(),activeGroup=this.getActiveGroup(),ctx=this.contextContainer;if(multiplier>1){this.setDimensions({width:scaledWidth,height:scaledHeight})}ctx.save();ctx.scale(multiplier/fabric.devicePixelRatio,multiplier/fabric.devicePixelRatio);if(cropping.left){cropping.left*=multiplier}if(cropping.top){cropping.top*=multiplier}if(cropping.width){cropping.width*=multiplier}else if(multiplier<1){cropping.width=scaledWidth}if(cropping.height){cropping.height*=multiplier}else if(multiplier<1){cropping.height=scaledHeight}if(activeGroup){this._tempRemoveBordersControlsFromGroup(activeGroup)}else if(activeObject&&this.deactivateAll){this.deactivateAll()}var data=this.__toDataURL(format,quality,cropping);this.width=origWidth;this.height=origHeight;this.setDimensions({width:origWidth,height:origHeight});if(activeGroup){this._restoreBordersControlsOnGroup(activeGroup)}else if(activeObject&&this.setActiveObject){this.setActiveObject(activeObject)}this.contextTop&&this.clearContext(this.contextTop);this.renderAll();return data},toDataURLWithMultiplier:function(format,multiplier,quality){return this.toDataURL({format:format,multiplier:multiplier,quality:quality})},_tempRemoveBordersControlsFromGroup:function(group){group.origHasControls=group.hasControls;group.origBorderColor=group.borderColor;group.hasControls=true;group.borderColor="rgba(0,0,0,0)";group.forEachObject(function(o){o.origBorderColor=o.borderColor;o.borderColor="rgba(0,0,0,0)"})},_restoreBordersControlsOnGroup:function(group){group.hideControls=group.origHideControls;group.borderColor=group.origBorderColor;group.forEachObject(function(o){o.borderColor=o.origBorderColor;delete o.origBorderColor})}});fabric.util.object.extend(fabric.StaticCanvas.prototype,{loadFromDatalessJSON:function(json,callback,reviver){return this.loadFromJSON(json,callback,reviver)},loadFromJSON:function(json,callback,reviver){if(!json){return}var serialized=typeof json==="string"?JSON.parse(json):json;this.clear();var _this=this;this._enlivenObjects(serialized.objects,function(){_this._setBgOverlay(serialized,callback)},reviver);return this},_setBgOverlay:function(serialized,callback){var _this=this,loaded={backgroundColor:false,overlayColor:false,backgroundImage:false,overlayImage:false};if(!serialized.backgroundImage&&!serialized.overlayImage&&!serialized.background&&!serialized.overlay){callback&&callback();return}var cbIfLoaded=function(){if(loaded.backgroundImage&&loaded.overlayImage&&loaded.backgroundColor&&loaded.overlayColor){_this.renderAll();callback&&callback()}};this.__setBgOverlay("backgroundImage",serialized.backgroundImage,loaded,cbIfLoaded);this.__setBgOverlay("overlayImage",serialized.overlayImage,loaded,cbIfLoaded);this.__setBgOverlay("backgroundColor",serialized.background,loaded,cbIfLoaded);this.__setBgOverlay("overlayColor",serialized.overlay,loaded,cbIfLoaded);cbIfLoaded()},__setBgOverlay:function(property,value,loaded,callback){var _this=this;if(!value){loaded[property]=true;return}if(property==="backgroundImage"||property==="overlayImage"){fabric.Image.fromObject(value,function(img){_this[property]=img;loaded[property]=true;callback&&callback()})}else{this["set"+fabric.util.string.capitalize(property,true)](value,function(){loaded[property]=true;callback&&callback()})}},_enlivenObjects:function(objects,callback,reviver){var _this=this;if(!objects||objects.length===0){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,true)});_this.renderOnAddRemove=renderOnAddRemove;callback&&callback()},null,reviver)},_toDataURL:function(format,callback){this.clone(function(clone){callback(clone.toDataURL(format))})},_toDataURLWithMultiplier:function(format,multiplier,callback){this.clone(function(clone){callback(clone.toDataURLWithMultiplier(format,multiplier))})},clone:function(callback,properties){var data=JSON.stringify(this.toJSON(properties));this.cloneWithoutData(function(clone){clone.loadFromJSON(data,function(){callback&&callback(clone)})})},cloneWithoutData:function(callback){var el=fabric.document.createElement("canvas");el.width=this.getWidth();el.height=this.getHeight();var clone=new fabric.Canvas(el);clone.clipTo=this.clipTo;if(this.backgroundImage){clone.setBackgroundImage(this.backgroundImage.src,function(){clone.renderAll();callback&&callback(clone)});clone.backgroundImageOpacity=this.backgroundImageOpacity;clone.backgroundImageStretch=this.backgroundImageStretch}else{callback&&callback(clone)}}});(function(global){"use strict";var fabric=global.fabric||(global.fabric={}),extend=fabric.util.object.extend,toFixed=fabric.util.toFixed,capitalize=fabric.util.string.capitalize,degreesToRadians=fabric.util.degreesToRadians,supportsLineDash=fabric.StaticCanvas.supports("setLineDash");if(fabric.Object){return}fabric.Object=fabric.util.createClass({type:"object",originX:"left",originY:"top",top:0,left:0,width:0,height:0,scaleX:1,scaleY:1,flipX:false,flipY:false,opacity:1,angle:0,skewX:0,skewY:0,cornerSize:12,transparentCorners:true,hoverCursor:null,padding:0,borderColor:"rgba(102,153,255,0.75)",cornerColor:"rgba(102,153,255,0.5)",centeredScaling:false,centeredRotation:true,fill:"rgb(0,0,0)",fillRule:"nonzero",globalCompositeOperation:"source-over",backgroundColor:"",stroke:null,strokeWidth:1,strokeDashArray:null,strokeLineCap:"butt",strokeLineJoin:"miter",strokeMiterLimit:10,shadow:null,borderOpacityWhenMoving:.4,borderScaleFactor:1,transformMatrix:null,minScaleLimit:.01,selectable:true,evented:true,visible:true,hasControls:true,hasBorders:true,hasRotatingPoint:true,rotatingPointOffset:40,perPixelTargetFind:false,includeDefaultValues:true,clipTo:null,lockMovementX:false,lockMovementY:false,lockRotation:false,lockScalingX:false,lockScalingY:false,lockUniScaling:false,lockSkewingX:false,lockSkewingY:false,lockScalingFlip: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 "+"alignX alignY meetOrSlice skewX skewY").split(" "),initialize:function(options){if(options){this.setOptions(options)}},_initGradient:function(options){if(options.fill&&options.fill.colorStops&&!(options.fill instanceof fabric.Gradient)){this.set("fill",new fabric.Gradient(options.fill))}if(options.stroke&&options.stroke.colorStops&&!(options.stroke instanceof fabric.Gradient)){this.set("stroke",new fabric.Gradient(options.stroke))}},_initPattern:function(options){if(options.fill&&options.fill.source&&!(options.fill instanceof fabric.Pattern)){this.set("fill",new fabric.Pattern(options.fill))}if(options.stroke&&options.stroke.source&&!(options.stroke instanceof fabric.Pattern)){this.set("stroke",new fabric.Pattern(options.stroke))}},_initClipping:function(options){if(!options.clipTo||typeof options.clipTo!=="string"){return}var functionBody=fabric.util.getFunctionBody(options.clipTo);if(typeof functionBody!=="undefined"){this.clipTo=new Function("ctx",functionBody)}},setOptions:function(options){for(var prop in options){this.set(prop,options[prop])}this._initGradient(options);this._initPattern(options);this._initClipping(options)},transform:function(ctx,fromLeft){if(this.group&&this.canvas.preserveObjectStacking&&this.group===this.canvas._activeGroup){this.group.transform(ctx)}var center=fromLeft?this._getLeftTopCoords():this.getCenterPoint();ctx.translate(center.x,center.y);ctx.rotate(degreesToRadians(this.angle));ctx.scale(this.scaleX*(this.flipX?-1:1),this.scaleY*(this.flipY?-1:1));ctx.transform(1,0,Math.tan(degreesToRadians(this.skewX)),1,0,0);ctx.transform(1,Math.tan(degreesToRadians(this.skewY)),0,1,0,0)},toObject:function(propertiesToInclude){var NUM_FRACTION_DIGITS=fabric.Object.NUM_FRACTION_DIGITS,object={type:this.type,originX:this.originX,originY:this.originY,left:toFixed(this.left,NUM_FRACTION_DIGITS),top:toFixed(this.top,NUM_FRACTION_DIGITS),width:toFixed(this.width,NUM_FRACTION_DIGITS),height:toFixed(this.height,NUM_FRACTION_DIGITS),fill:this.fill&&this.fill.toObject?this.fill.toObject():this.fill,stroke:this.stroke&&this.stroke.toObject?this.stroke.toObject():this.stroke,strokeWidth:toFixed(this.strokeWidth,NUM_FRACTION_DIGITS),strokeDashArray:this.strokeDashArray?this.strokeDashArray.concat():this.strokeDashArray,strokeLineCap:this.strokeLineCap,strokeLineJoin:this.strokeLineJoin,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),flipX:this.flipX,flipY:this.flipY,opacity:toFixed(this.opacity,NUM_FRACTION_DIGITS),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():this.transformMatrix,skewX:toFixed(this.skewX,NUM_FRACTION_DIGITS),skewY:toFixed(this.skewY,NUM_FRACTION_DIGITS)};if(!this.includeDefaultValues){object=this._removeDefaultValues(object)}fabric.util.populateWithProperties(this,object,propertiesToInclude);return object},toDatalessObject:function(propertiesToInclude){return this.toObject(propertiesToInclude)},_removeDefaultValues:function(object){var prototype=fabric.util.getKlass(object.type).prototype,stateProperties=prototype.stateProperties;stateProperties.forEach(function(prop){if(object[prop]===prototype[prop]){delete object[prop]}var isArray=Object.prototype.toString.call(object[prop])==="[object Array]"&&Object.prototype.toString.call(prototype[prop])==="[object Array]";if(isArray&&object[prop].length===0&&prototype[prop].length===0){delete object[prop]}});return object},toString:function(){return"#"},get:function(property){return this[property]},_setObject:function(obj){for(var prop in obj){this._set(prop,obj[prop])}},set:function(key,value){if(typeof key==="object"){this._setObject(key)}else{if(typeof value==="function"&&key!=="clipTo"){this._set(key,value(this.get(key)))}else{this._set(key,value)}}return this},_set:function(key,value){var shouldConstrainValue=key==="scaleX"||key==="scaleY";if(shouldConstrainValue){value=this._constrainScale(value)}if(key==="scaleX"&&value<0){this.flipX=!this.flipX;value*=-1}else if(key==="scaleY"&&value<0){this.flipY=!this.flipY;value*=-1}else if(key==="width"||key==="height"){this.minScaleLimit=toFixed(Math.min(.1,1/Math.max(this.width,this.height)),2)}else if(key==="shadow"&&value&&!(value instanceof fabric.Shadow)){value=new fabric.Shadow(value)}this[key]=value;return this},setOnGroup:function(){},toggle:function(property){var value=this.get(property);if(typeof value==="boolean"){this.set(property,!value)}return this},setSourcePath:function(value){this.sourcePath=value;return this},getViewportTransform:function(){if(this.canvas&&this.canvas.viewportTransform){return this.canvas.viewportTransform}return[1,0,0,1,0,0]},render:function(ctx,noTransform){if(this.width===0&&this.height===0||!this.visible){return}ctx.save();this._setupCompositeOperation(ctx);if(!noTransform){this.transform(ctx)}this._setStrokeStyles(ctx);this._setFillStyles(ctx);if(this.transformMatrix){ctx.transform.apply(ctx,this.transformMatrix)}this._setOpacity(ctx);this._setShadow(ctx);this.clipTo&&fabric.util.clipContext(this,ctx);this._render(ctx,noTransform);this.clipTo&&ctx.restore();ctx.restore()},_setOpacity:function(ctx){if(this.group){this.group._setOpacity(ctx)}ctx.globalAlpha*=this.opacity},_setStrokeStyles:function(ctx){if(this.stroke){ctx.lineWidth=this.strokeWidth;ctx.lineCap=this.strokeLineCap;ctx.lineJoin=this.strokeLineJoin;ctx.miterLimit=this.strokeMiterLimit;ctx.strokeStyle=this.stroke.toLive?this.stroke.toLive(ctx,this):this.stroke}},_setFillStyles:function(ctx){if(this.fill){ctx.fillStyle=this.fill.toLive?this.fill.toLive(ctx,this):this.fill}},_renderControls:function(ctx,noTransform){if(!this.active||noTransform||this.group&&this.group!==this.canvas.getActiveGroup()){return}var vpt=this.getViewportTransform(),matrix=this.calcTransformMatrix(),options;matrix=fabric.util.multiplyTransformMatrices(vpt,matrix);options=fabric.util.qrDecompose(matrix);ctx.save();ctx.translate(options.translateX,options.translateY);if(this.group&&this.group===this.canvas.getActiveGroup()){ctx.rotate(degreesToRadians(options.angle));this.drawBordersInGroup(ctx,options)}else{ctx.rotate(degreesToRadians(this.angle));this.drawBorders(ctx)}this.drawControls(ctx);ctx.restore()},_setShadow:function(ctx){if(!this.shadow){return}var multX=this.canvas&&this.canvas.viewportTransform[0]||1,multY=this.canvas&&this.canvas.viewportTransform[3]||1;if(this.canvas&&this.canvas._isRetinaScaling()){multX*=fabric.devicePixelRatio;multY*=fabric.devicePixelRatio}ctx.shadowColor=this.shadow.color;ctx.shadowBlur=this.shadow.blur*(multX+multY)*(this.scaleX+this.scaleY)/4;ctx.shadowOffsetX=this.shadow.offsetX*multX*this.scaleX;ctx.shadowOffsetY=this.shadow.offsetY*multY*this.scaleY},_removeShadow:function(ctx){if(!this.shadow){return}ctx.shadowColor="";ctx.shadowBlur=ctx.shadowOffsetX=ctx.shadowOffsetY=0},_renderFill:function(ctx){if(!this.fill){return}ctx.save();if(this.fill.gradientTransform){var g=this.fill.gradientTransform;ctx.transform.apply(ctx,g)}if(this.fill.toLive){ctx.translate(-this.width/2+this.fill.offsetX||0,-this.height/2+this.fill.offsetY||0)}if(this.fillRule==="evenodd"){ctx.fill("evenodd")}else{ctx.fill()}ctx.restore()},_renderStroke:function(ctx){if(!this.stroke||this.strokeWidth===0){return}if(this.shadow&&!this.shadow.affectStroke){this._removeShadow(ctx)}ctx.save();if(this.strokeDashArray){if(1&this.strokeDashArray.length){this.strokeDashArray.push.apply(this.strokeDashArray,this.strokeDashArray)}if(supportsLineDash){ctx.setLineDash(this.strokeDashArray);this._stroke&&this._stroke(ctx)}else{this._renderDashedStroke&&this._renderDashedStroke(ctx)}ctx.stroke()}else{if(this.stroke.gradientTransform){var g=this.stroke.gradientTransform;ctx.transform.apply(ctx,g)}this._stroke?this._stroke(ctx):ctx.stroke()}ctx.restore()},clone:function(callback,propertiesToInclude){if(this.constructor.fromObject){return this.constructor.fromObject(this.toObject(propertiesToInclude),callback)}return new fabric.Object(this.toObject(propertiesToInclude))},cloneAsImage:function(callback){var dataUrl=this.toDataURL();fabric.util.loadImage(dataUrl,function(img){if(callback){callback(new fabric.Image(img)) +}});return this},toDataURL:function(options){options||(options={});var el=fabric.util.createCanvasElement(),boundingRect=this.getBoundingRect();el.width=boundingRect.width;el.height=boundingRect.height;fabric.util.wrapElement(el,"div");var canvas=new fabric.StaticCanvas(el);if(options.format==="jpg"){options.format="jpeg"}if(options.format==="jpeg"){canvas.backgroundColor="#fff"}var origParams={active:this.get("active"),left:this.getLeft(),top:this.getTop()};this.set("active",false);this.setPositionByOrigin(new fabric.Point(el.width/2,el.height/2),"center","center");var originalCanvas=this.canvas;canvas.add(this);var data=canvas.toDataURL(options);this.set(origParams).setCoords();this.canvas=originalCanvas;canvas.dispose();canvas=null;return data},isType:function(type){return this.type===type},complexity:function(){return 0},toJSON:function(propertiesToInclude){return this.toObject(propertiesToInclude)},setGradient:function(property,options){options||(options={});var gradient={colorStops:[]};gradient.type=options.type||(options.r1||options.r2?"radial":"linear");gradient.coords={x1:options.x1,y1:options.y1,x2:options.x2,y2:options.y2};if(options.r1||options.r2){gradient.coords.r1=options.r1;gradient.coords.r2=options.r2}options.gradientTransform&&(gradient.gradientTransform=options.gradientTransform);for(var position in options.colorStops){var color=new fabric.Color(options.colorStops[position]);gradient.colorStops.push({offset:position,color:color.toRgb(),opacity:color.getAlpha()})}return this.set(property,fabric.Gradient.forObject(this,gradient))},setPatternFill:function(options){return this.set("fill",new fabric.Pattern(options))},setShadow:function(options){return this.set("shadow",options?new fabric.Shadow(options):null)},setColor:function(color){this.set("fill",color);return this},setAngle:function(angle){var shouldCenterOrigin=(this.originX!=="center"||this.originY!=="center")&&this.centeredRotation;if(shouldCenterOrigin){this._setOriginToCenter()}this.set("angle",angle);if(shouldCenterOrigin){this._resetOrigin()}return this},centerH:function(){this.canvas.centerObjectH(this);return this},centerV:function(){this.canvas.centerObjectV(this);return this},center:function(){this.canvas.centerObject(this);return this},remove:function(){this.canvas.remove(this);return this},getLocalPointer:function(e,pointer){pointer=pointer||this.canvas.getPointer(e);var pClicked=new fabric.Point(pointer.x,pointer.y),objectLeftTop=this._getLeftTopCoords();if(this.angle){pClicked=fabric.util.rotatePoint(pClicked,objectLeftTop,fabric.util.degreesToRadians(-this.angle))}return{x:pClicked.x-objectLeftTop.x,y:pClicked.y-objectLeftTop.y}},_setupCompositeOperation:function(ctx){if(this.globalCompositeOperation){ctx.globalCompositeOperation=this.globalCompositeOperation}}});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.__uid=0})(typeof exports!=="undefined"?exports:this);(function(){var degreesToRadians=fabric.util.degreesToRadians,originXOffset={left:-.5,center:0,right:.5},originYOffset={top:-.5,center:0,bottom:.5};fabric.util.object.extend(fabric.Object.prototype,{translateToGivenOrigin:function(point,fromOriginX,fromOriginY,toOriginX,toOriginY){var x=point.x,y=point.y,offsetX=originXOffset[toOriginX]-originXOffset[fromOriginX],offsetY=originYOffset[toOriginY]-originYOffset[fromOriginY],dim;if(offsetX||offsetY){dim=this._getTransformedDimensions();x=point.x+offsetX*dim.x;y=point.y+offsetY*dim.y}return new fabric.Point(x,y)},translateToCenterPoint:function(point,originX,originY){var p=this.translateToGivenOrigin(point,originX,originY,"center","center");if(this.angle){return fabric.util.rotatePoint(p,point,degreesToRadians(this.angle))}return p},translateToOriginPoint:function(center,originX,originY){var p=this.translateToGivenOrigin(center,"center","center",originX,originY);if(this.angle){return fabric.util.rotatePoint(p,center,degreesToRadians(this.angle))}return p},getCenterPoint:function(){var leftTop=new fabric.Point(this.left,this.top);return this.translateToCenterPoint(leftTop,this.originX,this.originY)},getPointByOrigin:function(originX,originY){var center=this.getCenterPoint();return this.translateToOriginPoint(center,originX,originY)},toLocalPoint:function(point,originX,originY){var center=this.getCenterPoint(),p,p2;if(originX&&originY){p=this.translateToGivenOrigin(center,"center","center",originX,originY)}else{p=new fabric.Point(this.left,this.top)}p2=new fabric.Point(point.x,point.y);if(this.angle){p2=fabric.util.rotatePoint(p2,center,-degreesToRadians(this.angle))}return p2.subtractEquals(p)},setPositionByOrigin:function(pos,originX,originY){var center=this.translateToCenterPoint(pos,originX,originY),position=this.translateToOriginPoint(center,this.originX,this.originY);this.set("left",position.x);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;this.left+=xFull*(originXOffset[to]-originXOffset[this.originX]);this.top+=yFull*(originXOffset[to]-originXOffset[this.originX]);this.setCoords();this.originX=to},_setOriginToCenter:function(){this._originalOriginX=this.originX;this._originalOriginY=this.originY;var center=this.getCenterPoint();this.originX="center";this.originY="center";this.left=center.x;this.top=center.y},_resetOrigin:function(){var originPoint=this.translateToOriginPoint(this.getCenterPoint(),this._originalOriginX,this._originalOriginY);this.originX=this._originalOriginX;this.originY=this._originalOriginY;this.left=originPoint.x;this.top=originPoint.y;this._originalOriginX=null;this._originalOriginY=null},_getLeftTopCoords:function(){return this.translateToOriginPoint(this.getCenterPoint(),"left","top")}})})();(function(){function getCoords(oCoords){return[new fabric.Point(oCoords.tl.x,oCoords.tl.y),new fabric.Point(oCoords.tr.x,oCoords.tr.y),new fabric.Point(oCoords.br.x,oCoords.br.y),new fabric.Point(oCoords.bl.x,oCoords.bl.y)]}var degreesToRadians=fabric.util.degreesToRadians,multiplyMatrices=fabric.util.multiplyTransformMatrices;fabric.util.object.extend(fabric.Object.prototype,{oCoords:null,intersectsWithRect:function(pointTL,pointBR){var oCoords=getCoords(this.oCoords),intersection=fabric.Intersection.intersectPolygonRectangle(oCoords,pointTL,pointBR);return intersection.status==="Intersection"},intersectsWithObject:function(other){var intersection=fabric.Intersection.intersectPolygonPolygon(getCoords(this.oCoords),getCoords(other.oCoords));return intersection.status==="Intersection"},isContainedWithinObject:function(other){var boundingRect=other.getBoundingRect(),point1=new fabric.Point(boundingRect.left,boundingRect.top),point2=new fabric.Point(boundingRect.left+boundingRect.width,boundingRect.top+boundingRect.height);return this.isContainedWithinRect(point1,point2)},isContainedWithinRect:function(pointTL,pointBR){var boundingRect=this.getBoundingRect();return boundingRect.left>=pointTL.x&&boundingRect.left+boundingRect.width<=pointBR.x&&boundingRect.top>=pointTL.y&&boundingRect.top+boundingRect.height<=pointBR.y},containsPoint:function(point){var lines=this._getImageLines(this.oCoords),xPoints=this._findCrossPoints(point,lines);return xPoints!==0&&xPoints%2===1},_getImageLines:function(oCoords){return{topline:{o:oCoords.tl,d:oCoords.tr},rightline:{o:oCoords.tr,d:oCoords.br},bottomline:{o:oCoords.br,d:oCoords.bl},leftline:{o:oCoords.bl,d:oCoords.tl}}},_findCrossPoints:function(point,oCoords){var b1,b2,a1,a2,xi,yi,xcount=0,iLine;for(var lineKey in oCoords){iLine=oCoords[lineKey];if(iLine.o.y=point.y&&iLine.d.y>=point.y){continue}if(iLine.o.x===iLine.d.x&&iLine.o.x>=point.x){xi=iLine.o.x;yi=point.y}else{b1=0;b2=(iLine.d.y-iLine.o.y)/(iLine.d.x-iLine.o.x);a1=point.y-b1*point.x;a2=iLine.o.y-b2*iLine.o.x;xi=-(a1-a2)/(b1-b2);yi=a1+b1*xi}if(xi>=point.x){xcount+=1}if(xcount===2){break}}return xcount},getBoundingRectWidth:function(){return this.getBoundingRect().width},getBoundingRectHeight:function(){return this.getBoundingRect().height},getBoundingRect:function(){this.oCoords||this.setCoords();return fabric.util.makeBoundingBoxFromPoints([this.oCoords.tl,this.oCoords.tr,this.oCoords.br,this.oCoords.bl])},getWidth:function(){return this._getTransformedDimensions().x},getHeight:function(){return this._getTransformedDimensions().y},_constrainScale:function(value){if(Math.abs(value)0?Math.atan(currentHeight/currentWidth):0,_hypotenuse=currentWidth/Math.cos(_angle)/2,offsetX=Math.cos(_angle+theta)*_hypotenuse,offsetY=Math.sin(_angle+theta)*_hypotenuse,coords=fabric.util.transformPoint(this.getCenterPoint(),vpt),tl=new fabric.Point(coords.x-offsetX,coords.y-offsetY),tr=new fabric.Point(tl.x+currentWidth*cosTh,tl.y+currentWidth*sinTh),bl=new fabric.Point(tl.x-currentHeight*sinTh,tl.y+currentHeight*cosTh),br=new fabric.Point(coords.x+offsetX,coords.y+offsetY),ml=new fabric.Point((tl.x+bl.x)/2,(tl.y+bl.y)/2),mt=new fabric.Point((tr.x+tl.x)/2,(tr.y+tl.y)/2),mr=new fabric.Point((br.x+tr.x)/2,(br.y+tr.y)/2),mb=new fabric.Point((br.x+bl.x)/2,(br.y+bl.y)/2),mtr=new fabric.Point(mt.x+sinTh*this.rotatingPointOffset,mt.y-cosTh*this.rotatingPointOffset);this.oCoords={tl:tl,tr:tr,br:br,bl:bl,ml:ml,mt:mt,mr:mr,mb:mb,mtr:mtr};this._setCornerCoords&&this._setCornerCoords();return this},_calcRotateMatrix:function(){if(this.angle){var theta=degreesToRadians(this.angle),cos=Math.cos(theta),sin=Math.sin(theta);return[cos,sin,-sin,cos,0,0]}return[1,0,0,1,0,0]},calcTransformMatrix:function(){var center=this.getCenterPoint(),translateMatrix=[1,0,0,1,center.x,center.y],rotateMatrix=this._calcRotateMatrix(),dimensionMatrix=this._calcDimensionsTransformMatrix(this.skewX,this.skewY,true),matrix=this.group?this.group.calcTransformMatrix():[1,0,0,1,0,0];matrix=multiplyMatrices(matrix,translateMatrix);matrix=multiplyMatrices(matrix,rotateMatrix);matrix=multiplyMatrices(matrix,dimensionMatrix);return matrix},_calcDimensionsTransformMatrix:function(skewX,skewY,flipping){var skewMatrixX=[1,0,Math.tan(degreesToRadians(skewX)),1],skewMatrixY=[1,Math.tan(degreesToRadians(skewY)),0,1],scaleX=this.scaleX*(flipping&&this.flipX?-1:1),scaleY=this.scaleY*(flipping&&this.flipY?-1:1),scaleMatrix=[scaleX,0,0,scaleY],m=multiplyMatrices(scaleMatrix,skewMatrixX,true);return multiplyMatrices(m,skewMatrixY,true)}})})();fabric.util.object.extend(fabric.Object.prototype,{sendToBack:function(){if(this.group){fabric.StaticCanvas.prototype.sendToBack.call(this.group,this)}else{this.canvas.sendToBack(this)}return this},bringToFront:function(){if(this.group){fabric.StaticCanvas.prototype.bringToFront.call(this.group,this)}else{this.canvas.bringToFront(this)}return this},sendBackwards:function(intersecting){if(this.group){fabric.StaticCanvas.prototype.sendBackwards.call(this.group,this,intersecting)}else{this.canvas.sendBackwards(this,intersecting)}return this},bringForward:function(intersecting){if(this.group){fabric.StaticCanvas.prototype.bringForward.call(this.group,this,intersecting)}else{this.canvas.bringForward(this,intersecting)}return this},moveTo:function(index){if(this.group){fabric.StaticCanvas.prototype.moveTo.call(this.group,this,index)}else{this.canvas.moveTo(this,index)}return this}});fabric.util.object.extend(fabric.Object.prototype,{getSvgStyles:function(skipShadow){var fill=this.fill?this.fill.toLive?"url(#SVGID_"+this.fill.id+")":this.fill:"none",fillRule=this.fillRule,stroke=this.stroke?this.stroke.toLive?"url(#SVGID_"+this.stroke.id+")":this.stroke:"none",strokeWidth=this.strokeWidth?this.strokeWidth:"0",strokeDashArray=this.strokeDashArray?this.strokeDashArray.join(" "):"none",strokeLineCap=this.strokeLineCap?this.strokeLineCap:"butt",strokeLineJoin=this.strokeLineJoin?this.strokeLineJoin:"miter",strokeMiterLimit=this.strokeMiterLimit?this.strokeMiterLimit:"4",opacity=typeof this.opacity!=="undefined"?this.opacity:"1",visibility=this.visible?"":" visibility: hidden;",filter=skipShadow?"":this.getSvgFilter();return["stroke: ",stroke,"; ","stroke-width: ",strokeWidth,"; ","stroke-dasharray: ",strokeDashArray,"; ","stroke-linecap: ",strokeLineCap,"; ","stroke-linejoin: ",strokeLineJoin,"; ","stroke-miterlimit: ",strokeMiterLimit,"; ","fill: ",fill,"; ","fill-rule: ",fillRule,"; ","opacity: ",opacity,";",filter,visibility].join("")},getSvgFilter:function(){return this.shadow?"filter: url(#SVGID_"+this.shadow.id+");":""},getSvgTransform:function(){if(this.group&&this.group.type==="path-group"){return""}var toFixed=fabric.util.toFixed,angle=this.getAngle(),skewX=this.getSkewX()%360,skewY=this.getSkewY()%360,center=this.getCenterPoint(),NUM_FRACTION_DIGITS=fabric.Object.NUM_FRACTION_DIGITS,translatePart=this.type==="path-group"?"":"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)+")":"",addTranslateX=this.type==="path-group"?this.width:0,flipXPart=this.flipX?" matrix(-1 0 0 1 "+addTranslateX+" 0) ":"",addTranslateY=this.type==="path-group"?this.height:0,flipYPart=this.flipY?" matrix(1 0 0 -1 0 "+addTranslateY+")":"";return[translatePart,anglePart,scalePart,flipXPart,flipYPart,skewXPart,skewYPart].join("")},getSvgTransformMatrix:function(){return this.transformMatrix?" matrix("+this.transformMatrix.join(" ")+") ":""},_createBaseSVGMarkup:function(){var markup=[];if(this.fill&&this.fill.toLive){markup.push(this.fill.toSVG(this,false))}if(this.stroke&&this.stroke.toLive){markup.push(this.stroke.toSVG(this,false))}if(this.shadow){markup.push(this.shadow.toSVG(this))}return markup}});fabric.util.object.extend(fabric.Object.prototype,{hasStateChanged:function(){return this.stateProperties.some(function(prop){return this.get(prop)!==this.originalState[prop]},this)},saveState:function(options){this.stateProperties.forEach(function(prop){this.originalState[prop]=this.get(prop)},this);if(options&&options.stateProperties){options.stateProperties.forEach(function(prop){this.originalState[prop]=this.get(prop)},this)}return this},setupState:function(){this.originalState={};this.saveState();return this}});(function(){var degreesToRadians=fabric.util.degreesToRadians,isVML=function(){return typeof G_vmlCanvasManager!=="undefined"};fabric.util.object.extend(fabric.Object.prototype,{_controlsVisibility:null,_findTargetCorner:function(pointer){if(!this.hasControls||!this.active){return false}var ex=pointer.x,ey=pointer.y,xPoints,lines;this.__corner=0;for(var i in this.oCoords){if(!this.isControlVisible(i)){continue}if(i==="mtr"&&!this.hasRotatingPoint){continue}if(this.get("lockUniScaling")&&(i==="mt"||i==="mr"||i==="mb"||i==="ml")){continue}lines=this._getImageLines(this.oCoords[i].corner);xPoints=this._findCrossPoints({x:ex,y:ey},lines);if(xPoints!==0&&xPoints%2===1){this.__corner=i;return i}}return false},_setCornerCoords:function(){var coords=this.oCoords,newTheta=degreesToRadians(45-this.angle),cornerHypotenuse=this.cornerSize*.707106,cosHalfOffset=cornerHypotenuse*Math.cos(newTheta),sinHalfOffset=cornerHypotenuse*Math.sin(newTheta),x,y;for(var point in coords){x=coords[point].x;y=coords[point].y;coords[point].corner={tl:{x:x-sinHalfOffset,y:y-cosHalfOffset},tr:{x:x+cosHalfOffset,y:y-sinHalfOffset},bl:{x:x-cosHalfOffset,y:y+sinHalfOffset},br:{x:x+sinHalfOffset,y:y+cosHalfOffset}}}},_getNonTransformedDimensions:function(){var strokeWidth=this.strokeWidth,w=this.width,h=this.height,addStrokeToW=true,addStrokeToH=true;if(this.type==="line"&&this.strokeLineCap==="butt"){addStrokeToH=w;addStrokeToW=h}if(addStrokeToH){h+=h<0?-strokeWidth:strokeWidth}if(addStrokeToW){w+=w<0?-strokeWidth:strokeWidth}return{x:w,y:h}},_getTransformedDimensions:function(skewX,skewY){if(typeof skewX==="undefined"){skewX=this.skewX}if(typeof skewY==="undefined"){skewY=this.skewY}var dimensions=this._getNonTransformedDimensions(),dimX=dimensions.x/2,dimY=dimensions.y/2,points=[{x:-dimX,y:-dimY},{x:dimX,y:-dimY},{x:-dimX,y:dimY},{x:dimX,y:dimY}],i,transformMatrix=this._calcDimensionsTransformMatrix(skewX,skewY,false),bbox;for(i=0;i\n');return reviver?reviver(markup.join("")):markup.join("")},complexity:function(){return 1}});fabric.Line.ATTRIBUTE_NAMES=fabric.SHARED_ATTRIBUTES.concat("x1 y1 x2 y2".split(" "));fabric.Line.fromElement=function(element,options){var parsedAttributes=fabric.parseAttributes(element,fabric.Line.ATTRIBUTE_NAMES),points=[parsedAttributes.x1||0,parsedAttributes.y1||0,parsedAttributes.x2||0,parsedAttributes.y2||0];return new fabric.Line(points,extend(parsedAttributes,options))};fabric.Line.fromObject=function(object){var points=[object.x1,object.y1,object.x2,object.y2];return new fabric.Line(points,object)};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;return function(){switch(this.get(origin)){case nearest:return Math.min(this.get(axis1),this.get(axis2));case center:return Math.min(this.get(axis1),this.get(axis2))+.5*this.get(dimension);case farthest:return Math.max(this.get(axis1),this.get(axis2))}}}})(typeof exports!=="undefined"?exports:this);(function(global){"use strict";var fabric=global.fabric||(global.fabric={}),pi=Math.PI,extend=fabric.util.object.extend;if(fabric.Circle){fabric.warn("fabric.Circle is already defined.");return}fabric.Circle=fabric.util.createClass(fabric.Object,{type:"circle",radius:0,startAngle:0,endAngle:pi*2,initialize:function(options){options=options||{};this.callSuper("initialize",options);this.set("radius",options.radius||0);this.startAngle=options.startAngle||this.startAngle;this.endAngle=options.endAngle||this.endAngle},_set:function(key,value){this.callSuper("_set",key,value);if(key==="radius"){this.setRadius(value)}return this},toObject:function(propertiesToInclude){return extend(this.callSuper("toObject",propertiesToInclude),{radius:this.get("radius"),startAngle:this.startAngle,endAngle:this.endAngle})},toSVG:function(reviver){var markup=this._createBaseSVGMarkup(),x=0,y=0,angle=(this.endAngle-this.startAngle)%(2*pi);if(angle===0){if(this.group&&this.group.type==="path-group"){x=this.left+this.radius;y=this.top+this.radius}markup.push("\n')}else{var startX=Math.cos(this.startAngle)*this.radius,startY=Math.sin(this.startAngle)*this.radius,endX=Math.cos(this.endAngle)*this.radius,endY=Math.sin(this.endAngle)*this.radius,largeFlag=angle>pi?"1":"0";markup.push('\n')}return reviver?reviver(markup.join("")):markup.join("")},_render:function(ctx,noTransform){ctx.beginPath();ctx.arc(noTransform?this.left+this.radius:0,noTransform?this.top+this.radius:0,this.radius,this.startAngle,this.endAngle,false);this._renderFill(ctx);this._renderStroke(ctx)},getRadiusX:function(){return this.get("radius")*this.get("scaleX")},getRadiusY:function(){return this.get("radius")*this.get("scaleY")},setRadius:function(value){this.radius=value;return this.set("width",value*2).set("height",value*2)},complexity:function(){return 1}});fabric.Circle.ATTRIBUTE_NAMES=fabric.SHARED_ATTRIBUTES.concat("cx cy r".split(" "));fabric.Circle.fromElement=function(element,options){options||(options={});var parsedAttributes=fabric.parseAttributes(element,fabric.Circle.ATTRIBUTE_NAMES);if(!isValidRadius(parsedAttributes)){throw new Error("value of `r` attribute is required and can not be negative")}parsedAttributes.left=parsedAttributes.left||0;parsedAttributes.top=parsedAttributes.top||0;var obj=new fabric.Circle(extend(parsedAttributes,options));obj.left-=obj.radius;obj.top-=obj.radius;return obj};function isValidRadius(attributes){return"radius"in attributes&&attributes.radius>=0}fabric.Circle.fromObject=function(object){return new fabric.Circle(object)}})(typeof exports!=="undefined"?exports:this);(function(global){"use strict";var fabric=global.fabric||(global.fabric={});if(fabric.Triangle){fabric.warn("fabric.Triangle is already defined");return}fabric.Triangle=fabric.util.createClass(fabric.Object,{type:"triangle",initialize:function(options){options=options||{};this.callSuper("initialize",options);this.set("width",options.width||100).set("height",options.height||100)},_render:function(ctx){var widthBy2=this.width/2,heightBy2=this.height/2;ctx.beginPath();ctx.moveTo(-widthBy2,heightBy2);ctx.lineTo(0,-heightBy2);ctx.lineTo(widthBy2,heightBy2);ctx.closePath();this._renderFill(ctx);this._renderStroke(ctx)},_renderDashedStroke:function(ctx){var widthBy2=this.width/2,heightBy2=this.height/2;ctx.beginPath();fabric.util.drawDashedLine(ctx,-widthBy2,heightBy2,0,-heightBy2,this.strokeDashArray);fabric.util.drawDashedLine(ctx,0,-heightBy2,widthBy2,heightBy2,this.strokeDashArray);fabric.util.drawDashedLine(ctx,widthBy2,heightBy2,-widthBy2,heightBy2,this.strokeDashArray);ctx.closePath()},toSVG:function(reviver){var markup=this._createBaseSVGMarkup(),widthBy2=this.width/2,heightBy2=this.height/2,points=[-widthBy2+" "+heightBy2,"0 "+-heightBy2,widthBy2+" "+heightBy2].join(",");markup.push("');return reviver?reviver(markup.join("")):markup.join("")},complexity:function(){return 1}});fabric.Triangle.fromObject=function(object){return new fabric.Triangle(object)}})(typeof exports!=="undefined"?exports:this);(function(global){"use strict";var fabric=global.fabric||(global.fabric={}),piBy2=Math.PI*2,extend=fabric.util.object.extend;if(fabric.Ellipse){fabric.warn("fabric.Ellipse is already defined."); +return}fabric.Ellipse=fabric.util.createClass(fabric.Object,{type:"ellipse",rx:0,ry:0,initialize:function(options){options=options||{};this.callSuper("initialize",options);this.set("rx",options.rx||0);this.set("ry",options.ry||0)},_set:function(key,value){this.callSuper("_set",key,value);switch(key){case"rx":this.rx=value;this.set("width",value*2);break;case"ry":this.ry=value;this.set("height",value*2);break}return this},getRx:function(){return this.get("rx")*this.get("scaleX")},getRy:function(){return this.get("ry")*this.get("scaleY")},toObject:function(propertiesToInclude){return extend(this.callSuper("toObject",propertiesToInclude),{rx:this.get("rx"),ry:this.get("ry")})},toSVG:function(reviver){var markup=this._createBaseSVGMarkup(),x=0,y=0;if(this.group&&this.group.type==="path-group"){x=this.left+this.rx;y=this.top+this.ry}markup.push("\n');return reviver?reviver(markup.join("")):markup.join("")},_render:function(ctx,noTransform){ctx.beginPath();ctx.save();ctx.transform(1,0,0,this.ry/this.rx,0,0);ctx.arc(noTransform?this.left+this.rx:0,noTransform?(this.top+this.ry)*this.rx/this.ry:0,this.rx,0,piBy2,false);ctx.restore();this._renderFill(ctx);this._renderStroke(ctx)},complexity:function(){return 1}});fabric.Ellipse.ATTRIBUTE_NAMES=fabric.SHARED_ATTRIBUTES.concat("cx cy rx ry".split(" "));fabric.Ellipse.fromElement=function(element,options){options||(options={});var parsedAttributes=fabric.parseAttributes(element,fabric.Ellipse.ATTRIBUTE_NAMES);parsedAttributes.left=parsedAttributes.left||0;parsedAttributes.top=parsedAttributes.top||0;var ellipse=new fabric.Ellipse(extend(parsedAttributes,options));ellipse.top-=ellipse.ry;ellipse.left-=ellipse.rx;return ellipse};fabric.Ellipse.fromObject=function(object){return new fabric.Ellipse(object)}})(typeof exports!=="undefined"?exports:this);(function(global){"use strict";var fabric=global.fabric||(global.fabric={}),extend=fabric.util.object.extend;if(fabric.Rect){fabric.warn("fabric.Rect is already defined");return}var stateProperties=fabric.Object.prototype.stateProperties.concat();stateProperties.push("rx","ry","x","y");fabric.Rect=fabric.util.createClass(fabric.Object,{stateProperties:stateProperties,type:"rect",rx:0,ry:0,strokeDashArray:null,initialize:function(options){options=options||{};this.callSuper("initialize",options);this._initRxRy()},_initRxRy:function(){if(this.rx&&!this.ry){this.ry=this.rx}else if(this.ry&&!this.rx){this.rx=this.ry}},_render:function(ctx,noTransform){if(this.width===1&&this.height===1){ctx.fillRect(-.5,-.5,1,1);return}var rx=this.rx?Math.min(this.rx,this.width/2):0,ry=this.ry?Math.min(this.ry,this.height/2):0,w=this.width,h=this.height,x=noTransform?this.left:-this.width/2,y=noTransform?this.top:-this.height/2,isRounded=rx!==0||ry!==0,k=1-.5522847498;ctx.beginPath();ctx.moveTo(x+rx,y);ctx.lineTo(x+w-rx,y);isRounded&&ctx.bezierCurveTo(x+w-k*rx,y,x+w,y+k*ry,x+w,y+ry);ctx.lineTo(x+w,y+h-ry);isRounded&&ctx.bezierCurveTo(x+w,y+h-k*ry,x+w-k*rx,y+h,x+w-rx,y+h);ctx.lineTo(x+rx,y+h);isRounded&&ctx.bezierCurveTo(x+k*rx,y+h,x,y+h-k*ry,x,y+h-ry);ctx.lineTo(x,y+ry);isRounded&&ctx.bezierCurveTo(x,y+k*ry,x+k*rx,y,x+rx,y);ctx.closePath();this._renderFill(ctx);this._renderStroke(ctx)},_renderDashedStroke:function(ctx){var x=-this.width/2,y=-this.height/2,w=this.width,h=this.height;ctx.beginPath();fabric.util.drawDashedLine(ctx,x,y,x+w,y,this.strokeDashArray);fabric.util.drawDashedLine(ctx,x+w,y,x+w,y+h,this.strokeDashArray);fabric.util.drawDashedLine(ctx,x+w,y+h,x,y+h,this.strokeDashArray);fabric.util.drawDashedLine(ctx,x,y+h,x,y,this.strokeDashArray);ctx.closePath()},toObject:function(propertiesToInclude){var object=extend(this.callSuper("toObject",propertiesToInclude),{rx:this.get("rx")||0,ry:this.get("ry")||0});if(!this.includeDefaultValues){this._removeDefaultValues(object)}return object},toSVG:function(reviver){var markup=this._createBaseSVGMarkup(),x=this.left,y=this.top;if(!(this.group&&this.group.type==="path-group")){x=-this.width/2;y=-this.height/2}markup.push("\n');return reviver?reviver(markup.join("")):markup.join("")},complexity:function(){return 1}});fabric.Rect.ATTRIBUTE_NAMES=fabric.SHARED_ATTRIBUTES.concat("x y rx ry width height".split(" "));fabric.Rect.fromElement=function(element,options){if(!element){return null}options=options||{};var parsedAttributes=fabric.parseAttributes(element,fabric.Rect.ATTRIBUTE_NAMES);parsedAttributes.left=parsedAttributes.left||0;parsedAttributes.top=parsedAttributes.top||0;var rect=new fabric.Rect(extend(options?fabric.util.object.clone(options):{},parsedAttributes));rect.visible=rect.width>0&&rect.height>0;return rect};fabric.Rect.fromObject=function(object){return new fabric.Rect(object)}})(typeof exports!=="undefined"?exports:this);(function(global){"use strict";var fabric=global.fabric||(global.fabric={});if(fabric.Polyline){fabric.warn("fabric.Polyline is already defined");return}fabric.Polyline=fabric.util.createClass(fabric.Object,{type:"polyline",points:null,minX:0,minY:0,initialize:function(points,options){return fabric.Polygon.prototype.initialize.call(this,points,options)},_calcDimensions:function(){return fabric.Polygon.prototype._calcDimensions.call(this)},_applyPointOffset:function(){return fabric.Polygon.prototype._applyPointOffset.call(this)},toObject:function(propertiesToInclude){return fabric.Polygon.prototype.toObject.call(this,propertiesToInclude)},toSVG:function(reviver){return fabric.Polygon.prototype.toSVG.call(this,reviver)},_render:function(ctx,noTransform){if(!fabric.Polygon.prototype.commonRender.call(this,ctx,noTransform)){return}this._renderFill(ctx);this._renderStroke(ctx)},_renderDashedStroke:function(ctx){var p1,p2;ctx.beginPath();for(var i=0,len=this.points.length;i\n');return reviver?reviver(markup.join("")):markup.join("")},_render:function(ctx,noTransform){if(!this.commonRender(ctx,noTransform)){return}this._renderFill(ctx);if(this.stroke||this.strokeDashArray){ctx.closePath();this._renderStroke(ctx)}},commonRender:function(ctx,noTransform){var point,len=this.points.length;if(!len||isNaN(this.points[len-1].y)){return false}noTransform||ctx.translate(-this.pathOffset.x,-this.pathOffset.y);ctx.beginPath();ctx.moveTo(this.points[0].x,this.points[0].y);for(var i=0;i"},toObject:function(propertiesToInclude){var o=extend(this.callSuper("toObject",propertiesToInclude),{path:this.path.map(function(item){return item.slice()}),pathOffset:this.pathOffset});if(this.sourcePath){o.sourcePath=this.sourcePath}if(this.transformMatrix){o.transformMatrix=this.transformMatrix}return o},toDatalessObject:function(propertiesToInclude){var o=this.toObject(propertiesToInclude);if(this.sourcePath){o.path=this.sourcePath}delete o.sourcePath;return o},toSVG:function(reviver){var chunks=[],markup=this._createBaseSVGMarkup(),addTransform="";for(var i=0,len=this.path.length;i\n");return reviver?reviver(markup.join("")):markup.join("")},complexity:function(){return this.path.length},_parsePath:function(){var result=[],coords=[],currentPath,parsed,re=/([-+]?((\d+\.\d+)|((\d+)|(\.\d+)))(?:e[-+]?\d+)?)/gi,match,coordsStr;for(var i=0,coordsParsed,len=this.path.length;icommandLength){for(var k=1,klen=coordsParsed.length;k\n");for(var i=0,len=objects.length;i\n");return reviver?reviver(markup.join("")):markup.join("")},toString:function(){return"#"},isSameColor:function(){var firstPathFill=this.getObjects()[0].get("fill")||"";if(typeof firstPathFill!=="string"){return false}firstPathFill=firstPathFill.toLowerCase();return this.getObjects().every(function(path){var pathFill=path.get("fill")||"";return typeof pathFill==="string"&&pathFill.toLowerCase()===firstPathFill})},complexity:function(){return this.paths.reduce(function(total,path){return total+(path&&path.complexity?path.complexity():0)},0)},getObjects:function(){return this.paths}});fabric.PathGroup.fromObject=function(object,callback){if(typeof object.paths==="string"){fabric.loadSVGFromURL(object.paths,function(elements){var pathUrl=object.paths;delete object.paths;var pathGroup=fabric.util.groupSVGElements(elements,object,pathUrl);callback(pathGroup)})}else{fabric.util.enlivenObjects(object.paths,function(enlivenedObjects){delete object.paths;callback(new fabric.PathGroup(enlivenedObjects,object))})}};fabric.PathGroup.async=true})(typeof exports!=="undefined"?exports:this);(function(global){"use strict";var fabric=global.fabric||(global.fabric={}),extend=fabric.util.object.extend,min=fabric.util.array.min,max=fabric.util.array.max,invoke=fabric.util.array.invoke;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,initialize:function(objects,options,isAlreadyGrouped){options=options||{};this._objects=[];isAlreadyGrouped&&this.callSuper("initialize",options);this._objects=objects||[];for(var i=this._objects.length;i--;){this._objects[i].group=this}this.originalState={};if(options.originX){this.originX=options.originX}if(options.originY){this.originY=options.originY}if(isAlreadyGrouped){this._updateObjectsCoords(true)}else{this._calcBounds();this._updateObjectsCoords();this.callSuper("initialize",options)}this.setCoords();this.saveCoords()},_updateObjectsCoords:function(skipCoordsChange){for(var i=this._objects.length;i--;){this._updateObjectCoords(this._objects[i],skipCoordsChange)}},_updateObjectCoords:function(object,skipCoordsChange){object.__origHasControls=object.hasControls;object.hasControls=false;if(skipCoordsChange){return}var objectLeft=object.getLeft(),objectTop=object.getTop(),center=this.getCenterPoint();object.set({originalLeft:objectLeft,originalTop:objectTop,left:objectLeft-center.x,top:objectTop-center.y});object.setCoords()},toString:function(){return"#"},addWithUpdate:function(object){this._restoreObjectsState();fabric.util.resetObjectTransform(this);if(object){this._objects.push(object);object.group=this;object._set("canvas",this.canvas)}this.forEachObject(this._setObjectActive,this);this._calcBounds();this._updateObjectsCoords();return this},_setObjectActive:function(object){object.set("active",true);object.group=this},removeWithUpdate:function(object){this._restoreObjectsState();fabric.util.resetObjectTransform(this);this.forEachObject(this._setObjectActive,this);this.remove(object);this._calcBounds();this._updateObjectsCoords();return this},_onObjectAdded:function(object){object.group=this;object._set("canvas",this.canvas)},_onObjectRemoved:function(object){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"){while(i--){this._objects[i].set(key,value)}}else{while(i--){this._objects[i].setOnGroup(key,value)}}this.callSuper("_set",key,value)},toObject:function(propertiesToInclude){return extend(this.callSuper("toObject",propertiesToInclude),{objects:invoke(this._objects,"toObject",propertiesToInclude)})},render:function(ctx){if(!this.visible){return}ctx.save();if(this.transformMatrix){ctx.transform.apply(ctx,this.transformMatrix)}this.transform(ctx);this._setShadow(ctx);this.clipTo&&fabric.util.clipContext(this,ctx);for(var i=0,len=this._objects.length;i\n');for(var i=0,len=this._objects.length;i\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;i0){object.resizeFilters=this.resizeFilters.map(function(filterObj){return filterObj&&filterObj.toObject()})}if(!this.includeDefaultValues){this._removeDefaultValues(object)}return object},toSVG:function(reviver){var markup=this._createBaseSVGMarkup(),x=-this.width/2,y=-this.height/2,preserveAspectRatio="none";if(this.group&&this.group.type==="path-group"){x=this.left;y=this.top}if(this.alignX!=="none"&&this.alignY!=="none"){preserveAspectRatio="x"+this.alignX+"Y"+this.alignY+" "+this.meetOrSlice}markup.push('\n','\n");if(this.stroke||this.strokeDashArray){var origFill=this.fill;this.fill=null;markup.push("\n');this.fill=origFill}markup.push("\n");return reviver?reviver(markup.join("")):markup.join("")},getSrc:function(){if(this.getElement()){return this.getElement().src||this.getElement()._src}},setSrc:function(src,callback,options){fabric.util.loadImage(src,function(img){return this.setElement(img,callback,options)},this,options&&options.crossOrigin)},toString:function(){return'#'},clone:function(callback,propertiesToInclude){this.constructor.fromObject(this.toObject(propertiesToInclude),callback)},applyFilters:function(callback,filters,imgElement,forResizing){filters=filters||this.filters;imgElement=imgElement||this._originalElement;if(!imgElement){return}var imgEl=imgElement,canvasEl=fabric.util.createCanvasElement(),replacement=fabric.util.createImage(),_this=this;canvasEl.width=imgEl.width;canvasEl.height=imgEl.height;canvasEl.getContext("2d").drawImage(imgEl,0,0,imgEl.width,imgEl.height);if(filters.length===0){this._element=imgElement;callback&&callback();return canvasEl}filters.forEach(function(filter){filter&&filter.applyTo(canvasEl,filter.scaleX||_this.scaleX,filter.scaleY||_this.scaleY);if(!forResizing&&filter&&filter.type==="Resize"){_this.width*=filter.scaleX;_this.height*=filter.scaleY}});replacement.width=canvasEl.width;replacement.height=canvasEl.height;if(fabric.isLikelyNode){replacement.src=canvasEl.toBuffer(undefined,fabric.Image.pngCompression);_this._element=replacement;!forResizing&&(_this._filteredEl=replacement);callback&&callback()}else{replacement.onload=function(){_this._element=replacement;!forResizing&&(_this._filteredEl=replacement);callback&&callback();replacement.onload=canvasEl=imgEl=null};replacement.src=canvasEl.toDataURL("image/png")}return canvasEl},_render:function(ctx,noTransform){var x,y,imageMargins=this._findMargins(),elementToDraw;x=noTransform?this.left:-this.width/2;y=noTransform?this.top:-this.height/2;if(this.meetOrSlice==="slice"){ctx.beginPath();ctx.rect(x,y,this.width,this.height);ctx.clip()}if(this.isMoving===false&&this.resizeFilters.length&&this._needsResize()){this._lastScaleX=this.scaleX;this._lastScaleY=this.scaleY;elementToDraw=this.applyFilters(null,this.resizeFilters,this._filteredEl||this._originalElement,true)}else{elementToDraw=this._element}elementToDraw&&ctx.drawImage(elementToDraw,x+imageMargins.marginX,y+imageMargins.marginY,imageMargins.width,imageMargins.height);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);this.set("height",element.height)},_initElement:function(element,options){this.setElement(fabric.util.getById(element),null,options);fabric.util.addClass(this.getElement(),fabric.Image.CSS_CANVAS)},_initConfig:function(options){options||(options={});this.setOptions(options);this._setWidthHeight(options);if(this._element&&this.crossOrigin){this._element.crossOrigin=this.crossOrigin}},_initFilters:function(filters,callback){if(filters&&filters.length){fabric.util.enlivenObjects(filters,function(enlivenedObjects){callback&&callback(enlivenedObjects)},"fabric.Image.filters")}else{callback&&callback()}},_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},complexity:function(){return 1}});fabric.Image.CSS_CANVAS="canvas-img";fabric.Image.prototype.getSvgSrc=fabric.Image.prototype.getSrc;fabric.Image.fromObject=function(object,callback){fabric.util.loadImage(object.src,function(img){fabric.Image.prototype._initFilters.call(object,object.filters,function(filters){object.filters=filters||[];fabric.Image.prototype._initFilters.call(object,object.resizeFilters,function(resizeFilters){object.resizeFilters=resizeFilters||[];var instance=new fabric.Image(img,object);callback&&callback(instance)})})},null,object.crossOrigin)};fabric.Image.fromURL=function(url,callback,imgOptions){fabric.util.loadImage(url,function(img){callback&&callback(new fabric.Image(img,imgOptions))},null,imgOptions&&imgOptions.crossOrigin)};fabric.Image.ATTRIBUTE_NAMES=fabric.SHARED_ATTRIBUTES.concat("x y width height preserveAspectRatio xlink:href".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)}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;if(angle>0){return Math.round((angle-1)/90)*90}return Math.round(angle/90)*90},straighten:function(){this.setAngle(this._getAngleValueForStraighten());return this},fxStraighten:function(callbacks){callbacks=callbacks||{};var empty=function(){},onComplete=callbacks.onComplete||empty,onChange=callbacks.onChange||empty,_this=this;fabric.util.animate({startValue:this.get("angle"),endValue:this._getAngleValueForStraighten(),duration:this.FX_DURATION,onChange:function(value){_this.setAngle(value);onChange()},onComplete:function(){_this.setCoords();onComplete()},onStart:function(){_this.set("active",false)}});return this}});fabric.util.object.extend(fabric.StaticCanvas.prototype,{straightenObject:function(object){object.straighten();this.renderAll();return this},fxStraightenObject:function(object){object.fxStraighten({onChange:this.renderAll.bind(this)});return this}});fabric.Image.filters=fabric.Image.filters||{};fabric.Image.filters.BaseFilter=fabric.util.createClass({type:"BaseFilter",initialize:function(options){if(options){this.setOptions(options)}},setOptions:function(options){for(var prop in options){this[prop]=options[prop]}},toObject:function(){return{type:this.type}},toJSON:function(){return this.toObject()}});(function(global){"use strict";var fabric=global.fabric||(global.fabric={}),extend=fabric.util.object.extend;fabric.Image.filters.Brightness=fabric.util.createClass(fabric.Image.filters.BaseFilter,{type:"Brightness",initialize:function(options){options=options||{};this.brightness=options.brightness||0},applyTo:function(canvasEl){var context=canvasEl.getContext("2d"),imageData=context.getImageData(0,0,canvasEl.width,canvasEl.height),data=imageData.data,brightness=this.brightness;for(var i=0,len=data.length;ish||scx<0||scx>sw){continue}srcOff=(scy*sw+scx)*4;wt=weights[cy*side+cx];r+=src[srcOff]*wt;g+=src[srcOff+1]*wt;b+=src[srcOff+2]*wt;a+=src[srcOff+3]*wt}}dst[dstOff]=r;dst[dstOff+1]=g;dst[dstOff+2]=b;dst[dstOff+3]=a+alphaFac*(255-a)}}context.putImageData(output,0,0)},toObject:function(){return extend(this.callSuper("toObject"),{opaque:this.opaque,matrix:this.matrix})}});fabric.Image.filters.Convolute.fromObject=function(object){return new fabric.Image.filters.Convolute(object)}})(typeof exports!=="undefined"?exports:this);(function(global){"use strict";var fabric=global.fabric||(global.fabric={}),extend=fabric.util.object.extend;fabric.Image.filters.GradientTransparency=fabric.util.createClass(fabric.Image.filters.BaseFilter,{type:"GradientTransparency",initialize:function(options){options=options||{};this.threshold=options.threshold||100},applyTo:function(canvasEl){var context=canvasEl.getContext("2d"),imageData=context.getImageData(0,0,canvasEl.width,canvasEl.height),data=imageData.data,threshold=this.threshold,total=data.length;for(var i=0,len=data.length;i-1?options.channel:0},applyTo:function(canvasEl){if(!this.mask){return}var context=canvasEl.getContext("2d"),imageData=context.getImageData(0,0,canvasEl.width,canvasEl.height),data=imageData.data,maskEl=this.mask.getElement(),maskCanvasEl=fabric.util.createCanvasElement(),channel=this.channel,i,iLen=imageData.width*imageData.height*4;maskCanvasEl.width=canvasEl.width;maskCanvasEl.height=canvasEl.height;maskCanvasEl.getContext("2d").drawImage(maskEl,0,0,canvasEl.width,canvasEl.height);var maskImageData=maskCanvasEl.getContext("2d").getImageData(0,0,canvasEl.width,canvasEl.height),maskData=maskImageData.data;for(i=0;ilimit&&g>limit&&b>limit&&abs(r-g)width){multW=2;signW=-1}if(newHeight>height){multH=2;signH=-1}imageData=context.getImageData(0,0,width,height);canvasEl.width=max(newWidth,width);canvasEl.height=max(newHeight,height);context.putImageData(imageData,0,0);while(!doneW||!doneH){width=stepW;height=stepH;if(newWidth*signWlobes){return 0}x*=Math.PI;if(abs(x)<1e-16){return 1}var xx=x/lobes;return sin(x)*sin(xx)/x/xx}}function process(u){var v,i,weight,idx,a,red,green,blue,alpha,fX,fY;center.x=(u+.5)*ratioX;icenter.x=floor(center.x);for(v=0;v=oW){continue}fX=floor(1e3*abs(i-center.x));if(!cacheLanc[fX]){cacheLanc[fX]={}}for(var j=icenter.y-range2Y;j<=icenter.y+range2Y;j++){if(j<0||j>=oH){continue}fY=floor(1e3*abs(j-center.y));if(!cacheLanc[fX][fY]){cacheLanc[fX][fY]=lanczos(sqrt(pow(fX*rcpRatioX,2)+pow(fY*rcpRatioY,2))/1e3)}weight=cacheLanc[fX][fY];if(weight>0){idx=(j*oW+i)*4;a+=weight;red+=weight*srcData[idx];green+=weight*srcData[idx+1];blue+=weight*srcData[idx+2];alpha+=weight*srcData[idx+3]}}}idx=(v*dW+u)*4;destData[idx]=red/a;destData[idx+1]=green/a;destData[idx+2]=blue/a;destData[idx+3]=alpha/a}if(++u1&&w<-1){continue}weight=2*w*w*w-3*w*w+1;if(weight>0){dx=4*(xx+yy*oW);gxA+=weight*data[dx+3];weightsAlpha+=weight;if(data[dx+3]<255){weight=weight*data[dx+3]/250}gxR+=weight*data[dx];gxG+=weight*data[dx+1];gxB+=weight*data[dx+2];weights+=weight}}}data2[x2]=gxR/weights;data2[x2+1]=gxG/weights;data2[x2+2]=gxB/weights;data2[x2+3]=gxA/weightsAlpha}}return img2},toObject:function(){return{type:this.type,scaleX:this.scaleX,scaleY:this.scaleY,resizeType:this.resizeType,lanczosLobes:this.lanczosLobes}}});fabric.Image.filters.Resize.fromObject=function(object){return new fabric.Image.filters.Resize(object)}})(typeof exports!=="undefined"?exports:this);(function(global){"use strict";var fabric=global.fabric||(global.fabric={}),extend=fabric.util.object.extend,clone=fabric.util.object.clone,toFixed=fabric.util.toFixed,supportsLineDash=fabric.StaticCanvas.supports("setLineDash"),NUM_FRACTION_DIGITS=fabric.Object.NUM_FRACTION_DIGITS;if(fabric.Text){fabric.warn("fabric.Text is already defined");return}var stateProperties=fabric.Object.prototype.stateProperties.concat();stateProperties.push("fontFamily","fontWeight","fontSize","text","textDecoration","textAlign","fontStyle","lineHeight","textBackgroundColor");fabric.Text=fabric.util.createClass(fabric.Object,{_dimensionAffectingProps:{fontSize:true,fontWeight:true,fontFamily:true,fontStyle:true,lineHeight:true,stroke:true,strokeWidth:true,text:true,textAlign:true},_reNewline:/\r?\n/,_reSpacesAndTabs:/[ \t\r]+/g,type:"text",fontSize:40,fontWeight:"normal",fontFamily:"Times New Roman",textDecoration:"",textAlign:"left",fontStyle:"",lineHeight:1.16,textBackgroundColor:"",stateProperties:stateProperties,stroke:null,shadow:null,_fontSizeFraction:.25,_fontSizeMult:1.13,initialize:function(text,options){options=options||{};this.text=text;this.__skipDimension=true;this.setOptions(options);this.__skipDimension=false;this._initDimensions()},_initDimensions:function(ctx){if(this.__skipDimension){return}if(!ctx){ctx=fabric.util.createCanvasElement().getContext("2d");this._setTextStyles(ctx)}this._textLines=this._splitTextIntoLines();this._clearCache();this._cacheLinesWidth=this.textAlign!=="justify";this.width=this._getTextWidth(ctx);this._cacheLinesWidth=true;this.height=this._getTextHeight(ctx)},toString:function(){return"#'},_render:function(ctx){this.clipTo&&fabric.util.clipContext(this,ctx);this._setOpacity(ctx);this._setShadow(ctx);this._setupCompositeOperation(ctx);this._renderTextBackground(ctx);this._setStrokeStyles(ctx);this._setFillStyles(ctx);this._renderText(ctx);this._renderTextDecoration(ctx);this.clipTo&&ctx.restore()},_renderText:function(ctx){this._translateForTextAlign(ctx);this._renderTextFill(ctx);this._renderTextStroke(ctx);this._translateForTextAlign(ctx,true)},_translateForTextAlign:function(ctx,back){if(this.textAlign!=="left"&&this.textAlign!=="justify"){var sign=back?-1:1;ctx.translate(this.textAlign==="center"?sign*this.width/2:sign*this.width,0)}},_setTextStyles:function(ctx){ctx.textBaseline="alphabetic";if(!this.skipTextAlign){ctx.textAlign=this.textAlign}ctx.font=this._getFontDeclaration()},_getTextHeight:function(){return this._textLines.length*this._getHeightOfLine()},_getTextWidth:function(ctx){var maxWidth=this._getLineWidth(ctx,0);for(var i=1,len=this._textLines.length;imaxWidth){maxWidth=currentLineWidth}}return maxWidth},_renderChars:function(method,ctx,chars,left,top){var shortM=method.slice(0,-4);if(this[shortM].toLive){var offsetX=-this.width/2+this[shortM].offsetX||0,offsetY=-this.height/2+this[shortM].offsetY||0;ctx.save();ctx.translate(offsetX,offsetY);left-=offsetX;top-=offsetY}ctx[method](chars,left,top);this[shortM].toLive&&ctx.restore()},_renderTextLine:function(method,ctx,line,left,top,lineIndex){top-=this.fontSize*this._fontSizeFraction;var lineWidth=this._getLineWidth(ctx,lineIndex);if(this.textAlign!=="justify"||this.width0?widthDiff/numSpaces:0,leftOffset=0,word; +for(var i=0,len=words.length;i1){width=this.width}else{width=ctx.measureText(line).width}}else{width=ctx.measureText(line).width}this._cacheLinesWidth&&(this.__lineWidths[lineIndex]=width);return width},_renderTextDecoration:function(ctx){if(!this.textDecoration){return}var halfOfVerticalBox=this.height/2,_this=this,offsets=[];function renderLinesAtOffset(offsets){var i,lineHeight=0,len,j,oLen,lineWidth,lineLeftOffset,heightOfLine;for(i=0,len=_this._textLines.length;i-1){offsets.push(.85)}if(this.textDecoration.indexOf("line-through")>-1){offsets.push(.43)}if(this.textDecoration.indexOf("overline")>-1){offsets.push(-.12)}if(offsets.length>0){renderLinesAtOffset(offsets)}},_getFontDeclaration:function(){return[fabric.isLikelyNode?this.fontWeight:this.fontStyle,fabric.isLikelyNode?this.fontStyle:this.fontWeight,this.fontSize+"px",fabric.isLikelyNode?'"'+this.fontFamily+'"':this.fontFamily].join(" ")},render:function(ctx,noTransform){if(!this.visible){return}ctx.save();this._setTextStyles(ctx);if(this._shouldClearCache()){this._initDimensions(ctx)}if(!noTransform){this.transform(ctx)}if(this.transformMatrix){ctx.transform.apply(ctx,this.transformMatrix)}if(this.group&&this.group.type==="path-group"){ctx.translate(this.left,this.top)}this._render(ctx);ctx.restore()},_splitTextIntoLines:function(){return this.text.split(this._reNewline)},toObject:function(propertiesToInclude){var object=extend(this.callSuper("toObject",propertiesToInclude),{text:this.text,fontSize:this.fontSize,fontWeight:this.fontWeight,fontFamily:this.fontFamily,fontStyle:this.fontStyle,lineHeight:this.lineHeight,textDecoration:this.textDecoration,textAlign:this.textAlign,textBackgroundColor:this.textBackgroundColor});if(!this.includeDefaultValues){this._removeDefaultValues(object)}return object},toSVG:function(reviver){var markup=this._createBaseSVGMarkup(),offsets=this._getSVGLeftTopOffsets(this.ctx),textAndBg=this._getSVGTextAndBg(offsets.textTop,offsets.textLeft);this._wrapSVGTextAndBg(markup,textAndBg);return reviver?reviver(markup.join("")):markup.join("")},_getSVGLeftTopOffsets:function(ctx){var lineTop=this._getHeightOfLine(ctx,0),textLeft=-this.width/2,textTop=0;return{textLeft:textLeft+(this.group&&this.group.type==="path-group"?this.left:0),textTop:textTop+(this.group&&this.group.type==="path-group"?-this.top:0),lineTop:lineTop}},_wrapSVGTextAndBg:function(markup,textAndBg){var noShadow=true,filter=this.getSvgFilter(),style=filter===""?"":' style="'+filter+'"';markup.push(' \n",textAndBg.textBgRects.join("")," \n',textAndBg.textSpans.join("")," \n"," \n")},_getSVGTextAndBg:function(textTopOffset,textLeftOffset){var textSpans=[],textBgRects=[],height=0;this._setSVGBg(textBgRects);for(var i=0,len=this._textLines.length;i",fabric.util.string.escapeXml(this._textLines[i]),"\n")},_setSVGTextLineJustifed:function(i,textSpans,yPos,textLeftOffset){var ctx=fabric.util.createCanvasElement().getContext("2d");this._setTextStyles(ctx);var line=this._textLines[i],words=line.split(/\s+/),wordsWidth=this._getWidthOfWords(ctx,line),widthDiff=this.width-wordsWidth,numSpaces=words.length-1,spaceWidth=numSpaces>0?widthDiff/numSpaces:0,word,attributes=this._getFillAttributes(this.fill),len;textLeftOffset+=this._getLineLeftOffset(this._getLineWidth(ctx,i));for(i=0,len=words.length;i",fabric.util.string.escapeXml(word),"\n");textLeftOffset+=this._getWidthOfWords(ctx,word)+spaceWidth}},_setSVGTextLineBg:function(textBgRects,i,textLeftOffset,textTopOffset,height){textBgRects.push(" \n')},_setSVGBg:function(textBgRects){if(this.backgroundColor){textBgRects.push(" \n')}},_getFillAttributes:function(value){var fillColor=value&&typeof value==="string"?new fabric.Color(value):"";if(!fillColor||!fillColor.getSource()||fillColor.getAlpha()===1){return'fill="'+value+'"'}return'opacity="'+fillColor.getAlpha()+'" fill="'+fillColor.setAlpha(1).toRgb()+'"'},_set:function(key,value){this.callSuper("_set",key,value);if(key in this._dimensionAffectingProps){this._initDimensions();this.setCoords()}},complexity:function(){return 1}});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){if(!element){return null}var parsedAttributes=fabric.parseAttributes(element,fabric.Text.ATTRIBUTE_NAMES);options=fabric.util.object.extend(options?fabric.util.object.clone(options):{},parsedAttributes);options.top=options.top||0;options.left=options.left||0;if("dx"in parsedAttributes){options.left+=parsedAttributes.dx}if("dy"in parsedAttributes){options.top+=parsedAttributes.dy}if(!("fontSize"in options)){options.fontSize=fabric.Text.DEFAULT_SVG_FONT_SIZE}if(!options.originX){options.originX="left"}var textContent="";if(!("textContent"in element)){if("firstChild"in element&&element.firstChild!==null){if("data"in element.firstChild&&element.firstChild.data!==null){textContent=element.firstChild.data}}}else{textContent=element.textContent}textContent=textContent.replace(/^\s+|\s+$|\n+/g,"").replace(/\s+/g," ");var text=new fabric.Text(textContent,options),offX=0;if(text.originX==="left"){offX=text.getWidth()/2}if(text.originX==="right"){offX=-text.getWidth()/2}text.set({left:text.getLeft()+offX,top:text.getTop()-text.getHeight()/2+text.fontSize*(.18+text._fontSizeFraction)});return text};fabric.Text.fromObject=function(object){return new fabric.Text(object.text,clone(object))};fabric.util.createAccessors(fabric.Text)})(typeof exports!=="undefined"?exports:this);(function(){var clone=fabric.util.object.clone;fabric.IText=fabric.util.createClass(fabric.Text,fabric.Observable,{type:"i-text",selectionStart:0,selectionEnd:0,selectionColor:"rgba(17,119,255,0.3)",isEditing:false,editable:true,editingBorderColor:"rgba(102,153,255,0.25)",cursorWidth:2,cursorColor:"#333",cursorDelay:1e3,cursorDuration:600,styles:null,caching:true,_reSpace:/\s|\n/,_currentCursorOpacity:0,_selectionDirection:null,_abortCursorAnimation:false,_charWidthsCache:{},__widthOfSpace:[],initialize:function(text,options){this.styles=options?options.styles||{}:{};this.callSuper("initialize",text,options);this.initBehavior()},_clearCache:function(){this.callSuper("_clearCache");this.__widthOfSpace=[]},isEmptyStyles:function(){if(!this.styles){return true}var obj=this.styles;for(var p1 in obj){for(var p2 in obj[p1]){for(var p3 in obj[p1][p2]){return false}}}return true},setSelectionStart:function(index){index=Math.max(index,0);if(this.selectionStart!==index){this.fire("selection:changed");this.canvas&&this.canvas.fire("text:selection:changed",{target:this});this.selectionStart=index}this._updateTextarea()},setSelectionEnd:function(index){index=Math.min(index,this.text.length);if(this.selectionEnd!==index){this.fire("selection:changed");this.canvas&&this.canvas.fire("text:selection:changed",{target:this});this.selectionEnd=index}this._updateTextarea()},getSelectionStyles:function(startIndex,endIndex){if(arguments.length===2){var styles=[];for(var i=startIndex;i=start.charIndex&&(i!==endLine||jstartLine&&i0||this.skipFillStrokeCheck)){this.callSuper("_renderChars",method,ctx,line,left,top)}},_renderChar:function(method,ctx,lineIndex,i,_char,left,top,lineHeight){var charWidth,charHeight,shouldFill,shouldStroke,decl=this._getStyleDeclaration(lineIndex,i),offset,textDecoration;if(decl){charHeight=this._getHeightOfChar(ctx,_char,lineIndex,i);shouldStroke=decl.stroke;shouldFill=decl.fill;textDecoration=decl.textDecoration}else{charHeight=this.fontSize}shouldStroke=(shouldStroke||this.stroke)&&method==="strokeText";shouldFill=(shouldFill||this.fill)&&method==="fillText";decl&&ctx.save();charWidth=this._applyCharStylesGetWidth(ctx,_char,lineIndex,i,decl||{});textDecoration=textDecoration||this.textDecoration;if(decl&&decl.textBackgroundColor){this._removeShadow(ctx)}shouldFill&&ctx.fillText(_char,left,top);shouldStroke&&ctx.strokeText(_char,left,top);if(textDecoration||textDecoration!==""){offset=this._fontSizeFraction*lineHeight/this.lineHeight;this._renderCharDecoration(ctx,textDecoration,left,top,offset,charWidth,charHeight)}decl&&ctx.restore();ctx.translate(charWidth,0)},_hasStyleChanged:function(prevStyle,thisStyle){return prevStyle.fill!==thisStyle.fill||prevStyle.fontSize!==thisStyle.fontSize||prevStyle.textBackgroundColor!==thisStyle.textBackgroundColor||prevStyle.textDecoration!==thisStyle.textDecoration||prevStyle.fontFamily!==thisStyle.fontFamily||prevStyle.fontWeight!==thisStyle.fontWeight||prevStyle.fontStyle!==thisStyle.fontStyle||prevStyle.stroke!==thisStyle.stroke||prevStyle.strokeWidth!==thisStyle.strokeWidth},_renderCharDecoration:function(ctx,textDecoration,left,top,offset,charWidth,charHeight){if(!textDecoration){return}var decorationWeight=charHeight/15,positions={underline:top+charHeight/10,"line-through":top-charHeight*(this._fontSizeFraction+this._fontSizeMult-1)+decorationWeight,overline:top-(this._fontSizeMult-this._fontSizeFraction)*charHeight},decorations=["underline","line-through","overline"],i,decoration;for(i=0;i-1){ctx.fillRect(left,positions[decoration],charWidth,decorationWeight)}}},_renderTextLine:function(method,ctx,line,left,top,lineIndex){if(!this.isEmptyStyles()){top+=this.fontSize*(this._fontSizeFraction+.03)}this.callSuper("_renderTextLine",method,ctx,line,left,top,lineIndex)},_renderTextDecoration:function(ctx){if(this.isEmptyStyles()){return this.callSuper("_renderTextDecoration",ctx)}},_renderTextLinesBackground:function(ctx){this.callSuper("_renderTextLinesBackground",ctx);var lineTopOffset=0,heightOfLine,lineWidth,lineLeftOffset,leftOffset=this._getLeftOffset(),topOffset=this._getTopOffset(),line,_char,style;for(var i=0,len=this._textLines.length;imaxHeight){maxHeight=currentCharHeight}}this.__lineHeights[lineIndex]=maxHeight*this.lineHeight*this._fontSizeMult;return this.__lineHeights[lineIndex]},_getTextHeight:function(ctx){var height=0;for(var i=0,len=this._textLines.length;i-1){offset++;index--}return startFrom-offset},findWordBoundaryRight:function(startFrom){var offset=0,index=startFrom;if(this._reSpace.test(this.text.charAt(index))){while(this._reSpace.test(this.text.charAt(index))){offset++;index++}}while(/\S/.test(this.text.charAt(index))&&index-1){offset++; +index--}return startFrom-offset},findLineBoundaryRight:function(startFrom){var offset=0,index=startFrom;while(!/\n/.test(this.text.charAt(index))&&index0&&index=_this.__selectionStartOnMouseDown){_this.setSelectionStart(_this.__selectionStartOnMouseDown);_this.setSelectionEnd(newSelectionStart)}else{_this.setSelectionStart(newSelectionStart);_this.setSelectionEnd(_this.__selectionStartOnMouseDown)}})},_setEditingProps:function(){this.hoverCursor="text";if(this.canvas){this.canvas.defaultCursor=this.canvas.moveCursor="text"}this.borderColor=this.editingBorderColor;this.hasControls=this.selectable=false;this.lockMovementX=this.lockMovementY=true},_updateTextarea:function(){if(!this.hiddenTextarea||this.inCompositionMode){return}this.hiddenTextarea.value=this.text;this.hiddenTextarea.selectionStart=this.selectionStart;this.hiddenTextarea.selectionEnd=this.selectionEnd;if(this.selectionStart===this.selectionEnd){var p=this._calcTextareaPosition();this.hiddenTextarea.style.left=p.x+"px";this.hiddenTextarea.style.top=p.y+"px"}},_calcTextareaPosition:function(){var chars=this.text.split(""),boundaries=this._getCursorBoundaries(chars,"cursor"),cursorLocation=this.get2DCursorLocation(),lineIndex=cursorLocation.lineIndex,charIndex=cursorLocation.charIndex,charHeight=this.getCurrentCharFontSize(lineIndex,charIndex),leftOffset=lineIndex===0&&charIndex===0?this._getLineLeftOffset(this._getLineWidth(this.ctx,lineIndex)):boundaries.leftOffset,m=this.calcTransformMatrix(),p={x:boundaries.left+leftOffset,y:boundaries.top+boundaries.topOffset+charHeight};this.hiddenTextarea.style.fontSize=charHeight+"px";return fabric.util.transformPoint(p,m)},_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(){if(!this._savedProps){return}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;if(this.canvas){this.canvas.defaultCursor=this._savedProps.defaultCursor;this.canvas.moveCursor=this._savedProps.moveCursor}},exitEditing:function(){this.selected=false;this.isEditing=false;this.selectable=true;this.selectionEnd=this.selectionStart;this.hiddenTextarea&&this.canvas&&this.hiddenTextarea.parentNode.removeChild(this.hiddenTextarea);this.hiddenTextarea=null;this.abortCursorAnimation();this._restoreEditingProps();this._currentCursorOpacity=0;this.fire("editing:exited");this.canvas&&this.canvas.fire("text:editing:exited",{target:this});return this},_removeExtraneousStyles:function(){for(var prop in this.styles){if(!this._textLines[prop]){delete this.styles[prop]}}},_removeCharsFromTo:function(start,end){while(end!==start){this._removeSingleCharAndStyle(start+1);end--}this.setSelectionStart(start)},_removeSingleCharAndStyle:function(index){var isBeginningOfLine=this.text[index-1]==="\n",indexStyle=isBeginningOfLine?index:index-1;this.removeStyleObject(isBeginningOfLine,indexStyle);this.text=this.text.slice(0,index-1)+this.text.slice(index);this._textLines=this._splitTextIntoLines()},insertChars:function(_chars,useCopiedStyle){var style;if(this.selectionEnd-this.selectionStart>1){this._removeCharsFromTo(this.selectionStart,this.selectionEnd);this.setSelectionEnd(this.selectionStart)}if(!useCopiedStyle&&this.isEmptyStyles()){this.insertChar(_chars,false);return}for(var i=0,len=_chars.length;i=charIndex){newLineStyles[parseInt(index,10)-charIndex]=this.styles[lineIndex][index];delete this.styles[lineIndex][index]}}this.styles[lineIndex+1]=newLineStyles}this._forceClearCache=true},insertCharStyleObject:function(lineIndex,charIndex,style){var currentLineStyles=this.styles[lineIndex],currentLineStylesCloned=clone(currentLineStyles);if(charIndex===0&&!style){charIndex=1}for(var index in currentLineStylesCloned){var numericIndex=parseInt(index,10);if(numericIndex>=charIndex){currentLineStyles[numericIndex+1]=currentLineStylesCloned[numericIndex];if(!currentLineStylesCloned[numericIndex-1]){delete currentLineStyles[numericIndex]}}}this.styles[lineIndex][charIndex]=style||clone(currentLineStyles[charIndex-1]);this._forceClearCache=true},insertStyleObjects:function(_chars,isEndOfLine,styleObject){var cursorLocation=this.get2DCursorLocation(),lineIndex=cursorLocation.lineIndex,charIndex=cursorLocation.charIndex;if(!this._getLineStyle(lineIndex)){this._setLineStyle(lineIndex,{})}if(_chars==="\n"){this.insertNewlineStyleObject(lineIndex,charIndex,isEndOfLine)}else{this.insertCharStyleObject(lineIndex,charIndex,styleObject)}},shiftLineStyles:function(lineIndex,offset){var clonedStyles=clone(this.styles);for(var line in this.styles){var numericLine=parseInt(line,10);if(numericLine>lineIndex){this.styles[numericLine+offset]=clonedStyles[numericLine];if(!clonedStyles[numericLine-offset]){delete this.styles[numericLine]}}}},removeStyleObject:function(isBeginningOfLine,index){var cursorLocation=this.get2DCursorLocation(index),lineIndex=cursorLocation.lineIndex,charIndex=cursorLocation.charIndex;this._removeStyleObject(isBeginningOfLine,cursorLocation,lineIndex,charIndex)},_getTextOnPreviousLine:function(lIndex){return this._textLines[lIndex-1]},_removeStyleObject:function(isBeginningOfLine,cursorLocation,lineIndex,charIndex){if(isBeginningOfLine){var textOnPreviousLine=this._getTextOnPreviousLine(cursorLocation.lineIndex),newCharIndexOnPrevLine=textOnPreviousLine?textOnPreviousLine.length:0;if(!this.styles[lineIndex-1]){this.styles[lineIndex-1]={}}for(charIndex in this.styles[lineIndex]){this.styles[lineIndex-1][parseInt(charIndex,10)+newCharIndexOnPrevLine]=this.styles[lineIndex][charIndex]}this.shiftLineStyles(cursorLocation.lineIndex,-1)}else{var currentLineStyles=this.styles[lineIndex];if(currentLineStyles){delete currentLineStyles[charIndex]}var currentLineStylesCloned=clone(currentLineStyles);for(var i in currentLineStylesCloned){var numericIndex=parseInt(i,10);if(numericIndex>=charIndex&&numericIndex!==0){currentLineStyles[numericIndex-1]=currentLineStylesCloned[numericIndex];delete currentLineStyles[numericIndex]}}}},insertNewline:function(){this.insertChars("\n")}})})();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(options){this.__newClickTime=+new Date;var newPointer=this.canvas.getPointer(options.e);if(this.isTripleClick(newPointer)){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;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},_stopEvent:function(e){e.preventDefault&&e.preventDefault();e.stopPropagation&&e.stopPropagation()},initCursorSelectionHandlers:function(){this.initSelectedHandler();this.initMousedownHandler();this.initMouseupHandler();this.initClicks()},initClicks:function(){this.on("dblclick",function(options){this.selectWord(this.getSelectionStartFromPointer(options.e))});this.on("tripleclick",function(options){this.selectLine(this.getSelectionStartFromPointer(options.e))})},initMousedownHandler:function(){this.on("mousedown",function(options){if(!this.editable){return}var pointer=this.canvas.getPointer(options.e);this.__mousedownX=pointer.x;this.__mousedownY=pointer.y;this.__isMousedown=true;if(this.hiddenTextarea&&this.canvas){this.canvas.wrapperEl.appendChild(this.hiddenTextarea)}if(this.selected){this.setCursorByClick(options.e)}if(this.isEditing){this.__selectionStartOnMouseDown=this.selectionStart;this.initDelayedCursor(true)}})},_isObjectMoved:function(e){var pointer=this.canvas.getPointer(e);return this.__mousedownX!==pointer.x||this.__mousedownY!==pointer.y},initMouseupHandler:function(){this.on("mouseup",function(options){this.__isMousedown=false;if(!this.editable||this._isObjectMoved(options.e)){return}if(this.__lastSelected&&!this.__corner){this.enterEditing(options.e);this.initDelayedCursor(true)}this.selected=true})},setCursorByClick:function(e){var newSelectionStart=this.getSelectionStartFromPointer(e);if(e.shiftKey){if(newSelectionStartdistanceBtwLastCharAndCursor?0:1,newSelectionStart=index+offset;if(this.flipX){newSelectionStart=jlen-newSelectionStart}if(newSelectionStart>this.text.length){newSelectionStart=this.text.length}return newSelectionStart}});fabric.util.object.extend(fabric.IText.prototype,{initHiddenTextarea:function(e){var p;if(e&&this.canvas){p=this.canvas.getPointer(e)}else{this.oCoords||this.setCoords();p=this.oCoords.tl}this.hiddenTextarea=fabric.document.createElement("textarea");this.hiddenTextarea.setAttribute("autocapitalize","off");this.hiddenTextarea.style.cssText="position: absolute; top: "+p.y+"px; left: "+p.x+"px; opacity: 0;"+" width: 0px; height: 0px; z-index: -999;";if(this.canvas){this.canvas.lowerCanvasEl.parentNode.appendChild(this.hiddenTextarea)}else{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.cut.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));if(!this._clickHandlerInitialized&&this.canvas){fabric.util.addListener(this.canvas.upperCanvasEl,"click",this.onClick.bind(this));this._clickHandlerInitialized=true}},_keysMap:{8:"removeChars",9:"exitEditing",27:"exitEditing",13:"insertNewline",33:"moveCursorUp",34:"moveCursorDown",35:"moveCursorRight",36:"moveCursorLeft",37:"moveCursorLeft",38:"moveCursorUp",39:"moveCursorRight",40:"moveCursorDown",46:"forwardDelete"},_ctrlKeysMap:{65:"selectAll",67:"copy",88:"cut"},onClick:function(){this.hiddenTextarea&&this.hiddenTextarea.focus()},onKeyDown:function(e){if(!this.isEditing){return}if(e.keyCode in this._keysMap){this[this._keysMap[e.keyCode]](e)}else{return}e.stopImmediatePropagation();e.preventDefault();this.canvas&&this.canvas.renderAll()},onKeyUp:function(e){if(!this.isEditing||this._copyDone){this._copyDone=false;return}if(e.keyCode in this._ctrlKeysMap&&(e.ctrlKey||e.metaKey)){this[this._ctrlKeysMap[e.keyCode]](e)}else{return}e.stopImmediatePropagation();e.preventDefault();this.canvas&&this.canvas.renderAll()},onInput:function(e){if(!this.isEditing||this.inCompositionMode){return}var offset=this.selectionStart||0,offsetEnd=this.selectionEnd||0,textLength=this.text.length,newTextLength=this.hiddenTextarea.value.length,diff,charsToInsert,start;if(newTextLength>textLength){start=this._selectionDirection==="left"?offsetEnd:offset;diff=newTextLength-textLength;charsToInsert=this.hiddenTextarea.value.slice(start,start+diff)}else{diff=newTextLength-textLength+offsetEnd-offset;charsToInsert=this.hiddenTextarea.value.slice(offset,offset+diff)}this.insertChars(charsToInsert);e.stopPropagation()},onCompositionStart:function(){this.inCompositionMode=true;this.prevCompositionLength=0;this.compositionStart=this.selectionStart},onCompositionEnd:function(){this.inCompositionMode=false},onCompositionUpdate:function(e){var data=e.data;this.selectionStart=this.compositionStart;this.selectionEnd=this.selectionEnd===this.selectionStart?this.compositionStart+this.prevCompositionLength:this.selectionEnd;this.insertChars(data,false);this.prevCompositionLength=data.length},forwardDelete:function(e){if(this.selectionStart===this.selectionEnd){if(this.selectionStart===this.text.length){return}this.moveCursorRight(e)}this.removeChars(e)},copy:function(e){if(this.selectionStart===this.selectionEnd){return}var selectedText=this.getSelectedText(),clipboardData=this._getClipboardData(e);if(clipboardData){clipboardData.setData("text",selectedText)}fabric.copiedText=selectedText;fabric.copiedTextStyle=this.getSelectionStyles(this.selectionStart,this.selectionEnd);e.stopImmediatePropagation();e.preventDefault();this._copyDone=true},paste:function(e){var copiedText=null,clipboardData=this._getClipboardData(e),useCopiedStyle=true;if(clipboardData){copiedText=clipboardData.getData("text").replace(/\r/g,"");if(!fabric.copiedTextStyle||fabric.copiedText!==copiedText){useCopiedStyle=false}}else{copiedText=fabric.copiedText}if(copiedText){this.insertChars(copiedText,useCopiedStyle)}e.stopImmediatePropagation();e.preventDefault()},cut:function(e){if(this.selectionStart===this.selectionEnd){return}this.copy(e);this.removeChars(e)},_getClipboardData:function(e){return e&&e.clipboardData||fabric.window.clipboardData},getDownCursorOffset:function(e,isRight){var selectionProp=isRight?this.selectionEnd:this.selectionStart,cursorLocation=this.get2DCursorLocation(selectionProp),_char,lineLeftOffset,lineIndex=cursorLocation.lineIndex,textOnSameLineBeforeCursor=this._textLines[lineIndex].slice(0,cursorLocation.charIndex),textOnSameLineAfterCursor=this._textLines[lineIndex].slice(cursorLocation.charIndex),textOnNextLine=this._textLines[lineIndex+1]||"";if(lineIndex===this._textLines.length-1||e.metaKey||e.keyCode===34){return this.text.length-selectionProp}var widthOfSameLineBeforeCursor=this._getLineWidth(this.ctx,lineIndex);lineLeftOffset=this._getLineLeftOffset(widthOfSameLineBeforeCursor);var widthOfCharsOnSameLineBeforeCursor=lineLeftOffset;for(var i=0,len=textOnSameLineBeforeCursor.length;iwidthOfCharsOnSameLineBeforeCursor){foundMatch=true;var leftEdge=widthOfCharsOnNextLine-widthOfChar,rightEdge=widthOfCharsOnNextLine,offsetFromLeftEdge=Math.abs(leftEdge-widthOfCharsOnSameLineBeforeCursor),offsetFromRightEdge=Math.abs(rightEdge-widthOfCharsOnSameLineBeforeCursor);indexOnNextLine=offsetFromRightEdgethis.text.length){this.setSelectionEnd(this.text.length)}},getUpCursorOffset:function(e,isRight){var selectionProp=isRight?this.selectionEnd:this.selectionStart,cursorLocation=this.get2DCursorLocation(selectionProp),lineIndex=cursorLocation.lineIndex;if(lineIndex===0||e.metaKey||e.keyCode===33){return selectionProp}var textOnSameLineBeforeCursor=this._textLines[lineIndex].slice(0,cursorLocation.charIndex),textOnPreviousLine=this._textLines[lineIndex-1]||"",_char,widthOfSameLineBeforeCursor=this._getLineWidth(this.ctx,cursorLocation.lineIndex),lineLeftOffset=this._getLineLeftOffset(widthOfSameLineBeforeCursor),widthOfCharsOnSameLineBeforeCursor=lineLeftOffset;for(var i=0,len=textOnSameLineBeforeCursor.length;iwidthOfCharsOnSameLineBeforeCursor){foundMatch=true;var leftEdge=widthOfCharsOnPreviousLine-widthOfChar,rightEdge=widthOfCharsOnPreviousLine,offsetFromLeftEdge=Math.abs(leftEdge-widthOfCharsOnSameLineBeforeCursor),offsetFromRightEdge=Math.abs(rightEdge-widthOfCharsOnSameLineBeforeCursor);indexOnPrevLine=offsetFromRightEdge=this.text.length&&this.selectionEnd>=this.text.length){return}this.abortCursorAnimation();this._currentCursorOpacity=1;if(e.shiftKey){this.moveCursorRightWithShift(e)}else{this.moveCursorRightWithoutShift(e)}this.initDelayedCursor()},moveCursorRightWithShift:function(e){if(this._selectionDirection==="left"&&this.selectionStart!==this.selectionEnd){this._moveRight(e,"selectionStart")}else{this._selectionDirection="right";this._moveRight(e,"selectionEnd")}},moveCursorRightWithoutShift:function(e){this._selectionDirection="right";if(this.selectionStart===this.selectionEnd){this._moveRight(e,"selectionStart");this.setSelectionEnd(this.selectionStart)}else{this.setSelectionEnd(this.selectionEnd+this.getNumNewLinesInSelectedText());this.setSelectionStart(this.selectionEnd)}},removeChars:function(e){if(this.selectionStart===this.selectionEnd){this._removeCharsNearCursor(e)}else{this._removeCharsFromTo(this.selectionStart,this.selectionEnd)}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(e){if(this.selectionStart===0){return}if(e.metaKey){var leftLineBoundary=this.findLineBoundaryLeft(this.selectionStart);this._removeCharsFromTo(leftLineBoundary,this.selectionStart);this.setSelectionStart(leftLineBoundary)}else if(e.altKey){var leftWordBoundary=this.findWordBoundaryLeft(this.selectionStart);this._removeCharsFromTo(leftWordBoundary,this.selectionStart);this.setSelectionStart(leftWordBoundary)}else{this._removeSingleCharAndStyle(this.selectionStart);this.setSelectionStart(this.selectionStart-1)}}});(function(){var toFixed=fabric.util.toFixed,NUM_FRACTION_DIGITS=fabric.Object.NUM_FRACTION_DIGITS;fabric.util.object.extend(fabric.IText.prototype,{_setSVGTextLineText:function(lineIndex,textSpans,height,textLeftOffset,textTopOffset,textBgRects){if(!this._getLineStyle(lineIndex)){fabric.Text.prototype._setSVGTextLineText.call(this,lineIndex,textSpans,height,textLeftOffset,textTopOffset)}else{this._setSVGTextLineChars(lineIndex,textSpans,height,textLeftOffset,textBgRects)}},_setSVGTextLineChars:function(lineIndex,textSpans,height,textLeftOffset,textBgRects){var chars=this._textLines[lineIndex],charOffset=0,lineLeftOffset=this._getLineLeftOffset(this._getLineWidth(this.ctx,lineIndex))-this.width/2,lineOffset=this._getSVGLineTopOffset(lineIndex),heightOfLine=this._getHeightOfLine(this.ctx,lineIndex);for(var i=0,len=chars.length;i\n'].join("")},_createTextCharSpan:function(_char,styleDecl,lineLeftOffset,lineTopOffset,charOffset){var fillStyles=this.getSvgStyles.call(fabric.util.object.extend({visible:true,fill:this.fill,stroke:this.stroke,type:"text",getSvgFilter:fabric.Object.prototype.getSvgFilter},styleDecl));return[' ',fabric.util.string.escapeXml(_char),"\n"].join("")}})})();(function(global){"use strict";var fabric=global.fabric||(global.fabric={}),clone=fabric.util.object.clone;fabric.Textbox=fabric.util.createClass(fabric.IText,fabric.Observable,{type:"textbox",minWidth:20,dynamicMinWidth:0,__cachedLines:null,initialize:function(text,options){this.ctx=fabric.util.createCanvasElement().getContext("2d");this.callSuper("initialize",text,options);this.set({lockUniScaling:false,lockScalingY:true,lockScalingFlip:true,hasBorders:true});this.setControlsVisibility(fabric.Textbox.getTextboxControlVisibility());this._dimensionAffectingProps.width=true},_initDimensions:function(ctx){if(this.__skipDimension){return}if(!ctx){ctx=fabric.util.createCanvasElement().getContext("2d");this._setTextStyles(ctx)}this.dynamicMinWidth=0;this._textLines=this._splitTextIntoLines();if(this.dynamicMinWidth>this.width){this._set("width",this.dynamicMinWidth)}this._clearCache();this.height=this._getTextHeight(ctx)},_generateStyleMap:function(){var realLineCount=0,realLineCharCount=0,charCount=0,map={};for(var i=0;i=this.width&&!lineJustStarted){lines.push(line);line="";lineWidth=wordWidth;lineJustStarted=true}if(!lineJustStarted){line+=infix}line+=word;infixWidth=this._measureText(ctx,infix,lineIndex,offset);offset++;lineJustStarted=false;if(wordWidth>largestWordWidth){largestWordWidth=wordWidth}}i&&lines.push(line);if(largestWordWidth>this.dynamicMinWidth){this.dynamicMinWidth=largestWordWidth}return lines},_splitTextIntoLines:function(){var originalAlign=this.textAlign;this.ctx.save();this._setTextStyles(this.ctx);this.textAlign="left";var lines=this._wrapText(this.ctx,this.text);this.textAlign=originalAlign;this.ctx.restore();this._textLines=lines;this._styleMap=this._generateStyleMap();return lines},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}},get2DCursorLocation:function(selectionStart){if(typeof selectionStart==="undefined"){selectionStart=this.selectionStart}var numLines=this._textLines.length,removed=0;for(var i=0;i=t.getMinWidth()){t.set("width",w);return true}}else{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}}};var clone=fabric.util.object.clone;fabric.util.object.extend(fabric.Textbox.prototype,{_removeExtraneousStyles:function(){for(var prop in this._styleMap){if(!this._textLines[prop]){delete this.styles[this._styleMap[prop].line]}}},insertCharStyleObject:function(lineIndex,charIndex,style){var map=this._styleMap[lineIndex];lineIndex=map.line;charIndex=map.offset+charIndex;fabric.IText.prototype.insertCharStyleObject.apply(this,[lineIndex,charIndex,style])},insertNewlineStyleObject:function(lineIndex,charIndex,isEndOfLine){var map=this._styleMap[lineIndex];lineIndex=map.line;charIndex=map.offset+charIndex;fabric.IText.prototype.insertNewlineStyleObject.apply(this,[lineIndex,charIndex,isEndOfLine])},shiftLineStyles:function(lineIndex,offset){var clonedStyles=clone(this.styles),map=this._styleMap[lineIndex];lineIndex=map.line;for(var line in this.styles){var numericLine=parseInt(line,10);if(numericLine>lineIndex){this.styles[numericLine+offset]=clonedStyles[numericLine];if(!clonedStyles[numericLine-offset]){delete this.styles[numericLine]}}}},_getTextOnPreviousLine:function(lIndex){var textOnPreviousLine=this._textLines[lIndex-1];while(this._styleMap[lIndex-2]&&this._styleMap[lIndex-2].line===this._styleMap[lIndex-1].line){textOnPreviousLine=this._textLines[lIndex-2]+textOnPreviousLine;lIndex--}return textOnPreviousLine},removeStyleObject:function(isBeginningOfLine,index){var cursorLocation=this.get2DCursorLocation(index),map=this._styleMap[cursorLocation.lineIndex],lineIndex=map.line,charIndex=map.offset+cursorLocation.charIndex;this._removeStyleObject(isBeginningOfLine,cursorLocation,lineIndex,charIndex)}})})();(function(){var override=fabric.IText.prototype._getNewSelectionStartFromOffset;fabric.IText.prototype._getNewSelectionStartFromOffset=function(mouseOffset,prevWidth,width,index,jlen){index=override.call(this,mouseOffset,prevWidth,width,index,jlen);var tmp=0,removed=0;for(var i=0;i=index){break}if(this.text[tmp+removed]==="\n"||this.text[tmp+removed]===" "){removed++}}return index-i+removed}})();(function(){if(typeof document!=="undefined"&&typeof window!=="undefined"){return}var DOMParser=require("xmldom").DOMParser,URL=require("url"),HTTP=require("http"),HTTPS=require("https"),Canvas=require("canvas"),Image=require("canvas").Image;function request(url,encoding,callback){var oURL=URL.parse(url);if(!oURL.port){oURL.port=oURL.protocol.indexOf("https:")===0?443:80}var reqHandler=oURL.protocol.indexOf("https:")===0?HTTPS:HTTP,req=reqHandler.request({hostname:oURL.hostname,port:oURL.port,path:oURL.path,method:"GET"},function(response){var body="";if(encoding){response.setEncoding(encoding)}response.on("end",function(){callback(body)});response.on("data",function(chunk){if(response.statusCode===200){body+=chunk}})});req.on("error",function(err){if(err.errno===process.ECONNREFUSED){fabric.log("ECONNREFUSED: connection refused to "+oURL.hostname+":"+oURL.port)}else{fabric.log(err.message)}callback(null)});req.end()}function requestFs(path,callback){var fs=require("fs");fs.readFile(path,function(err,data){if(err){fabric.log(err);throw err}else{callback(data)}})}fabric.util.loadImage=function(url,callback,context){function createImageAndCallBack(data){if(data){img.src=new Buffer(data,"binary");img._src=url;callback&&callback.call(context,img)}else{img=null;callback&&callback.call(context,null,true)}}var img=new Image;if(url&&(url instanceof Buffer||url.indexOf("data")===0)){img.src=img._src=url;callback&&callback.call(context,img)}else if(url&&url.indexOf("http")!==0){requestFs(url,createImageAndCallBack)}else if(url){request(url,"binary",createImageAndCallBack)}else{callback&&callback.call(context,url)}};fabric.loadSVGFromURL=function(url,callback,reviver){url=url.replace(/^\n\s*/,"").replace(/\?.*$/,"").trim();if(url.indexOf("http")!==0){requestFs(url,function(body){fabric.loadSVGFromString(body.toString(),callback,reviver)})}else{request(url,"",function(body){fabric.loadSVGFromString(body,callback,reviver)})}};fabric.loadSVGFromString=function(string,callback,reviver){var doc=(new DOMParser).parseFromString(string);fabric.parseSVGDocument(doc.documentElement,function(results,options){callback&&callback(results,options)},reviver)};fabric.util.getScript=function(url,callback){request(url,"",function(body){eval(body);callback&&callback()})};fabric.Image.fromObject=function(object,callback){fabric.util.loadImage(object.src,function(img){var oImg=new fabric.Image(img);oImg._initConfig(object);oImg._initFilters(object.filters,function(filters){oImg.filters=filters||[];oImg._initFilters(object.resizeFilters,function(resizeFilters){oImg.resizeFilters=resizeFilters||[];callback&&callback(oImg)})})})};fabric.createCanvasForNode=function(width,height,options,nodeCanvasOptions){nodeCanvasOptions=nodeCanvasOptions||options;var canvasEl=fabric.document.createElement("canvas"),nodeCanvas=new Canvas(width||600,height||600,nodeCanvasOptions);canvasEl.style={};canvasEl.width=nodeCanvas.width;canvasEl.height=nodeCanvas.height;var FabricCanvas=fabric.Canvas||fabric.StaticCanvas,fabricCanvas=new FabricCanvas(canvasEl,options);fabricCanvas.contextContainer=nodeCanvas.getContext("2d");fabricCanvas.nodeCanvas=nodeCanvas;fabricCanvas.Font=Canvas.Font;return fabricCanvas};fabric.StaticCanvas.prototype.createPNGStream=function(){return this.nodeCanvas.createPNGStream()};fabric.StaticCanvas.prototype.createJPEGStream=function(opts){return this.nodeCanvas.createJPEGStream(opts)};var origSetWidth=fabric.StaticCanvas.prototype.setWidth;fabric.StaticCanvas.prototype.setWidth=function(width,options){origSetWidth.call(this,width,options);this.nodeCanvas.width=width;return this};if(fabric.Canvas){fabric.Canvas.prototype.setWidth=fabric.StaticCanvas.prototype.setWidth}var origSetHeight=fabric.StaticCanvas.prototype.setHeight;fabric.StaticCanvas.prototype.setHeight=function(height,options){origSetHeight.call(this,height,options);this.nodeCanvas.height=height;return this};if(fabric.Canvas){fabric.Canvas.prototype.setHeight=fabric.StaticCanvas.prototype.setHeight}})(); \ No newline at end of file diff --git a/dist/fabric.min.js.gz b/dist/fabric.min.js.gz index 4f04c711..7fe29032 100644 Binary files a/dist/fabric.min.js.gz and b/dist/fabric.min.js.gz differ diff --git a/dist/fabric.require.js b/dist/fabric.require.js index 24244cf3..5ff17737 100644 --- a/dist/fabric.require.js +++ b/dist/fabric.require.js @@ -1,11895 +1,11 @@ -var fabric = fabric || { - version: "1.6.0-rc.1" -}; - -if (typeof exports !== "undefined") { - exports.fabric = fabric; -} - -if (typeof document !== "undefined" && typeof window !== "undefined") { - fabric.document = document; - fabric.window = window; - window.fabric = fabric; -} else { - fabric.document = require("jsdom").jsdom(""); - if (fabric.document.createWindow) { - fabric.window = fabric.document.createWindow(); - } else { - fabric.window = fabric.document.parentWindow; - } -} - -fabric.isTouchSupported = "ontouchstart" in fabric.document.documentElement; - -fabric.isLikelyNode = typeof Buffer !== "undefined" && typeof window === "undefined"; - -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.devicePixelRatio = fabric.window.devicePixelRatio || fabric.window.webkitDevicePixelRatio || fabric.window.mozDevicePixelRatio || 1; - -(function() { - function _removeEventListener(eventName, handler) { - if (!this.__eventListeners[eventName]) { - return; - } - var eventListener = this.__eventListeners[eventName]; - if (handler) { - eventListener[eventListener.indexOf(handler)] = false; - } else { - fabric.util.array.fill(eventListener, false); - } - } - function observe(eventName, handler) { - if (!this.__eventListeners) { - this.__eventListeners = {}; - } - if (arguments.length === 1) { - for (var prop in eventName) { - this.on(prop, eventName[prop]); - } - } else { - if (!this.__eventListeners[eventName]) { - this.__eventListeners[eventName] = []; - } - this.__eventListeners[eventName].push(handler); - } - return this; - } - function stopObserving(eventName, handler) { - if (!this.__eventListeners) { - return; - } - if (arguments.length === 0) { - for (eventName in this.__eventListeners) { - _removeEventListener.call(this, eventName); - } - } else if (arguments.length === 1 && typeof arguments[0] === "object") { - for (var prop in eventName) { - _removeEventListener.call(this, prop, eventName[prop]); - } - } else { - _removeEventListener.call(this, eventName, handler); - } - return this; - } - function fire(eventName, options) { - if (!this.__eventListeners) { - return; - } - var listenersForEvent = this.__eventListeners[eventName]; - if (!listenersForEvent) { - return; - } - for (var i = 0, len = listenersForEvent.length; i < len; i++) { - listenersForEvent[i] && listenersForEvent[i].call(this, options || {}); - } - this.__eventListeners[eventName] = listenersForEvent.filter(function(value) { - return value !== false; - }); - return this; - } - fabric.Observable = { - observe: observe, - stopObserving: stopObserving, - fire: fire, - on: observe, - off: stopObserving, - trigger: fire - }; -})(); - -fabric.Collection = { - add: function() { - this._objects.push.apply(this._objects, arguments); - for (var i = 0, length = arguments.length; i < length; i++) { - this._onObjectAdded(arguments[i]); - } - this.renderOnAddRemove && this.renderAll(); - return this; - }, - insertAt: function(object, index, nonSplicing) { - var objects = this.getObjects(); - if (nonSplicing) { - objects[index] = object; - } else { - objects.splice(index, 0, object); - } - this._onObjectAdded(object); - this.renderOnAddRemove && this.renderAll(); - return this; - }, - remove: function() { - var objects = this.getObjects(), index; - for (var i = 0, length = arguments.length; i < length; i++) { - index = objects.indexOf(arguments[i]); - if (index !== -1) { - objects.splice(index, 1); - this._onObjectRemoved(arguments[i]); - } - } - this.renderOnAddRemove && this.renderAll(); - return this; - }, - forEachObject: function(callback, context) { - var objects = this.getObjects(), i = objects.length; - while (i--) { - callback.call(context, objects[i], i, objects); - } - return this; - }, - getObjects: function(type) { - if (typeof type === "undefined") { - return this._objects; - } - return this._objects.filter(function(o) { - return o.type === type; - }); - }, - item: function(index) { - return this.getObjects()[index]; - }, - isEmpty: function() { - return this.getObjects().length === 0; - }, - size: function() { - return this.getObjects().length; - }, - contains: function(object) { - return this.getObjects().indexOf(object) > -1; - }, - complexity: function() { - return this.getObjects().reduce(function(memo, current) { - memo += current.complexity ? current.complexity() : 0; - return memo; - }, 0); - } -}; - -(function(global) { - var sqrt = Math.sqrt, atan2 = Math.atan2, pow = Math.pow, abs = Math.abs, PiBy180 = Math.PI / 180; - fabric.util = { - removeFromArray: function(array, value) { - var idx = array.indexOf(value); - if (idx !== -1) { - array.splice(idx, 1); - } - return array; - }, - getRandomInt: function(min, max) { - return Math.floor(Math.random() * (max - min + 1)) + min; - }, - degreesToRadians: function(degrees) { - return degrees * PiBy180; - }, - radiansToDegrees: function(radians) { - return radians / PiBy180; - }, - rotatePoint: function(point, origin, radians) { - point.subtractEquals(origin); - var v = fabric.util.rotateVector(point, radians); - return new fabric.Point(v.x, v.y).addEquals(origin); - }, - rotateVector: function(vector, radians) { - var sin = Math.sin(radians), cos = Math.cos(radians), rx = vector.x * cos - vector.y * sin, ry = vector.x * sin + vector.y * cos; - return { - x: rx, - y: ry - }; - }, - transformPoint: function(p, t, ignoreOffset) { - if (ignoreOffset) { - return new fabric.Point(t[0] * p.x + t[2] * p.y, t[1] * p.x + t[3] * p.y); - } - return new fabric.Point(t[0] * p.x + t[2] * p.y + t[4], t[1] * p.x + t[3] * p.y + t[5]); - }, - makeBoundingBoxFromPoints: function(points) { - var xPoints = [ points[0].x, points[1].x, points[2].x, points[3].x ], minX = fabric.util.array.min(xPoints), maxX = fabric.util.array.max(xPoints), width = Math.abs(minX - maxX), yPoints = [ points[0].y, points[1].y, points[2].y, points[3].y ], minY = fabric.util.array.min(yPoints), maxY = fabric.util.array.max(yPoints), height = Math.abs(minY - maxY); - return { - left: minX, - top: minY, - width: width, - height: height - }; - }, - invertTransform: function(t) { - var a = 1 / (t[0] * t[3] - t[1] * t[2]), r = [ a * t[3], -a * t[1], -a * t[2], a * t[0] ], o = fabric.util.transformPoint({ - x: t[4], - y: t[5] - }, r, true); - r[4] = -o.x; - r[5] = -o.y; - return r; - }, - toFixed: function(number, fractionDigits) { - return parseFloat(Number(number).toFixed(fractionDigits)); - }, - parseUnit: function(value, fontSize) { - var unit = /\D{0,2}$/.exec(value), number = parseFloat(value); - if (!fontSize) { - fontSize = fabric.Text.DEFAULT_SVG_FONT_SIZE; - } - switch (unit[0]) { - case "mm": - return number * fabric.DPI / 25.4; - - case "cm": - return number * fabric.DPI / 2.54; - - case "in": - return number * fabric.DPI; - - case "pt": - return number * fabric.DPI / 72; - - case "pc": - return number * fabric.DPI / 72 * 12; - - case "em": - return number * fontSize; - - default: - return number; - } - }, - falseFunction: function() { - return false; - }, - getKlass: function(type, namespace) { - type = fabric.util.string.camelize(type.charAt(0).toUpperCase() + type.slice(1)); - return fabric.util.resolveNamespace(namespace)[type]; - }, - resolveNamespace: function(namespace) { - if (!namespace) { - return fabric; - } - var parts = namespace.split("."), len = parts.length, obj = global || fabric.window; - for (var i = 0; i < len; ++i) { - obj = obj[parts[i]]; - } - return obj; - }, - loadImage: function(url, callback, context, crossOrigin) { - if (!url) { - callback && callback.call(context, url); - return; - } - var img = fabric.util.createImage(); - img.onload = function() { - callback && callback.call(context, img); - img = img.onload = img.onerror = null; - }; - img.onerror = function() { - fabric.log("Error loading " + img.src); - callback && callback.call(context, null, true); - img = img.onload = img.onerror = null; - }; - if (url.indexOf("data") !== 0 && crossOrigin) { - img.crossOrigin = crossOrigin; - } - img.src = url; - }, - enlivenObjects: function(objects, callback, namespace, reviver) { - objects = objects || []; - function onLoaded() { - if (++numLoadedObjects === numTotalObjects) { - callback && callback(enlivenedObjects); - } - } - var enlivenedObjects = [], numLoadedObjects = 0, numTotalObjects = objects.length; - if (!numTotalObjects) { - callback && callback(enlivenedObjects); - return; - } - objects.forEach(function(o, index) { - if (!o || !o.type) { - onLoaded(); - return; - } - var klass = fabric.util.getKlass(o.type, namespace); - if (klass.async) { - klass.fromObject(o, function(obj, error) { - if (!error) { - enlivenedObjects[index] = obj; - reviver && reviver(o, enlivenedObjects[index]); - } - onLoaded(); - }); - } else { - enlivenedObjects[index] = klass.fromObject(o); - reviver && reviver(o, enlivenedObjects[index]); - onLoaded(); - } - }); - }, - groupSVGElements: function(elements, options, path) { - var object; - object = new fabric.PathGroup(elements, options); - if (typeof path !== "undefined") { - object.setSourcePath(path); - } - return object; - }, - populateWithProperties: function(source, destination, properties) { - if (properties && Object.prototype.toString.call(properties) === "[object Array]") { - for (var i = 0, len = properties.length; i < len; i++) { - if (properties[i] in source) { - destination[properties[i]] = source[properties[i]]; - } - } - } - }, - drawDashedLine: function(ctx, x, y, x2, y2, da) { - var dx = x2 - x, dy = y2 - y, len = sqrt(dx * dx + dy * dy), rot = atan2(dy, dx), dc = da.length, di = 0, draw = true; - ctx.save(); - ctx.translate(x, y); - ctx.moveTo(0, 0); - ctx.rotate(rot); - x = 0; - while (len > x) { - x += da[di++ % dc]; - if (x > len) { - x = len; - } - ctx[draw ? "lineTo" : "moveTo"](x, 0); - draw = !draw; - } - ctx.restore(); - }, - createCanvasElement: function(canvasEl) { - canvasEl || (canvasEl = fabric.document.createElement("canvas")); - if (!canvasEl.getContext && typeof G_vmlCanvasManager !== "undefined") { - G_vmlCanvasManager.initElement(canvasEl); - } - return canvasEl; - }, - createImage: function() { - return fabric.isLikelyNode ? new (require("canvas").Image)() : fabric.document.createElement("img"); - }, - createAccessors: function(klass) { - var proto = klass.prototype; - for (var i = proto.stateProperties.length; i--; ) { - var 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(); - receiver.clipTo(ctx); - ctx.clip(); - }, - multiplyTransformMatrices: function(a, b, is2x2) { - return [ a[0] * b[0] + a[2] * b[1], a[1] * b[0] + a[3] * b[1], a[0] * b[2] + a[2] * b[3], a[1] * b[2] + a[3] * b[3], is2x2 ? 0 : a[0] * b[4] + a[2] * b[5] + a[4], is2x2 ? 0 : a[1] * b[4] + a[3] * b[5] + a[5] ]; - }, - qrDecompose: function(a) { - var angle = atan2(a[1], a[0]), denom = pow(a[0], 2) + pow(a[1], 2), scaleX = sqrt(denom), scaleY = (a[0] * a[3] - a[2] * a[1]) / scaleX, skewX = atan2(a[0] * a[2] + a[1] * a[3], denom); - return { - angle: angle / PiBy180, - scaleX: scaleX, - scaleY: scaleY, - skewX: skewX / PiBy180, - skewY: 0, - translateX: a[4], - translateY: a[5] - }; - }, - customTransformMatrix: function(scaleX, scaleY, skewX) { - var skewMatrixX = [ 1, 0, abs(Math.tan(skewX * PiBy180)), 1 ], scaleMatrix = [ abs(scaleX), 0, 0, abs(scaleY) ]; - return fabric.util.multiplyTransformMatrices(scaleMatrix, skewMatrixX, true); - }, - resetObjectTransform: function(target) { - target.scaleX = 1; - target.scaleY = 1; - target.skewX = 0; - target.skewY = 0; - target.flipX = false; - target.flipY = false; - target.setAngle(0); - }, - getFunctionBody: function(fn) { - return (String(fn).match(/function[^{]*\{([\s\S]*)\}/) || {})[1]; - }, - isTransparent: function(ctx, x, y, tolerance) { - if (tolerance > 0) { - if (x > tolerance) { - x -= tolerance; - } else { - x = 0; - } - if (y > tolerance) { - y -= tolerance; - } else { - y = 0; - } - } - var _isTransparent = true, imageData = ctx.getImageData(x, y, tolerance * 2 || 1, tolerance * 2 || 1); - for (var i = 3, l = imageData.data.length; i < l; i += 4) { - var temp = imageData.data[i]; - _isTransparent = temp <= 0; - if (_isTransparent === false) { - break; - } - } - imageData = null; - return _isTransparent; - }, - parsePreserveAspectRatioAttribute: function(attribute) { - var meetOrSlice = "meet", alignX = "Mid", alignY = "Mid", aspectRatioAttrs = attribute.split(" "), align; - if (aspectRatioAttrs && aspectRatioAttrs.length) { - meetOrSlice = aspectRatioAttrs.pop(); - if (meetOrSlice !== "meet" && meetOrSlice !== "slice") { - align = meetOrSlice; - meetOrSlice = "meet"; - } else if (aspectRatioAttrs.length) { - align = aspectRatioAttrs.pop(); - } - } - alignX = align !== "none" ? align.slice(1, 4) : "none"; - alignY = align !== "none" ? align.slice(5, 8) : "none"; - return { - meetOrSlice: meetOrSlice, - alignX: alignX, - alignY: alignY - }; - } - }; -})(typeof exports !== "undefined" ? exports : this); - -(function() { - var arcToSegmentsCache = {}, segmentToBezierCache = {}, boundsOfCurveCache = {}, _join = Array.prototype.join; - function arcToSegments(toX, toY, rx, ry, large, sweep, rotateX) { - var argsString = _join.call(arguments); - if (arcToSegmentsCache[argsString]) { - return arcToSegmentsCache[argsString]; - } - var PI = Math.PI, th = rotateX * PI / 180, sinTh = Math.sin(th), cosTh = Math.cos(th), fromX = 0, fromY = 0; - rx = Math.abs(rx); - ry = Math.abs(ry); - var px = -cosTh * toX * .5 - sinTh * toY * .5, py = -cosTh * toY * .5 + sinTh * toX * .5, rx2 = rx * rx, ry2 = ry * ry, py2 = py * py, px2 = px * px, pl = rx2 * ry2 - rx2 * py2 - ry2 * px2, root = 0; - if (pl < 0) { - var s = Math.sqrt(1 - pl / (rx2 * ry2)); - rx *= s; - ry *= s; - } else { - root = (large === sweep ? -1 : 1) * Math.sqrt(pl / (rx2 * py2 + ry2 * px2)); - } - var cx = root * rx * py / ry, cy = -root * ry * px / rx, cx1 = cosTh * cx - sinTh * cy + toX * .5, cy1 = sinTh * cx + cosTh * cy + toY * .5, mTheta = calcVectorAngle(1, 0, (px - cx) / rx, (py - cy) / ry), dtheta = calcVectorAngle((px - cx) / rx, (py - cy) / ry, (-px - cx) / rx, (-py - cy) / ry); - if (sweep === 0 && dtheta > 0) { - dtheta -= 2 * PI; - } else if (sweep === 1 && dtheta < 0) { - dtheta += 2 * PI; - } - var segments = Math.ceil(Math.abs(dtheta / PI * 2)), result = [], mDelta = dtheta / segments, mT = 8 / 3 * Math.sin(mDelta / 4) * Math.sin(mDelta / 4) / Math.sin(mDelta / 2), th3 = mTheta + mDelta; - for (var i = 0; i < segments; i++) { - result[i] = segmentToBezier(mTheta, th3, cosTh, sinTh, rx, ry, cx1, cy1, mT, fromX, fromY); - fromX = result[i][4]; - fromY = result[i][5]; - mTheta = th3; - th3 += mDelta; - } - arcToSegmentsCache[argsString] = result; - return result; - } - function segmentToBezier(th2, th3, cosTh, sinTh, rx, ry, cx1, cy1, mT, fromX, fromY) { - var argsString2 = _join.call(arguments); - if (segmentToBezierCache[argsString2]) { - return segmentToBezierCache[argsString2]; - } - var costh2 = Math.cos(th2), sinth2 = Math.sin(th2), costh3 = Math.cos(th3), sinth3 = Math.sin(th3), toX = cosTh * rx * costh3 - sinTh * ry * sinth3 + cx1, toY = sinTh * rx * costh3 + cosTh * ry * sinth3 + cy1, cp1X = fromX + mT * (-cosTh * rx * sinth2 - sinTh * ry * costh2), cp1Y = fromY + mT * (-sinTh * rx * sinth2 + cosTh * ry * costh2), cp2X = toX + mT * (cosTh * rx * sinth3 + sinTh * ry * costh3), cp2Y = toY + mT * (sinTh * rx * sinth3 - cosTh * ry * costh3); - segmentToBezierCache[argsString2] = [ cp1X, cp1Y, cp2X, cp2Y, toX, toY ]; - return segmentToBezierCache[argsString2]; - } - function calcVectorAngle(ux, uy, vx, vy) { - var ta = Math.atan2(uy, ux), tb = Math.atan2(vy, vx); - if (tb >= ta) { - return tb - ta; - } else { - return 2 * Math.PI - (ta - tb); - } - } - fabric.util.drawArc = function(ctx, fx, fy, coords) { - var rx = coords[0], ry = coords[1], rot = coords[2], large = coords[3], sweep = coords[4], tx = coords[5], ty = coords[6], segs = [ [], [], [], [] ], segsNorm = arcToSegments(tx - fx, ty - fy, rx, ry, large, sweep, rot); - for (var i = 0, len = segsNorm.length; i < len; i++) { - segs[i][0] = segsNorm[i][0] + fx; - segs[i][1] = segsNorm[i][1] + fy; - segs[i][2] = segsNorm[i][2] + fx; - segs[i][3] = segsNorm[i][3] + fy; - segs[i][4] = segsNorm[i][4] + fx; - segs[i][5] = segsNorm[i][5] + fy; - ctx.bezierCurveTo.apply(ctx, segs[i]); - } - }; - fabric.util.getBoundsOfArc = function(fx, fy, rx, ry, rot, large, sweep, tx, ty) { - var fromX = 0, fromY = 0, bound = [], bounds = [], segs = arcToSegments(tx - fx, ty - fy, rx, ry, large, sweep, rot), boundCopy = [ [], [] ]; - for (var i = 0, len = segs.length; i < len; i++) { - bound = getBoundsOfCurve(fromX, fromY, segs[i][0], segs[i][1], segs[i][2], segs[i][3], segs[i][4], segs[i][5]); - boundCopy[0].x = bound[0].x + fx; - boundCopy[0].y = bound[0].y + fy; - boundCopy[1].x = bound[1].x + fx; - boundCopy[1].y = bound[1].y + fy; - bounds.push(boundCopy[0]); - bounds.push(boundCopy[1]); - fromX = segs[i][4]; - fromY = segs[i][5]; - } - return bounds; - }; - function getBoundsOfCurve(x0, y0, x1, y1, x2, y2, x3, y3) { - var argsString = _join.call(arguments); - if (boundsOfCurveCache[argsString]) { - return boundsOfCurveCache[argsString]; - } - var sqrt = Math.sqrt, min = Math.min, max = Math.max, abs = Math.abs, tvalues = [], bounds = [ [], [] ], a, b, c, t, t1, t2, b2ac, sqrtb2ac; - b = 6 * x0 - 12 * x1 + 6 * x2; - a = -3 * x0 + 9 * x1 - 9 * x2 + 3 * x3; - c = 3 * x1 - 3 * x0; - for (var i = 0; i < 2; ++i) { - if (i > 0) { - b = 6 * y0 - 12 * y1 + 6 * y2; - a = -3 * y0 + 9 * y1 - 9 * y2 + 3 * y3; - c = 3 * y1 - 3 * y0; - } - if (abs(a) < 1e-12) { - if (abs(b) < 1e-12) { - continue; - } - t = -c / b; - if (0 < t && t < 1) { - tvalues.push(t); - } - continue; - } - b2ac = b * b - 4 * c * a; - if (b2ac < 0) { - continue; - } - sqrtb2ac = sqrt(b2ac); - t1 = (-b + sqrtb2ac) / (2 * a); - if (0 < t1 && t1 < 1) { - tvalues.push(t1); - } - t2 = (-b - sqrtb2ac) / (2 * a); - if (0 < t2 && t2 < 1) { - tvalues.push(t2); - } - } - var x, y, j = tvalues.length, jlen = j, mt; - while (j--) { - t = tvalues[j]; - mt = 1 - t; - x = mt * mt * mt * x0 + 3 * mt * mt * t * x1 + 3 * mt * t * t * x2 + t * t * t * x3; - bounds[0][j] = x; - y = mt * mt * mt * y0 + 3 * mt * mt * t * y1 + 3 * mt * t * t * y2 + t * t * t * y3; - bounds[1][j] = y; - } - bounds[0][jlen] = x0; - bounds[1][jlen] = y0; - bounds[0][jlen + 1] = x3; - bounds[1][jlen + 1] = y3; - var result = [ { - x: min.apply(null, bounds[0]), - y: min.apply(null, bounds[1]) - }, { - x: max.apply(null, bounds[0]), - y: max.apply(null, bounds[1]) - } ]; - boundsOfCurveCache[argsString] = result; - return result; - } - fabric.util.getBoundsOfCurve = getBoundsOfCurve; -})(); - -(function() { - var slice = Array.prototype.slice; - if (!Array.prototype.indexOf) { - Array.prototype.indexOf = function(searchElement) { - if (this === void 0 || this === null) { - throw new TypeError(); - } - var t = Object(this), len = t.length >>> 0; - if (len === 0) { - return -1; - } - var n = 0; - if (arguments.length > 0) { - n = Number(arguments[1]); - if (n !== n) { - n = 0; - } else if (n !== 0 && n !== Number.POSITIVE_INFINITY && n !== Number.NEGATIVE_INFINITY) { - n = (n > 0 || -1) * Math.floor(Math.abs(n)); - } - } - if (n >= len) { - return -1; - } - var k = n >= 0 ? n : Math.max(len - Math.abs(n), 0); - for (;k < len; k++) { - if (k in t && t[k] === searchElement) { - return k; - } - } - return -1; - }; - } - if (!Array.prototype.forEach) { - Array.prototype.forEach = function(fn, context) { - for (var i = 0, len = this.length >>> 0; i < len; i++) { - if (i in this) { - fn.call(context, this[i], i, this); - } - } - }; - } - if (!Array.prototype.map) { - Array.prototype.map = function(fn, context) { - var result = []; - for (var i = 0, len = this.length >>> 0; i < len; i++) { - if (i in this) { - result[i] = fn.call(context, this[i], i, this); - } - } - return result; - }; - } - if (!Array.prototype.every) { - Array.prototype.every = function(fn, context) { - for (var i = 0, len = this.length >>> 0; i < len; i++) { - if (i in this && !fn.call(context, this[i], i, this)) { - return false; - } - } - return true; - }; - } - if (!Array.prototype.some) { - Array.prototype.some = function(fn, context) { - for (var i = 0, len = this.length >>> 0; i < len; i++) { - if (i in this && fn.call(context, this[i], i, this)) { - return true; - } - } - return false; - }; - } - if (!Array.prototype.filter) { - Array.prototype.filter = function(fn, context) { - var result = [], val; - for (var i = 0, len = this.length >>> 0; i < len; i++) { - if (i in this) { - val = this[i]; - if (fn.call(context, val, i, this)) { - result.push(val); - } - } - } - return result; - }; - } - if (!Array.prototype.reduce) { - Array.prototype.reduce = function(fn) { - var len = this.length >>> 0, i = 0, rv; - if (arguments.length > 1) { - rv = arguments[1]; - } else { - do { - if (i in this) { - rv = this[i++]; - break; - } - if (++i >= len) { - throw new TypeError(); - } - } while (true); - } - for (;i < len; i++) { - if (i in this) { - rv = fn.call(null, rv, this[i], i, this); - } - } - return rv; - }; - } - function invoke(array, method) { - var args = slice.call(arguments, 2), result = []; - for (var i = 0, len = array.length; i < len; i++) { - result[i] = args.length ? array[i][method].apply(array[i], args) : array[i][method].call(array[i]); - } - return result; - } - function max(array, byProperty) { - return find(array, byProperty, function(value1, value2) { - return value1 >= value2; - }); - } - function min(array, byProperty) { - return find(array, byProperty, function(value1, value2) { - return value1 < value2; - }); - } - function fill(array, value) { - var k = array.length; - while (k--) { - array[k] = value; - } - return array; - } - function find(array, byProperty, condition) { - if (!array || array.length === 0) { - return; - } - var i = array.length - 1, result = byProperty ? array[i][byProperty] : array[i]; - if (byProperty) { - while (i--) { - if (condition(array[i][byProperty], result)) { - result = array[i][byProperty]; - } - } - } else { - while (i--) { - if (condition(array[i], result)) { - result = array[i]; - } - } - } - return result; - } - fabric.util.array = { - fill: fill, - invoke: invoke, - min: min, - max: max - }; -})(); - -(function() { - function extend(destination, source) { - for (var property in source) { - destination[property] = source[property]; - } - return destination; - } - function clone(object) { - return extend({}, object); - } - fabric.util.object = { - extend: extend, - clone: clone - }; -})(); - -(function() { - if (!String.prototype.trim) { - String.prototype.trim = function() { - return this.replace(/^[\s\xA0]+/, "").replace(/[\s\xA0]+$/, ""); - }; - } - function camelize(string) { - return string.replace(/-+(.)?/g, function(match, character) { - return character ? character.toUpperCase() : ""; - }); - } - function capitalize(string, firstLetterOnly) { - return string.charAt(0).toUpperCase() + (firstLetterOnly ? string.slice(1) : string.slice(1).toLowerCase()); - } - function escapeXml(string) { - return string.replace(/&/g, "&").replace(/"/g, """).replace(/'/g, "'").replace(//g, ">"); - } - fabric.util.string = { - camelize: camelize, - capitalize: capitalize, - escapeXml: escapeXml - }; -})(); - -(function() { - var slice = Array.prototype.slice, apply = Function.prototype.apply, Dummy = function() {}; - if (!Function.prototype.bind) { - Function.prototype.bind = function(thisArg) { - var _this = this, args = slice.call(arguments, 1), bound; - if (args.length) { - bound = function() { - return apply.call(_this, this instanceof Dummy ? this : thisArg, args.concat(slice.call(arguments))); - }; - } else { - bound = function() { - return apply.call(_this, this instanceof Dummy ? this : thisArg, arguments); - }; - } - Dummy.prototype = this.prototype; - bound.prototype = new Dummy(); - return bound; - }; - } -})(); - -(function() { - var slice = Array.prototype.slice, emptyFunction = function() {}, IS_DONTENUM_BUGGY = function() { - for (var p in { - toString: 1 - }) { - if (p === "toString") { - return false; - } - } - return true; - }(), addMethods = function(klass, source, parent) { - for (var property in source) { - if (property in klass.prototype && typeof klass.prototype[property] === "function" && (source[property] + "").indexOf("callSuper") > -1) { - klass.prototype[property] = function(property) { - return function() { - var superclass = this.constructor.superclass; - this.constructor.superclass = parent; - var returnValue = source[property].apply(this, arguments); - this.constructor.superclass = superclass; - if (property !== "initialize") { - return returnValue; - } - }; - }(property); - } else { - klass.prototype[property] = source[property]; - } - if (IS_DONTENUM_BUGGY) { - if (source.toString !== Object.prototype.toString) { - klass.prototype.toString = source.toString; - } - if (source.valueOf !== Object.prototype.valueOf) { - klass.prototype.valueOf = source.valueOf; - } - } - } - }; - function Subclass() {} - function callSuper(methodName) { - var fn = this.constructor.superclass.prototype[methodName]; - return arguments.length > 1 ? fn.apply(this, slice.call(arguments, 1)) : fn.call(this); - } - function createClass() { - var parent = null, properties = slice.call(arguments, 0); - if (typeof properties[0] === "function") { - parent = properties.shift(); - } - function klass() { - this.initialize.apply(this, arguments); - } - klass.superclass = parent; - klass.subclasses = []; - if (parent) { - Subclass.prototype = parent.prototype; - klass.prototype = new Subclass(); - parent.subclasses.push(klass); - } - for (var i = 0, length = properties.length; i < length; i++) { - addMethods(klass, properties[i], parent); - } - if (!klass.prototype.initialize) { - klass.prototype.initialize = emptyFunction; - } - klass.prototype.constructor = klass; - klass.prototype.callSuper = callSuper; - return klass; - } - fabric.util.createClass = createClass; -})(); - -(function() { - var unknown = "unknown"; - function areHostMethods(object) { - var methodNames = Array.prototype.slice.call(arguments, 1), t, i, len = methodNames.length; - for (i = 0; i < len; i++) { - t = typeof object[methodNames[i]]; - if (!/^(?:function|object|unknown)$/.test(t)) { - return false; - } - } - return true; - } - var getElement, setElement, getUniqueId = function() { - var uid = 0; - return function(element) { - return element.__uniqueID || (element.__uniqueID = "uniqueID__" + uid++); - }; - }(); - (function() { - var elements = {}; - getElement = function(uid) { - return elements[uid]; - }; - setElement = function(uid, element) { - elements[uid] = element; - }; - })(); - function createListener(uid, handler) { - return { - handler: handler, - wrappedHandler: createWrappedHandler(uid, handler) - }; - } - function createWrappedHandler(uid, handler) { - return function(e) { - handler.call(getElement(uid), e || fabric.window.event); - }; - } - function createDispatcher(uid, eventName) { - return function(e) { - if (handlers[uid] && handlers[uid][eventName]) { - var handlersForEvent = handlers[uid][eventName]; - for (var i = 0, len = handlersForEvent.length; i < len; i++) { - handlersForEvent[i].call(this, e || fabric.window.event); - } - } - }; - } - var shouldUseAddListenerRemoveListener = areHostMethods(fabric.document.documentElement, "addEventListener", "removeEventListener") && areHostMethods(fabric.window, "addEventListener", "removeEventListener"), shouldUseAttachEventDetachEvent = areHostMethods(fabric.document.documentElement, "attachEvent", "detachEvent") && areHostMethods(fabric.window, "attachEvent", "detachEvent"), listeners = {}, handlers = {}, addListener, removeListener; - if (shouldUseAddListenerRemoveListener) { - addListener = function(element, eventName, handler) { - element.addEventListener(eventName, handler, false); - }; - removeListener = function(element, eventName, handler) { - element.removeEventListener(eventName, handler, false); - }; - } else if (shouldUseAttachEventDetachEvent) { - addListener = function(element, eventName, handler) { - var uid = getUniqueId(element); - setElement(uid, element); - if (!listeners[uid]) { - listeners[uid] = {}; - } - if (!listeners[uid][eventName]) { - listeners[uid][eventName] = []; - } - var listener = createListener(uid, handler); - listeners[uid][eventName].push(listener); - element.attachEvent("on" + eventName, listener.wrappedHandler); - }; - removeListener = function(element, eventName, handler) { - var uid = getUniqueId(element), listener; - if (listeners[uid] && listeners[uid][eventName]) { - for (var i = 0, len = listeners[uid][eventName].length; i < len; i++) { - listener = listeners[uid][eventName][i]; - if (listener && listener.handler === handler) { - element.detachEvent("on" + eventName, listener.wrappedHandler); - listeners[uid][eventName][i] = null; - } - } - } - }; - } else { - addListener = function(element, eventName, handler) { - var uid = getUniqueId(element); - if (!handlers[uid]) { - handlers[uid] = {}; - } - if (!handlers[uid][eventName]) { - handlers[uid][eventName] = []; - var existingHandler = element["on" + eventName]; - if (existingHandler) { - handlers[uid][eventName].push(existingHandler); - } - element["on" + eventName] = createDispatcher(uid, eventName); - } - handlers[uid][eventName].push(handler); - }; - removeListener = function(element, eventName, handler) { - var uid = getUniqueId(element); - if (handlers[uid] && handlers[uid][eventName]) { - var handlersForEvent = handlers[uid][eventName]; - for (var i = 0, len = handlersForEvent.length; i < len; i++) { - if (handlersForEvent[i] === handler) { - handlersForEvent.splice(i, 1); - } - } - } - }; - } - fabric.util.addListener = addListener; - fabric.util.removeListener = removeListener; - function getPointer(event) { - event || (event = fabric.window.event); - var element = event.target || (typeof event.srcElement !== unknown ? event.srcElement : null), scroll = fabric.util.getScrollLeftTop(element); - return { - x: pointerX(event) + scroll.left, - y: pointerY(event) + scroll.top - }; - } - var pointerX = function(event) { - return typeof event.clientX !== unknown ? event.clientX : 0; - }, pointerY = function(event) { - return typeof event.clientY !== unknown ? event.clientY : 0; - }; - function _getPointer(event, pageProp, clientProp) { - var touchProp = event.type === "touchend" ? "changedTouches" : "touches"; - return event[touchProp] && event[touchProp][0] ? event[touchProp][0][pageProp] - (event[touchProp][0][pageProp] - event[touchProp][0][clientProp]) || event[clientProp] : event[clientProp]; - } - if (fabric.isTouchSupported) { - pointerX = function(event) { - return _getPointer(event, "pageX", "clientX"); - }; - pointerY = function(event) { - return _getPointer(event, "pageY", "clientY"); - }; - } - fabric.util.getPointer = getPointer; - fabric.util.object.extend(fabric.util, fabric.Observable); -})(); - -(function() { - function setStyle(element, styles) { - var elementStyle = element.style; - if (!elementStyle) { - return element; - } - if (typeof styles === "string") { - element.style.cssText += ";" + styles; - return styles.indexOf("opacity") > -1 ? setOpacity(element, styles.match(/opacity:\s*(\d?\.?\d*)/)[1]) : element; - } - for (var property in styles) { - if (property === "opacity") { - setOpacity(element, styles[property]); - } else { - var normalizedProperty = property === "float" || property === "cssFloat" ? typeof elementStyle.styleFloat === "undefined" ? "cssFloat" : "styleFloat" : property; - elementStyle[normalizedProperty] = styles[property]; - } - } - return element; - } - var parseEl = fabric.document.createElement("div"), supportsOpacity = typeof parseEl.style.opacity === "string", supportsFilters = typeof parseEl.style.filter === "string", reOpacity = /alpha\s*\(\s*opacity\s*=\s*([^\)]+)\)/, setOpacity = function(element) { - return element; - }; - if (supportsOpacity) { - setOpacity = function(element, value) { - element.style.opacity = value; - return element; - }; - } else if (supportsFilters) { - setOpacity = function(element, value) { - var es = element.style; - if (element.currentStyle && !element.currentStyle.hasLayout) { - es.zoom = 1; - } - if (reOpacity.test(es.filter)) { - value = value >= .9999 ? "" : "alpha(opacity=" + value * 100 + ")"; - es.filter = es.filter.replace(reOpacity, value); - } else { - es.filter += " alpha(opacity=" + value * 100 + ")"; - } - return element; - }; - } - fabric.util.setStyle = setStyle; -})(); - -(function() { - var _slice = Array.prototype.slice; - function getById(id) { - return typeof id === "string" ? fabric.document.getElementById(id) : id; - } - var sliceCanConvertNodelists, toArray = function(arrayLike) { - return _slice.call(arrayLike, 0); - }; - try { - sliceCanConvertNodelists = toArray(fabric.document.childNodes) instanceof Array; - } catch (err) {} - if (!sliceCanConvertNodelists) { - toArray = function(arrayLike) { - var arr = new Array(arrayLike.length), i = arrayLike.length; - while (i--) { - arr[i] = arrayLike[i]; - } - return arr; - }; - } - function makeElement(tagName, attributes) { - var el = fabric.document.createElement(tagName); - for (var prop in attributes) { - if (prop === "class") { - el.className = attributes[prop]; - } else if (prop === "for") { - el.htmlFor = attributes[prop]; - } else { - el.setAttribute(prop, attributes[prop]); - } - } - return el; - } - function addClass(element, className) { - if (element && (" " + element.className + " ").indexOf(" " + className + " ") === -1) { - element.className += (element.className ? " " : "") + className; - } - } - function wrapElement(element, wrapper, attributes) { - if (typeof wrapper === "string") { - wrapper = makeElement(wrapper, attributes); - } - if (element.parentNode) { - element.parentNode.replaceChild(wrapper, element); - } - wrapper.appendChild(element); - return wrapper; - } - function getScrollLeftTop(element) { - var left = 0, top = 0, docElement = fabric.document.documentElement, body = fabric.document.body || { - scrollLeft: 0, - scrollTop: 0 - }; - while (element && (element.parentNode || element.host)) { - element = element.parentNode || element.host; - if (element === fabric.document) { - left = body.scrollLeft || docElement.scrollLeft || 0; - top = body.scrollTop || docElement.scrollTop || 0; - } else { - left += element.scrollLeft || 0; - top += element.scrollTop || 0; - } - if (element.nodeType === 1 && fabric.util.getElementStyle(element, "position") === "fixed") { - break; - } - } - return { - left: left, - top: top - }; - } - function getElementOffset(element) { - var docElem, doc = element && element.ownerDocument, box = { - left: 0, - top: 0 - }, offset = { - left: 0, - top: 0 - }, scrollLeftTop, offsetAttributes = { - borderLeftWidth: "left", - borderTopWidth: "top", - paddingLeft: "left", - paddingTop: "top" - }; - if (!doc) { - return offset; - } - for (var attr in offsetAttributes) { - offset[offsetAttributes[attr]] += parseInt(getElementStyle(element, attr), 10) || 0; - } - docElem = doc.documentElement; - if (typeof element.getBoundingClientRect !== "undefined") { - box = element.getBoundingClientRect(); - } - scrollLeftTop = getScrollLeftTop(element); - return { - left: box.left + scrollLeftTop.left - (docElem.clientLeft || 0) + offset.left, - top: box.top + scrollLeftTop.top - (docElem.clientTop || 0) + offset.top - }; - } - var getElementStyle; - if (fabric.document.defaultView && fabric.document.defaultView.getComputedStyle) { - getElementStyle = function(element, attr) { - var style = fabric.document.defaultView.getComputedStyle(element, null); - return style ? style[attr] : undefined; - }; - } else { - getElementStyle = function(element, attr) { - var value = element.style[attr]; - if (!value && element.currentStyle) { - value = element.currentStyle[attr]; - } - return value; - }; - } - (function() { - var style = fabric.document.documentElement.style, selectProp = "userSelect" in style ? "userSelect" : "MozUserSelect" in style ? "MozUserSelect" : "WebkitUserSelect" in style ? "WebkitUserSelect" : "KhtmlUserSelect" in style ? "KhtmlUserSelect" : ""; - function makeElementUnselectable(element) { - if (typeof element.onselectstart !== "undefined") { - element.onselectstart = fabric.util.falseFunction; - } - if (selectProp) { - element.style[selectProp] = "none"; - } else if (typeof element.unselectable === "string") { - element.unselectable = "on"; - } - return element; - } - function makeElementSelectable(element) { - if (typeof element.onselectstart !== "undefined") { - element.onselectstart = null; - } - if (selectProp) { - element.style[selectProp] = ""; - } else if (typeof element.unselectable === "string") { - element.unselectable = ""; - } - return element; - } - fabric.util.makeElementUnselectable = makeElementUnselectable; - fabric.util.makeElementSelectable = makeElementSelectable; - })(); - (function() { - function getScript(url, callback) { - var headEl = fabric.document.getElementsByTagName("head")[0], scriptEl = fabric.document.createElement("script"), loading = true; - scriptEl.onload = scriptEl.onreadystatechange = function(e) { - if (loading) { - if (typeof this.readyState === "string" && this.readyState !== "loaded" && this.readyState !== "complete") { - return; - } - loading = false; - callback(e || fabric.window.event); - scriptEl = scriptEl.onload = scriptEl.onreadystatechange = null; - } - }; - scriptEl.src = url; - headEl.appendChild(scriptEl); - } - fabric.util.getScript = getScript; - })(); - fabric.util.getById = getById; - fabric.util.toArray = toArray; - fabric.util.makeElement = makeElement; - fabric.util.addClass = addClass; - fabric.util.wrapElement = wrapElement; - fabric.util.getScrollLeftTop = getScrollLeftTop; - fabric.util.getElementOffset = getElementOffset; - fabric.util.getElementStyle = getElementStyle; -})(); - -(function() { - function addParamToUrl(url, param) { - return url + (/\?/.test(url) ? "&" : "?") + param; - } - var makeXHR = function() { - var factories = [ function() { - return new ActiveXObject("Microsoft.XMLHTTP"); - }, function() { - return new ActiveXObject("Msxml2.XMLHTTP"); - }, function() { - return new ActiveXObject("Msxml2.XMLHTTP.3.0"); - }, function() { - return new XMLHttpRequest(); - } ]; - for (var i = factories.length; i--; ) { - try { - var req = factories[i](); - if (req) { - return factories[i]; - } - } catch (err) {} - } - }(); - function emptyFn() {} - function request(url, options) { - options || (options = {}); - var method = options.method ? options.method.toUpperCase() : "GET", onComplete = options.onComplete || function() {}, xhr = makeXHR(), body; - xhr.onreadystatechange = function() { - if (xhr.readyState === 4) { - onComplete(xhr); - xhr.onreadystatechange = emptyFn; - } - }; - if (method === "GET") { - body = null; - if (typeof options.parameters === "string") { - url = addParamToUrl(url, options.parameters); - } - } - xhr.open(method, url, true); - if (method === "POST" || method === "PUT") { - xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded"); - } - xhr.send(body); - return xhr; - } - fabric.util.request = request; -})(); - -fabric.log = function() {}; - -fabric.warn = function() {}; - -if (typeof console !== "undefined") { - [ "log", "warn" ].forEach(function(methodName) { - if (typeof console[methodName] !== "undefined" && typeof console[methodName].apply === "function") { - fabric[methodName] = function() { - return console[methodName].apply(console, arguments); - }; - } - }); -} - -(function() { - 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) { - 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(); - return; - } - onChange(easing(currentTime, startValue, byValue, duration)); - if (time > finish) { - options.onComplete && options.onComplete(); - return; - } - requestAnimFrame(tick); - })(start); - }); - } - var _requestAnimFrame = fabric.window.requestAnimationFrame || fabric.window.webkitRequestAnimationFrame || fabric.window.mozRequestAnimationFrame || fabric.window.oRequestAnimationFrame || fabric.window.msRequestAnimationFrame || function(callback) { - fabric.window.setTimeout(callback, 1e3 / 60); - }; - function requestAnimFrame() { - return _requestAnimFrame.apply(fabric.window, arguments); - } - fabric.util.animate = animate; - fabric.util.requestAnimFrame = requestAnimFrame; -})(); - -(function() { - function normalize(a, c, p, s) { - if (a < Math.abs(c)) { - a = c; - s = p / 4; - } else { - if (c === 0 && a === 0) { - s = p / (2 * Math.PI) * Math.asin(1); - } else { - s = p / (2 * Math.PI) * Math.asin(c / a); - } - } - return { - a: a, - c: c, - p: p, - s: s - }; - } - function elastic(opts, t, d) { - return opts.a * Math.pow(2, 10 * (t -= 1)) * Math.sin((t * d - opts.s) * (2 * Math.PI) / opts.p); - } - function easeOutCubic(t, b, c, d) { - return c * ((t = t / d - 1) * t * t + 1) + b; - } - function easeInOutCubic(t, b, c, d) { - t /= d / 2; - if (t < 1) { - return c / 2 * t * t * t + b; - } - return c / 2 * ((t -= 2) * t * t + 2) + b; - } - function easeInQuart(t, b, c, d) { - return c * (t /= d) * t * t * t + b; - } - function easeOutQuart(t, b, c, d) { - return -c * ((t = t / d - 1) * t * t * t - 1) + b; - } - function easeInOutQuart(t, b, c, d) { - t /= d / 2; - if (t < 1) { - return c / 2 * t * t * t * t + b; - } - return -c / 2 * ((t -= 2) * t * t * t - 2) + b; - } - function easeInQuint(t, b, c, d) { - return c * (t /= d) * t * t * t * t + b; - } - function easeOutQuint(t, b, c, d) { - return c * ((t = t / d - 1) * t * t * t * t + 1) + b; - } - function easeInOutQuint(t, b, c, d) { - t /= d / 2; - if (t < 1) { - return c / 2 * t * t * t * t * t + b; - } - return c / 2 * ((t -= 2) * t * t * t * t + 2) + b; - } - function easeInSine(t, b, c, d) { - return -c * Math.cos(t / d * (Math.PI / 2)) + c + b; - } - function easeOutSine(t, b, c, d) { - return c * Math.sin(t / d * (Math.PI / 2)) + b; - } - function easeInOutSine(t, b, c, d) { - return -c / 2 * (Math.cos(Math.PI * t / d) - 1) + b; - } - function easeInExpo(t, b, c, d) { - return t === 0 ? b : c * Math.pow(2, 10 * (t / d - 1)) + b; - } - function easeOutExpo(t, b, c, d) { - return t === d ? b + c : c * (-Math.pow(2, -10 * t / d) + 1) + b; - } - function easeInOutExpo(t, b, c, d) { - if (t === 0) { - return b; - } - if (t === d) { - return b + c; - } - t /= d / 2; - if (t < 1) { - return c / 2 * Math.pow(2, 10 * (t - 1)) + b; - } - return c / 2 * (-Math.pow(2, -10 * --t) + 2) + b; - } - function easeInCirc(t, b, c, d) { - return -c * (Math.sqrt(1 - (t /= d) * t) - 1) + b; - } - function easeOutCirc(t, b, c, d) { - return c * Math.sqrt(1 - (t = t / d - 1) * t) + b; - } - function easeInOutCirc(t, b, c, d) { - t /= d / 2; - if (t < 1) { - return -c / 2 * (Math.sqrt(1 - t * t) - 1) + b; - } - return c / 2 * (Math.sqrt(1 - (t -= 2) * t) + 1) + b; - } - function easeInElastic(t, b, c, d) { - var s = 1.70158, p = 0, a = c; - if (t === 0) { - return b; - } - t /= d; - if (t === 1) { - return b + c; - } - if (!p) { - p = d * .3; - } - var opts = normalize(a, c, p, s); - return -elastic(opts, t, d) + b; - } - function easeOutElastic(t, b, c, d) { - var s = 1.70158, p = 0, a = c; - if (t === 0) { - return b; - } - t /= d; - if (t === 1) { - return b + c; - } - if (!p) { - p = d * .3; - } - var opts = normalize(a, c, p, s); - return opts.a * Math.pow(2, -10 * t) * Math.sin((t * d - opts.s) * (2 * Math.PI) / opts.p) + opts.c + b; - } - function easeInOutElastic(t, b, c, d) { - var s = 1.70158, p = 0, a = c; - if (t === 0) { - return b; - } - t /= d / 2; - if (t === 2) { - return b + c; - } - if (!p) { - p = d * (.3 * 1.5); - } - var opts = normalize(a, c, p, s); - if (t < 1) { - return -.5 * elastic(opts, t, d) + b; - } - return opts.a * Math.pow(2, -10 * (t -= 1)) * Math.sin((t * d - opts.s) * (2 * Math.PI) / opts.p) * .5 + opts.c + b; - } - function easeInBack(t, b, c, d, s) { - if (s === undefined) { - s = 1.70158; - } - return c * (t /= d) * t * ((s + 1) * t - s) + b; - } - function easeOutBack(t, b, c, d, s) { - if (s === undefined) { - s = 1.70158; - } - return c * ((t = t / d - 1) * t * ((s + 1) * t + s) + 1) + b; - } - function easeInOutBack(t, b, c, d, s) { - if (s === undefined) { - s = 1.70158; - } - t /= d / 2; - if (t < 1) { - return c / 2 * (t * t * (((s *= 1.525) + 1) * t - s)) + b; - } - return c / 2 * ((t -= 2) * t * (((s *= 1.525) + 1) * t + s) + 2) + b; - } - function easeInBounce(t, b, c, d) { - return c - easeOutBounce(d - t, 0, c, d) + b; - } - function easeOutBounce(t, b, c, d) { - if ((t /= d) < 1 / 2.75) { - return c * (7.5625 * t * t) + b; - } else if (t < 2 / 2.75) { - return c * (7.5625 * (t -= 1.5 / 2.75) * t + .75) + b; - } else if (t < 2.5 / 2.75) { - return c * (7.5625 * (t -= 2.25 / 2.75) * t + .9375) + b; - } else { - return c * (7.5625 * (t -= 2.625 / 2.75) * t + .984375) + b; - } - } - function easeInOutBounce(t, b, c, d) { - if (t < d / 2) { - return easeInBounce(t * 2, 0, c, d) * .5 + b; - } - return easeOutBounce(t * 2 - d, 0, c, d) * .5 + c * .5 + b; - } - fabric.util.ease = { - easeInQuad: function(t, b, c, d) { - return c * (t /= d) * t + b; - }, - easeOutQuad: function(t, b, c, d) { - return -c * (t /= d) * (t - 2) + b; - }, - easeInOutQuad: function(t, b, c, d) { - t /= d / 2; - if (t < 1) { - return c / 2 * t * t + b; - } - return -c / 2 * (--t * (t - 2) - 1) + b; - }, - easeInCubic: function(t, b, c, d) { - return c * (t /= d) * t * t + b; - }, - easeOutCubic: easeOutCubic, - easeInOutCubic: easeInOutCubic, - easeInQuart: easeInQuart, - easeOutQuart: easeOutQuart, - easeInOutQuart: easeInOutQuart, - easeInQuint: easeInQuint, - easeOutQuint: easeOutQuint, - easeInOutQuint: easeInOutQuint, - easeInSine: easeInSine, - easeOutSine: easeOutSine, - easeInOutSine: easeInOutSine, - easeInExpo: easeInExpo, - easeOutExpo: easeOutExpo, - easeInOutExpo: easeInOutExpo, - easeInCirc: easeInCirc, - easeOutCirc: easeOutCirc, - easeInOutCirc: easeInOutCirc, - easeInElastic: easeInElastic, - easeOutElastic: easeOutElastic, - easeInOutElastic: easeInOutElastic, - easeInBack: easeInBack, - easeOutBack: easeOutBack, - easeInOutBack: easeInOutBack, - easeInBounce: easeInBounce, - easeOutBounce: easeOutBounce, - easeInOutBounce: easeInOutBounce - }; -})(); - -(function(global) { - "use strict"; - var fabric = global.fabric || (global.fabric = {}), extend = fabric.util.object.extend, capitalize = fabric.util.string.capitalize, clone = fabric.util.object.clone, toFixed = fabric.util.toFixed, parseUnit = fabric.util.parseUnit, multiplyTransformMatrices = fabric.util.multiplyTransformMatrices, reAllowedSVGTagNames = /^(path|circle|polygon|polyline|ellipse|rect|line|image|text)$/i, reViewBoxTagNames = /^(symbol|image|marker|pattern|view|svg)$/i, reNotAllowedAncestors = /^(?:pattern|defs|symbol|metadata)$/i, reAllowedParents = /^(symbol|g|a|svg)$/i, attributesMap = { - 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" - }, colorAttributes = { - stroke: "strokeOpacity", - fill: "fillOpacity" - }; - fabric.cssRules = {}; - fabric.gradientDefs = {}; - function normalizeAttr(attr) { - if (attr in attributesMap) { - return attributesMap[attr]; - } - return attr; - } - function normalizeValue(attr, value, parentAttributes, fontSize) { - var isArray = Object.prototype.toString.call(value) === "[object Array]", parsed; - if ((attr === "fill" || attr === "stroke") && value === "none") { - value = ""; - } else if (attr === "strokeDashArray") { - value = value.replace(/,/g, " ").split(/\s+/).map(function(n) { - return parseFloat(n); - }); - } else if (attr === "transformMatrix") { - if (parentAttributes && parentAttributes.transformMatrix) { - value = multiplyTransformMatrices(parentAttributes.transformMatrix, fabric.parseTransformAttribute(value)); - } else { - value = fabric.parseTransformAttribute(value); - } - } else if (attr === "visible") { - value = value === "none" || value === "hidden" ? false : true; - if (parentAttributes && parentAttributes.visible === false) { - value = false; - } - } else if (attr === "originX") { - value = value === "start" ? "left" : value === "end" ? "right" : "center"; - } else { - parsed = isArray ? value.map(parseUnit) : parseUnit(value, fontSize); - } - return !isArray && isNaN(parsed) ? value : parsed; - } - function _setStrokeFillOpacity(attributes) { - for (var attr in colorAttributes) { - if (typeof attributes[colorAttributes[attr]] === "undefined" || attributes[attr] === "") { - continue; - } - if (typeof attributes[attr] === "undefined") { - if (!fabric.Object.prototype[attr]) { - continue; - } - attributes[attr] = fabric.Object.prototype[attr]; - } - if (attributes[attr].indexOf("url(") === 0) { - continue; - } - var color = new fabric.Color(attributes[attr]); - attributes[attr] = color.setAlpha(toFixed(color.getAlpha() * attributes[colorAttributes[attr]], 2)).toRgba(); - } - return attributes; - } - fabric.parseTransformAttribute = function() { - function rotateMatrix(matrix, args) { - var angle = args[0], x = args.length === 3 ? args[1] : 0, y = args.length === 3 ? args[2] : 0; - matrix[0] = Math.cos(angle); - matrix[1] = Math.sin(angle); - matrix[2] = -Math.sin(angle); - matrix[3] = Math.cos(angle); - matrix[4] = x - (matrix[0] * x + matrix[2] * y); - matrix[5] = y - (matrix[1] * x + matrix[3] * y); - } - function scaleMatrix(matrix, args) { - var multiplierX = args[0], multiplierY = args.length === 2 ? args[1] : args[0]; - matrix[0] = multiplierX; - matrix[3] = multiplierY; - } - function skewXMatrix(matrix, args) { - matrix[2] = Math.tan(fabric.util.degreesToRadians(args[0])); - } - function skewYMatrix(matrix, args) { - matrix[1] = Math.tan(fabric.util.degreesToRadians(args[0])); - } - function translateMatrix(matrix, args) { - matrix[4] = args[0]; - if (args.length === 2) { - matrix[5] = args[1]; - } - } - var iMatrix = [ 1, 0, 0, 1, 0, 0 ], number = fabric.reNum, commaWsp = "(?:\\s+,?\\s*|,\\s*)", skewX = "(?:(skewX)\\s*\\(\\s*(" + number + ")\\s*\\))", skewY = "(?:(skewY)\\s*\\(\\s*(" + number + ")\\s*\\))", rotate = "(?:(rotate)\\s*\\(\\s*(" + number + ")(?:" + commaWsp + "(" + number + ")" + commaWsp + "(" + number + "))?\\s*\\))", scale = "(?:(scale)\\s*\\(\\s*(" + number + ")(?:" + commaWsp + "(" + number + "))?\\s*\\))", translate = "(?:(translate)\\s*\\(\\s*(" + number + ")(?:" + commaWsp + "(" + number + "))?\\s*\\))", matrix = "(?:(matrix)\\s*\\(\\s*" + "(" + number + ")" + commaWsp + "(" + number + ")" + commaWsp + "(" + number + ")" + commaWsp + "(" + number + ")" + commaWsp + "(" + number + ")" + commaWsp + "(" + number + ")" + "\\s*\\))", transform = "(?:" + matrix + "|" + translate + "|" + scale + "|" + rotate + "|" + skewX + "|" + skewY + ")", transforms = "(?:" + transform + "(?:" + commaWsp + "*" + transform + ")*" + ")", transformList = "^\\s*(?:" + transforms + "?)\\s*$", reTransformList = new RegExp(transformList), reTransform = new RegExp(transform, "g"); - return function(attributeValue) { - var matrix = iMatrix.concat(), matrices = []; - if (!attributeValue || attributeValue && !reTransformList.test(attributeValue)) { - return matrix; - } - attributeValue.replace(reTransform, function(match) { - var m = new RegExp(transform).exec(match).filter(function(match) { - return match !== "" && match != null; - }), operation = m[1], args = m.slice(2).map(parseFloat); - switch (operation) { - case "translate": - translateMatrix(matrix, args); - break; - - case "rotate": - args[0] = fabric.util.degreesToRadians(args[0]); - rotateMatrix(matrix, args); - break; - - case "scale": - scaleMatrix(matrix, args); - break; - - case "skewX": - skewXMatrix(matrix, args); - break; - - case "skewY": - skewYMatrix(matrix, args); - break; - - case "matrix": - matrix = args; - break; - } - matrices.push(matrix.concat()); - matrix = iMatrix.concat(); - }); - var combinedMatrix = matrices[0]; - while (matrices.length > 1) { - matrices.shift(); - combinedMatrix = fabric.util.multiplyTransformMatrices(combinedMatrix, matrices[0]); - } - return combinedMatrix; - }; - }(); - function parseStyleString(style, oStyle) { - var attr, value; - style.replace(/;\s*$/, "").split(";").forEach(function(chunk) { - var pair = chunk.split(":"); - attr = normalizeAttr(pair[0].trim().toLowerCase()); - value = normalizeValue(attr, pair[1].trim()); - oStyle[attr] = value; - }); - } - function parseStyleObject(style, oStyle) { - var attr, value; - for (var prop in style) { - if (typeof style[prop] === "undefined") { - continue; - } - attr = normalizeAttr(prop.toLowerCase()); - value = normalizeValue(attr, style[prop]); - oStyle[attr] = value; - } - } - function getGlobalStylesForElement(element, svgUid) { - var styles = {}; - for (var rule in fabric.cssRules[svgUid]) { - if (elementMatchesRule(element, rule.split(" "))) { - for (var property in fabric.cssRules[svgUid][rule]) { - styles[property] = fabric.cssRules[svgUid][rule][property]; - } - } - } - return styles; - } - function elementMatchesRule(element, selectors) { - var firstMatching, parentMatching = true; - firstMatching = selectorMatches(element, selectors.pop()); - if (firstMatching && selectors.length) { - parentMatching = doesSomeParentMatch(element, selectors); - } - return firstMatching && parentMatching && selectors.length === 0; - } - function doesSomeParentMatch(element, selectors) { - var selector, parentMatching = true; - while (element.parentNode && element.parentNode.nodeType === 1 && selectors.length) { - if (parentMatching) { - selector = selectors.pop(); - } - element = element.parentNode; - parentMatching = selectorMatches(element, selector); - } - return selectors.length === 0; - } - function selectorMatches(element, selector) { - var nodeName = element.nodeName, classNames = element.getAttribute("class"), id = element.getAttribute("id"), matcher; - matcher = new RegExp("^" + nodeName, "i"); - selector = selector.replace(matcher, ""); - if (id && selector.length) { - matcher = new RegExp("#" + id + "(?![a-zA-Z\\-]+)", "i"); - selector = selector.replace(matcher, ""); - } - if (classNames && selector.length) { - classNames = classNames.split(" "); - for (var i = classNames.length; i--; ) { - matcher = new RegExp("\\." + classNames[i] + "(?![a-zA-Z\\-]+)", "i"); - selector = selector.replace(matcher, ""); - } - } - return selector.length === 0; - } - function elementById(doc, id) { - var el; - doc.getElementById && (el = doc.getElementById(id)); - if (el) { - return el; - } - var node, i, nodelist = doc.getElementsByTagName("*"); - for (i = 0; i < nodelist.length; i++) { - node = nodelist[i]; - if (id === node.getAttribute("id")) { - return node; - } - } - } - function parseUseDirectives(doc) { - var nodelist = doc.getElementsByTagName("use"), i = 0; - while (nodelist.length && i < nodelist.length) { - var el = nodelist[i], xlink = el.getAttribute("xlink:href").substr(1), x = el.getAttribute("x") || 0, y = el.getAttribute("y") || 0, el2 = elementById(doc, xlink).cloneNode(true), currentTrans = (el2.getAttribute("transform") || "") + " translate(" + x + ", " + y + ")", parentNode, oldLength = nodelist.length, attr, j, attrs, l; - applyViewboxTransform(el2); - if (/^svg$/i.test(el2.nodeName)) { - var el3 = el2.ownerDocument.createElement("g"); - for (j = 0, attrs = el2.attributes, l = attrs.length; j < l; j++) { - attr = attrs.item(j); - el3.setAttribute(attr.nodeName, attr.nodeValue); - } - while (el2.firstChild != null) { - el3.appendChild(el2.firstChild); - } - el2 = el3; - } - for (j = 0, attrs = el.attributes, l = attrs.length; j < l; j++) { - attr = attrs.item(j); - if (attr.nodeName === "x" || attr.nodeName === "y" || attr.nodeName === "xlink:href") { - continue; - } - if (attr.nodeName === "transform") { - currentTrans = attr.nodeValue + " " + currentTrans; - } else { - el2.setAttribute(attr.nodeName, attr.nodeValue); - } - } - el2.setAttribute("transform", currentTrans); - el2.setAttribute("instantiated_by_use", "1"); - el2.removeAttribute("id"); - parentNode = el.parentNode; - parentNode.replaceChild(el2, el); - if (nodelist.length === oldLength) { - i++; - } - } - } - var reViewBoxAttrValue = new RegExp("^" + "\\s*(" + fabric.reNum + "+)\\s*,?" + "\\s*(" + fabric.reNum + "+)\\s*,?" + "\\s*(" + fabric.reNum + "+)\\s*,?" + "\\s*(" + fabric.reNum + "+)\\s*" + "$"); - function applyViewboxTransform(element) { - var viewBoxAttr = element.getAttribute("viewBox"), scaleX = 1, scaleY = 1, minX = 0, minY = 0, viewBoxWidth, viewBoxHeight, matrix, el, widthAttr = element.getAttribute("width"), heightAttr = element.getAttribute("height"), x = element.getAttribute("x") || 0, y = element.getAttribute("y") || 0, preserveAspectRatio = element.getAttribute("preserveAspectRatio") || "", missingViewBox = !viewBoxAttr || !reViewBoxTagNames.test(element.tagName) || !(viewBoxAttr = viewBoxAttr.match(reViewBoxAttrValue)), missingDimAttr = !widthAttr || !heightAttr || widthAttr === "100%" || heightAttr === "100%", toBeParsed = missingViewBox && missingDimAttr, parsedDim = {}, translateMatrix = ""; - parsedDim.width = 0; - parsedDim.height = 0; - parsedDim.toBeParsed = toBeParsed; - if (toBeParsed) { - return parsedDim; - } - if (missingViewBox) { - parsedDim.width = parseUnit(widthAttr); - parsedDim.height = parseUnit(heightAttr); - return parsedDim; - } - minX = -parseFloat(viewBoxAttr[1]), minY = -parseFloat(viewBoxAttr[2]), viewBoxWidth = parseFloat(viewBoxAttr[3]), - viewBoxHeight = parseFloat(viewBoxAttr[4]); - if (!missingDimAttr) { - parsedDim.width = parseUnit(widthAttr); - parsedDim.height = parseUnit(heightAttr); - scaleX = parsedDim.width / viewBoxWidth; - scaleY = parsedDim.height / viewBoxHeight; - } else { - parsedDim.width = viewBoxWidth; - parsedDim.height = viewBoxHeight; - } - preserveAspectRatio = fabric.util.parsePreserveAspectRatioAttribute(preserveAspectRatio); - if (preserveAspectRatio.alignX !== "none") { - scaleY = scaleX = scaleX > scaleY ? scaleY : scaleX; - } - if (scaleX === 1 && scaleY === 1 && minX === 0 && minY === 0 && x === 0 && y === 0) { - return parsedDim; - } - if (x || y) { - translateMatrix = " translate(" + parseUnit(x) + " " + parseUnit(y) + ") "; - } - matrix = translateMatrix + " matrix(" + scaleX + " 0" + " 0 " + scaleY + " " + minX * scaleX + " " + minY * scaleY + ") "; - if (element.tagName === "svg") { - el = element.ownerDocument.createElement("g"); - while (element.firstChild != null) { - el.appendChild(element.firstChild); - } - element.appendChild(el); - } else { - el = element; - matrix = el.getAttribute("transform") + matrix; - } - el.setAttribute("transform", matrix); - return parsedDim; - } - fabric.parseSVGDocument = function() { - function hasAncestorWithNodeName(element, nodeName) { - while (element && (element = element.parentNode)) { - if (nodeName.test(element.nodeName) && !element.getAttribute("instantiated_by_use")) { - return true; - } - } - return false; - } - return function(doc, callback, reviver) { - if (!doc) { - return; - } - parseUseDirectives(doc); - var startTime = new Date(), svgUid = fabric.Object.__uid++, options = applyViewboxTransform(doc), descendants = fabric.util.toArray(doc.getElementsByTagName("*")); - options.svgUid = svgUid; - if (descendants.length === 0 && fabric.isLikelyNode) { - descendants = doc.selectNodes('//*[name(.)!="svg"]'); - var arr = []; - for (var i = 0, len = descendants.length; i < len; i++) { - arr[i] = descendants[i]; - } - descendants = arr; - } - var elements = descendants.filter(function(el) { - applyViewboxTransform(el); - return reAllowedSVGTagNames.test(el.tagName) && !hasAncestorWithNodeName(el, reNotAllowedAncestors); - }); - if (!elements || elements && !elements.length) { - callback && callback([], {}); - return; - } - fabric.gradientDefs[svgUid] = fabric.getGradientDefs(doc); - fabric.cssRules[svgUid] = fabric.getCSSRules(doc); - fabric.parseElements(elements, function(instances) { - fabric.documentParsingTime = new Date() - startTime; - if (callback) { - callback(instances, options); - } - }, clone(options), reviver); - }; - }(); - var svgCache = { - has: function(name, callback) { - callback(false); - }, - get: function() {}, - set: function() {} - }; - function _enlivenCachedObject(cachedObject) { - var objects = cachedObject.objects, options = cachedObject.options; - objects = objects.map(function(o) { - return fabric[capitalize(o.type)].fromObject(o); - }); - return { - objects: objects, - options: options - }; - } - function _createSVGPattern(markup, canvas, property) { - if (canvas[property] && canvas[property].toSVG) { - markup.push(' \n', ' \n \n'); - } - } - var reFontDeclaration = new RegExp("(normal|italic)?\\s*(normal|small-caps)?\\s*" + "(normal|bold|bolder|lighter|100|200|300|400|500|600|700|800|900)?\\s*(" + fabric.reNum + "(?:px|cm|mm|em|pt|pc|in)*)(?:\\/(normal|" + fabric.reNum + "))?\\s+(.*)"); - extend(fabric, { - parseFontDeclaration: function(value, oStyle) { - var match = value.match(reFontDeclaration); - if (!match) { - return; - } - var fontStyle = match[1], fontWeight = match[3], fontSize = match[4], lineHeight = match[5], fontFamily = match[6]; - if (fontStyle) { - oStyle.fontStyle = fontStyle; - } - if (fontWeight) { - oStyle.fontWeight = isNaN(parseFloat(fontWeight)) ? fontWeight : parseFloat(fontWeight); - } - if (fontSize) { - oStyle.fontSize = parseUnit(fontSize); - } - if (fontFamily) { - oStyle.fontFamily = fontFamily; - } - if (lineHeight) { - oStyle.lineHeight = lineHeight === "normal" ? 1 : lineHeight; - } - }, - getGradientDefs: function(doc) { - var linearGradientEls = doc.getElementsByTagName("linearGradient"), radialGradientEls = doc.getElementsByTagName("radialGradient"), el, i, j = 0, id, xlink, elList = [], gradientDefs = {}, idsToXlinkMap = {}; - elList.length = linearGradientEls.length + radialGradientEls.length; - i = linearGradientEls.length; - while (i--) { - elList[j++] = linearGradientEls[i]; - } - i = radialGradientEls.length; - while (i--) { - elList[j++] = radialGradientEls[i]; - } - while (j--) { - el = elList[j]; - xlink = el.getAttribute("xlink:href"); - id = el.getAttribute("id"); - if (xlink) { - idsToXlinkMap[id] = xlink.substr(1); - } - gradientDefs[id] = el; - } - for (id in idsToXlinkMap) { - var el2 = gradientDefs[idsToXlinkMap[id]].cloneNode(true); - el = gradientDefs[id]; - while (el2.firstChild) { - el.appendChild(el2.firstChild); - } - } - return gradientDefs; - }, - parseAttributes: function(element, attributes, svgUid) { - if (!element) { - return; - } - var value, parentAttributes = {}, fontSize; - if (typeof svgUid === "undefined") { - svgUid = element.getAttribute("svgUid"); - } - if (element.parentNode && reAllowedParents.test(element.parentNode.nodeName)) { - parentAttributes = fabric.parseAttributes(element.parentNode, attributes, svgUid); - } - fontSize = parentAttributes && parentAttributes.fontSize || element.getAttribute("font-size") || fabric.Text.DEFAULT_SVG_FONT_SIZE; - var ownAttributes = attributes.reduce(function(memo, attr) { - value = element.getAttribute(attr); - if (value) { - attr = normalizeAttr(attr); - value = normalizeValue(attr, value, parentAttributes, fontSize); - memo[attr] = value; - } - return memo; - }, {}); - ownAttributes = extend(ownAttributes, extend(getGlobalStylesForElement(element, svgUid), fabric.parseStyleAttribute(element))); - if (ownAttributes.font) { - fabric.parseFontDeclaration(ownAttributes.font, ownAttributes); - } - return _setStrokeFillOpacity(extend(parentAttributes, ownAttributes)); - }, - parseElements: function(elements, callback, options, reviver) { - new fabric.ElementsParser(elements, callback, options, reviver).parse(); - }, - parseStyleAttribute: function(element) { - var oStyle = {}, style = element.getAttribute("style"); - if (!style) { - return oStyle; - } - if (typeof style === "string") { - parseStyleString(style, oStyle); - } else { - parseStyleObject(style, oStyle); - } - return oStyle; - }, - parsePointsAttribute: function(points) { - if (!points) { - return null; - } - points = points.replace(/,/g, " ").trim(); - points = points.split(/\s+/); - var parsedPoints = [], i, len; - i = 0; - len = points.length; - for (;i < len; i += 2) { - parsedPoints.push({ - x: parseFloat(points[i]), - y: parseFloat(points[i + 1]) - }); - } - return parsedPoints; - }, - getCSSRules: function(doc) { - var styles = doc.getElementsByTagName("style"), allRules = {}, rules; - for (var i = 0, len = styles.length; i < len; i++) { - var styleContents = styles[i].textContent || styles[i].text; - styleContents = styleContents.replace(/\/\*[\s\S]*?\*\//g, ""); - if (styleContents.trim() === "") { - continue; - } - rules = styleContents.match(/[^{]*\{[\s\S]*?\}/g); - rules = rules.map(function(rule) { - return rule.trim(); - }); - rules.forEach(function(rule) { - var match = rule.match(/([\s\S]*?)\s*\{([^}]*)\}/), ruleObj = {}, declaration = match[2].trim(), propertyValuePairs = declaration.replace(/;$/, "").split(/\s*;\s*/); - for (var i = 0, len = propertyValuePairs.length; i < len; i++) { - var pair = propertyValuePairs[i].split(/\s*:\s*/), property = normalizeAttr(pair[0]), value = normalizeValue(property, pair[1], pair[0]); - ruleObj[property] = value; - } - rule = match[1]; - rule.split(",").forEach(function(_rule) { - _rule = _rule.replace(/^svg/i, "").trim(); - if (_rule === "") { - return; - } - allRules[_rule] = fabric.util.object.clone(ruleObj); - }); - }); - } - return allRules; - }, - loadSVGFromURL: function(url, callback, reviver) { - url = url.replace(/^\n\s*/, "").trim(); - svgCache.has(url, function(hasUrl) { - if (hasUrl) { - svgCache.get(url, function(value) { - var enlivedRecord = _enlivenCachedObject(value); - callback(enlivedRecord.objects, enlivedRecord.options); - }); - } else { - new fabric.util.request(url, { - method: "get", - onComplete: onComplete - }); - } - }); - function onComplete(r) { - var xml = r.responseXML; - if (xml && !xml.documentElement && fabric.window.ActiveXObject && r.responseText) { - xml = new ActiveXObject("Microsoft.XMLDOM"); - xml.async = "false"; - xml.loadXML(r.responseText.replace(//i, "")); - } - if (!xml || !xml.documentElement) { - return; - } - fabric.parseSVGDocument(xml.documentElement, function(results, options) { - svgCache.set(url, { - objects: fabric.util.array.invoke(results, "toObject"), - options: options - }); - callback(results, options); - }, reviver); - } - }, - loadSVGFromString: function(string, callback, reviver) { - string = string.trim(); - var doc; - if (typeof DOMParser !== "undefined") { - var parser = new DOMParser(); - if (parser && parser.parseFromString) { - doc = parser.parseFromString(string, "text/xml"); - } - } else if (fabric.window.ActiveXObject) { - doc = new ActiveXObject("Microsoft.XMLDOM"); - doc.async = "false"; - doc.loadXML(string.replace(//i, "")); - } - fabric.parseSVGDocument(doc.documentElement, function(results, options) { - callback(results, options); - }, reviver); - }, - createSVGFontFacesMarkup: function(objects) { - var markup = "", fontList = {}, obj, fontFamily, style, row, rowIndex, char, charIndex, fontPaths = fabric.fontPaths; - for (var i = 0, len = objects.length; i < len; i++) { - obj = objects[i]; - fontFamily = obj.fontFamily; - if (obj.type.indexOf("text") === -1 || fontList[fontFamily] || !fontPaths[fontFamily]) { - continue; - } - fontList[fontFamily] = true; - if (!obj.styles) { - continue; - } - style = obj.styles; - for (rowIndex in style) { - char = style[rowIndex]; - for (charIndex in row) { - char = row[charIndex]; - fontFamily = char.fontFamily; - if (!fontList[fontFamily] && fontPaths[fontFamily]) { - fontList[fontFamily] = true; - } - } - } - } - for (var j in fontList) { - markup += [ " @font-face {\n", " font-family: '", j, "';\n", " src: url('", fontPaths[j], "');\n", " }\n" ].join(""); - } - if (markup) { - markup = [ ' \n" ].join(""); - } - return markup; - }, - createSVGRefElementsMarkup: function(canvas) { - var markup = []; - _createSVGPattern(markup, canvas, "backgroundColor"); - _createSVGPattern(markup, canvas, "overlayColor"); - return markup.join(""); - } - }); -})(typeof exports !== "undefined" ? exports : this); - -fabric.ElementsParser = function(elements, callback, options, reviver) { - this.elements = elements; - this.callback = callback; - this.options = options; - this.reviver = reviver; - this.svgUid = options && options.svgUid || 0; -}; - -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 i = 0, len = this.elements.length; i < len; i++) { - this.elements[i].setAttribute("svgUid", this.svgUid); - (function(_this, i) { - setTimeout(function() { - _this.createObject(_this.elements[i], i); - }, 0); - })(this, i); - } -}; - -fabric.ElementsParser.prototype.createObject = function(el, index) { - var klass = fabric[fabric.util.string.capitalize(el.tagName)]; - if (klass && klass.fromElement) { - try { - this._createObject(klass, el, index); - } catch (err) { - fabric.log(err); - } - } else { - this.checkIfDone(); - } -}; - -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"); - this.reviver && this.reviver(el, obj); - this.instances[index] = obj; - this.checkIfDone(); - } -}; - -fabric.ElementsParser.prototype.createCallback = function(index, el) { - var _this = this; - return function(obj) { - _this.resolveGradient(obj, "fill"); - _this.resolveGradient(obj, "stroke"); - _this.reviver && _this.reviver(el, obj); - _this.instances[index] = obj; - _this.checkIfDone(); - }; -}; - -fabric.ElementsParser.prototype.resolveGradient = function(obj, property) { - var instanceFillValue = obj.get(property); - if (!/^url\(/.test(instanceFillValue)) { - return; - } - var gradientId = instanceFillValue.slice(5, instanceFillValue.length - 1); - if (fabric.gradientDefs[this.svgUid][gradientId]) { - obj.set(property, fabric.Gradient.fromElement(fabric.gradientDefs[this.svgUid][gradientId], obj)); - } -}; - -fabric.ElementsParser.prototype.checkIfDone = function() { - if (--this.numElements === 0) { - this.instances = this.instances.filter(function(el) { - return el != null; - }); - this.callback(this.instances); - } -}; - -(function(global) { - "use strict"; - var fabric = global.fabric || (global.fabric = {}); - if (fabric.Point) { - fabric.warn("fabric.Point is already defined"); - return; - } - fabric.Point = Point; - function Point(x, y) { - this.x = x; - this.y = y; - } - Point.prototype = { - constructor: Point, - add: function(that) { - return new Point(this.x + that.x, this.y + that.y); - }, - addEquals: function(that) { - this.x += that.x; - this.y += that.y; - return this; - }, - scalarAdd: function(scalar) { - return new Point(this.x + scalar, this.y + scalar); - }, - scalarAddEquals: function(scalar) { - this.x += scalar; - this.y += scalar; - return this; - }, - subtract: function(that) { - return new Point(this.x - that.x, this.y - that.y); - }, - subtractEquals: function(that) { - this.x -= that.x; - this.y -= that.y; - return this; - }, - scalarSubtract: function(scalar) { - return new Point(this.x - scalar, this.y - scalar); - }, - scalarSubtractEquals: function(scalar) { - this.x -= scalar; - this.y -= scalar; - return this; - }, - multiply: function(scalar) { - return new Point(this.x * scalar, this.y * scalar); - }, - multiplyEquals: function(scalar) { - this.x *= scalar; - this.y *= scalar; - return this; - }, - divide: function(scalar) { - return new Point(this.x / scalar, this.y / scalar); - }, - divideEquals: function(scalar) { - this.x /= scalar; - this.y /= scalar; - return this; - }, - eq: function(that) { - return this.x === that.x && this.y === that.y; - }, - lt: function(that) { - return this.x < that.x && this.y < that.y; - }, - lte: function(that) { - return this.x <= that.x && this.y <= that.y; - }, - gt: function(that) { - return this.x > that.x && this.y > that.y; - }, - gte: function(that) { - return this.x >= that.x && this.y >= that.y; - }, - lerp: function(that, t) { - return new Point(this.x + (that.x - this.x) * t, this.y + (that.y - this.y) * t); - }, - distanceFrom: function(that) { - var dx = this.x - that.x, dy = this.y - that.y; - return Math.sqrt(dx * dx + dy * dy); - }, - midPointFrom: function(that) { - return new Point(this.x + (that.x - this.x) / 2, this.y + (that.y - this.y) / 2); - }, - min: function(that) { - return new Point(Math.min(this.x, that.x), Math.min(this.y, that.y)); - }, - max: function(that) { - return new Point(Math.max(this.x, that.x), Math.max(this.y, that.y)); - }, - toString: function() { - return this.x + "," + this.y; - }, - setXY: function(x, y) { - this.x = x; - this.y = y; - }, - setFromPoint: function(that) { - this.x = that.x; - this.y = that.y; - }, - swap: function(that) { - var x = this.x, y = this.y; - this.x = that.x; - this.y = that.y; - that.x = x; - that.y = y; - } - }; -})(typeof exports !== "undefined" ? exports : this); - -(function(global) { - "use strict"; - var fabric = global.fabric || (global.fabric = {}); - if (fabric.Intersection) { - fabric.warn("fabric.Intersection is already defined"); - return; - } - function Intersection(status) { - this.status = status; - this.points = []; - } - fabric.Intersection = Intersection; - fabric.Intersection.prototype = { - appendPoint: function(point) { - this.points.push(point); - }, - appendPoints: function(points) { - this.points = this.points.concat(points); - } - }; - fabric.Intersection.intersectLineLine = function(a1, a2, b1, b2) { - var result, uaT = (b2.x - b1.x) * (a1.y - b1.y) - (b2.y - b1.y) * (a1.x - b1.x), ubT = (a2.x - a1.x) * (a1.y - b1.y) - (a2.y - a1.y) * (a1.x - b1.x), uB = (b2.y - b1.y) * (a2.x - a1.x) - (b2.x - b1.x) * (a2.y - a1.y); - if (uB !== 0) { - var ua = uaT / uB, ub = ubT / uB; - if (0 <= ua && ua <= 1 && 0 <= ub && ub <= 1) { - result = new Intersection("Intersection"); - result.points.push(new fabric.Point(a1.x + ua * (a2.x - a1.x), a1.y + ua * (a2.y - a1.y))); - } else { - result = new Intersection(); - } - } else { - if (uaT === 0 || ubT === 0) { - result = new Intersection("Coincident"); - } else { - result = new Intersection("Parallel"); - } - } - return result; - }; - fabric.Intersection.intersectLinePolygon = function(a1, a2, points) { - var result = new Intersection(), length = points.length; - for (var i = 0; i < length; i++) { - var b1 = points[i], b2 = points[(i + 1) % length], inter = Intersection.intersectLineLine(a1, a2, b1, b2); - result.appendPoints(inter.points); - } - if (result.points.length > 0) { - result.status = "Intersection"; - } - return result; - }; - fabric.Intersection.intersectPolygonPolygon = function(points1, points2) { - var result = new Intersection(), length = points1.length; - for (var i = 0; i < length; i++) { - var a1 = points1[i], a2 = points1[(i + 1) % length], inter = Intersection.intersectLinePolygon(a1, a2, points2); - result.appendPoints(inter.points); - } - if (result.points.length > 0) { - result.status = "Intersection"; - } - return result; - }; - fabric.Intersection.intersectPolygonRectangle = function(points, r1, r2) { - var min = r1.min(r2), max = r1.max(r2), topRight = new fabric.Point(max.x, min.y), bottomLeft = new fabric.Point(min.x, max.y), inter1 = Intersection.intersectLinePolygon(min, topRight, points), inter2 = Intersection.intersectLinePolygon(topRight, max, points), inter3 = Intersection.intersectLinePolygon(max, bottomLeft, points), inter4 = Intersection.intersectLinePolygon(bottomLeft, min, points), result = new Intersection(); - result.appendPoints(inter1.points); - result.appendPoints(inter2.points); - result.appendPoints(inter3.points); - result.appendPoints(inter4.points); - if (result.points.length > 0) { - result.status = "Intersection"; - } - return result; - }; -})(typeof exports !== "undefined" ? exports : this); - -(function(global) { - "use strict"; - var fabric = global.fabric || (global.fabric = {}); - if (fabric.Color) { - fabric.warn("fabric.Color is already defined."); - return; - } - function Color(color) { - if (!color) { - this.setSource([ 0, 0, 0, 1 ]); - } else { - this._tryParsingColor(color); - } - } - fabric.Color = Color; - fabric.Color.prototype = { - _tryParsingColor: function(color) { - var source; - if (color in Color.colorNameMap) { - color = Color.colorNameMap[color]; - } - if (color === "transparent") { - this.setSource([ 255, 255, 255, 0 ]); - return; - } - source = Color.sourceFromHex(color); - if (!source) { - source = Color.sourceFromRgb(color); - } - if (!source) { - source = Color.sourceFromHsl(color); - } - if (source) { - this.setSource(source); - } - }, - _rgbToHsl: function(r, g, b) { - r /= 255, g /= 255, b /= 255; - var h, s, l, max = fabric.util.array.max([ r, g, b ]), min = fabric.util.array.min([ r, g, b ]); - l = (max + min) / 2; - if (max === min) { - h = s = 0; - } else { - var d = max - min; - s = l > .5 ? d / (2 - max - min) : d / (max + min); - switch (max) { - case r: - h = (g - b) / d + (g < b ? 6 : 0); - break; - - case g: - h = (b - r) / d + 2; - break; - - case b: - h = (r - g) / d + 4; - break; - } - h /= 6; - } - return [ Math.round(h * 360), Math.round(s * 100), Math.round(l * 100) ]; - }, - getSource: function() { - return this._source; - }, - setSource: function(source) { - this._source = source; - }, - toRgb: function() { - var source = this.getSource(); - return "rgb(" + source[0] + "," + source[1] + "," + source[2] + ")"; - }, - toRgba: function() { - var source = this.getSource(); - return "rgba(" + source[0] + "," + source[1] + "," + source[2] + "," + source[3] + ")"; - }, - toHsl: function() { - var source = this.getSource(), hsl = this._rgbToHsl(source[0], source[1], source[2]); - return "hsl(" + hsl[0] + "," + hsl[1] + "%," + hsl[2] + "%)"; - }, - toHsla: function() { - var source = this.getSource(), hsl = this._rgbToHsl(source[0], source[1], source[2]); - return "hsla(" + hsl[0] + "," + hsl[1] + "%," + hsl[2] + "%," + source[3] + ")"; - }, - toHex: function() { - var source = this.getSource(), r, g, b; - r = source[0].toString(16); - r = r.length === 1 ? "0" + r : r; - g = source[1].toString(16); - g = g.length === 1 ? "0" + g : g; - b = source[2].toString(16); - b = b.length === 1 ? "0" + b : b; - return r.toUpperCase() + g.toUpperCase() + b.toUpperCase(); - }, - getAlpha: function() { - return this.getSource()[3]; - }, - setAlpha: function(alpha) { - var source = this.getSource(); - source[3] = alpha; - this.setSource(source); - return this; - }, - toGrayscale: function() { - var source = this.getSource(), average = parseInt((source[0] * .3 + source[1] * .59 + source[2] * .11).toFixed(0), 10), currentAlpha = source[3]; - this.setSource([ average, average, average, currentAlpha ]); - return this; - }, - toBlackWhite: function(threshold) { - var source = this.getSource(), average = (source[0] * .3 + source[1] * .59 + source[2] * .11).toFixed(0), currentAlpha = source[3]; - threshold = threshold || 127; - average = Number(average) < Number(threshold) ? 0 : 255; - this.setSource([ average, average, average, currentAlpha ]); - return this; - }, - overlayWith: function(otherColor) { - if (!(otherColor instanceof Color)) { - otherColor = new Color(otherColor); - } - var result = [], alpha = this.getAlpha(), otherAlpha = .5, source = this.getSource(), otherSource = otherColor.getSource(); - for (var i = 0; i < 3; i++) { - result.push(Math.round(source[i] * (1 - otherAlpha) + otherSource[i] * otherAlpha)); - } - result[3] = alpha; - this.setSource(result); - 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.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]{6}|[0-9a-f]{3})$/i; - fabric.Color.colorNameMap = { - aqua: "#00FFFF", - black: "#000000", - blue: "#0000FF", - fuchsia: "#FF00FF", - gray: "#808080", - green: "#008000", - lime: "#00FF00", - maroon: "#800000", - navy: "#000080", - olive: "#808000", - orange: "#FFA500", - purple: "#800080", - red: "#FF0000", - silver: "#C0C0C0", - teal: "#008080", - white: "#FFFFFF", - yellow: "#FFFF00" - }; - function hue2rgb(p, q, t) { - if (t < 0) { - t += 1; - } - if (t > 1) { - t -= 1; - } - if (t < 1 / 6) { - return p + (q - p) * 6 * t; - } - if (t < 1 / 2) { - return q; - } - if (t < 2 / 3) { - return p + (q - p) * (2 / 3 - t) * 6; - } - return p; - } - fabric.Color.fromRgb = function(color) { - return Color.fromSource(Color.sourceFromRgb(color)); - }; - fabric.Color.sourceFromRgb = function(color) { - var match = color.match(Color.reRGBa); - if (match) { - var r = parseInt(match[1], 10) / (/%$/.test(match[1]) ? 100 : 1) * (/%$/.test(match[1]) ? 255 : 1), g = parseInt(match[2], 10) / (/%$/.test(match[2]) ? 100 : 1) * (/%$/.test(match[2]) ? 255 : 1), b = parseInt(match[3], 10) / (/%$/.test(match[3]) ? 100 : 1) * (/%$/.test(match[3]) ? 255 : 1); - return [ parseInt(r, 10), parseInt(g, 10), parseInt(b, 10), match[4] ? parseFloat(match[4]) : 1 ]; - } - }; - fabric.Color.fromRgba = Color.fromRgb; - fabric.Color.fromHsl = function(color) { - return Color.fromSource(Color.sourceFromHsl(color)); - }; - fabric.Color.sourceFromHsl = function(color) { - var match = color.match(Color.reHSLa); - if (!match) { - return; - } - var h = (parseFloat(match[1]) % 360 + 360) % 360 / 360, s = parseFloat(match[2]) / (/%$/.test(match[2]) ? 100 : 1), l = parseFloat(match[3]) / (/%$/.test(match[3]) ? 100 : 1), r, g, b; - if (s === 0) { - r = g = b = l; - } else { - var q = l <= .5 ? l * (s + 1) : l + s - l * s, p = l * 2 - q; - r = hue2rgb(p, q, h + 1 / 3); - g = hue2rgb(p, q, h); - b = hue2rgb(p, q, h - 1 / 3); - } - return [ Math.round(r * 255), Math.round(g * 255), Math.round(b * 255), match[4] ? parseFloat(match[4]) : 1 ]; - }; - fabric.Color.fromHsla = Color.fromHsl; - fabric.Color.fromHex = function(color) { - return Color.fromSource(Color.sourceFromHex(color)); - }; - fabric.Color.sourceFromHex = function(color) { - if (color.match(Color.reHex)) { - var value = color.slice(color.indexOf("#") + 1), isShortNotation = value.length === 3, r = isShortNotation ? value.charAt(0) + value.charAt(0) : value.substring(0, 2), g = isShortNotation ? value.charAt(1) + value.charAt(1) : value.substring(2, 4), b = isShortNotation ? value.charAt(2) + value.charAt(2) : value.substring(4, 6); - return [ parseInt(r, 16), parseInt(g, 16), parseInt(b, 16), 1 ]; - } - }; - fabric.Color.fromSource = function(source) { - var oColor = new Color(); - oColor.setSource(source); - return oColor; - }; -})(typeof exports !== "undefined" ? exports : this); - -(function() { - function getColorStop(el) { - var style = el.getAttribute("style"), offset = el.getAttribute("offset") || 0, color, colorAlpha, opacity; - offset = parseFloat(offset) / (/%$/.test(offset) ? 100 : 1); - offset = offset < 0 ? 0 : offset > 1 ? 1 : offset; - if (style) { - var keyValuePairs = style.split(/\s*;\s*/); - if (keyValuePairs[keyValuePairs.length - 1] === "") { - keyValuePairs.pop(); - } - for (var i = keyValuePairs.length; i--; ) { - var split = keyValuePairs[i].split(/\s*:\s*/), key = split[0].trim(), value = split[1].trim(); - if (key === "stop-color") { - color = value; - } else if (key === "stop-opacity") { - opacity = value; - } - } - } - if (!color) { - color = el.getAttribute("stop-color") || "rgb(0,0,0)"; - } - if (!opacity) { - opacity = el.getAttribute("stop-opacity"); - } - color = new fabric.Color(color); - colorAlpha = color.getAlpha(); - opacity = isNaN(parseFloat(opacity)) ? 1 : parseFloat(opacity); - opacity *= colorAlpha; - return { - offset: offset, - color: color.toRgb(), - opacity: opacity - }; - } - function getLinearCoords(el) { - return { - x1: el.getAttribute("x1") || 0, - y1: el.getAttribute("y1") || 0, - x2: el.getAttribute("x2") || "100%", - y2: el.getAttribute("y2") || 0 - }; - } - function getRadialCoords(el) { - return { - x1: el.getAttribute("fx") || el.getAttribute("cx") || "50%", - y1: el.getAttribute("fy") || el.getAttribute("cy") || "50%", - r1: 0, - x2: el.getAttribute("cx") || "50%", - y2: el.getAttribute("cy") || "50%", - r2: el.getAttribute("r") || "50%" - }; - } - fabric.Gradient = fabric.util.createClass({ - offsetX: 0, - offsetY: 0, - initialize: function(options) { - options || (options = {}); - var coords = {}; - this.id = fabric.Object.__uid++; - this.type = options.type || "linear"; - coords = { - x1: options.coords.x1 || 0, - y1: options.coords.y1 || 0, - x2: options.coords.x2 || 0, - y2: options.coords.y2 || 0 - }; - if (this.type === "radial") { - coords.r1 = options.coords.r1 || 0; - coords.r2 = options.coords.r2 || 0; - } - this.coords = coords; - this.colorStops = options.colorStops.slice(); - if (options.gradientTransform) { - this.gradientTransform = options.gradientTransform; - } - this.offsetX = options.offsetX || this.offsetX; - this.offsetY = options.offsetY || this.offsetY; - }, - addColorStop: function(colorStop) { - for (var position in colorStop) { - var color = new fabric.Color(colorStop[position]); - this.colorStops.push({ - offset: position, - color: color.toRgb(), - opacity: color.getAlpha() - }); - } - return this; - }, - toObject: function() { - return { - type: this.type, - coords: this.coords, - colorStops: this.colorStops, - offsetX: this.offsetX, - offsetY: this.offsetY, - gradientTransform: this.gradientTransform ? this.gradientTransform.concat() : this.gradientTransform - }; - }, - toSVG: function(object) { - var coords = fabric.util.object.clone(this.coords), markup, commonAttributes; - this.colorStops.sort(function(a, b) { - return a.offset - b.offset; - }); - if (!(object.group && object.group.type === "path-group")) { - for (var prop in coords) { - if (prop === "x1" || prop === "x2" || prop === "r2") { - coords[prop] += this.offsetX - object.width / 2; - } else if (prop === "y1" || prop === "y2") { - coords[prop] += this.offsetY - object.height / 2; - } - } - } - commonAttributes = 'id="SVGID_' + this.id + '" gradientUnits="userSpaceOnUse"'; - if (this.gradientTransform) { - commonAttributes += ' gradientTransform="matrix(' + this.gradientTransform.join(" ") + ')" '; - } - if (this.type === "linear") { - markup = [ "\n' ]; - } else if (this.type === "radial") { - markup = [ "\n' ]; - } - for (var i = 0; i < this.colorStops.length; i++) { - markup.push("\n'); - } - markup.push(this.type === "linear" ? "\n" : "\n"); - return markup.join(""); - }, - toLive: function(ctx, object) { - var gradient, prop, coords = fabric.util.object.clone(this.coords); - if (!this.type) { - return; - } - if (object.group && object.group.type === "path-group") { - for (prop in coords) { - if (prop === "x1" || prop === "x2") { - coords[prop] += -this.offsetX + object.width / 2; - } else if (prop === "y1" || prop === "y2") { - coords[prop] += -this.offsetY + object.height / 2; - } - } - } - if (this.type === "linear") { - gradient = ctx.createLinearGradient(coords.x1, coords.y1, coords.x2, coords.y2); - } else if (this.type === "radial") { - gradient = ctx.createRadialGradient(coords.x1, coords.y1, coords.r1, coords.x2, coords.y2, coords.r2); - } - for (var i = 0, len = this.colorStops.length; i < len; i++) { - var color = this.colorStops[i].color, opacity = this.colorStops[i].opacity, offset = this.colorStops[i].offset; - if (typeof opacity !== "undefined") { - color = new fabric.Color(color).setAlpha(opacity).toRgba(); - } - gradient.addColorStop(parseFloat(offset), color); - } - return gradient; - } - }); - fabric.util.object.extend(fabric.Gradient, { - fromElement: function(el, instance) { - var colorStopEls = el.getElementsByTagName("stop"), type = el.nodeName === "linearGradient" ? "linear" : "radial", gradientUnits = el.getAttribute("gradientUnits") || "objectBoundingBox", gradientTransform = el.getAttribute("gradientTransform"), colorStops = [], coords = {}, ellipseMatrix; - if (type === "linear") { - coords = getLinearCoords(el); - } else if (type === "radial") { - coords = getRadialCoords(el); - } - for (var i = colorStopEls.length; i--; ) { - colorStops.push(getColorStop(colorStopEls[i])); - } - ellipseMatrix = _convertPercentUnitsToValues(instance, coords, gradientUnits); - var gradient = new fabric.Gradient({ - type: type, - coords: coords, - colorStops: colorStops, - offsetX: -instance.left, - offsetY: -instance.top - }); - if (gradientTransform || ellipseMatrix !== "") { - gradient.gradientTransform = fabric.parseTransformAttribute((gradientTransform || "") + ellipseMatrix); - } - return gradient; - }, - forObject: function(obj, options) { - options || (options = {}); - _convertPercentUnitsToValues(obj, options.coords, "userSpaceOnUse"); - return new fabric.Gradient(options); - } - }); - function _convertPercentUnitsToValues(object, options, gradientUnits) { - var propValue, addFactor = 0, multFactor = 1, ellipseMatrix = ""; - for (var prop in options) { - propValue = parseFloat(options[prop], 10); - if (typeof options[prop] === "string" && /^\d+%$/.test(options[prop])) { - multFactor = .01; - } else { - multFactor = 1; - } - if (prop === "x1" || prop === "x2" || prop === "r2") { - multFactor *= gradientUnits === "objectBoundingBox" ? object.width : 1; - addFactor = gradientUnits === "objectBoundingBox" ? object.left || 0 : 0; - } else if (prop === "y1" || prop === "y2") { - multFactor *= gradientUnits === "objectBoundingBox" ? object.height : 1; - addFactor = gradientUnits === "objectBoundingBox" ? object.top || 0 : 0; - } - options[prop] = propValue * multFactor + addFactor; - } - if (object.type === "ellipse" && options.r2 !== null && gradientUnits === "objectBoundingBox" && object.rx !== object.ry) { - var scaleFactor = object.ry / object.rx; - ellipseMatrix = " scale(1, " + scaleFactor + ")"; - if (options.y1) { - options.y1 /= scaleFactor; - } - if (options.y2) { - options.y2 /= scaleFactor; - } - } - return ellipseMatrix; - } -})(); - -fabric.Pattern = fabric.util.createClass({ - repeat: "repeat", - offsetX: 0, - offsetY: 0, - initialize: function(options) { - options || (options = {}); - this.id = fabric.Object.__uid++; - if (options.source) { - if (typeof options.source === "string") { - if (typeof fabric.util.getFunctionBody(options.source) !== "undefined") { - this.source = new Function(fabric.util.getFunctionBody(options.source)); - } else { - var _this = this; - this.source = fabric.util.createImage(); - fabric.util.loadImage(options.source, function(img) { - _this.source = img; - }); - } - } else { - this.source = options.source; - } - } - if (options.repeat) { - this.repeat = options.repeat; - } - if (options.offsetX) { - this.offsetX = options.offsetX; - } - if (options.offsetY) { - this.offsetY = options.offsetY; - } - }, - toObject: function() { - var source; - if (typeof this.source === "function") { - source = String(this.source); - } else if (typeof this.source.src === "string") { - source = this.source.src; - } else if (typeof this.source === "object" && this.source.toDataURL) { - source = this.source.toDataURL(); - } - return { - source: source, - repeat: this.repeat, - offsetX: this.offsetX, - offsetY: this.offsetY - }; - }, - toSVG: function(object) { - var patternSource = typeof this.source === "function" ? this.source() : this.source, patternWidth = patternSource.width / object.getWidth(), patternHeight = patternSource.height / object.getHeight(), patternOffsetX = this.offsetX / object.getWidth(), patternOffsetY = this.offsetY / object.getHeight(), patternImgSrc = ""; - if (this.repeat === "repeat-x" || this.repeat === "no-repeat") { - patternHeight = 1; - } - if (this.repeat === "repeat-y" || this.repeat === "no-repeat") { - patternWidth = 1; - } - if (patternSource.src) { - patternImgSrc = patternSource.src; - } else if (patternSource.toDataURL) { - patternImgSrc = patternSource.toDataURL(); - } - return '\n' + '\n' + "\n"; - }, - toLive: function(ctx) { - var source = typeof this.source === "function" ? this.source() : this.source; - if (!source) { - return ""; - } - if (typeof source.src !== "undefined") { - if (!source.complete) { - return ""; - } - if (source.naturalWidth === 0 || source.naturalHeight === 0) { - return ""; - } - } - return ctx.createPattern(source, this.repeat); - } -}); - -(function(global) { - "use strict"; - var fabric = global.fabric || (global.fabric = {}), toFixed = fabric.util.toFixed; - if (fabric.Shadow) { - fabric.warn("fabric.Shadow is already defined."); - return; - } - fabric.Shadow = fabric.util.createClass({ - color: "rgb(0,0,0)", - blur: 0, - offsetX: 0, - offsetY: 0, - affectStroke: false, - includeDefaultValues: true, - initialize: function(options) { - if (typeof options === "string") { - options = this._parseShadow(options); - } - for (var prop in options) { - this[prop] = options[prop]; - } - this.id = fabric.Object.__uid++; - }, - _parseShadow: function(shadow) { - var shadowStr = shadow.trim(), offsetsAndBlur = fabric.Shadow.reOffsetsAndBlur.exec(shadowStr) || [], color = shadowStr.replace(fabric.Shadow.reOffsetsAndBlur, "") || "rgb(0,0,0)"; - return { - color: color.trim(), - offsetX: parseInt(offsetsAndBlur[1], 10) || 0, - offsetY: parseInt(offsetsAndBlur[2], 10) || 0, - blur: parseInt(offsetsAndBlur[3], 10) || 0 - }; - }, - toString: function() { - return [ this.offsetX, this.offsetY, this.blur, this.color ].join("px "); - }, - toSVG: function(object) { - var fBoxX = 40, fBoxY = 40, NUM_FRACTION_DIGITS = fabric.Object.NUM_FRACTION_DIGITS, offset = fabric.util.rotateVector({ - x: this.offsetX, - y: this.offsetY - }, fabric.util.degreesToRadians(-object.angle)), BLUR_BOX = 20; - if (object.width && object.height) { - fBoxX = toFixed((Math.abs(offset.x) + this.blur) / object.width, NUM_FRACTION_DIGITS) * 100 + BLUR_BOX; - fBoxY = toFixed((Math.abs(offset.y) + this.blur) / object.height, NUM_FRACTION_DIGITS) * 100 + BLUR_BOX; - } - if (object.flipX) { - offset.x *= -1; - } - if (object.flipY) { - offset.y *= -1; - } - return '\n" + ' \n' + ' \n' + ' \n' + ' \n' + " \n" + " \n" + ' \n' + " \n" + "\n"; - }, - toObject: function() { - if (this.includeDefaultValues) { - return { - color: this.color, - blur: this.blur, - offsetX: this.offsetX, - offsetY: this.offsetY, - affectStroke: this.affectStroke - }; - } - var obj = {}, proto = fabric.Shadow.prototype; - [ "color", "blur", "offsetX", "offsetY", "affectStroke" ].forEach(function(prop) { - if (this[prop] !== proto[prop]) { - obj[prop] = this[prop]; - } - }, this); - return obj; - } - }); - fabric.Shadow.reOffsetsAndBlur = /(?:\s|^)(-?\d+(?:px)?(?:\s?|$))?(-?\d+(?:px)?(?:\s?|$))?(\d+(?:px)?)?(?:\s?|$)(?:$|\s)/; -})(typeof exports !== "undefined" ? exports : this); - -(function() { - "use strict"; - if (fabric.StaticCanvas) { - fabric.warn("fabric.StaticCanvas is already defined."); - return; - } - var extend = fabric.util.object.extend, getElementOffset = fabric.util.getElementOffset, removeFromArray = fabric.util.removeFromArray, toFixed = fabric.util.toFixed, CANVAS_INIT_ERROR = new Error("Could not initialize `canvas` element"); - fabric.StaticCanvas = fabric.util.createClass({ - initialize: function(el, options) { - options || (options = {}); - this._initStatic(el, options); - }, - backgroundColor: "", - backgroundImage: null, - overlayColor: "", - overlayImage: null, - includeDefaultValues: true, - stateful: true, - renderOnAddRemove: true, - clipTo: null, - controlsAboveOverlay: false, - allowTouchScrolling: false, - imageSmoothingEnabled: true, - preserveObjectStacking: false, - viewportTransform: [ 1, 0, 0, 1, 0, 0 ], - onBeforeScaleRotate: function() {}, - enableRetinaScaling: true, - _initStatic: function(el, options) { - this._objects = []; - this._createLowerCanvas(el); - this._initOptions(options); - this._setImageSmoothing(); - if (!this.interactive) { - this._initRetinaScaling(); - } - if (options.overlayImage) { - this.setOverlayImage(options.overlayImage, this.renderAll.bind(this)); - } - if (options.backgroundImage) { - this.setBackgroundImage(options.backgroundImage, this.renderAll.bind(this)); - } - if (options.backgroundColor) { - this.setBackgroundColor(options.backgroundColor, this.renderAll.bind(this)); - } - if (options.overlayColor) { - this.setOverlayColor(options.overlayColor, this.renderAll.bind(this)); - } - this.calcOffset(); - }, - _isRetinaScaling: function() { - return fabric.devicePixelRatio !== 1 && this.enableRetinaScaling; - }, - _initRetinaScaling: function() { - if (!this._isRetinaScaling()) { - return; - } - 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() { - this._offset = getElementOffset(this.lowerCanvasEl); - return this; - }, - setOverlayImage: function(image, callback, options) { - return this.__setBgOverlayImage("overlayImage", image, callback, options); - }, - setBackgroundImage: function(image, callback, options) { - return this.__setBgOverlayImage("backgroundImage", image, callback, options); - }, - setOverlayColor: function(overlayColor, callback) { - return this.__setBgOverlayColor("overlayColor", overlayColor, callback); - }, - setBackgroundColor: function(backgroundColor, callback) { - return this.__setBgOverlayColor("backgroundColor", backgroundColor, callback); - }, - _setImageSmoothing: function() { - var ctx = this.getContext(); - ctx.imageSmoothingEnabled = ctx.imageSmoothingEnabled || ctx.webkitImageSmoothingEnabled || ctx.mozImageSmoothingEnabled || ctx.msImageSmoothingEnabled || ctx.oImageSmoothingEnabled; - ctx.imageSmoothingEnabled = this.imageSmoothingEnabled; - }, - __setBgOverlayImage: function(property, image, callback, options) { - if (typeof image === "string") { - fabric.util.loadImage(image, function(img) { - this[property] = new fabric.Image(img, options); - callback && callback(img); - }, this, options && options.crossOrigin); - } else { - options && image.setOptions(options); - this[property] = image; - callback && callback(image); - } - return this; - }, - __setBgOverlayColor: function(property, color, callback) { - if (color && color.source) { - var _this = this; - fabric.util.loadImage(color.source, function(img) { - _this[property] = new fabric.Pattern({ - source: img, - repeat: color.repeat, - offsetX: color.offsetX, - offsetY: color.offsetY - }); - callback && callback(); - }); - } else { - this[property] = color; - callback && callback(); - } - return this; - }, - _createCanvasElement: function() { - var element = fabric.document.createElement("canvas"); - if (!element.style) { - element.style = {}; - } - if (!element) { - throw CANVAS_INIT_ERROR; - } - this._initCanvasElement(element); - return element; - }, - _initCanvasElement: function(element) { - fabric.util.createCanvasElement(element); - if (typeof element.getContext === "undefined") { - throw CANVAS_INIT_ERROR; - } - }, - _initOptions: function(options) { - for (var prop in options) { - this[prop] = options[prop]; - } - this.width = this.width || parseInt(this.lowerCanvasEl.width, 10) || 0; - this.height = this.height || parseInt(this.lowerCanvasEl.height, 10) || 0; - if (!this.lowerCanvasEl.style) { - return; - } - 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(canvasEl) { - this.lowerCanvasEl = fabric.util.getById(canvasEl) || this._createCanvasElement(); - this._initCanvasElement(this.lowerCanvasEl); - fabric.util.addClass(this.lowerCanvasEl, "lower-canvas"); - if (this.interactive) { - this._applyCanvasStyle(this.lowerCanvasEl); - } - this.contextContainer = this.lowerCanvasEl.getContext("2d"); - }, - getWidth: function() { - return this.width; - }, - getHeight: function() { - return this.height; - }, - setWidth: function(value, options) { - return this.setDimensions({ - width: value - }, options); - }, - setHeight: function(value, options) { - return this.setDimensions({ - height: value - }, options); - }, - setDimensions: function(dimensions, options) { - var cssValue; - options = options || {}; - for (var prop in dimensions) { - cssValue = dimensions[prop]; - if (!options.cssOnly) { - this._setBackstoreDimension(prop, dimensions[prop]); - cssValue += "px"; - } - if (!options.backstoreOnly) { - this._setCssDimension(prop, cssValue); - } - } - this._initRetinaScaling(); - this._setImageSmoothing(); - this.calcOffset(); - if (!options.cssOnly) { - this.renderAll(); - } - return this; - }, - _setBackstoreDimension: function(prop, value) { - this.lowerCanvasEl[prop] = value; - if (this.upperCanvasEl) { - this.upperCanvasEl[prop] = value; - } - if (this.cacheCanvasEl) { - this.cacheCanvasEl[prop] = value; - } - this[prop] = value; - return this; - }, - _setCssDimension: function(prop, value) { - this.lowerCanvasEl.style[prop] = value; - if (this.upperCanvasEl) { - this.upperCanvasEl.style[prop] = value; - } - if (this.wrapperEl) { - this.wrapperEl.style[prop] = value; - } - return this; - }, - getZoom: function() { - return Math.sqrt(this.viewportTransform[0] * this.viewportTransform[3]); - }, - setViewportTransform: function(vpt) { - var activeGroup = this.getActiveGroup(); - this.viewportTransform = vpt; - this.renderAll(); - for (var i = 0, len = this._objects.length; i < len; i++) { - this._objects[i].setCoords(); - } - if (activeGroup) { - activeGroup.setCoords(); - } - return this; - }, - zoomToPoint: function(point, value) { - var before = point; - point = fabric.util.transformPoint(point, fabric.util.invertTransform(this.viewportTransform)); - this.viewportTransform[0] = value; - this.viewportTransform[3] = value; - var after = fabric.util.transformPoint(point, this.viewportTransform); - this.viewportTransform[4] += before.x - after.x; - this.viewportTransform[5] += before.y - after.y; - this.renderAll(); - for (var i = 0, len = this._objects.length; i < len; i++) { - this._objects[i].setCoords(); - } - return this; - }, - setZoom: function(value) { - this.zoomToPoint(new fabric.Point(0, 0), value); - return this; - }, - absolutePan: function(point) { - this.viewportTransform[4] = -point.x; - this.viewportTransform[5] = -point.y; - this.renderAll(); - for (var i = 0, len = this._objects.length; i < len; i++) { - this._objects[i].setCoords(); - } - return this; - }, - relativePan: function(point) { - return this.absolutePan(new fabric.Point(-point.x - this.viewportTransform[4], -point.y - this.viewportTransform[5])); - }, - getElement: function() { - return this.lowerCanvasEl; - }, - getActiveObject: function() { - return null; - }, - getActiveGroup: function() { - return null; - }, - _onObjectAdded: function(obj) { - this.stateful && obj.setupState(); - obj._set("canvas", this); - obj.setCoords(); - this.fire("object:added", { - target: obj - }); - obj.fire("added"); - }, - _onObjectRemoved: function(obj) { - if (this.getActiveObject() === obj) { - this.fire("before:selection:cleared", { - target: obj - }); - this._discardActiveObject(); - this.fire("selection:cleared"); - } - this.fire("object:removed", { - target: obj - }); - obj.fire("removed"); - }, - clearContext: function(ctx) { - ctx.clearRect(0, 0, this.width, this.height); - return this; - }, - getContext: function() { - return this.contextContainer; - }, - clear: function() { - this._objects.length = 0; - if (this.discardActiveGroup) { - this.discardActiveGroup(); - } - if (this.discardActiveObject) { - this.discardActiveObject(); - } - this.clearContext(this.contextContainer); - if (this.contextTop) { - this.clearContext(this.contextTop); - } - this.fire("canvas:cleared"); - this.renderAll(); - return this; - }, - _chooseObjectsToRender: function() { - var activeGroup = this.getActiveGroup(), object, objsToRender = [], activeGroupObjects = []; - if (activeGroup && !this.preserveObjectStacking) { - for (var i = 0, length = this._objects.length; i < length; i++) { - object = this._objects[i]; - if (!activeGroup.contains(object)) { - objsToRender.push(object); - } else { - activeGroupObjects.push(object); - } - } - activeGroup._set("_objects", activeGroupObjects); - } else { - objsToRender = this._objects; - } - return objsToRender; - }, - renderAll: function() { - var canvasToDrawOn = this.contextContainer, objsToRender; - if (this.contextTop && this.selection && !this._groupSelector && !this.isDrawingMode) { - this.clearContext(this.contextTop); - } - this.clearContext(canvasToDrawOn); - this.fire("before:render"); - if (this.clipTo) { - fabric.util.clipContext(this, canvasToDrawOn); - } - this._renderBackground(canvasToDrawOn); - canvasToDrawOn.save(); - objsToRender = this._chooseObjectsToRender(); - canvasToDrawOn.transform.apply(canvasToDrawOn, this.viewportTransform); - this._renderObjects(canvasToDrawOn, objsToRender); - this.preserveObjectStacking || this._renderObjects(canvasToDrawOn, [ this.getActiveGroup() ]); - canvasToDrawOn.restore(); - if (!this.controlsAboveOverlay && this.interactive) { - this.drawControls(canvasToDrawOn); - } - if (this.clipTo) { - canvasToDrawOn.restore(); - } - this._renderOverlay(canvasToDrawOn); - if (this.controlsAboveOverlay && this.interactive) { - this.drawControls(canvasToDrawOn); - } - this.fire("after:render"); - return this; - }, - _renderObjects: function(ctx, objects) { - for (var i = 0, length = objects.length; i < length; ++i) { - objects[i] && objects[i].render(ctx); - } - }, - _renderBackgroundOrOverlay: function(ctx, property) { - var object = this[property + "Color"]; - if (object) { - ctx.fillStyle = object.toLive ? object.toLive(ctx) : object; - ctx.fillRect(object.offsetX || 0, object.offsetY || 0, this.width, this.height); - } - object = this[property + "Image"]; - if (object) { - object.render(ctx); - } - }, - _renderBackground: function(ctx) { - this._renderBackgroundOrOverlay(ctx, "background"); - }, - _renderOverlay: function(ctx) { - this._renderBackgroundOrOverlay(ctx, "overlay"); - }, - renderTop: function() { - var ctx = this.contextTop || this.contextContainer; - this.clearContext(ctx); - if (this.selection && this._groupSelector) { - this._drawSelection(); - } - this.fire("after:render"); - return this; - }, - getCenter: function() { - return { - top: this.getHeight() / 2, - left: this.getWidth() / 2 - }; - }, - centerObjectH: function(object) { - this._centerObject(object, new fabric.Point(this.getCenter().left, object.getCenterPoint().y)); - this.renderAll(); - return this; - }, - centerObjectV: function(object) { - this._centerObject(object, new fabric.Point(object.getCenterPoint().x, this.getCenter().top)); - this.renderAll(); - return this; - }, - centerObject: function(object) { - var center = this.getCenter(); - this._centerObject(object, new fabric.Point(center.left, center.top)); - this.renderAll(); - return this; - }, - _centerObject: function(object, center) { - object.setPositionByOrigin(center, "center", "center"); - return this; - }, - toDatalessJSON: function(propertiesToInclude) { - return this.toDatalessObject(propertiesToInclude); - }, - toObject: function(propertiesToInclude) { - return this._toObjectMethod("toObject", propertiesToInclude); - }, - toDatalessObject: function(propertiesToInclude) { - return this._toObjectMethod("toDatalessObject", propertiesToInclude); - }, - _toObjectMethod: function(methodName, propertiesToInclude) { - var data = { - objects: this._toObjects(methodName, propertiesToInclude) - }; - extend(data, this.__serializeBgOverlay()); - fabric.util.populateWithProperties(this, data, propertiesToInclude); - return data; - }, - _toObjects: function(methodName, propertiesToInclude) { - return this.getObjects().map(function(instance) { - return this._toObject(instance, methodName, propertiesToInclude); - }, this); - }, - _toObject: function(instance, methodName, propertiesToInclude) { - var originalValue; - if (!this.includeDefaultValues) { - originalValue = instance.includeDefaultValues; - instance.includeDefaultValues = false; - } - var originalProperties = this._realizeGroupTransformOnObject(instance), object = instance[methodName](propertiesToInclude); - if (!this.includeDefaultValues) { - instance.includeDefaultValues = originalValue; - } - this._unwindGroupTransformOnObject(instance, originalProperties); - return object; - }, - _realizeGroupTransformOnObject: function(instance) { - var layoutProps = [ "angle", "flipX", "flipY", "height", "left", "scaleX", "scaleY", "top", "width" ]; - if (instance.group && instance.group === this.getActiveGroup()) { - var originalValues = {}; - layoutProps.forEach(function(prop) { - originalValues[prop] = instance[prop]; - }); - this.getActiveGroup().realizeTransform(instance); - return originalValues; - } else { - return null; - } - }, - _unwindGroupTransformOnObject: function(instance, originalValues) { - if (originalValues) { - instance.set(originalValues); - } - }, - __serializeBgOverlay: function() { - var data = { - background: this.backgroundColor && this.backgroundColor.toObject ? this.backgroundColor.toObject() : this.backgroundColor - }; - if (this.overlayColor) { - data.overlay = this.overlayColor.toObject ? this.overlayColor.toObject() : this.overlayColor; - } - if (this.backgroundImage) { - data.backgroundImage = this.backgroundImage.toObject(); - } - if (this.overlayImage) { - data.overlayImage = this.overlayImage.toObject(); - } - return data; - }, - svgViewportTransformation: true, - toSVG: function(options, reviver) { - options || (options = {}); - var markup = []; - this._setSVGPreamble(markup, options); - this._setSVGHeader(markup, options); - this._setSVGBgOverlayColor(markup, "backgroundColor"); - this._setSVGBgOverlayImage(markup, "backgroundImage"); - this._setSVGObjects(markup, reviver); - this._setSVGBgOverlayColor(markup, "overlayColor"); - this._setSVGBgOverlayImage(markup, "overlayImage"); - markup.push(""); - return markup.join(""); - }, - _setSVGPreamble: function(markup, options) { - if (options.suppressPreamble) { - return; - } - markup.push('\n', '\n'); - }, - _setSVGHeader: function(markup, options) { - var width = options.width || this.width, height = options.height || this.height, vpt, viewBox = 'viewBox="0 0 ' + this.width + " " + this.height + '" ', NUM_FRACTION_DIGITS = fabric.Object.NUM_FRACTION_DIGITS; - if (options.viewBox) { - viewBox = 'viewBox="' + options.viewBox.x + " " + options.viewBox.y + " " + options.viewBox.width + " " + options.viewBox.height + '" '; - } else { - if (this.svgViewportTransformation) { - vpt = this.viewportTransform; - viewBox = 'viewBox="' + toFixed(-vpt[4] / vpt[0], NUM_FRACTION_DIGITS) + " " + toFixed(-vpt[5] / vpt[3], NUM_FRACTION_DIGITS) + " " + toFixed(this.width / vpt[0], NUM_FRACTION_DIGITS) + " " + toFixed(this.height / vpt[3], NUM_FRACTION_DIGITS) + '" '; - } - } - markup.push("\n', "Created with Fabric.js ", fabric.version, "\n", "", fabric.createSVGFontFacesMarkup(this.getObjects()), fabric.createSVGRefElementsMarkup(this), "\n"); - }, - _setSVGObjects: function(markup, reviver) { - for (var i = 0, objects = this.getObjects(), len = objects.length; i < len; i++) { - var instance = objects[i], originalProperties = this._realizeGroupTransformOnObject(instance); - markup.push(instance.toSVG(reviver)); - this._unwindGroupTransformOnObject(instance, originalProperties); - } - }, - _setSVGBgOverlayImage: function(markup, property) { - if (this[property] && this[property].toSVG) { - markup.push(this[property].toSVG()); - } - }, - _setSVGBgOverlayColor: function(markup, property) { - if (this[property] && this[property].source) { - markup.push('\n"); - } else if (this[property] && property === "overlayColor") { - markup.push('\n"); - } - }, - sendToBack: function(object) { - removeFromArray(this._objects, object); - this._objects.unshift(object); - return this.renderAll && this.renderAll(); - }, - bringToFront: function(object) { - removeFromArray(this._objects, object); - this._objects.push(object); - return this.renderAll && this.renderAll(); - }, - sendBackwards: function(object, intersecting) { - var idx = this._objects.indexOf(object); - if (idx !== 0) { - var newIdx = this._findNewLowerIndex(object, idx, intersecting); - removeFromArray(this._objects, object); - this._objects.splice(newIdx, 0, object); - this.renderAll && this.renderAll(); - } - return this; - }, - _findNewLowerIndex: function(object, idx, intersecting) { - var newIdx; - if (intersecting) { - newIdx = idx; - for (var i = idx - 1; i >= 0; --i) { - var isIntersecting = object.intersectsWithObject(this._objects[i]) || object.isContainedWithinObject(this._objects[i]) || this._objects[i].isContainedWithinObject(object); - if (isIntersecting) { - newIdx = i; - break; - } - } - } else { - newIdx = idx - 1; - } - return newIdx; - }, - bringForward: function(object, intersecting) { - var idx = this._objects.indexOf(object); - if (idx !== this._objects.length - 1) { - var newIdx = this._findNewUpperIndex(object, idx, intersecting); - removeFromArray(this._objects, object); - this._objects.splice(newIdx, 0, object); - this.renderAll && this.renderAll(); - } - return this; - }, - _findNewUpperIndex: function(object, idx, intersecting) { - var newIdx; - if (intersecting) { - newIdx = idx; - for (var i = idx + 1; i < this._objects.length; ++i) { - var isIntersecting = object.intersectsWithObject(this._objects[i]) || object.isContainedWithinObject(this._objects[i]) || this._objects[i].isContainedWithinObject(object); - if (isIntersecting) { - newIdx = i; - break; - } - } - } else { - newIdx = idx + 1; - } - return newIdx; - }, - moveTo: function(object, index) { - removeFromArray(this._objects, object); - this._objects.splice(index, 0, object); - return this.renderAll && this.renderAll(); - }, - dispose: function() { - this.clear(); - return this; - }, - toString: function() { - return "#"; - } - }); - extend(fabric.StaticCanvas.prototype, fabric.Observable); - extend(fabric.StaticCanvas.prototype, fabric.Collection); - extend(fabric.StaticCanvas.prototype, fabric.DataURLExporter); - extend(fabric.StaticCanvas, { - EMPTY_JSON: '{"objects": [], "background": "white"}', - supports: function(methodName) { - var el = fabric.util.createCanvasElement(); - if (!el || !el.getContext) { - return null; - } - var ctx = el.getContext("2d"); - if (!ctx) { - return null; - } - switch (methodName) { - case "getImageData": - return typeof ctx.getImageData !== "undefined"; - - case "setLineDash": - return typeof ctx.setLineDash !== "undefined"; - - case "toDataURL": - return typeof el.toDataURL !== "undefined"; - - case "toDataURLWithQuality": - try { - el.toDataURL("image/jpeg", 0); - return true; - } catch (e) {} - return false; - - 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(options) { - this.shadow = new fabric.Shadow(options); - return this; - }, - _setBrushStyles: function() { - var ctx = this.canvas.contextTop; - ctx.strokeStyle = this.color; - ctx.lineWidth = this.width; - ctx.lineCap = this.strokeLineCap; - ctx.lineJoin = this.strokeLineJoin; - if (this.strokeDashArray && fabric.StaticCanvas.supports("setLineDash")) { - ctx.setLineDash(this.strokeDashArray); - } - }, - _setShadow: function() { - if (!this.shadow) { - return; - } - var ctx = this.canvas.contextTop; - ctx.shadowColor = this.shadow.color; - ctx.shadowBlur = this.shadow.blur; - ctx.shadowOffsetX = this.shadow.offsetX; - ctx.shadowOffsetY = this.shadow.offsetY; - }, - _resetShadow: function() { - var ctx = this.canvas.contextTop; - ctx.shadowColor = ""; - ctx.shadowBlur = ctx.shadowOffsetX = ctx.shadowOffsetY = 0; - } -}); - -(function() { - fabric.PencilBrush = fabric.util.createClass(fabric.BaseBrush, { - initialize: function(canvas) { - this.canvas = canvas; - this._points = []; - }, - onMouseDown: function(pointer) { - this._prepareForDrawing(pointer); - this._captureDrawingPath(pointer); - this._render(); - }, - onMouseMove: function(pointer) { - this._captureDrawingPath(pointer); - this.canvas.clearContext(this.canvas.contextTop); - this._render(); - }, - onMouseUp: function() { - this._finalizeAndAddPath(); - }, - _prepareForDrawing: function(pointer) { - var p = new fabric.Point(pointer.x, pointer.y); - this._reset(); - this._addPoint(p); - this.canvas.contextTop.moveTo(p.x, p.y); - }, - _addPoint: function(point) { - this._points.push(point); - }, - _reset: function() { - this._points.length = 0; - this._setBrushStyles(); - this._setShadow(); - }, - _captureDrawingPath: function(pointer) { - var pointerPoint = new fabric.Point(pointer.x, pointer.y); - this._addPoint(pointerPoint); - }, - _render: function() { - var ctx = this.canvas.contextTop, v = this.canvas.viewportTransform, p1 = this._points[0], p2 = this._points[1]; - ctx.save(); - ctx.transform(v[0], v[1], v[2], v[3], v[4], v[5]); - ctx.beginPath(); - if (this._points.length === 2 && p1.x === p2.x && p1.y === p2.y) { - p1.x -= .5; - p2.x += .5; - } - ctx.moveTo(p1.x, p1.y); - for (var i = 1, len = this._points.length; i < len; i++) { - var midPoint = p1.midPointFrom(p2); - ctx.quadraticCurveTo(p1.x, p1.y, midPoint.x, midPoint.y); - p1 = this._points[i]; - p2 = this._points[i + 1]; - } - ctx.lineTo(p1.x, p1.y); - ctx.stroke(); - ctx.restore(); - }, - convertPointsToSVGPath: function(points) { - var path = [], p1 = new fabric.Point(points[0].x, points[0].y), p2 = new fabric.Point(points[1].x, points[1].y); - path.push("M ", points[0].x, " ", points[0].y, " "); - for (var i = 1, len = points.length; i < len; i++) { - var midPoint = p1.midPointFrom(p2); - path.push("Q ", p1.x, " ", p1.y, " ", midPoint.x, " ", midPoint.y, " "); - p1 = new fabric.Point(points[i].x, points[i].y); - if (i + 1 < points.length) { - p2 = new fabric.Point(points[i + 1].x, points[i + 1].y); - } - } - path.push("L ", p1.x, " ", p1.y, " "); - return path; - }, - createPath: function(pathData) { - var path = new fabric.Path(pathData, { - fill: null, - stroke: this.color, - strokeWidth: this.width, - strokeLineCap: this.strokeLineCap, - strokeLineJoin: this.strokeLineJoin, - strokeDashArray: this.strokeDashArray, - originX: "center", - originY: "center" - }); - if (this.shadow) { - this.shadow.affectStroke = true; - path.setShadow(this.shadow); - } - return path; - }, - _finalizeAndAddPath: function() { - var ctx = this.canvas.contextTop; - 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(); - return; - } - var path = this.createPath(pathData); - this.canvas.add(path); - path.setCoords(); - this.canvas.clearContext(this.canvas.contextTop); - this._resetShadow(); - this.canvas.renderAll(); - this.canvas.fire("path:created", { - path: path - }); - } - }); -})(); - -fabric.CircleBrush = fabric.util.createClass(fabric.BaseBrush, { - width: 10, - initialize: function(canvas) { - this.canvas = canvas; - this.points = []; - }, - drawDot: function(pointer) { - var point = this.addPoint(pointer), ctx = this.canvas.contextTop, v = this.canvas.viewportTransform; - ctx.save(); - ctx.transform(v[0], v[1], v[2], v[3], v[4], v[5]); - ctx.fillStyle = point.fill; - ctx.beginPath(); - ctx.arc(point.x, point.y, point.radius, 0, Math.PI * 2, false); - ctx.closePath(); - ctx.fill(); - ctx.restore(); - }, - onMouseDown: function(pointer) { - this.points.length = 0; - this.canvas.clearContext(this.canvas.contextTop); - this._setShadow(); - this.drawDot(pointer); - }, - onMouseMove: function(pointer) { - this.drawDot(pointer); - }, - onMouseUp: function() { - var originalRenderOnAddRemove = this.canvas.renderOnAddRemove; - this.canvas.renderOnAddRemove = false; - var circles = []; - for (var i = 0, len = this.points.length; i < len; i++) { - var point = this.points[i], circle = new fabric.Circle({ - radius: point.radius, - left: point.x, - top: point.y, - originX: "center", - originY: "center", - fill: point.fill - }); - this.shadow && circle.setShadow(this.shadow); - circles.push(circle); - } - var group = new fabric.Group(circles, { - originX: "center", - originY: "center" - }); - group.canvas = this.canvas; - this.canvas.add(group); - this.canvas.fire("path:created", { - path: group - }); - this.canvas.clearContext(this.canvas.contextTop); - this._resetShadow(); - this.canvas.renderOnAddRemove = originalRenderOnAddRemove; - this.canvas.renderAll(); - }, - 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(); - pointerPoint.radius = circleRadius; - pointerPoint.fill = circleColor; - this.points.push(pointerPoint); - return pointerPoint; - } -}); - -fabric.SprayBrush = fabric.util.createClass(fabric.BaseBrush, { - width: 10, - density: 20, - dotWidth: 1, - dotWidthVariance: 1, - randomOpacity: false, - optimizeOverlapping: true, - initialize: function(canvas) { - this.canvas = canvas; - this.sprayChunks = []; - }, - onMouseDown: function(pointer) { - this.sprayChunks.length = 0; - this.canvas.clearContext(this.canvas.contextTop); - this._setShadow(); - this.addSprayChunk(pointer); - this.render(); - }, - onMouseMove: function(pointer) { - this.addSprayChunk(pointer); - this.render(); - }, - onMouseUp: function() { - var originalRenderOnAddRemove = this.canvas.renderOnAddRemove; - this.canvas.renderOnAddRemove = false; - var rects = []; - for (var i = 0, ilen = this.sprayChunks.length; i < ilen; i++) { - var sprayChunk = this.sprayChunks[i]; - for (var j = 0, jlen = sprayChunk.length; j < jlen; j++) { - var rect = new fabric.Rect({ - width: sprayChunk[j].width, - height: sprayChunk[j].width, - left: sprayChunk[j].x + 1, - top: sprayChunk[j].y + 1, - originX: "center", - originY: "center", - fill: this.color - }); - this.shadow && rect.setShadow(this.shadow); - rects.push(rect); - } - } - if (this.optimizeOverlapping) { - rects = this._getOptimizedRects(rects); - } - var group = new fabric.Group(rects, { - originX: "center", - originY: "center" - }); - group.canvas = this.canvas; - this.canvas.add(group); - this.canvas.fire("path:created", { - path: group - }); - this.canvas.clearContext(this.canvas.contextTop); - this._resetShadow(); - this.canvas.renderOnAddRemove = originalRenderOnAddRemove; - this.canvas.renderAll(); - }, - _getOptimizedRects: function(rects) { - var uniqueRects = {}, key; - for (var i = 0, len = rects.length; i < len; i++) { - key = rects[i].left + "" + rects[i].top; - if (!uniqueRects[key]) { - uniqueRects[key] = rects[i]; - } - } - var uniqueRectsArray = []; - for (key in uniqueRects) { - uniqueRectsArray.push(uniqueRects[key]); - } - return uniqueRectsArray; - }, - render: function() { - var ctx = this.canvas.contextTop; - ctx.fillStyle = this.color; - var v = this.canvas.viewportTransform; - ctx.save(); - ctx.transform(v[0], v[1], v[2], v[3], v[4], v[5]); - for (var i = 0, len = this.sprayChunkPoints.length; i < len; i++) { - var point = this.sprayChunkPoints[i]; - if (typeof point.opacity !== "undefined") { - ctx.globalAlpha = point.opacity; - } - ctx.fillRect(point.x, point.y, point.width, point.width); - } - ctx.restore(); - }, - addSprayChunk: function(pointer) { - this.sprayChunkPoints = []; - var x, y, width, radius = this.width / 2; - for (var i = 0; i < this.density; i++) { - x = fabric.util.getRandomInt(pointer.x - radius, pointer.x + radius); - y = fabric.util.getRandomInt(pointer.y - radius, pointer.y + radius); - if (this.dotWidthVariance) { - width = fabric.util.getRandomInt(Math.max(1, this.dotWidth - this.dotWidthVariance), this.dotWidth + this.dotWidthVariance); - } else { - width = this.dotWidth; - } - var point = new fabric.Point(x, y); - point.width = width; - if (this.randomOpacity) { - point.opacity = fabric.util.getRandomInt(0, 100) / 100; - } - this.sprayChunkPoints.push(point); - } - this.sprayChunks.push(this.sprayChunkPoints); - } -}); - -fabric.PatternBrush = fabric.util.createClass(fabric.PencilBrush, { - getPatternSrc: function() { - var dotWidth = 20, dotDistance = 5, patternCanvas = fabric.document.createElement("canvas"), patternCtx = patternCanvas.getContext("2d"); - patternCanvas.width = patternCanvas.height = dotWidth + dotDistance; - patternCtx.fillStyle = this.color; - patternCtx.beginPath(); - patternCtx.arc(dotWidth / 2, dotWidth / 2, dotWidth / 2, 0, Math.PI * 2, false); - patternCtx.closePath(); - patternCtx.fill(); - return patternCanvas; - }, - getPatternSrcFunction: function() { - return String(this.getPatternSrc).replace("this.color", '"' + this.color + '"'); - }, - getPattern: function() { - return this.canvas.contextTop.createPattern(this.source || this.getPatternSrc(), "repeat"); - }, - _setBrushStyles: function() { - this.callSuper("_setBrushStyles"); - this.canvas.contextTop.strokeStyle = this.getPattern(); - }, - createPath: function(pathData) { - var path = this.callSuper("createPath", pathData); - path.stroke = new fabric.Pattern({ - source: this.source || this.getPatternSrcFunction() - }); - return path; - } -}); - -(function() { - var getPointer = fabric.util.getPointer, degreesToRadians = fabric.util.degreesToRadians, radiansToDegrees = fabric.util.radiansToDegrees, atan2 = Math.atan2, abs = Math.abs, STROKE_OFFSET = .5; - fabric.Canvas = fabric.util.createClass(fabric.StaticCanvas, { - initialize: function(el, options) { - options || (options = {}); - this._initStatic(el, options); - this._initInteractive(); - this._createCacheCanvas(); - }, - uniScaleTransform: false, - centeredScaling: false, - centeredRotation: false, - interactive: true, - selection: true, - selectionColor: "rgba(100, 100, 255, 0.3)", - selectionDashArray: [], - selectionBorderColor: "rgba(255, 255, 255, 0.3)", - selectionLineWidth: 1, - hoverCursor: "move", - moveCursor: "move", - defaultCursor: "default", - freeDrawingCursor: "crosshair", - rotationCursor: "crosshair", - containerClass: "canvas-container", - perPixelTargetFind: false, - targetFindTolerance: 0, - skipTargetFind: false, - isDrawingMode: false, - _initInteractive: function() { - this._currentTransform = null; - this._groupSelector = null; - this._initWrapperElement(); - this._createUpperCanvas(); - this._initEventListeners(); - this._initRetinaScaling(); - this.freeDrawingBrush = fabric.PencilBrush && new fabric.PencilBrush(this); - this.calcOffset(); - }, - _resetCurrentTransform: function() { - var t = this._currentTransform; - t.target.set({ - scaleX: t.original.scaleX, - scaleY: t.original.scaleY, - skewX: t.original.skewX, - skewY: t.original.skewY, - left: t.original.left, - top: t.original.top - }); - if (this._shouldCenterTransform(t.target)) { - if (t.action === "rotate") { - this._setOriginToCenter(t.target); - } else { - if (t.originX !== "center") { - if (t.originX === "right") { - t.mouseXSign = -1; - } else { - t.mouseXSign = 1; - } - } - if (t.originY !== "center") { - if (t.originY === "bottom") { - t.mouseYSign = -1; - } else { - t.mouseYSign = 1; - } - } - t.originX = "center"; - t.originY = "center"; - } - } else { - t.originX = t.original.originX; - t.originY = t.original.originY; - } - }, - containsPoint: function(e, target) { - var pointer = this.getPointer(e, true), xy = this._normalizePointer(target, pointer); - return target.containsPoint(xy) || target._findTargetCorner(pointer); - }, - _normalizePointer: function(object, pointer) { - var activeGroup = this.getActiveGroup(), isObjectInGroup = activeGroup && object.type !== "group" && activeGroup.contains(object), lt, m; - if (isObjectInGroup) { - m = fabric.util.multiplyTransformMatrices(this.viewportTransform, activeGroup.calcTransformMatrix()); - m = fabric.util.invertTransform(m); - pointer = fabric.util.transformPoint(pointer, m, false); - lt = fabric.util.transformPoint(activeGroup.getCenterPoint(), m, false); - pointer.x -= lt.x; - pointer.y -= lt.y; - } - return { - x: pointer.x, - y: pointer.y - }; - }, - isTargetTransparent: function(target, x, y) { - var hasBorders = target.hasBorders, transparentCorners = target.transparentCorners; - target.hasBorders = target.transparentCorners = false; - target.render(this.contextCache); - target._renderControls(this.contextCache); - target.hasBorders = hasBorders; - target.transparentCorners = transparentCorners; - var isTransparent = fabric.util.isTransparent(this.contextCache, x, y, this.targetFindTolerance); - this.clearContext(this.contextCache); - return isTransparent; - }, - _shouldClearSelection: function(e, target) { - var activeGroup = this.getActiveGroup(), activeObject = this.getActiveObject(); - return !target || target && activeGroup && !activeGroup.contains(target) && activeGroup !== target && !e.shiftKey || target && !target.evented || target && !target.selectable && activeObject && activeObject !== target; - }, - _shouldCenterTransform: function(target) { - if (!target) { - return; - } - var t = this._currentTransform, centerTransform; - if (t.action === "scale" || t.action === "scaleX" || t.action === "scaleY") { - centerTransform = this.centeredScaling || target.centeredScaling; - } else if (t.action === "rotate") { - centerTransform = this.centeredRotation || target.centeredRotation; - } - return centerTransform ? !t.altKey : t.altKey; - }, - _getOriginFromCorner: function(target, corner) { - var origin = { - x: target.originX, - y: target.originY - }; - if (corner === "ml" || corner === "tl" || corner === "bl") { - origin.x = "right"; - } else if (corner === "mr" || corner === "tr" || corner === "br") { - origin.x = "left"; - } - if (corner === "tl" || corner === "mt" || corner === "tr") { - origin.y = "bottom"; - } else if (corner === "bl" || corner === "mb" || corner === "br") { - origin.y = "top"; - } - return origin; - }, - _getActionFromCorner: function(target, corner, e) { - if (!corner) { - return "drag"; - } - switch (corner) { - case "mtr": - return "rotate"; - - case "ml": - case "mr": - return e.shiftKey ? "skewY" : "scaleX"; - - case "mt": - case "mb": - return e.shiftKey ? "skewX" : "scaleY"; - - default: - return "scale"; - } - }, - _setupCurrentTransform: function(e, target) { - if (!target) { - return; - } - var pointer = this.getPointer(e), corner = target._findTargetCorner(this.getPointer(e, true)), action = this._getActionFromCorner(target, corner, e), origin = this._getOriginFromCorner(target, corner); - this._currentTransform = { - target: target, - action: action, - corner: corner, - scaleX: target.scaleX, - scaleY: target.scaleY, - skewX: target.skewX, - skewY: target.skewY, - offsetX: pointer.x - target.left, - offsetY: pointer.y - target.top, - originX: origin.x, - originY: origin.y, - ex: pointer.x, - ey: pointer.y, - lastX: pointer.x, - lastY: pointer.y, - left: target.left, - top: target.top, - theta: degreesToRadians(target.angle), - width: target.width * target.scaleX, - mouseXSign: 1, - mouseYSign: 1, - shiftKey: e.shiftKey, - altKey: e.altKey - }; - this._currentTransform.original = { - left: target.left, - top: target.top, - scaleX: target.scaleX, - scaleY: target.scaleY, - skewX: target.skewX, - skewY: target.skewY, - originX: origin.x, - originY: origin.y - }; - this._resetCurrentTransform(); - }, - _translateObject: function(x, y) { - var transform = this._currentTransform, target = transform.target, newLeft = x - transform.offsetX, newTop = y - transform.offsetY, moveX = !target.get("lockMovementX") && target.left !== newLeft, moveY = !target.get("lockMovementY") && target.top !== newTop; - moveX && target.set("left", newLeft); - moveY && target.set("top", newTop); - return moveX || moveY; - }, - _changeSkewTransformOrigin: function(mouseMove, t, by) { - var property = "originX", origins = { - 0: "center" - }, skew = t.target.skewX, originA = "left", originB = "right", corner = t.corner === "mt" || t.corner === "ml" ? 1 : -1, flipSign = 1; - mouseMove = mouseMove > 0 ? 1 : -1; - if (by === "y") { - skew = t.target.skewY; - originA = "top"; - originB = "bottom"; - property = "originY"; - } - origins[-1] = originA; - origins[1] = originB; - t.target.flipX && (flipSign *= -1); - t.target.flipY && (flipSign *= -1); - if (skew === 0) { - t.skewSign = -corner * mouseMove * flipSign; - t[property] = origins[-mouseMove]; - } else { - skew = skew > 0 ? 1 : -1; - t.skewSign = skew; - t[property] = origins[skew * corner * flipSign]; - } - }, - _skewObject: function(x, y, by) { - var t = this._currentTransform, target = t.target, skewed = false, lockSkewingX = target.get("lockSkewingX"), lockSkewingY = target.get("lockSkewingY"); - if (lockSkewingX && by === "x" || lockSkewingY && by === "y") { - return false; - } - var center = target.getCenterPoint(), actualMouseByCenter = target.toLocalPoint(new fabric.Point(x, y), "center", "center")[by], lastMouseByCenter = target.toLocalPoint(new fabric.Point(t.lastX, t.lastY), "center", "center")[by], actualMouseByOrigin, constraintPosition, dim = target._getTransformedDimensions(); - this._changeSkewTransformOrigin(actualMouseByCenter - lastMouseByCenter, t, by); - actualMouseByOrigin = target.toLocalPoint(new fabric.Point(x, y), t.originX, t.originY)[by], - constraintPosition = target.translateToOriginPoint(center, t.originX, t.originY); - skewed = this._setObjectSkew(actualMouseByOrigin, t, by, dim); - t.lastX = x; - t.lastY = y; - target.setPositionByOrigin(constraintPosition, t.originX, t.originY); - return skewed; - }, - _setObjectSkew: function(localMouse, transform, by, _dim) { - var target = transform.target, newValue, skewed = false, skewSign = transform.skewSign, newDim, dimNoSkew, otherBy, _otherBy, _by, newDimMouse, skewX, skewY; - if (by === "x") { - otherBy = "y"; - _otherBy = "Y"; - _by = "X"; - skewX = 0; - skewY = target.skewY; - } else { - otherBy = "x"; - _otherBy = "X"; - _by = "Y"; - skewX = target.skewX; - skewY = 0; - } - dimNoSkew = target._getTransformedDimensions(skewX, skewY); - newDimMouse = 2 * Math.abs(localMouse) - dimNoSkew[by]; - if (newDimMouse <= 2) { - newValue = 0; - } else { - newValue = skewSign * Math.atan(newDimMouse / target["scale" + _by] / (dimNoSkew[otherBy] / target["scale" + _otherBy])); - newValue = fabric.util.radiansToDegrees(newValue); - } - skewed = target["skew" + _by] !== newValue; - target.set("skew" + _by, newValue); - if (target["skew" + _otherBy] !== 0) { - newDim = target._getTransformedDimensions(); - newValue = _dim[otherBy] / newDim[otherBy] * target["scale" + _otherBy]; - target.set("scale" + _otherBy, newValue); - } - return skewed; - }, - _scaleObject: function(x, y, by) { - var t = this._currentTransform, target = t.target, lockScalingX = target.get("lockScalingX"), lockScalingY = target.get("lockScalingY"), lockScalingFlip = target.get("lockScalingFlip"); - if (lockScalingX && lockScalingY) { - return false; - } - var constraintPosition = target.translateToOriginPoint(target.getCenterPoint(), t.originX, t.originY), localMouse = target.toLocalPoint(new fabric.Point(x, y), t.originX, t.originY), dim = target._getTransformedDimensions(), scaled = false; - this._setLocalMouse(localMouse, t); - scaled = this._setObjectScale(localMouse, t, lockScalingX, lockScalingY, by, lockScalingFlip, dim); - target.setPositionByOrigin(constraintPosition, t.originX, t.originY); - return scaled; - }, - _setObjectScale: function(localMouse, transform, lockScalingX, lockScalingY, by, lockScalingFlip, _dim) { - var target = transform.target, forbidScalingX = false, forbidScalingY = false, scaled = false, changeX, changeY, scaleX, scaleY; - scaleX = localMouse.x * target.scaleX / _dim.x; - scaleY = localMouse.y * target.scaleY / _dim.y; - changeX = target.scaleX !== scaleX; - changeY = target.scaleY !== scaleY; - if (lockScalingFlip && scaleX <= 0 && scaleX < target.scaleX) { - forbidScalingX = true; - } - if (lockScalingFlip && scaleY <= 0 && scaleY < target.scaleY) { - forbidScalingY = true; - } - if (by === "equally" && !lockScalingX && !lockScalingY) { - forbidScalingX || forbidScalingY || (scaled = this._scaleObjectEqually(localMouse, target, transform, _dim)); - } else if (!by) { - forbidScalingX || lockScalingX || target.set("scaleX", scaleX) && (scaled = scaled || changeX); - forbidScalingY || lockScalingY || target.set("scaleY", scaleY) && (scaled = scaled || changeY); - } else if (by === "x" && !target.get("lockUniScaling")) { - forbidScalingX || lockScalingX || target.set("scaleX", scaleX) && (scaled = scaled || changeX); - } else if (by === "y" && !target.get("lockUniScaling")) { - forbidScalingY || lockScalingY || target.set("scaleY", scaleY) && (scaled = scaled || changeY); - } - transform.newScaleX = scaleX; - transform.newScaleY = scaleY; - forbidScalingX || forbidScalingY || this._flipObject(transform, by); - return scaled; - }, - _scaleObjectEqually: function(localMouse, target, transform, _dim) { - var dist = localMouse.y + localMouse.x, lastDist = _dim.y * transform.original.scaleY / target.scaleY + _dim.x * transform.original.scaleX / target.scaleX, scaled; - transform.newScaleX = transform.original.scaleX * dist / lastDist; - transform.newScaleY = transform.original.scaleY * dist / lastDist; - scaled = transform.newScaleX !== target.scaleX || transform.newScaleY !== target.scaleY; - target.set("scaleX", transform.newScaleX); - target.set("scaleY", transform.newScaleY); - return scaled; - }, - _flipObject: function(transform, by) { - if (transform.newScaleX < 0 && by !== "y") { - if (transform.originX === "left") { - transform.originX = "right"; - } else if (transform.originX === "right") { - transform.originX = "left"; - } - } - if (transform.newScaleY < 0 && by !== "x") { - if (transform.originY === "top") { - transform.originY = "bottom"; - } else if (transform.originY === "bottom") { - transform.originY = "top"; - } - } - }, - _setLocalMouse: function(localMouse, t) { - var target = t.target; - if (t.originX === "right") { - localMouse.x *= -1; - } else if (t.originX === "center") { - localMouse.x *= t.mouseXSign * 2; - if (localMouse.x < 0) { - t.mouseXSign = -t.mouseXSign; - } - } - if (t.originY === "bottom") { - localMouse.y *= -1; - } else if (t.originY === "center") { - localMouse.y *= t.mouseYSign * 2; - if (localMouse.y < 0) { - t.mouseYSign = -t.mouseYSign; - } - } - if (abs(localMouse.x) > target.padding) { - if (localMouse.x < 0) { - localMouse.x += target.padding; - } else { - localMouse.x -= target.padding; - } - } else { - localMouse.x = 0; - } - if (abs(localMouse.y) > target.padding) { - if (localMouse.y < 0) { - localMouse.y += target.padding; - } else { - localMouse.y -= target.padding; - } - } else { - localMouse.y = 0; - } - }, - _rotateObject: function(x, y) { - var t = this._currentTransform; - if (t.target.get("lockRotation")) { - return false; - } - var lastAngle = atan2(t.ey - t.top, t.ex - t.left), curAngle = atan2(y - t.top, x - t.left), angle = radiansToDegrees(curAngle - lastAngle + t.theta); - if (angle < 0) { - angle = 360 + angle; - } - t.target.angle = angle % 360; - return true; - }, - setCursor: function(value) { - this.upperCanvasEl.style.cursor = value; - }, - _resetObjectTransform: function(target) { - target.scaleX = 1; - target.scaleY = 1; - target.skewX = 0; - target.skewY = 0; - target.setAngle(0); - }, - _drawSelection: function() { - var ctx = this.contextTop, groupSelector = this._groupSelector, left = groupSelector.left, top = groupSelector.top, aleft = abs(left), atop = abs(top); - ctx.fillStyle = this.selectionColor; - ctx.fillRect(groupSelector.ex - (left > 0 ? 0 : -left), groupSelector.ey - (top > 0 ? 0 : -top), aleft, atop); - ctx.lineWidth = this.selectionLineWidth; - ctx.strokeStyle = this.selectionBorderColor; - if (this.selectionDashArray.length > 1) { - var px = groupSelector.ex + STROKE_OFFSET - (left > 0 ? 0 : aleft), py = groupSelector.ey + STROKE_OFFSET - (top > 0 ? 0 : atop); - ctx.beginPath(); - fabric.util.drawDashedLine(ctx, px, py, px + aleft, py, this.selectionDashArray); - fabric.util.drawDashedLine(ctx, px, py + atop - 1, px + aleft, py + atop - 1, this.selectionDashArray); - fabric.util.drawDashedLine(ctx, px, py, px, py + atop, this.selectionDashArray); - fabric.util.drawDashedLine(ctx, px + aleft - 1, py, px + aleft - 1, py + atop, this.selectionDashArray); - ctx.closePath(); - ctx.stroke(); - } else { - ctx.strokeRect(groupSelector.ex + STROKE_OFFSET - (left > 0 ? 0 : aleft), groupSelector.ey + STROKE_OFFSET - (top > 0 ? 0 : atop), aleft, atop); - } - }, - _isLastRenderedObject: function(e) { - return this.controlsAboveOverlay && this.lastRenderedObjectWithControlsAboveOverlay && this.lastRenderedObjectWithControlsAboveOverlay.visible && this.containsPoint(e, this.lastRenderedObjectWithControlsAboveOverlay) && this.lastRenderedObjectWithControlsAboveOverlay._findTargetCorner(this.getPointer(e, true)); - }, - findTarget: function(e, skipGroup) { - if (this.skipTargetFind) { - return; - } - if (this._isLastRenderedObject(e)) { - return this.lastRenderedObjectWithControlsAboveOverlay; - } - var activeGroup = this.getActiveGroup(); - if (activeGroup && !skipGroup && this.containsPoint(e, activeGroup)) { - return activeGroup; - } - var target = this._searchPossibleTargets(e, skipGroup); - this._fireOverOutEvents(target, e); - return target; - }, - _fireOverOutEvents: function(target, e) { - if (target) { - if (this._hoveredTarget !== target) { - if (this._hoveredTarget) { - this.fire("mouse:out", { - target: this._hoveredTarget, - e: e - }); - this._hoveredTarget.fire("mouseout"); - } - this.fire("mouse:over", { - target: target, - e: e - }); - target.fire("mouseover"); - this._hoveredTarget = target; - } - } else if (this._hoveredTarget) { - this.fire("mouse:out", { - target: this._hoveredTarget, - e: e - }); - this._hoveredTarget.fire("mouseout"); - this._hoveredTarget = null; - } - }, - _checkTarget: function(e, obj, pointer) { - if (obj && obj.visible && obj.evented && this.containsPoint(e, obj)) { - if ((this.perPixelTargetFind || obj.perPixelTargetFind) && !obj.isEditing) { - var isTransparent = this.isTargetTransparent(obj, pointer.x, pointer.y); - if (!isTransparent) { - return true; - } - } else { - return true; - } - } - }, - _searchPossibleTargets: function(e, skipGroup) { - var target, pointer = this.getPointer(e, true), i = this._objects.length; - while (i--) { - if ((!this._objects[i].group || skipGroup) && this._checkTarget(e, this._objects[i], pointer)) { - this.relatedTarget = this._objects[i]; - target = this._objects[i]; - break; - } - } - return target; - }, - getPointer: function(e, ignoreZoom, upperCanvasEl) { - if (!upperCanvasEl) { - upperCanvasEl = this.upperCanvasEl; - } - var pointer = getPointer(e), bounds = upperCanvasEl.getBoundingClientRect(), boundsWidth = bounds.width || 0, boundsHeight = bounds.height || 0, cssScale; - if (!boundsWidth || !boundsHeight) { - if ("top" in bounds && "bottom" in bounds) { - boundsHeight = Math.abs(bounds.top - bounds.bottom); - } - if ("right" in bounds && "left" in bounds) { - boundsWidth = Math.abs(bounds.right - bounds.left); - } - } - this.calcOffset(); - pointer.x = pointer.x - this._offset.left; - pointer.y = pointer.y - this._offset.top; - if (!ignoreZoom) { - pointer = fabric.util.transformPoint(pointer, fabric.util.invertTransform(this.viewportTransform)); - } - if (boundsWidth === 0 || boundsHeight === 0) { - cssScale = { - width: 1, - height: 1 - }; - } else { - cssScale = { - width: upperCanvasEl.width / boundsWidth, - height: upperCanvasEl.height / boundsHeight - }; - } - return { - x: pointer.x * cssScale.width, - y: pointer.y * cssScale.height - }; - }, - _createUpperCanvas: function() { - var lowerCanvasClass = this.lowerCanvasEl.className.replace(/\s*lower-canvas\s*/, ""); - this.upperCanvasEl = this._createCanvasElement(); - fabric.util.addClass(this.upperCanvasEl, "upper-canvas " + lowerCanvasClass); - 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(element) { - var width = this.getWidth() || element.width, height = this.getHeight() || element.height; - fabric.util.setStyle(element, { - position: "absolute", - width: width + "px", - height: height + "px", - left: 0, - top: 0 - }); - element.width = width; - element.height = height; - fabric.util.makeElementUnselectable(element); - }, - _copyCanvasStyle: function(fromEl, toEl) { - toEl.style.cssText = fromEl.style.cssText; - }, - getSelectionContext: function() { - return this.contextTop; - }, - getSelectionElement: function() { - return this.upperCanvasEl; - }, - _setActiveObject: function(object) { - if (this._activeObject) { - this._activeObject.set("active", false); - } - this._activeObject = object; - object.set("active", true); - }, - setActiveObject: function(object, e) { - this._setActiveObject(object); - this.renderAll(); - this.fire("object:selected", { - target: object, - e: e - }); - object.fire("selected", { - e: e - }); - return this; - }, - getActiveObject: function() { - return this._activeObject; - }, - _discardActiveObject: function() { - if (this._activeObject) { - this._activeObject.set("active", false); - } - this._activeObject = null; - }, - discardActiveObject: function(e) { - this._discardActiveObject(); - this.renderAll(); - this.fire("selection:cleared", { - e: e - }); - return this; - }, - _setActiveGroup: function(group) { - this._activeGroup = group; - if (group) { - group.set("active", true); - } - }, - setActiveGroup: function(group, e) { - this._setActiveGroup(group); - if (group) { - this.fire("object:selected", { - target: group, - e: e - }); - group.fire("selected", { - e: e - }); - } - return this; - }, - getActiveGroup: function() { - return this._activeGroup; - }, - _discardActiveGroup: function() { - var g = this.getActiveGroup(); - if (g) { - g.destroy(); - } - this.setActiveGroup(null); - }, - discardActiveGroup: function(e) { - this._discardActiveGroup(); - this.fire("selection:cleared", { - e: e - }); - return this; - }, - deactivateAll: function() { - var allObjects = this.getObjects(), i = 0, len = allObjects.length; - for (;i < len; i++) { - allObjects[i].set("active", false); - } - this._discardActiveGroup(); - this._discardActiveObject(); - return this; - }, - deactivateAllWithDispatch: function(e) { - var activeObject = this.getActiveGroup() || this.getActiveObject(); - if (activeObject) { - this.fire("before:selection:cleared", { - target: activeObject, - e: e - }); - } - this.deactivateAll(); - if (activeObject) { - this.fire("selection:cleared", { - e: e - }); - } - return this; - }, - dispose: function() { - this.callSuper("dispose"); - var wrapper = this.wrapperEl; - this.removeListeners(); - wrapper.removeChild(this.upperCanvasEl); - wrapper.removeChild(this.lowerCanvasEl); - delete this.upperCanvasEl; - if (wrapper.parentNode) { - wrapper.parentNode.replaceChild(this.lowerCanvasEl, this.wrapperEl); - } - delete this.wrapperEl; - return this; - }, - drawControls: function(ctx) { - var activeGroup = this.getActiveGroup(); - if (activeGroup) { - activeGroup._renderControls(ctx); - } else { - this._drawObjectsControls(ctx); - } - }, - _drawObjectsControls: function(ctx) { - for (var i = 0, len = this._objects.length; i < len; ++i) { - if (!this._objects[i] || !this._objects[i].active) { - continue; - } - this._objects[i]._renderControls(ctx); - this.lastRenderedObjectWithControlsAboveOverlay = this._objects[i]; - } - } - }); - for (var prop in fabric.StaticCanvas) { - if (prop !== "prototype") { - fabric.Canvas[prop] = fabric.StaticCanvas[prop]; - } - } - if (fabric.isTouchSupported) { - fabric.Canvas.prototype._setCursorFromEvent = function() {}; - } - fabric.Element = fabric.Canvas; -})(); - -(function() { - var cursorOffset = { - mt: 0, - tr: 1, - mr: 2, - br: 3, - mb: 4, - bl: 5, - ml: 6, - tl: 7 - }, addListener = fabric.util.addListener, removeListener = fabric.util.removeListener; - 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._bindEvents(); - addListener(fabric.window, "resize", this._onResize); - addListener(this.upperCanvasEl, "mousedown", this._onMouseDown); - addListener(this.upperCanvasEl, "mousemove", this._onMouseMove); - addListener(this.upperCanvasEl, "mousewheel", this._onMouseWheel); - addListener(this.upperCanvasEl, "touchstart", this._onMouseDown); - addListener(this.upperCanvasEl, "touchmove", this._onMouseMove); - if (typeof eventjs !== "undefined" && "add" in eventjs) { - eventjs.add(this.upperCanvasEl, "gesture", this._onGesture); - eventjs.add(this.upperCanvasEl, "drag", this._onDrag); - eventjs.add(this.upperCanvasEl, "orientation", this._onOrientationChange); - eventjs.add(this.upperCanvasEl, "shake", this._onShake); - eventjs.add(this.upperCanvasEl, "longpress", this._onLongPress); - } - }, - _bindEvents: function() { - this._onMouseDown = this._onMouseDown.bind(this); - this._onMouseMove = this._onMouseMove.bind(this); - this._onMouseUp = this._onMouseUp.bind(this); - this._onResize = this._onResize.bind(this); - this._onGesture = this._onGesture.bind(this); - this._onDrag = this._onDrag.bind(this); - this._onShake = this._onShake.bind(this); - this._onLongPress = this._onLongPress.bind(this); - this._onOrientationChange = this._onOrientationChange.bind(this); - this._onMouseWheel = this._onMouseWheel.bind(this); - }, - removeListeners: function() { - removeListener(fabric.window, "resize", this._onResize); - removeListener(this.upperCanvasEl, "mousedown", this._onMouseDown); - removeListener(this.upperCanvasEl, "mousemove", this._onMouseMove); - removeListener(this.upperCanvasEl, "mousewheel", this._onMouseWheel); - removeListener(this.upperCanvasEl, "touchstart", this._onMouseDown); - removeListener(this.upperCanvasEl, "touchmove", this._onMouseMove); - if (typeof eventjs !== "undefined" && "remove" in eventjs) { - eventjs.remove(this.upperCanvasEl, "gesture", this._onGesture); - eventjs.remove(this.upperCanvasEl, "drag", this._onDrag); - eventjs.remove(this.upperCanvasEl, "orientation", this._onOrientationChange); - eventjs.remove(this.upperCanvasEl, "shake", this._onShake); - eventjs.remove(this.upperCanvasEl, "longpress", this._onLongPress); - } - }, - _onGesture: function(e, self) { - this.__onTransformGesture && this.__onTransformGesture(e, self); - }, - _onDrag: function(e, self) { - this.__onDrag && this.__onDrag(e, self); - }, - _onMouseWheel: function(e, self) { - this.__onMouseWheel && this.__onMouseWheel(e, self); - }, - _onOrientationChange: function(e, self) { - this.__onOrientationChange && this.__onOrientationChange(e, self); - }, - _onShake: function(e, self) { - this.__onShake && this.__onShake(e, self); - }, - _onLongPress: function(e, self) { - this.__onLongPress && this.__onLongPress(e, self); - }, - _onMouseDown: function(e) { - this.__onMouseDown(e); - addListener(fabric.document, "touchend", this._onMouseUp); - addListener(fabric.document, "touchmove", this._onMouseMove); - removeListener(this.upperCanvasEl, "mousemove", this._onMouseMove); - removeListener(this.upperCanvasEl, "touchmove", this._onMouseMove); - if (e.type === "touchstart") { - removeListener(this.upperCanvasEl, "mousedown", this._onMouseDown); - } else { - addListener(fabric.document, "mouseup", this._onMouseUp); - addListener(fabric.document, "mousemove", this._onMouseMove); - } - }, - _onMouseUp: function(e) { - this.__onMouseUp(e); - removeListener(fabric.document, "mouseup", this._onMouseUp); - removeListener(fabric.document, "touchend", this._onMouseUp); - removeListener(fabric.document, "mousemove", this._onMouseMove); - removeListener(fabric.document, "touchmove", this._onMouseMove); - addListener(this.upperCanvasEl, "mousemove", this._onMouseMove); - addListener(this.upperCanvasEl, "touchmove", this._onMouseMove); - if (e.type === "touchend") { - var _this = this; - setTimeout(function() { - addListener(_this.upperCanvasEl, "mousedown", _this._onMouseDown); - }, 400); - } - }, - _onMouseMove: function(e) { - !this.allowTouchScrolling && e.preventDefault && e.preventDefault(); - this.__onMouseMove(e); - }, - _onResize: function() { - this.calcOffset(); - }, - _shouldRender: function(target, pointer) { - var activeObject = this.getActiveGroup() || this.getActiveObject(); - return !!(target && (target.isMoving || target !== activeObject) || !target && !!activeObject || !target && !activeObject && !this._groupSelector || pointer && this._previousPointer && this.selection && (pointer.x !== this._previousPointer.x || pointer.y !== this._previousPointer.y)); - }, - __onMouseUp: function(e) { - var target; - if (this.isDrawingMode && this._isCurrentlyDrawing) { - this._onMouseUpInDrawingMode(e); - return; - } - if (this._currentTransform) { - this._finalizeCurrentTransform(); - target = this._currentTransform.target; - } else { - target = this.findTarget(e, true); - } - var shouldRender = this._shouldRender(target, this.getPointer(e)); - this._maybeGroupObjects(e); - if (target) { - target.isMoving = false; - } - shouldRender && this.renderAll(); - this._handleCursorAndEvent(e, target); - }, - _handleCursorAndEvent: function(e, target) { - this._setCursorFromEvent(e, target); - var _this = this; - setTimeout(function() { - _this._setCursorFromEvent(e, target); - }, 50); - this.fire("mouse:up", { - target: target, - e: e - }); - target && target.fire("mouseup", { - e: e - }); - }, - _finalizeCurrentTransform: function() { - var transform = this._currentTransform, target = transform.target; - if (target._scaling) { - target._scaling = false; - } - target.setCoords(); - this._restoreOriginXY(target); - if (transform.actionPerformed || this.stateful && target.hasStateChanged()) { - this.fire("object:modified", { - target: target - }); - target.fire("modified"); - } - }, - _restoreOriginXY: function(target) { - if (this._previousOriginX && this._previousOriginY) { - var originPoint = target.translateToOriginPoint(target.getCenterPoint(), this._previousOriginX, this._previousOriginY); - target.originX = this._previousOriginX; - target.originY = this._previousOriginY; - target.left = originPoint.x; - target.top = originPoint.y; - this._previousOriginX = null; - this._previousOriginY = null; - } - }, - _onMouseDownInDrawingMode: function(e) { - this._isCurrentlyDrawing = true; - this.discardActiveObject(e).renderAll(); - if (this.clipTo) { - fabric.util.clipContext(this, this.contextTop); - } - var ivt = fabric.util.invertTransform(this.viewportTransform), pointer = fabric.util.transformPoint(this.getPointer(e, true), ivt); - this.freeDrawingBrush.onMouseDown(pointer); - this.fire("mouse:down", { - e: e - }); - var target = this.findTarget(e); - if (typeof target !== "undefined") { - target.fire("mousedown", { - e: e, - target: target - }); - } - }, - _onMouseMoveInDrawingMode: function(e) { - if (this._isCurrentlyDrawing) { - var ivt = fabric.util.invertTransform(this.viewportTransform), pointer = fabric.util.transformPoint(this.getPointer(e, true), ivt); - this.freeDrawingBrush.onMouseMove(pointer); - } - this.setCursor(this.freeDrawingCursor); - this.fire("mouse:move", { - e: e - }); - var target = this.findTarget(e); - if (typeof target !== "undefined") { - target.fire("mousemove", { - e: e, - target: target - }); - } - }, - _onMouseUpInDrawingMode: function(e) { - this._isCurrentlyDrawing = false; - if (this.clipTo) { - this.contextTop.restore(); - } - this.freeDrawingBrush.onMouseUp(); - this.fire("mouse:up", { - e: e - }); - var target = this.findTarget(e); - if (typeof target !== "undefined") { - target.fire("mouseup", { - e: e, - target: target - }); - } - }, - __onMouseDown: function(e) { - var isLeftClick = "which" in e ? e.which === 1 : e.button === 0; - if (!isLeftClick && !fabric.isTouchSupported) { - return; - } - if (this.isDrawingMode) { - this._onMouseDownInDrawingMode(e); - return; - } - if (this._currentTransform) { - return; - } - var target = this.findTarget(e), pointer = this.getPointer(e, true); - this._previousPointer = pointer; - var shouldRender = this._shouldRender(target, pointer), shouldGroup = this._shouldGroup(e, target); - if (this._shouldClearSelection(e, target)) { - this._clearSelection(e, target, pointer); - } else if (shouldGroup) { - this._handleGrouping(e, target); - target = this.getActiveGroup(); - } - if (target && target.selectable && (target.__corner || !shouldGroup)) { - this._beforeTransform(e, target); - this._setupCurrentTransform(e, target); - } - shouldRender && this.renderAll(); - this.fire("mouse:down", { - target: target, - e: e - }); - target && target.fire("mousedown", { - e: e - }); - }, - _beforeTransform: function(e, target) { - this.stateful && target.saveState(); - if (target._findTargetCorner(this.getPointer(e))) { - this.onBeforeScaleRotate(target); - } - if (target !== this.getActiveGroup() && target !== this.getActiveObject()) { - this.deactivateAll(); - this.setActiveObject(target, e); - } - }, - _clearSelection: function(e, target, pointer) { - this.deactivateAllWithDispatch(e); - if (target && target.selectable) { - this.setActiveObject(target, e); - } else if (this.selection) { - this._groupSelector = { - ex: pointer.x, - ey: pointer.y, - top: 0, - left: 0 - }; - } - }, - _setOriginToCenter: function(target) { - this._previousOriginX = this._currentTransform.target.originX; - this._previousOriginY = this._currentTransform.target.originY; - var center = target.getCenterPoint(); - target.originX = "center"; - target.originY = "center"; - target.left = center.x; - target.top = center.y; - this._currentTransform.left = target.left; - this._currentTransform.top = target.top; - }, - _setCenterToOrigin: function(target) { - var originPoint = target.translateToOriginPoint(target.getCenterPoint(), this._previousOriginX, this._previousOriginY); - target.originX = this._previousOriginX; - target.originY = this._previousOriginY; - target.left = originPoint.x; - target.top = originPoint.y; - this._previousOriginX = null; - this._previousOriginY = null; - }, - __onMouseMove: function(e) { - var target, pointer; - if (this.isDrawingMode) { - this._onMouseMoveInDrawingMode(e); - return; - } - if (typeof e.touches !== "undefined" && e.touches.length > 1) { - return; - } - var groupSelector = this._groupSelector; - if (groupSelector) { - pointer = this.getPointer(e, true); - groupSelector.left = pointer.x - groupSelector.ex; - groupSelector.top = pointer.y - groupSelector.ey; - this.renderTop(); - } else if (!this._currentTransform) { - target = this.findTarget(e); - if (!target || target && !target.selectable) { - this.setCursor(this.defaultCursor); - } else { - this._setCursorFromEvent(e, target); - } - } else { - this._transformObject(e); - } - this.fire("mouse:move", { - target: target, - e: e - }); - target && target.fire("mousemove", { - e: e - }); - }, - _transformObject: function(e) { - var pointer = this.getPointer(e), transform = this._currentTransform; - transform.reset = false, transform.target.isMoving = true; - this._beforeScaleTransform(e, transform); - this._performTransformAction(e, transform, pointer); - this.renderAll(); - }, - _performTransformAction: function(e, transform, pointer) { - var x = pointer.x, y = pointer.y, target = transform.target, action = transform.action, actionPerformed = false; - if (action === "rotate") { - (actionPerformed = this._rotateObject(x, y)) && this._fire("rotating", target, e); - } else if (action === "scale") { - (actionPerformed = this._onScale(e, transform, x, y)) && this._fire("scaling", target, e); - } else if (action === "scaleX") { - (actionPerformed = this._scaleObject(x, y, "x")) && this._fire("scaling", target, e); - } else if (action === "scaleY") { - (actionPerformed = this._scaleObject(x, y, "y")) && this._fire("scaling", target, e); - } else if (action === "skewX") { - (actionPerformed = this._skewObject(x, y, "x")) && this._fire("skewing", target, e); - } else if (action === "skewY") { - (actionPerformed = this._skewObject(x, y, "y")) && this._fire("skewing", target, e); - } else { - (actionPerformed = this._translateObject(x, y)) && this._fire("moving", target, e); - this.setCursor(this.moveCursor); - } - transform.actionPerformed = actionPerformed; - }, - _fire: function(eventName, target, e) { - this.fire("object:" + eventName, { - target: target, - e: e - }); - target.fire(eventName, { - e: e - }); - }, - _beforeScaleTransform: function(e, transform) { - if (transform.action === "scale" || transform.action === "scaleX" || transform.action === "scaleY") { - var centerTransform = this._shouldCenterTransform(transform.target); - if (centerTransform && (transform.originX !== "center" || transform.originY !== "center") || !centerTransform && transform.originX === "center" && transform.originY === "center") { - this._resetCurrentTransform(); - transform.reset = true; - } - } - }, - _onScale: function(e, transform, x, y) { - if ((e.shiftKey || this.uniScaleTransform) && !transform.target.get("lockUniScaling")) { - transform.currentAction = "scale"; - return this._scaleObject(x, y); - } else { - if (!transform.reset && transform.currentAction === "scale") { - this._resetCurrentTransform(); - } - transform.currentAction = "scaleEqually"; - return this._scaleObject(x, y, "equally"); - } - }, - _setCursorFromEvent: function(e, target) { - if (!target || !target.selectable) { - this.setCursor(this.defaultCursor); - return false; - } else { - var activeGroup = this.getActiveGroup(), corner = target._findTargetCorner && (!activeGroup || !activeGroup.contains(target)) && target._findTargetCorner(this.getPointer(e, true)); - if (!corner) { - this.setCursor(target.hoverCursor || this.hoverCursor); - } else { - this._setCornerCursor(corner, target, e); - } - } - return true; - }, - _setCornerCursor: function(corner, target, e) { - if (corner in cursorOffset) { - this.setCursor(this._getRotatedCornerCursor(corner, target, e)); - } else if (corner === "mtr" && target.hasRotatingPoint) { - this.setCursor(this.rotationCursor); - } else { - this.setCursor(this.defaultCursor); - return false; - } - }, - _getRotatedCornerCursor: function(corner, target, e) { - var n = Math.round(target.getAngle() % 360 / 45); - if (n < 0) { - n += 8; - } - n += cursorOffset[corner]; - if (e.shiftKey && cursorOffset[corner] % 2 === 0) { - n += 2; - } - n %= 8; - return this.cursorMap[n]; - } - }); -})(); - -(function() { - var min = Math.min, max = Math.max; - fabric.util.object.extend(fabric.Canvas.prototype, { - _shouldGroup: function(e, target) { - var activeObject = this.getActiveObject(); - return e.shiftKey && target && target.selectable && (this.getActiveGroup() || activeObject && activeObject !== target) && this.selection; - }, - _handleGrouping: function(e, target) { - if (target === this.getActiveGroup()) { - target = this.findTarget(e, true); - if (!target || target.isType("group")) { - return; - } - } - if (this.getActiveGroup()) { - this._updateActiveGroup(target, e); - } else { - this._createActiveGroup(target, e); - } - if (this._activeGroup) { - this._activeGroup.saveCoords(); - } - }, - _updateActiveGroup: function(target, e) { - var activeGroup = this.getActiveGroup(); - if (activeGroup.contains(target)) { - activeGroup.removeWithUpdate(target); - target.set("active", false); - if (activeGroup.size() === 1) { - this.discardActiveGroup(e); - this.setActiveObject(activeGroup.item(0)); - return; - } - } else { - activeGroup.addWithUpdate(target); - } - this.fire("selection:created", { - target: activeGroup, - e: e - }); - activeGroup.set("active", true); - }, - _createActiveGroup: function(target, e) { - if (this._activeObject && target !== this._activeObject) { - var group = this._createGroup(target); - group.addWithUpdate(); - this.setActiveGroup(group); - this._activeObject = null; - this.fire("selection:created", { - target: group, - e: e - }); - } - target.set("active", true); - }, - _createGroup: function(target) { - var objects = this.getObjects(), isActiveLower = objects.indexOf(this._activeObject) < objects.indexOf(target), groupObjects = isActiveLower ? [ this._activeObject, target ] : [ target, this._activeObject ]; - return new fabric.Group(groupObjects, { - canvas: this - }); - }, - _groupSelectedObjects: function(e) { - var group = this._collectObjects(); - if (group.length === 1) { - this.setActiveObject(group[0], e); - } else if (group.length > 1) { - group = new fabric.Group(group.reverse(), { - canvas: this - }); - group.addWithUpdate(); - this.setActiveGroup(group, e); - group.saveCoords(); - this.fire("selection:created", { - target: group - }); - this.renderAll(); - } - }, - _collectObjects: function() { - var group = [], currentObject, x1 = this._groupSelector.ex, y1 = this._groupSelector.ey, x2 = x1 + this._groupSelector.left, y2 = y1 + this._groupSelector.top, selectionX1Y1 = new fabric.Point(min(x1, x2), min(y1, y2)), selectionX2Y2 = new fabric.Point(max(x1, x2), max(y1, y2)), isClick = x1 === x2 && y1 === y2; - for (var i = this._objects.length; i--; ) { - currentObject = this._objects[i]; - if (!currentObject || !currentObject.selectable || !currentObject.visible) { - continue; - } - if (currentObject.intersectsWithRect(selectionX1Y1, selectionX2Y2) || currentObject.isContainedWithinRect(selectionX1Y1, selectionX2Y2) || currentObject.containsPoint(selectionX1Y1) || currentObject.containsPoint(selectionX2Y2)) { - currentObject.set("active", true); - group.push(currentObject); - if (isClick) { - break; - } - } - } - return group; - }, - _maybeGroupObjects: function(e) { - if (this.selection && this._groupSelector) { - this._groupSelectedObjects(e); - } - var activeGroup = this.getActiveGroup(); - if (activeGroup) { - activeGroup.setObjectsCoords().setCoords(); - activeGroup.isMoving = false; - this.setCursor(this.defaultCursor); - } - this._groupSelector = null; - this._currentTransform = null; - } - }); -})(); - -fabric.util.object.extend(fabric.StaticCanvas.prototype, { - toDataURL: function(options) { - options || (options = {}); - var format = options.format || "png", quality = options.quality || 1, multiplier = options.multiplier || 1, cropping = { - left: options.left, - top: options.top, - width: options.width, - height: options.height - }; - if (this._isRetinaScaling()) { - multiplier *= fabric.devicePixelRatio; - } - if (multiplier !== 1) { - return this.__toDataURLWithMultiplier(format, quality, cropping, multiplier); - } else { - return this.__toDataURL(format, quality, cropping); - } - }, - __toDataURL: function(format, quality, cropping) { - this.renderAll(); - var canvasEl = this.contextContainer.canvas, croppedCanvasEl = this.__getCroppedCanvas(canvasEl, cropping); - if (format === "jpg") { - format = "jpeg"; - } - var data = fabric.StaticCanvas.supports("toDataURLWithQuality") ? (croppedCanvasEl || canvasEl).toDataURL("image/" + format, quality) : (croppedCanvasEl || canvasEl).toDataURL("image/" + format); - if (croppedCanvasEl) { - croppedCanvasEl = null; - } - return data; - }, - __getCroppedCanvas: function(canvasEl, cropping) { - var croppedCanvasEl, croppedCtx, shouldCrop = "left" in cropping || "top" in cropping || "width" in cropping || "height" in cropping; - if (shouldCrop) { - croppedCanvasEl = fabric.util.createCanvasElement(); - croppedCtx = croppedCanvasEl.getContext("2d"); - croppedCanvasEl.width = cropping.width || this.width; - croppedCanvasEl.height = cropping.height || this.height; - croppedCtx.drawImage(canvasEl, -cropping.left || 0, -cropping.top || 0); - } - return croppedCanvasEl; - }, - __toDataURLWithMultiplier: function(format, quality, cropping, multiplier) { - var origWidth = this.getWidth(), origHeight = this.getHeight(), scaledWidth = origWidth * multiplier, scaledHeight = origHeight * multiplier, activeObject = this.getActiveObject(), activeGroup = this.getActiveGroup(), ctx = this.contextContainer; - if (multiplier > 1) { - this.setDimensions({ - width: scaledWidth, - height: scaledHeight - }); - } - ctx.save(); - ctx.scale(multiplier / fabric.devicePixelRatio, multiplier / fabric.devicePixelRatio); - if (cropping.left) { - cropping.left *= multiplier; - } - if (cropping.top) { - cropping.top *= multiplier; - } - if (cropping.width) { - cropping.width *= multiplier; - } else if (multiplier < 1) { - cropping.width = scaledWidth; - } - if (cropping.height) { - cropping.height *= multiplier; - } else if (multiplier < 1) { - cropping.height = scaledHeight; - } - if (activeGroup) { - this._tempRemoveBordersControlsFromGroup(activeGroup); - } else if (activeObject && this.deactivateAll) { - this.deactivateAll(); - } - var data = this.__toDataURL(format, quality, cropping); - this.width = origWidth; - this.height = origHeight; - this.setDimensions({ - width: origWidth, - height: origHeight - }); - if (activeGroup) { - this._restoreBordersControlsOnGroup(activeGroup); - } else if (activeObject && this.setActiveObject) { - this.setActiveObject(activeObject); - } - this.contextTop && this.clearContext(this.contextTop); - this.renderAll(); - return data; - }, - toDataURLWithMultiplier: function(format, multiplier, quality) { - return this.toDataURL({ - format: format, - multiplier: multiplier, - quality: quality - }); - }, - _tempRemoveBordersControlsFromGroup: function(group) { - group.origHasControls = group.hasControls; - group.origBorderColor = group.borderColor; - group.hasControls = true; - group.borderColor = "rgba(0,0,0,0)"; - group.forEachObject(function(o) { - o.origBorderColor = o.borderColor; - o.borderColor = "rgba(0,0,0,0)"; - }); - }, - _restoreBordersControlsOnGroup: function(group) { - group.hideControls = group.origHideControls; - group.borderColor = group.origBorderColor; - group.forEachObject(function(o) { - o.borderColor = o.origBorderColor; - delete o.origBorderColor; - }); - } -}); - -fabric.util.object.extend(fabric.StaticCanvas.prototype, { - loadFromDatalessJSON: function(json, callback, reviver) { - return this.loadFromJSON(json, callback, reviver); - }, - loadFromJSON: function(json, callback, reviver) { - if (!json) { - return; - } - var serialized = typeof json === "string" ? JSON.parse(json) : json; - this.clear(); - var _this = this; - this._enlivenObjects(serialized.objects, function() { - _this._setBgOverlay(serialized, callback); - }, reviver); - return this; - }, - _setBgOverlay: function(serialized, callback) { - var _this = this, loaded = { - backgroundColor: false, - overlayColor: false, - backgroundImage: false, - overlayImage: false - }; - if (!serialized.backgroundImage && !serialized.overlayImage && !serialized.background && !serialized.overlay) { - callback && callback(); - return; - } - var cbIfLoaded = function() { - if (loaded.backgroundImage && loaded.overlayImage && loaded.backgroundColor && loaded.overlayColor) { - _this.renderAll(); - callback && callback(); - } - }; - this.__setBgOverlay("backgroundImage", serialized.backgroundImage, loaded, cbIfLoaded); - this.__setBgOverlay("overlayImage", serialized.overlayImage, loaded, cbIfLoaded); - this.__setBgOverlay("backgroundColor", serialized.background, loaded, cbIfLoaded); - this.__setBgOverlay("overlayColor", serialized.overlay, loaded, cbIfLoaded); - cbIfLoaded(); - }, - __setBgOverlay: function(property, value, loaded, callback) { - var _this = this; - if (!value) { - loaded[property] = true; - return; - } - if (property === "backgroundImage" || property === "overlayImage") { - fabric.Image.fromObject(value, function(img) { - _this[property] = img; - loaded[property] = true; - callback && callback(); - }); - } else { - this["set" + fabric.util.string.capitalize(property, true)](value, function() { - loaded[property] = true; - callback && callback(); - }); - } - }, - _enlivenObjects: function(objects, callback, reviver) { - var _this = this; - if (!objects || objects.length === 0) { - 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, true); - }); - _this.renderOnAddRemove = renderOnAddRemove; - callback && callback(); - }, null, reviver); - }, - _toDataURL: function(format, callback) { - this.clone(function(clone) { - callback(clone.toDataURL(format)); - }); - }, - _toDataURLWithMultiplier: function(format, multiplier, callback) { - this.clone(function(clone) { - callback(clone.toDataURLWithMultiplier(format, multiplier)); - }); - }, - clone: function(callback, properties) { - var data = JSON.stringify(this.toJSON(properties)); - this.cloneWithoutData(function(clone) { - clone.loadFromJSON(data, function() { - callback && callback(clone); - }); - }); - }, - cloneWithoutData: function(callback) { - var el = fabric.document.createElement("canvas"); - el.width = this.getWidth(); - el.height = this.getHeight(); - var clone = new fabric.Canvas(el); - clone.clipTo = this.clipTo; - if (this.backgroundImage) { - clone.setBackgroundImage(this.backgroundImage.src, function() { - clone.renderAll(); - callback && callback(clone); - }); - clone.backgroundImageOpacity = this.backgroundImageOpacity; - clone.backgroundImageStretch = this.backgroundImageStretch; - } else { - callback && callback(clone); - } - } -}); - -(function(global) { - "use strict"; - var fabric = global.fabric || (global.fabric = {}), extend = fabric.util.object.extend, toFixed = fabric.util.toFixed, capitalize = fabric.util.string.capitalize, degreesToRadians = fabric.util.degreesToRadians, supportsLineDash = fabric.StaticCanvas.supports("setLineDash"); - if (fabric.Object) { - return; - } - fabric.Object = fabric.util.createClass({ - type: "object", - originX: "left", - originY: "top", - top: 0, - left: 0, - width: 0, - height: 0, - scaleX: 1, - scaleY: 1, - flipX: false, - flipY: false, - opacity: 1, - angle: 0, - skewX: 0, - skewY: 0, - cornerSize: 12, - transparentCorners: true, - hoverCursor: null, - padding: 0, - borderColor: "rgba(102,153,255,0.75)", - cornerColor: "rgba(102,153,255,0.5)", - centeredScaling: false, - centeredRotation: true, - fill: "rgb(0,0,0)", - fillRule: "nonzero", - globalCompositeOperation: "source-over", - backgroundColor: "", - stroke: null, - strokeWidth: 1, - strokeDashArray: null, - strokeLineCap: "butt", - strokeLineJoin: "miter", - strokeMiterLimit: 10, - shadow: null, - borderOpacityWhenMoving: .4, - borderScaleFactor: 1, - transformMatrix: null, - minScaleLimit: .01, - selectable: true, - evented: true, - visible: true, - hasControls: true, - hasBorders: true, - hasRotatingPoint: true, - rotatingPointOffset: 40, - perPixelTargetFind: false, - includeDefaultValues: true, - clipTo: null, - lockMovementX: false, - lockMovementY: false, - lockRotation: false, - lockScalingX: false, - lockScalingY: false, - lockUniScaling: false, - lockSkewingX: false, - lockSkewingY: false, - lockScalingFlip: 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 " + "alignX alignY meetOrSlice skewX skewY").split(" "), - initialize: function(options) { - if (options) { - this.setOptions(options); - } - }, - _initGradient: function(options) { - if (options.fill && options.fill.colorStops && !(options.fill instanceof fabric.Gradient)) { - this.set("fill", new fabric.Gradient(options.fill)); - } - if (options.stroke && options.stroke.colorStops && !(options.stroke instanceof fabric.Gradient)) { - this.set("stroke", new fabric.Gradient(options.stroke)); - } - }, - _initPattern: function(options) { - if (options.fill && options.fill.source && !(options.fill instanceof fabric.Pattern)) { - this.set("fill", new fabric.Pattern(options.fill)); - } - if (options.stroke && options.stroke.source && !(options.stroke instanceof fabric.Pattern)) { - this.set("stroke", new fabric.Pattern(options.stroke)); - } - }, - _initClipping: function(options) { - if (!options.clipTo || typeof options.clipTo !== "string") { - return; - } - var functionBody = fabric.util.getFunctionBody(options.clipTo); - if (typeof functionBody !== "undefined") { - this.clipTo = new Function("ctx", functionBody); - } - }, - setOptions: function(options) { - for (var prop in options) { - this.set(prop, options[prop]); - } - this._initGradient(options); - this._initPattern(options); - this._initClipping(options); - }, - transform: function(ctx, fromLeft) { - if (this.group && this.canvas.preserveObjectStacking && this.group === this.canvas._activeGroup) { - this.group.transform(ctx); - } - var center = fromLeft ? this._getLeftTopCoords() : this.getCenterPoint(); - ctx.translate(center.x, center.y); - ctx.rotate(degreesToRadians(this.angle)); - ctx.scale(this.scaleX * (this.flipX ? -1 : 1), this.scaleY * (this.flipY ? -1 : 1)); - ctx.transform(1, 0, Math.tan(degreesToRadians(this.skewX)), 1, 0, 0); - ctx.transform(1, Math.tan(degreesToRadians(this.skewY)), 0, 1, 0, 0); - }, - toObject: function(propertiesToInclude) { - var NUM_FRACTION_DIGITS = fabric.Object.NUM_FRACTION_DIGITS, object = { - type: this.type, - originX: this.originX, - originY: this.originY, - left: toFixed(this.left, NUM_FRACTION_DIGITS), - top: toFixed(this.top, NUM_FRACTION_DIGITS), - width: toFixed(this.width, NUM_FRACTION_DIGITS), - height: toFixed(this.height, NUM_FRACTION_DIGITS), - fill: this.fill && this.fill.toObject ? this.fill.toObject() : this.fill, - stroke: this.stroke && this.stroke.toObject ? this.stroke.toObject() : this.stroke, - strokeWidth: toFixed(this.strokeWidth, NUM_FRACTION_DIGITS), - strokeDashArray: this.strokeDashArray ? this.strokeDashArray.concat() : this.strokeDashArray, - strokeLineCap: this.strokeLineCap, - strokeLineJoin: this.strokeLineJoin, - 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), - flipX: this.flipX, - flipY: this.flipY, - opacity: toFixed(this.opacity, NUM_FRACTION_DIGITS), - 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() : this.transformMatrix, - skewX: toFixed(this.skewX, NUM_FRACTION_DIGITS), - skewY: toFixed(this.skewY, NUM_FRACTION_DIGITS) - }; - if (!this.includeDefaultValues) { - object = this._removeDefaultValues(object); - } - fabric.util.populateWithProperties(this, object, propertiesToInclude); - return object; - }, - toDatalessObject: function(propertiesToInclude) { - return this.toObject(propertiesToInclude); - }, - _removeDefaultValues: function(object) { - var prototype = fabric.util.getKlass(object.type).prototype, stateProperties = prototype.stateProperties; - stateProperties.forEach(function(prop) { - if (object[prop] === prototype[prop]) { - delete object[prop]; - } - var isArray = Object.prototype.toString.call(object[prop]) === "[object Array]" && Object.prototype.toString.call(prototype[prop]) === "[object Array]"; - if (isArray && object[prop].length === 0 && prototype[prop].length === 0) { - delete object[prop]; - } - }); - return object; - }, - toString: function() { - return "#"; - }, - get: function(property) { - return this[property]; - }, - _setObject: function(obj) { - for (var prop in obj) { - this._set(prop, obj[prop]); - } - }, - set: function(key, value) { - if (typeof key === "object") { - this._setObject(key); - } else { - if (typeof value === "function" && key !== "clipTo") { - this._set(key, value(this.get(key))); - } else { - this._set(key, value); - } - } - return this; - }, - _set: function(key, value) { - var shouldConstrainValue = key === "scaleX" || key === "scaleY"; - if (shouldConstrainValue) { - value = this._constrainScale(value); - } - if (key === "scaleX" && value < 0) { - this.flipX = !this.flipX; - value *= -1; - } else if (key === "scaleY" && value < 0) { - this.flipY = !this.flipY; - value *= -1; - } else if (key === "width" || key === "height") { - this.minScaleLimit = toFixed(Math.min(.1, 1 / Math.max(this.width, this.height)), 2); - } else if (key === "shadow" && value && !(value instanceof fabric.Shadow)) { - value = new fabric.Shadow(value); - } - this[key] = value; - return this; - }, - setOnGroup: function() {}, - toggle: function(property) { - var value = this.get(property); - if (typeof value === "boolean") { - this.set(property, !value); - } - return this; - }, - setSourcePath: function(value) { - this.sourcePath = value; - return this; - }, - getViewportTransform: function() { - if (this.canvas && this.canvas.viewportTransform) { - return this.canvas.viewportTransform; - } - return [ 1, 0, 0, 1, 0, 0 ]; - }, - render: function(ctx, noTransform) { - if (this.width === 0 && this.height === 0 || !this.visible) { - return; - } - ctx.save(); - this._setupCompositeOperation(ctx); - if (!noTransform) { - this.transform(ctx); - } - this._setStrokeStyles(ctx); - this._setFillStyles(ctx); - if (this.transformMatrix) { - ctx.transform.apply(ctx, this.transformMatrix); - } - this._setOpacity(ctx); - this._setShadow(ctx); - this.clipTo && fabric.util.clipContext(this, ctx); - this._render(ctx, noTransform); - this.clipTo && ctx.restore(); - ctx.restore(); - }, - _setOpacity: function(ctx) { - if (this.group) { - this.group._setOpacity(ctx); - } - ctx.globalAlpha *= this.opacity; - }, - _setStrokeStyles: function(ctx) { - if (this.stroke) { - ctx.lineWidth = this.strokeWidth; - ctx.lineCap = this.strokeLineCap; - ctx.lineJoin = this.strokeLineJoin; - ctx.miterLimit = this.strokeMiterLimit; - ctx.strokeStyle = this.stroke.toLive ? this.stroke.toLive(ctx, this) : this.stroke; - } - }, - _setFillStyles: function(ctx) { - if (this.fill) { - ctx.fillStyle = this.fill.toLive ? this.fill.toLive(ctx, this) : this.fill; - } - }, - _renderControls: function(ctx, noTransform) { - if (!this.active || noTransform || this.group && this.group !== this.canvas.getActiveGroup()) { - return; - } - var vpt = this.getViewportTransform(), matrix = this.calcTransformMatrix(), options; - matrix = fabric.util.multiplyTransformMatrices(vpt, matrix); - options = fabric.util.qrDecompose(matrix); - ctx.save(); - ctx.translate(options.translateX, options.translateY); - if (this.group && this.group === this.canvas.getActiveGroup()) { - ctx.rotate(degreesToRadians(options.angle)); - this.drawBordersInGroup(ctx, options); - } else { - ctx.rotate(degreesToRadians(this.angle)); - this.drawBorders(ctx); - } - this.drawControls(ctx); - ctx.restore(); - }, - _setShadow: function(ctx) { - if (!this.shadow) { - return; - } - var multX = this.canvas && this.canvas.viewportTransform[0] || 1, multY = this.canvas && this.canvas.viewportTransform[3] || 1; - if (this.canvas && this.canvas._isRetinaScaling()) { - multX *= fabric.devicePixelRatio; - multY *= fabric.devicePixelRatio; - } - ctx.shadowColor = this.shadow.color; - ctx.shadowBlur = this.shadow.blur * (multX + multY) * (this.scaleX + this.scaleY) / 4; - ctx.shadowOffsetX = this.shadow.offsetX * multX * this.scaleX; - ctx.shadowOffsetY = this.shadow.offsetY * multY * this.scaleY; - }, - _removeShadow: function(ctx) { - if (!this.shadow) { - return; - } - ctx.shadowColor = ""; - ctx.shadowBlur = ctx.shadowOffsetX = ctx.shadowOffsetY = 0; - }, - _renderFill: function(ctx) { - if (!this.fill) { - return; - } - ctx.save(); - if (this.fill.gradientTransform) { - var g = this.fill.gradientTransform; - ctx.transform.apply(ctx, g); - } - if (this.fill.toLive) { - ctx.translate(-this.width / 2 + this.fill.offsetX || 0, -this.height / 2 + this.fill.offsetY || 0); - } - if (this.fillRule === "evenodd") { - ctx.fill("evenodd"); - } else { - ctx.fill(); - } - ctx.restore(); - }, - _renderStroke: function(ctx) { - if (!this.stroke || this.strokeWidth === 0) { - return; - } - if (this.shadow && !this.shadow.affectStroke) { - this._removeShadow(ctx); - } - ctx.save(); - if (this.strokeDashArray) { - if (1 & this.strokeDashArray.length) { - this.strokeDashArray.push.apply(this.strokeDashArray, this.strokeDashArray); - } - if (supportsLineDash) { - ctx.setLineDash(this.strokeDashArray); - this._stroke && this._stroke(ctx); - } else { - this._renderDashedStroke && this._renderDashedStroke(ctx); - } - ctx.stroke(); - } else { - if (this.stroke.gradientTransform) { - var g = this.stroke.gradientTransform; - ctx.transform.apply(ctx, g); - } - this._stroke ? this._stroke(ctx) : ctx.stroke(); - } - ctx.restore(); - }, - clone: function(callback, propertiesToInclude) { - if (this.constructor.fromObject) { - return this.constructor.fromObject(this.toObject(propertiesToInclude), callback); - } - return new fabric.Object(this.toObject(propertiesToInclude)); - }, - cloneAsImage: function(callback) { - var dataUrl = this.toDataURL(); - fabric.util.loadImage(dataUrl, function(img) { - if (callback) { - callback(new fabric.Image(img)); - } - }); - return this; - }, - toDataURL: function(options) { - options || (options = {}); - var el = fabric.util.createCanvasElement(), boundingRect = this.getBoundingRect(); - el.width = boundingRect.width; - el.height = boundingRect.height; - fabric.util.wrapElement(el, "div"); - var canvas = new fabric.StaticCanvas(el); - if (options.format === "jpg") { - options.format = "jpeg"; - } - if (options.format === "jpeg") { - canvas.backgroundColor = "#fff"; - } - var origParams = { - active: this.get("active"), - left: this.getLeft(), - top: this.getTop() - }; - this.set("active", false); - this.setPositionByOrigin(new fabric.Point(el.width / 2, el.height / 2), "center", "center"); - var originalCanvas = this.canvas; - canvas.add(this); - var data = canvas.toDataURL(options); - this.set(origParams).setCoords(); - this.canvas = originalCanvas; - canvas.dispose(); - canvas = null; - return data; - }, - isType: function(type) { - return this.type === type; - }, - complexity: function() { - return 0; - }, - toJSON: function(propertiesToInclude) { - return this.toObject(propertiesToInclude); - }, - setGradient: function(property, options) { - options || (options = {}); - var gradient = { - colorStops: [] - }; - gradient.type = options.type || (options.r1 || options.r2 ? "radial" : "linear"); - gradient.coords = { - x1: options.x1, - y1: options.y1, - x2: options.x2, - y2: options.y2 - }; - if (options.r1 || options.r2) { - gradient.coords.r1 = options.r1; - gradient.coords.r2 = options.r2; - } - options.gradientTransform && (gradient.gradientTransform = options.gradientTransform); - for (var position in options.colorStops) { - var color = new fabric.Color(options.colorStops[position]); - gradient.colorStops.push({ - offset: position, - color: color.toRgb(), - opacity: color.getAlpha() - }); - } - return this.set(property, fabric.Gradient.forObject(this, gradient)); - }, - setPatternFill: function(options) { - return this.set("fill", new fabric.Pattern(options)); - }, - setShadow: function(options) { - return this.set("shadow", options ? new fabric.Shadow(options) : null); - }, - setColor: function(color) { - this.set("fill", color); - return this; - }, - setAngle: function(angle) { - var shouldCenterOrigin = (this.originX !== "center" || this.originY !== "center") && this.centeredRotation; - if (shouldCenterOrigin) { - this._setOriginToCenter(); - } - this.set("angle", angle); - if (shouldCenterOrigin) { - this._resetOrigin(); - } - return this; - }, - centerH: function() { - this.canvas.centerObjectH(this); - return this; - }, - centerV: function() { - this.canvas.centerObjectV(this); - return this; - }, - center: function() { - this.canvas.centerObject(this); - return this; - }, - remove: function() { - this.canvas.remove(this); - return this; - }, - getLocalPointer: function(e, pointer) { - pointer = pointer || this.canvas.getPointer(e); - var pClicked = new fabric.Point(pointer.x, pointer.y), objectLeftTop = this._getLeftTopCoords(); - if (this.angle) { - pClicked = fabric.util.rotatePoint(pClicked, objectLeftTop, fabric.util.degreesToRadians(-this.angle)); - } - return { - x: pClicked.x - objectLeftTop.x, - y: pClicked.y - objectLeftTop.y - }; - }, - _setupCompositeOperation: function(ctx) { - if (this.globalCompositeOperation) { - ctx.globalCompositeOperation = this.globalCompositeOperation; - } - } - }); - 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.__uid = 0; -})(typeof exports !== "undefined" ? exports : this); - -(function() { - var degreesToRadians = fabric.util.degreesToRadians, originXOffset = { - left: -.5, - center: 0, - right: .5 - }, originYOffset = { - top: -.5, - center: 0, - bottom: .5 - }; - fabric.util.object.extend(fabric.Object.prototype, { - translateToGivenOrigin: function(point, fromOriginX, fromOriginY, toOriginX, toOriginY) { - var x = point.x, y = point.y, offsetX = originXOffset[toOriginX] - originXOffset[fromOriginX], offsetY = originYOffset[toOriginY] - originYOffset[fromOriginY], dim; - if (offsetX || offsetY) { - dim = this._getTransformedDimensions(); - x = point.x + offsetX * dim.x; - y = point.y + offsetY * dim.y; - } - return new fabric.Point(x, y); - }, - translateToCenterPoint: function(point, originX, originY) { - var p = this.translateToGivenOrigin(point, originX, originY, "center", "center"); - if (this.angle) { - return fabric.util.rotatePoint(p, point, degreesToRadians(this.angle)); - } - return p; - }, - translateToOriginPoint: function(center, originX, originY) { - var p = this.translateToGivenOrigin(center, "center", "center", originX, originY); - if (this.angle) { - return fabric.util.rotatePoint(p, center, degreesToRadians(this.angle)); - } - return p; - }, - getCenterPoint: function() { - var leftTop = new fabric.Point(this.left, this.top); - return this.translateToCenterPoint(leftTop, this.originX, this.originY); - }, - getPointByOrigin: function(originX, originY) { - var center = this.getCenterPoint(); - return this.translateToOriginPoint(center, originX, originY); - }, - toLocalPoint: function(point, originX, originY) { - var center = this.getCenterPoint(), p, p2; - if (originX && originY) { - p = this.translateToGivenOrigin(center, "center", "center", originX, originY); - } else { - p = new fabric.Point(this.left, this.top); - } - p2 = new fabric.Point(point.x, point.y); - if (this.angle) { - p2 = fabric.util.rotatePoint(p2, center, -degreesToRadians(this.angle)); - } - return p2.subtractEquals(p); - }, - setPositionByOrigin: function(pos, originX, originY) { - var center = this.translateToCenterPoint(pos, originX, originY), position = this.translateToOriginPoint(center, this.originX, this.originY); - this.set("left", position.x); - 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; - this.left += xFull * (originXOffset[to] - originXOffset[this.originX]); - this.top += yFull * (originXOffset[to] - originXOffset[this.originX]); - this.setCoords(); - this.originX = to; - }, - _setOriginToCenter: function() { - this._originalOriginX = this.originX; - this._originalOriginY = this.originY; - var center = this.getCenterPoint(); - this.originX = "center"; - this.originY = "center"; - this.left = center.x; - this.top = center.y; - }, - _resetOrigin: function() { - var originPoint = this.translateToOriginPoint(this.getCenterPoint(), this._originalOriginX, this._originalOriginY); - this.originX = this._originalOriginX; - this.originY = this._originalOriginY; - this.left = originPoint.x; - this.top = originPoint.y; - this._originalOriginX = null; - this._originalOriginY = null; - }, - _getLeftTopCoords: function() { - return this.translateToOriginPoint(this.getCenterPoint(), "left", "top"); - } - }); -})(); - -(function() { - function getCoords(oCoords) { - return [ new fabric.Point(oCoords.tl.x, oCoords.tl.y), new fabric.Point(oCoords.tr.x, oCoords.tr.y), new fabric.Point(oCoords.br.x, oCoords.br.y), new fabric.Point(oCoords.bl.x, oCoords.bl.y) ]; - } - var degreesToRadians = fabric.util.degreesToRadians, multiplyMatrices = fabric.util.multiplyTransformMatrices; - fabric.util.object.extend(fabric.Object.prototype, { - oCoords: null, - intersectsWithRect: function(pointTL, pointBR) { - var oCoords = getCoords(this.oCoords), intersection = fabric.Intersection.intersectPolygonRectangle(oCoords, pointTL, pointBR); - return intersection.status === "Intersection"; - }, - intersectsWithObject: function(other) { - var intersection = fabric.Intersection.intersectPolygonPolygon(getCoords(this.oCoords), getCoords(other.oCoords)); - return intersection.status === "Intersection"; - }, - isContainedWithinObject: function(other) { - var boundingRect = other.getBoundingRect(), point1 = new fabric.Point(boundingRect.left, boundingRect.top), point2 = new fabric.Point(boundingRect.left + boundingRect.width, boundingRect.top + boundingRect.height); - return this.isContainedWithinRect(point1, point2); - }, - isContainedWithinRect: function(pointTL, pointBR) { - var boundingRect = this.getBoundingRect(); - return boundingRect.left >= pointTL.x && boundingRect.left + boundingRect.width <= pointBR.x && boundingRect.top >= pointTL.y && boundingRect.top + boundingRect.height <= pointBR.y; - }, - containsPoint: function(point) { - var lines = this._getImageLines(this.oCoords), xPoints = this._findCrossPoints(point, lines); - return xPoints !== 0 && xPoints % 2 === 1; - }, - _getImageLines: function(oCoords) { - return { - topline: { - o: oCoords.tl, - d: oCoords.tr - }, - rightline: { - o: oCoords.tr, - d: oCoords.br - }, - bottomline: { - o: oCoords.br, - d: oCoords.bl - }, - leftline: { - o: oCoords.bl, - d: oCoords.tl - } - }; - }, - _findCrossPoints: function(point, oCoords) { - var b1, b2, a1, a2, xi, yi, xcount = 0, iLine; - for (var lineKey in oCoords) { - iLine = oCoords[lineKey]; - if (iLine.o.y < point.y && iLine.d.y < point.y) { - continue; - } - if (iLine.o.y >= point.y && iLine.d.y >= point.y) { - continue; - } - if (iLine.o.x === iLine.d.x && iLine.o.x >= point.x) { - xi = iLine.o.x; - yi = point.y; - } else { - b1 = 0; - b2 = (iLine.d.y - iLine.o.y) / (iLine.d.x - iLine.o.x); - a1 = point.y - b1 * point.x; - a2 = iLine.o.y - b2 * iLine.o.x; - xi = -(a1 - a2) / (b1 - b2); - yi = a1 + b1 * xi; - } - if (xi >= point.x) { - xcount += 1; - } - if (xcount === 2) { - break; - } - } - return xcount; - }, - getBoundingRectWidth: function() { - return this.getBoundingRect().width; - }, - getBoundingRectHeight: function() { - return this.getBoundingRect().height; - }, - getBoundingRect: function() { - this.oCoords || this.setCoords(); - return fabric.util.makeBoundingBoxFromPoints([ this.oCoords.tl, this.oCoords.tr, this.oCoords.br, this.oCoords.bl ]); - }, - getWidth: function() { - return this._getTransformedDimensions().x; - }, - getHeight: function() { - return this._getTransformedDimensions().y; - }, - _constrainScale: function(value) { - if (Math.abs(value) < this.minScaleLimit) { - if (value < 0) { - return -this.minScaleLimit; - } else { - return this.minScaleLimit; - } - } - return value; - }, - scale: function(value) { - value = this._constrainScale(value); - if (value < 0) { - this.flipX = !this.flipX; - this.flipY = !this.flipY; - value *= -1; - } - this.scaleX = value; - this.scaleY = value; - this.setCoords(); - return this; - }, - scaleToWidth: function(value) { - var boundingRectFactor = this.getBoundingRect().width / this.getWidth(); - return this.scale(value / this.width / boundingRectFactor); - }, - scaleToHeight: function(value) { - var boundingRectFactor = this.getBoundingRect().height / this.getHeight(); - return this.scale(value / this.height / boundingRectFactor); - }, - setCoords: function() { - var theta = degreesToRadians(this.angle), vpt = this.getViewportTransform(), dim = this._calculateCurrentDimensions(), currentWidth = dim.x, currentHeight = dim.y; - if (currentWidth < 0) { - currentWidth = Math.abs(currentWidth); - } - var sinTh = Math.sin(theta), cosTh = Math.cos(theta), _angle = currentWidth > 0 ? Math.atan(currentHeight / currentWidth) : 0, _hypotenuse = currentWidth / Math.cos(_angle) / 2, offsetX = Math.cos(_angle + theta) * _hypotenuse, offsetY = Math.sin(_angle + theta) * _hypotenuse, coords = fabric.util.transformPoint(this.getCenterPoint(), vpt), tl = new fabric.Point(coords.x - offsetX, coords.y - offsetY), tr = new fabric.Point(tl.x + currentWidth * cosTh, tl.y + currentWidth * sinTh), bl = new fabric.Point(tl.x - currentHeight * sinTh, tl.y + currentHeight * cosTh), br = new fabric.Point(coords.x + offsetX, coords.y + offsetY), ml = new fabric.Point((tl.x + bl.x) / 2, (tl.y + bl.y) / 2), mt = new fabric.Point((tr.x + tl.x) / 2, (tr.y + tl.y) / 2), mr = new fabric.Point((br.x + tr.x) / 2, (br.y + tr.y) / 2), mb = new fabric.Point((br.x + bl.x) / 2, (br.y + bl.y) / 2), mtr = new fabric.Point(mt.x + sinTh * this.rotatingPointOffset, mt.y - cosTh * this.rotatingPointOffset); - this.oCoords = { - tl: tl, - tr: tr, - br: br, - bl: bl, - ml: ml, - mt: mt, - mr: mr, - mb: mb, - mtr: mtr - }; - this._setCornerCoords && this._setCornerCoords(); - return this; - }, - _calcRotateMatrix: function() { - if (this.angle) { - var theta = degreesToRadians(this.angle), cos = Math.cos(theta), sin = Math.sin(theta); - return [ cos, sin, -sin, cos, 0, 0 ]; - } - return [ 1, 0, 0, 1, 0, 0 ]; - }, - calcTransformMatrix: function() { - var center = this.getCenterPoint(), translateMatrix = [ 1, 0, 0, 1, center.x, center.y ], rotateMatrix = this._calcRotateMatrix(), dimensionMatrix = this._calcDimensionsTransformMatrix(this.skewX, this.skewY, true), matrix = this.group ? this.group.calcTransformMatrix() : [ 1, 0, 0, 1, 0, 0 ]; - matrix = multiplyMatrices(matrix, translateMatrix); - matrix = multiplyMatrices(matrix, rotateMatrix); - matrix = multiplyMatrices(matrix, dimensionMatrix); - return matrix; - }, - _calcDimensionsTransformMatrix: function(skewX, skewY, flipping) { - var skewMatrixX = [ 1, 0, Math.tan(degreesToRadians(skewX)), 1 ], skewMatrixY = [ 1, Math.tan(degreesToRadians(skewY)), 0, 1 ], scaleX = this.scaleX * (flipping && this.flipX ? -1 : 1), scaleY = this.scaleY * (flipping && this.flipY ? -1 : 1), scaleMatrix = [ scaleX, 0, 0, scaleY ], m = multiplyMatrices(scaleMatrix, skewMatrixX, true); - return multiplyMatrices(m, skewMatrixY, true); - } - }); -})(); - -fabric.util.object.extend(fabric.Object.prototype, { - sendToBack: function() { - if (this.group) { - fabric.StaticCanvas.prototype.sendToBack.call(this.group, this); - } else { - this.canvas.sendToBack(this); - } - return this; - }, - bringToFront: function() { - if (this.group) { - fabric.StaticCanvas.prototype.bringToFront.call(this.group, this); - } else { - this.canvas.bringToFront(this); - } - return this; - }, - sendBackwards: function(intersecting) { - if (this.group) { - fabric.StaticCanvas.prototype.sendBackwards.call(this.group, this, intersecting); - } else { - this.canvas.sendBackwards(this, intersecting); - } - return this; - }, - bringForward: function(intersecting) { - if (this.group) { - fabric.StaticCanvas.prototype.bringForward.call(this.group, this, intersecting); - } else { - this.canvas.bringForward(this, intersecting); - } - return this; - }, - moveTo: function(index) { - if (this.group) { - fabric.StaticCanvas.prototype.moveTo.call(this.group, this, index); - } else { - this.canvas.moveTo(this, index); - } - return this; - } -}); - -fabric.util.object.extend(fabric.Object.prototype, { - getSvgStyles: function(skipShadow) { - var fill = this.fill ? this.fill.toLive ? "url(#SVGID_" + this.fill.id + ")" : this.fill : "none", fillRule = this.fillRule, stroke = this.stroke ? this.stroke.toLive ? "url(#SVGID_" + this.stroke.id + ")" : this.stroke : "none", strokeWidth = this.strokeWidth ? this.strokeWidth : "0", strokeDashArray = this.strokeDashArray ? this.strokeDashArray.join(" ") : "none", strokeLineCap = this.strokeLineCap ? this.strokeLineCap : "butt", strokeLineJoin = this.strokeLineJoin ? this.strokeLineJoin : "miter", strokeMiterLimit = this.strokeMiterLimit ? this.strokeMiterLimit : "4", opacity = typeof this.opacity !== "undefined" ? this.opacity : "1", visibility = this.visible ? "" : " visibility: hidden;", filter = skipShadow ? "" : this.getSvgFilter(); - return [ "stroke: ", stroke, "; ", "stroke-width: ", strokeWidth, "; ", "stroke-dasharray: ", strokeDashArray, "; ", "stroke-linecap: ", strokeLineCap, "; ", "stroke-linejoin: ", strokeLineJoin, "; ", "stroke-miterlimit: ", strokeMiterLimit, "; ", "fill: ", fill, "; ", "fill-rule: ", fillRule, "; ", "opacity: ", opacity, ";", filter, visibility ].join(""); - }, - getSvgFilter: function() { - return this.shadow ? "filter: url(#SVGID_" + this.shadow.id + ");" : ""; - }, - getSvgTransform: function() { - if (this.group && this.group.type === "path-group") { - return ""; - } - var toFixed = fabric.util.toFixed, angle = this.getAngle(), skewX = this.getSkewX() % 360, skewY = this.getSkewY() % 360, center = this.getCenterPoint(), NUM_FRACTION_DIGITS = fabric.Object.NUM_FRACTION_DIGITS, translatePart = this.type === "path-group" ? "" : "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) + ")" : "", addTranslateX = this.type === "path-group" ? this.width : 0, flipXPart = this.flipX ? " matrix(-1 0 0 1 " + addTranslateX + " 0) " : "", addTranslateY = this.type === "path-group" ? this.height : 0, flipYPart = this.flipY ? " matrix(1 0 0 -1 0 " + addTranslateY + ")" : ""; - return [ translatePart, anglePart, scalePart, flipXPart, flipYPart, skewXPart, skewYPart ].join(""); - }, - getSvgTransformMatrix: function() { - return this.transformMatrix ? " matrix(" + this.transformMatrix.join(" ") + ") " : ""; - }, - _createBaseSVGMarkup: function() { - var markup = []; - if (this.fill && this.fill.toLive) { - markup.push(this.fill.toSVG(this, false)); - } - if (this.stroke && this.stroke.toLive) { - markup.push(this.stroke.toSVG(this, false)); - } - if (this.shadow) { - markup.push(this.shadow.toSVG(this)); - } - return markup; - } -}); - -fabric.util.object.extend(fabric.Object.prototype, { - hasStateChanged: function() { - return this.stateProperties.some(function(prop) { - return this.get(prop) !== this.originalState[prop]; - }, this); - }, - saveState: function(options) { - this.stateProperties.forEach(function(prop) { - this.originalState[prop] = this.get(prop); - }, this); - if (options && options.stateProperties) { - options.stateProperties.forEach(function(prop) { - this.originalState[prop] = this.get(prop); - }, this); - } - return this; - }, - setupState: function() { - this.originalState = {}; - this.saveState(); - return this; - } -}); - -(function() { - var degreesToRadians = fabric.util.degreesToRadians, isVML = function() { - return typeof G_vmlCanvasManager !== "undefined"; - }; - fabric.util.object.extend(fabric.Object.prototype, { - _controlsVisibility: null, - _findTargetCorner: function(pointer) { - if (!this.hasControls || !this.active) { - return false; - } - var ex = pointer.x, ey = pointer.y, xPoints, lines; - this.__corner = 0; - for (var i in this.oCoords) { - if (!this.isControlVisible(i)) { - continue; - } - if (i === "mtr" && !this.hasRotatingPoint) { - continue; - } - if (this.get("lockUniScaling") && (i === "mt" || i === "mr" || i === "mb" || i === "ml")) { - continue; - } - lines = this._getImageLines(this.oCoords[i].corner); - xPoints = this._findCrossPoints({ - x: ex, - y: ey - }, lines); - if (xPoints !== 0 && xPoints % 2 === 1) { - this.__corner = i; - return i; - } - } - return false; - }, - _setCornerCoords: function() { - var coords = this.oCoords, newTheta = degreesToRadians(45 - this.angle), cornerHypotenuse = this.cornerSize * .707106, cosHalfOffset = cornerHypotenuse * Math.cos(newTheta), sinHalfOffset = cornerHypotenuse * Math.sin(newTheta), x, y; - for (var point in coords) { - x = coords[point].x; - y = coords[point].y; - coords[point].corner = { - tl: { - x: x - sinHalfOffset, - y: y - cosHalfOffset - }, - tr: { - x: x + cosHalfOffset, - y: y - sinHalfOffset - }, - bl: { - x: x - cosHalfOffset, - y: y + sinHalfOffset - }, - br: { - x: x + sinHalfOffset, - y: y + cosHalfOffset - } - }; - } - }, - _getNonTransformedDimensions: function() { - var strokeWidth = this.strokeWidth, w = this.width, h = this.height, addStrokeToW = true, addStrokeToH = true; - if (this.type === "line" && this.strokeLineCap === "butt") { - addStrokeToH = w; - addStrokeToW = h; - } - if (addStrokeToH) { - h += h < 0 ? -strokeWidth : strokeWidth; - } - if (addStrokeToW) { - w += w < 0 ? -strokeWidth : strokeWidth; - } - return { - x: w, - y: h - }; - }, - _getTransformedDimensions: function(skewX, skewY) { - if (typeof skewX === "undefined") { - skewX = this.skewX; - } - if (typeof skewY === "undefined") { - skewY = this.skewY; - } - var dimensions = this._getNonTransformedDimensions(), dimX = dimensions.x / 2, dimY = dimensions.y / 2, points = [ { - x: -dimX, - y: -dimY - }, { - x: dimX, - y: -dimY - }, { - x: -dimX, - y: dimY - }, { - x: dimX, - y: dimY - } ], i, transformMatrix = this._calcDimensionsTransformMatrix(skewX, skewY, false), bbox; - for (i = 0; i < points.length; i++) { - points[i] = fabric.util.transformPoint(points[i], transformMatrix); - } - bbox = fabric.util.makeBoundingBoxFromPoints(points); - return { - x: bbox.width, - y: bbox.height - }; - }, - _calculateCurrentDimensions: function() { - var vpt = this.getViewportTransform(), dim = this._getTransformedDimensions(), w = dim.x, h = dim.y; - w += 2 * this.padding; - h += 2 * this.padding; - return fabric.util.transformPoint(new fabric.Point(w, h), vpt, true); - }, - drawBorders: function(ctx) { - if (!this.hasBorders) { - return this; - } - var wh = this._calculateCurrentDimensions(), strokeWidth = 1 / this.borderScaleFactor, width = wh.x + strokeWidth, height = wh.y + strokeWidth; - ctx.save(); - ctx.globalAlpha = this.isMoving ? this.borderOpacityWhenMoving : 1; - ctx.strokeStyle = this.borderColor; - ctx.lineWidth = strokeWidth; - ctx.strokeRect(-width / 2, -height / 2, width, height); - if (this.hasRotatingPoint && this.isControlVisible("mtr") && !this.get("lockRotation") && this.hasControls) { - var rotateHeight = -height / 2; - ctx.beginPath(); - ctx.moveTo(0, rotateHeight); - ctx.lineTo(0, rotateHeight - this.rotatingPointOffset); - ctx.closePath(); - ctx.stroke(); - } - ctx.restore(); - return this; - }, - drawBordersInGroup: function(ctx, options) { - if (!this.hasBorders) { - return this; - } - 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 + 2 * this.padding, height = wh.y + strokeWidth + 2 * this.padding; - ctx.save(); - ctx.globalAlpha = this.isMoving ? this.borderOpacityWhenMoving : 1; - ctx.strokeStyle = this.borderColor; - ctx.lineWidth = strokeWidth; - ctx.strokeRect(-width / 2, -height / 2, width, height); - ctx.restore(); - return this; - }, - drawControls: function(ctx) { - if (!this.hasControls) { - return this; - } - var wh = this._calculateCurrentDimensions(), width = wh.x, height = wh.y, scaleOffset = this.cornerSize, left = -(width + scaleOffset) / 2, top = -(height + scaleOffset) / 2, methodName = this.transparentCorners ? "strokeRect" : "fillRect"; - ctx.save(); - ctx.lineWidth = 1; - ctx.globalAlpha = this.isMoving ? this.borderOpacityWhenMoving : 1; - ctx.strokeStyle = ctx.fillStyle = this.cornerColor; - this._drawControl("tl", ctx, methodName, left, top); - this._drawControl("tr", ctx, methodName, left + width, top); - this._drawControl("bl", ctx, methodName, left, top + height); - this._drawControl("br", ctx, methodName, left + width, top + height); - if (!this.get("lockUniScaling")) { - this._drawControl("mt", ctx, methodName, left + width / 2, top); - this._drawControl("mb", ctx, methodName, left + width / 2, top + height); - this._drawControl("mr", ctx, methodName, left + width, top + height / 2); - this._drawControl("ml", ctx, methodName, left, top + height / 2); - } - if (this.hasRotatingPoint) { - this._drawControl("mtr", ctx, methodName, left + width / 2, top - this.rotatingPointOffset); - } - ctx.restore(); - return this; - }, - _drawControl: function(control, ctx, methodName, left, top) { - if (!this.isControlVisible(control)) { - return; - } - var size = this.cornerSize; - isVML() || this.transparentCorners || ctx.clearRect(left, top, size, size); - ctx[methodName](left, top, size, size); - }, - isControlVisible: function(controlName) { - return this._getControlsVisibility()[controlName]; - }, - setControlVisible: function(controlName, visible) { - this._getControlsVisibility()[controlName] = visible; - return this; - }, - setControlsVisibility: function(options) { - options || (options = {}); - for (var p in options) { - this.setControlVisible(p, options[p]); - } - return this; - }, - _getControlsVisibility: function() { - if (!this._controlsVisibility) { - this._controlsVisibility = { - tl: true, - tr: true, - br: true, - bl: true, - ml: true, - mt: true, - mr: true, - mb: true, - mtr: true - }; - } - return this._controlsVisibility; - } - }); -})(); - -fabric.util.object.extend(fabric.StaticCanvas.prototype, { - FX_DURATION: 500, - fxCenterObjectH: function(object, callbacks) { - callbacks = callbacks || {}; - var empty = function() {}, onComplete = callbacks.onComplete || empty, onChange = callbacks.onChange || empty, _this = this; - fabric.util.animate({ - startValue: object.get("left"), - endValue: this.getCenter().left, - duration: this.FX_DURATION, - onChange: function(value) { - object.set("left", value); - _this.renderAll(); - onChange(); - }, - onComplete: function() { - object.setCoords(); - onComplete(); - } - }); - return this; - }, - fxCenterObjectV: function(object, callbacks) { - callbacks = callbacks || {}; - var empty = function() {}, onComplete = callbacks.onComplete || empty, onChange = callbacks.onChange || empty, _this = this; - fabric.util.animate({ - startValue: object.get("top"), - endValue: this.getCenter().top, - duration: this.FX_DURATION, - onChange: function(value) { - object.set("top", value); - _this.renderAll(); - onChange(); - }, - onComplete: function() { - object.setCoords(); - onComplete(); - } - }); - return this; - }, - fxRemove: function(object, callbacks) { - callbacks = callbacks || {}; - var empty = function() {}, onComplete = callbacks.onComplete || empty, onChange = callbacks.onChange || empty, _this = this; - fabric.util.animate({ - startValue: object.get("opacity"), - endValue: 0, - duration: this.FX_DURATION, - onStart: function() { - object.set("active", false); - }, - onChange: function(value) { - object.set("opacity", value); - _this.renderAll(); - onChange(); - }, - onComplete: function() { - _this.remove(object); - onComplete(); - } - }); - return this; - } -}); - -fabric.util.object.extend(fabric.Object.prototype, { - animate: function() { - if (arguments[0] && typeof arguments[0] === "object") { - var propsToAnimate = [], prop, skipCallbacks; - for (prop in arguments[0]) { - propsToAnimate.push(prop); - } - for (var i = 0, len = propsToAnimate.length; i < len; i++) { - prop = propsToAnimate[i]; - skipCallbacks = i !== len - 1; - this._animate(prop, arguments[0][prop], arguments[1], skipCallbacks); - } - } else { - this._animate.apply(this, arguments); - } - return this; - }, - _animate: function(property, to, options, skipCallbacks) { - var _this = this, propPair; - to = to.toString(); - if (!options) { - options = {}; - } else { - options = fabric.util.object.clone(options); - } - if (~property.indexOf(".")) { - propPair = property.split("."); - } - var currentValue = propPair ? this.get(propPair[0])[propPair[1]] : this.get(property); - if (!("from" in options)) { - options.from = currentValue; - } - if (~to.indexOf("=")) { - to = currentValue + parseFloat(to.replace("=", "")); - } else { - to = parseFloat(to); - } - fabric.util.animate({ - startValue: options.from, - endValue: to, - byValue: options.by, - easing: options.easing, - duration: options.duration, - abort: options.abort && function() { - return options.abort.call(_this); - }, - onChange: function(value) { - if (propPair) { - _this[propPair[0]][propPair[1]] = value; - } else { - _this.set(property, value); - } - if (skipCallbacks) { - return; - } - options.onChange && options.onChange(); - }, - onComplete: function() { - if (skipCallbacks) { - return; - } - _this.setCoords(); - options.onComplete && options.onComplete(); - } - }); - } -}); - -(function(global) { - "use strict"; - var fabric = global.fabric || (global.fabric = {}), extend = fabric.util.object.extend, coordProps = { - x1: 1, - x2: 1, - y1: 1, - y2: 1 - }, supportsLineDash = fabric.StaticCanvas.supports("setLineDash"); - if (fabric.Line) { - fabric.warn("fabric.Line is already defined"); - return; - } - fabric.Line = fabric.util.createClass(fabric.Object, { - type: "line", - x1: 0, - y1: 0, - x2: 0, - y2: 0, - initialize: function(points, options) { - options = options || {}; - if (!points) { - points = [ 0, 0, 0, 0 ]; - } - this.callSuper("initialize", options); - this.set("x1", points[0]); - this.set("y1", points[1]); - this.set("x2", points[2]); - this.set("y2", points[3]); - this._setWidthHeight(options); - }, - _setWidthHeight: function(options) { - options || (options = {}); - this.width = Math.abs(this.x2 - this.x1); - this.height = Math.abs(this.y2 - this.y1); - this.left = "left" in options ? options.left : this._getLeftToOriginX(); - this.top = "top" in options ? options.top : this._getTopToOriginY(); - }, - _set: function(key, value) { - this.callSuper("_set", key, value); - if (typeof coordProps[key] !== "undefined") { - this._setWidthHeight(); - } - return this; - }, - _getLeftToOriginX: makeEdgeToOriginGetter({ - origin: "originX", - axis1: "x1", - axis2: "x2", - dimension: "width" - }, { - nearest: "left", - center: "center", - farthest: "right" - }), - _getTopToOriginY: makeEdgeToOriginGetter({ - origin: "originY", - axis1: "y1", - axis2: "y2", - dimension: "height" - }, { - nearest: "top", - center: "center", - farthest: "bottom" - }), - _render: function(ctx, noTransform) { - ctx.beginPath(); - if (noTransform) { - var cp = this.getCenterPoint(); - ctx.translate(cp.x - this.strokeWidth / 2, cp.y - this.strokeWidth / 2); - } - if (!this.strokeDashArray || this.strokeDashArray && supportsLineDash) { - var p = this.calcLinePoints(); - ctx.moveTo(p.x1, p.y1); - ctx.lineTo(p.x2, p.y2); - } - ctx.lineWidth = this.strokeWidth; - var origStrokeStyle = ctx.strokeStyle; - ctx.strokeStyle = this.stroke || ctx.fillStyle; - this.stroke && this._renderStroke(ctx); - ctx.strokeStyle = origStrokeStyle; - }, - _renderDashedStroke: function(ctx) { - var p = this.calcLinePoints(); - ctx.beginPath(); - fabric.util.drawDashedLine(ctx, p.x1, p.y1, p.x2, p.y2, this.strokeDashArray); - ctx.closePath(); - }, - toObject: function(propertiesToInclude) { - return extend(this.callSuper("toObject", propertiesToInclude), this.calcLinePoints()); - }, - calcLinePoints: function() { - var xMult = this.x1 <= this.x2 ? -1 : 1, yMult = this.y1 <= this.y2 ? -1 : 1, x1 = xMult * this.width * .5, y1 = yMult * this.height * .5, x2 = xMult * this.width * -.5, y2 = yMult * this.height * -.5; - return { - x1: x1, - x2: x2, - y1: y1, - y2: y2 - }; - }, - toSVG: function(reviver) { - var markup = this._createBaseSVGMarkup(), p = { - x1: this.x1, - x2: this.x2, - y1: this.y1, - y2: this.y2 - }; - if (!(this.group && this.group.type === "path-group")) { - p = this.calcLinePoints(); - } - markup.push("\n'); - return reviver ? reviver(markup.join("")) : markup.join(""); - }, - complexity: function() { - return 1; - } - }); - fabric.Line.ATTRIBUTE_NAMES = fabric.SHARED_ATTRIBUTES.concat("x1 y1 x2 y2".split(" ")); - fabric.Line.fromElement = function(element, options) { - var parsedAttributes = fabric.parseAttributes(element, fabric.Line.ATTRIBUTE_NAMES), points = [ parsedAttributes.x1 || 0, parsedAttributes.y1 || 0, parsedAttributes.x2 || 0, parsedAttributes.y2 || 0 ]; - return new fabric.Line(points, extend(parsedAttributes, options)); - }; - fabric.Line.fromObject = function(object) { - var points = [ object.x1, object.y1, object.x2, object.y2 ]; - return new fabric.Line(points, object); - }; - 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; - return function() { - switch (this.get(origin)) { - case nearest: - return Math.min(this.get(axis1), this.get(axis2)); - - case center: - return Math.min(this.get(axis1), this.get(axis2)) + .5 * this.get(dimension); - - case farthest: - return Math.max(this.get(axis1), this.get(axis2)); - } - }; - } -})(typeof exports !== "undefined" ? exports : this); - -(function(global) { - "use strict"; - var fabric = global.fabric || (global.fabric = {}), pi = Math.PI, extend = fabric.util.object.extend; - if (fabric.Circle) { - fabric.warn("fabric.Circle is already defined."); - return; - } - fabric.Circle = fabric.util.createClass(fabric.Object, { - type: "circle", - radius: 0, - startAngle: 0, - endAngle: pi * 2, - initialize: function(options) { - options = options || {}; - this.callSuper("initialize", options); - this.set("radius", options.radius || 0); - this.startAngle = options.startAngle || this.startAngle; - this.endAngle = options.endAngle || this.endAngle; - }, - _set: function(key, value) { - this.callSuper("_set", key, value); - if (key === "radius") { - this.setRadius(value); - } - return this; - }, - toObject: function(propertiesToInclude) { - return extend(this.callSuper("toObject", propertiesToInclude), { - radius: this.get("radius"), - startAngle: this.startAngle, - endAngle: this.endAngle - }); - }, - toSVG: function(reviver) { - var markup = this._createBaseSVGMarkup(), x = 0, y = 0, angle = (this.endAngle - this.startAngle) % (2 * pi); - if (angle === 0) { - if (this.group && this.group.type === "path-group") { - x = this.left + this.radius; - y = this.top + this.radius; - } - markup.push("\n'); - } else { - var startX = Math.cos(this.startAngle) * this.radius, startY = Math.sin(this.startAngle) * this.radius, endX = Math.cos(this.endAngle) * this.radius, endY = Math.sin(this.endAngle) * this.radius, largeFlag = angle > pi ? "1" : "0"; - markup.push('\n'); - } - return reviver ? reviver(markup.join("")) : markup.join(""); - }, - _render: function(ctx, noTransform) { - ctx.beginPath(); - ctx.arc(noTransform ? this.left + this.radius : 0, noTransform ? this.top + this.radius : 0, this.radius, this.startAngle, this.endAngle, false); - this._renderFill(ctx); - this._renderStroke(ctx); - }, - getRadiusX: function() { - return this.get("radius") * this.get("scaleX"); - }, - getRadiusY: function() { - return this.get("radius") * this.get("scaleY"); - }, - setRadius: function(value) { - this.radius = value; - return this.set("width", value * 2).set("height", value * 2); - }, - complexity: function() { - return 1; - } - }); - fabric.Circle.ATTRIBUTE_NAMES = fabric.SHARED_ATTRIBUTES.concat("cx cy r".split(" ")); - fabric.Circle.fromElement = function(element, options) { - options || (options = {}); - var parsedAttributes = fabric.parseAttributes(element, fabric.Circle.ATTRIBUTE_NAMES); - if (!isValidRadius(parsedAttributes)) { - throw new Error("value of `r` attribute is required and can not be negative"); - } - parsedAttributes.left = parsedAttributes.left || 0; - parsedAttributes.top = parsedAttributes.top || 0; - var obj = new fabric.Circle(extend(parsedAttributes, options)); - obj.left -= obj.radius; - obj.top -= obj.radius; - return obj; - }; - function isValidRadius(attributes) { - return "radius" in attributes && attributes.radius >= 0; - } - fabric.Circle.fromObject = function(object) { - return new fabric.Circle(object); - }; -})(typeof exports !== "undefined" ? exports : this); - -(function(global) { - "use strict"; - var fabric = global.fabric || (global.fabric = {}); - if (fabric.Triangle) { - fabric.warn("fabric.Triangle is already defined"); - return; - } - fabric.Triangle = fabric.util.createClass(fabric.Object, { - type: "triangle", - initialize: function(options) { - options = options || {}; - this.callSuper("initialize", options); - this.set("width", options.width || 100).set("height", options.height || 100); - }, - _render: function(ctx) { - var widthBy2 = this.width / 2, heightBy2 = this.height / 2; - ctx.beginPath(); - ctx.moveTo(-widthBy2, heightBy2); - ctx.lineTo(0, -heightBy2); - ctx.lineTo(widthBy2, heightBy2); - ctx.closePath(); - this._renderFill(ctx); - this._renderStroke(ctx); - }, - _renderDashedStroke: function(ctx) { - var widthBy2 = this.width / 2, heightBy2 = this.height / 2; - ctx.beginPath(); - fabric.util.drawDashedLine(ctx, -widthBy2, heightBy2, 0, -heightBy2, this.strokeDashArray); - fabric.util.drawDashedLine(ctx, 0, -heightBy2, widthBy2, heightBy2, this.strokeDashArray); - fabric.util.drawDashedLine(ctx, widthBy2, heightBy2, -widthBy2, heightBy2, this.strokeDashArray); - ctx.closePath(); - }, - toSVG: function(reviver) { - var markup = this._createBaseSVGMarkup(), widthBy2 = this.width / 2, heightBy2 = this.height / 2, points = [ -widthBy2 + " " + heightBy2, "0 " + -heightBy2, widthBy2 + " " + heightBy2 ].join(","); - markup.push("'); - return reviver ? reviver(markup.join("")) : markup.join(""); - }, - complexity: function() { - return 1; - } - }); - fabric.Triangle.fromObject = function(object) { - return new fabric.Triangle(object); - }; -})(typeof exports !== "undefined" ? exports : this); - -(function(global) { - "use strict"; - var fabric = global.fabric || (global.fabric = {}), piBy2 = Math.PI * 2, extend = fabric.util.object.extend; - if (fabric.Ellipse) { - fabric.warn("fabric.Ellipse is already defined."); - return; - } - fabric.Ellipse = fabric.util.createClass(fabric.Object, { - type: "ellipse", - rx: 0, - ry: 0, - initialize: function(options) { - options = options || {}; - this.callSuper("initialize", options); - this.set("rx", options.rx || 0); - this.set("ry", options.ry || 0); - }, - _set: function(key, value) { - this.callSuper("_set", key, value); - switch (key) { - case "rx": - this.rx = value; - this.set("width", value * 2); - break; - - case "ry": - this.ry = value; - this.set("height", value * 2); - break; - } - return this; - }, - getRx: function() { - return this.get("rx") * this.get("scaleX"); - }, - getRy: function() { - return this.get("ry") * this.get("scaleY"); - }, - toObject: function(propertiesToInclude) { - return extend(this.callSuper("toObject", propertiesToInclude), { - rx: this.get("rx"), - ry: this.get("ry") - }); - }, - toSVG: function(reviver) { - var markup = this._createBaseSVGMarkup(), x = 0, y = 0; - if (this.group && this.group.type === "path-group") { - x = this.left + this.rx; - y = this.top + this.ry; - } - markup.push("\n'); - return reviver ? reviver(markup.join("")) : markup.join(""); - }, - _render: function(ctx, noTransform) { - ctx.beginPath(); - ctx.save(); - ctx.transform(1, 0, 0, this.ry / this.rx, 0, 0); - ctx.arc(noTransform ? this.left + this.rx : 0, noTransform ? (this.top + this.ry) * this.rx / this.ry : 0, this.rx, 0, piBy2, false); - ctx.restore(); - this._renderFill(ctx); - this._renderStroke(ctx); - }, - complexity: function() { - return 1; - } - }); - fabric.Ellipse.ATTRIBUTE_NAMES = fabric.SHARED_ATTRIBUTES.concat("cx cy rx ry".split(" ")); - fabric.Ellipse.fromElement = function(element, options) { - options || (options = {}); - var parsedAttributes = fabric.parseAttributes(element, fabric.Ellipse.ATTRIBUTE_NAMES); - parsedAttributes.left = parsedAttributes.left || 0; - parsedAttributes.top = parsedAttributes.top || 0; - var ellipse = new fabric.Ellipse(extend(parsedAttributes, options)); - ellipse.top -= ellipse.ry; - ellipse.left -= ellipse.rx; - return ellipse; - }; - fabric.Ellipse.fromObject = function(object) { - return new fabric.Ellipse(object); - }; -})(typeof exports !== "undefined" ? exports : this); - -(function(global) { - "use strict"; - var fabric = global.fabric || (global.fabric = {}), extend = fabric.util.object.extend; - if (fabric.Rect) { - fabric.warn("fabric.Rect is already defined"); - return; - } - var stateProperties = fabric.Object.prototype.stateProperties.concat(); - stateProperties.push("rx", "ry", "x", "y"); - fabric.Rect = fabric.util.createClass(fabric.Object, { - stateProperties: stateProperties, - type: "rect", - rx: 0, - ry: 0, - strokeDashArray: null, - initialize: function(options) { - options = options || {}; - this.callSuper("initialize", options); - this._initRxRy(); - }, - _initRxRy: function() { - if (this.rx && !this.ry) { - this.ry = this.rx; - } else if (this.ry && !this.rx) { - this.rx = this.ry; - } - }, - _render: function(ctx, noTransform) { - if (this.width === 1 && this.height === 1) { - ctx.fillRect(-.5, -.5, 1, 1); - return; - } - var rx = this.rx ? Math.min(this.rx, this.width / 2) : 0, ry = this.ry ? Math.min(this.ry, this.height / 2) : 0, w = this.width, h = this.height, x = noTransform ? this.left : -this.width / 2, y = noTransform ? this.top : -this.height / 2, isRounded = rx !== 0 || ry !== 0, k = 1 - .5522847498; - ctx.beginPath(); - ctx.moveTo(x + rx, y); - ctx.lineTo(x + w - rx, y); - isRounded && ctx.bezierCurveTo(x + w - k * rx, y, x + w, y + k * ry, x + w, y + ry); - ctx.lineTo(x + w, y + h - ry); - isRounded && ctx.bezierCurveTo(x + w, y + h - k * ry, x + w - k * rx, y + h, x + w - rx, y + h); - ctx.lineTo(x + rx, y + h); - isRounded && ctx.bezierCurveTo(x + k * rx, y + h, x, y + h - k * ry, x, y + h - ry); - ctx.lineTo(x, y + ry); - isRounded && ctx.bezierCurveTo(x, y + k * ry, x + k * rx, y, x + rx, y); - ctx.closePath(); - this._renderFill(ctx); - this._renderStroke(ctx); - }, - _renderDashedStroke: function(ctx) { - var x = -this.width / 2, y = -this.height / 2, w = this.width, h = this.height; - ctx.beginPath(); - fabric.util.drawDashedLine(ctx, x, y, x + w, y, this.strokeDashArray); - fabric.util.drawDashedLine(ctx, x + w, y, x + w, y + h, this.strokeDashArray); - fabric.util.drawDashedLine(ctx, x + w, y + h, x, y + h, this.strokeDashArray); - fabric.util.drawDashedLine(ctx, x, y + h, x, y, this.strokeDashArray); - ctx.closePath(); - }, - toObject: function(propertiesToInclude) { - var object = extend(this.callSuper("toObject", propertiesToInclude), { - rx: this.get("rx") || 0, - ry: this.get("ry") || 0 - }); - if (!this.includeDefaultValues) { - this._removeDefaultValues(object); - } - return object; - }, - toSVG: function(reviver) { - var markup = this._createBaseSVGMarkup(), x = this.left, y = this.top; - if (!(this.group && this.group.type === "path-group")) { - x = -this.width / 2; - y = -this.height / 2; - } - markup.push("\n'); - return reviver ? reviver(markup.join("")) : markup.join(""); - }, - complexity: function() { - return 1; - } - }); - fabric.Rect.ATTRIBUTE_NAMES = fabric.SHARED_ATTRIBUTES.concat("x y rx ry width height".split(" ")); - fabric.Rect.fromElement = function(element, options) { - if (!element) { - return null; - } - options = options || {}; - var parsedAttributes = fabric.parseAttributes(element, fabric.Rect.ATTRIBUTE_NAMES); - parsedAttributes.left = parsedAttributes.left || 0; - parsedAttributes.top = parsedAttributes.top || 0; - var rect = new fabric.Rect(extend(options ? fabric.util.object.clone(options) : {}, parsedAttributes)); - rect.visible = rect.width > 0 && rect.height > 0; - return rect; - }; - fabric.Rect.fromObject = function(object) { - return new fabric.Rect(object); - }; -})(typeof exports !== "undefined" ? exports : this); - -(function(global) { - "use strict"; - var fabric = global.fabric || (global.fabric = {}); - if (fabric.Polyline) { - fabric.warn("fabric.Polyline is already defined"); - return; - } - fabric.Polyline = fabric.util.createClass(fabric.Object, { - type: "polyline", - points: null, - minX: 0, - minY: 0, - initialize: function(points, options) { - return fabric.Polygon.prototype.initialize.call(this, points, options); - }, - _calcDimensions: function() { - return fabric.Polygon.prototype._calcDimensions.call(this); - }, - _applyPointOffset: function() { - return fabric.Polygon.prototype._applyPointOffset.call(this); - }, - toObject: function(propertiesToInclude) { - return fabric.Polygon.prototype.toObject.call(this, propertiesToInclude); - }, - toSVG: function(reviver) { - return fabric.Polygon.prototype.toSVG.call(this, reviver); - }, - _render: function(ctx, noTransform) { - if (!fabric.Polygon.prototype.commonRender.call(this, ctx, noTransform)) { - return; - } - this._renderFill(ctx); - this._renderStroke(ctx); - }, - _renderDashedStroke: function(ctx) { - var p1, p2; - ctx.beginPath(); - for (var i = 0, len = this.points.length; i < len; i++) { - p1 = this.points[i]; - p2 = this.points[i + 1] || p1; - fabric.util.drawDashedLine(ctx, p1.x, p1.y, p2.x, p2.y, this.strokeDashArray); - } - }, - complexity: function() { - return this.get("points").length; - } - }); - fabric.Polyline.ATTRIBUTE_NAMES = fabric.SHARED_ATTRIBUTES.concat(); - fabric.Polyline.fromElement = function(element, options) { - if (!element) { - return 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)); - }; - fabric.Polyline.fromObject = function(object) { - var points = object.points; - return new fabric.Polyline(points, object, true); - }; -})(typeof exports !== "undefined" ? exports : this); - -(function(global) { - "use strict"; - var fabric = global.fabric || (global.fabric = {}), extend = fabric.util.object.extend, min = fabric.util.array.min, max = fabric.util.array.max, toFixed = fabric.util.toFixed; - if (fabric.Polygon) { - fabric.warn("fabric.Polygon is already defined"); - return; - } - fabric.Polygon = fabric.util.createClass(fabric.Object, { - type: "polygon", - points: null, - minX: 0, - minY: 0, - initialize: function(points, options) { - options = options || {}; - this.points = points || []; - this.callSuper("initialize", options); - this._calcDimensions(); - if (!("top" in options)) { - this.top = this.minY; - } - if (!("left" in options)) { - this.left = this.minX; - } - this.pathOffset = { - x: this.minX + this.width / 2, - y: this.minY + this.height / 2 - }; - }, - _calcDimensions: function() { - var points = this.points, minX = min(points, "x"), minY = min(points, "y"), maxX = max(points, "x"), maxY = max(points, "y"); - this.width = maxX - minX || 0; - this.height = maxY - minY || 0; - this.minX = minX || 0, this.minY = minY || 0; - }, - toObject: function(propertiesToInclude) { - return extend(this.callSuper("toObject", propertiesToInclude), { - points: this.points.concat() - }); - }, - toSVG: function(reviver) { - var points = [], addTransform, markup = this._createBaseSVGMarkup(); - for (var i = 0, len = this.points.length; i < len; i++) { - points.push(toFixed(this.points[i].x, 2), ",", toFixed(this.points[i].y, 2), " "); - } - if (!(this.group && this.group.type === "path-group")) { - addTransform = " translate(" + -this.pathOffset.x + ", " + -this.pathOffset.y + ") "; - } - markup.push("<", this.type, " ", 'points="', points.join(""), '" style="', this.getSvgStyles(), '" transform="', this.getSvgTransform(), addTransform, " ", this.getSvgTransformMatrix(), '"/>\n'); - return reviver ? reviver(markup.join("")) : markup.join(""); - }, - _render: function(ctx, noTransform) { - if (!this.commonRender(ctx, noTransform)) { - return; - } - this._renderFill(ctx); - if (this.stroke || this.strokeDashArray) { - ctx.closePath(); - this._renderStroke(ctx); - } - }, - commonRender: function(ctx, noTransform) { - var point, len = this.points.length; - if (!len || isNaN(this.points[len - 1].y)) { - return false; - } - noTransform || ctx.translate(-this.pathOffset.x, -this.pathOffset.y); - ctx.beginPath(); - ctx.moveTo(this.points[0].x, this.points[0].y); - for (var i = 0; i < len; i++) { - point = this.points[i]; - ctx.lineTo(point.x, point.y); - } - return true; - }, - _renderDashedStroke: function(ctx) { - fabric.Polyline.prototype._renderDashedStroke.call(this, ctx); - ctx.closePath(); - }, - complexity: function() { - return this.points.length; - } - }); - fabric.Polygon.ATTRIBUTE_NAMES = fabric.SHARED_ATTRIBUTES.concat(); - fabric.Polygon.fromElement = function(element, options) { - if (!element) { - return 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)); - }; - fabric.Polygon.fromObject = function(object) { - return new fabric.Polygon(object.points, object, true); - }; -})(typeof exports !== "undefined" ? exports : this); - -(function(global) { - "use strict"; - var fabric = global.fabric || (global.fabric = {}), min = fabric.util.array.min, max = fabric.util.array.max, extend = fabric.util.object.extend, _toString = Object.prototype.toString, drawArc = fabric.util.drawArc, commandLengths = { - m: 2, - l: 2, - h: 1, - v: 1, - c: 6, - s: 4, - q: 4, - t: 2, - a: 7 - }, repeatedCommands = { - m: "l", - M: "L" - }; - if (fabric.Path) { - fabric.warn("fabric.Path is already defined"); - return; - } - fabric.Path = fabric.util.createClass(fabric.Object, { - type: "path", - path: null, - minX: 0, - minY: 0, - initialize: function(path, options) { - options = options || {}; - this.setOptions(options); - if (!path) { - path = []; - } - var fromArray = _toString.call(path) === "[object Array]"; - this.path = fromArray ? path : path.match && path.match(/[mzlhvcsqta][^mzlhvcsqta]*/gi); - if (!this.path) { - return; - } - if (!fromArray) { - this.path = this._parsePath(); - } - this._setPositionDimensions(options); - if (options.sourcePath) { - this.setSourcePath(options.sourcePath); - } - }, - _setPositionDimensions: function(options) { - var calcDim = this._parseDimensions(); - this.minX = calcDim.left; - this.minY = calcDim.top; - this.width = calcDim.width; - this.height = calcDim.height; - if (typeof options.left === "undefined") { - this.left = calcDim.left + (this.originX === "center" ? this.width / 2 : this.originX === "right" ? this.width : 0); - } - if (typeof options.top === "undefined") { - this.top = calcDim.top + (this.originY === "center" ? this.height / 2 : this.originY === "bottom" ? this.height : 0); - } - this.pathOffset = this.pathOffset || { - x: this.minX + this.width / 2, - y: this.minY + this.height / 2 - }; - }, - _render: function(ctx) { - var current, previous = null, subpathStartX = 0, subpathStartY = 0, x = 0, y = 0, controlX = 0, controlY = 0, tempX, tempY, l = -this.pathOffset.x, t = -this.pathOffset.y; - if (this.group && this.group.type === "path-group") { - l = 0; - t = 0; - } - ctx.beginPath(); - for (var i = 0, len = this.path.length; i < len; ++i) { - current = this.path[i]; - switch (current[0]) { - case "l": - x += current[1]; - y += current[2]; - ctx.lineTo(x + l, y + t); - break; - - case "L": - x = current[1]; - y = current[2]; - ctx.lineTo(x + l, y + t); - break; - - case "h": - x += current[1]; - ctx.lineTo(x + l, y + t); - break; - - case "H": - x = current[1]; - ctx.lineTo(x + l, y + t); - break; - - case "v": - y += current[1]; - ctx.lineTo(x + l, y + t); - break; - - case "V": - y = current[1]; - ctx.lineTo(x + l, y + t); - break; - - case "m": - x += current[1]; - y += current[2]; - subpathStartX = x; - subpathStartY = y; - ctx.moveTo(x + l, y + t); - break; - - case "M": - x = current[1]; - y = current[2]; - subpathStartX = x; - subpathStartY = y; - ctx.moveTo(x + l, y + t); - break; - - case "c": - tempX = x + current[5]; - tempY = y + current[6]; - controlX = x + current[3]; - controlY = y + current[4]; - ctx.bezierCurveTo(x + current[1] + l, y + current[2] + t, controlX + l, controlY + t, tempX + l, tempY + t); - x = tempX; - y = tempY; - break; - - case "C": - x = current[5]; - y = current[6]; - controlX = current[3]; - controlY = current[4]; - ctx.bezierCurveTo(current[1] + l, current[2] + t, controlX + l, controlY + t, x + l, y + t); - break; - - case "s": - tempX = x + current[3]; - tempY = y + current[4]; - if (previous[0].match(/[CcSs]/) === null) { - controlX = x; - controlY = y; - } else { - controlX = 2 * x - controlX; - controlY = 2 * y - controlY; - } - ctx.bezierCurveTo(controlX + l, controlY + t, x + current[1] + l, y + current[2] + t, tempX + l, tempY + t); - controlX = x + current[1]; - controlY = y + current[2]; - x = tempX; - y = tempY; - break; - - case "S": - tempX = current[3]; - tempY = current[4]; - if (previous[0].match(/[CcSs]/) === null) { - controlX = x; - controlY = y; - } else { - controlX = 2 * x - controlX; - controlY = 2 * y - controlY; - } - ctx.bezierCurveTo(controlX + l, controlY + t, current[1] + l, current[2] + t, tempX + l, tempY + t); - x = tempX; - y = tempY; - controlX = current[1]; - controlY = current[2]; - break; - - case "q": - tempX = x + current[3]; - tempY = y + current[4]; - controlX = x + current[1]; - controlY = y + current[2]; - ctx.quadraticCurveTo(controlX + l, controlY + t, tempX + l, tempY + t); - x = tempX; - y = tempY; - break; - - case "Q": - tempX = current[3]; - tempY = current[4]; - ctx.quadraticCurveTo(current[1] + l, current[2] + t, tempX + l, tempY + t); - x = tempX; - y = tempY; - controlX = current[1]; - controlY = current[2]; - break; - - case "t": - tempX = x + current[1]; - tempY = y + current[2]; - if (previous[0].match(/[QqTt]/) === null) { - controlX = x; - controlY = y; - } else { - controlX = 2 * x - controlX; - controlY = 2 * y - controlY; - } - ctx.quadraticCurveTo(controlX + l, controlY + t, tempX + l, tempY + t); - x = tempX; - y = tempY; - break; - - case "T": - tempX = current[1]; - tempY = current[2]; - if (previous[0].match(/[QqTt]/) === null) { - controlX = x; - controlY = y; - } else { - controlX = 2 * x - controlX; - controlY = 2 * y - controlY; - } - ctx.quadraticCurveTo(controlX + l, controlY + t, tempX + l, tempY + t); - x = tempX; - y = tempY; - break; - - case "a": - drawArc(ctx, x + l, y + t, [ current[1], current[2], current[3], current[4], current[5], current[6] + x + l, current[7] + y + t ]); - x += current[6]; - y += current[7]; - break; - - case "A": - drawArc(ctx, x + l, y + t, [ current[1], current[2], current[3], current[4], current[5], current[6] + l, current[7] + t ]); - x = current[6]; - y = current[7]; - break; - - case "z": - case "Z": - x = subpathStartX; - y = subpathStartY; - ctx.closePath(); - break; - } - previous = current; - } - this._renderFill(ctx); - this._renderStroke(ctx); - }, - toString: function() { - return "#"; - }, - toObject: function(propertiesToInclude) { - var o = extend(this.callSuper("toObject", propertiesToInclude), { - path: this.path.map(function(item) { - return item.slice(); - }), - pathOffset: this.pathOffset - }); - if (this.sourcePath) { - o.sourcePath = this.sourcePath; - } - if (this.transformMatrix) { - o.transformMatrix = this.transformMatrix; - } - return o; - }, - toDatalessObject: function(propertiesToInclude) { - var o = this.toObject(propertiesToInclude); - if (this.sourcePath) { - o.path = this.sourcePath; - } - delete o.sourcePath; - return o; - }, - toSVG: function(reviver) { - var chunks = [], markup = this._createBaseSVGMarkup(), addTransform = ""; - for (var i = 0, len = this.path.length; i < len; i++) { - chunks.push(this.path[i].join(" ")); - } - var path = chunks.join(" "); - if (!(this.group && this.group.type === "path-group")) { - addTransform = " translate(" + -this.pathOffset.x + ", " + -this.pathOffset.y + ") "; - } - markup.push("\n"); - return reviver ? reviver(markup.join("")) : markup.join(""); - }, - complexity: function() { - return this.path.length; - }, - _parsePath: function() { - var result = [], coords = [], currentPath, parsed, re = /([-+]?((\d+\.\d+)|((\d+)|(\.\d+)))(?:e[-+]?\d+)?)/gi, match, coordsStr; - for (var i = 0, coordsParsed, len = this.path.length; i < len; i++) { - currentPath = this.path[i]; - coordsStr = currentPath.slice(1).trim(); - coords.length = 0; - while (match = re.exec(coordsStr)) { - coords.push(match[0]); - } - coordsParsed = [ currentPath.charAt(0) ]; - for (var j = 0, jlen = coords.length; j < jlen; j++) { - parsed = parseFloat(coords[j]); - if (!isNaN(parsed)) { - coordsParsed.push(parsed); - } - } - var command = coordsParsed[0], commandLength = commandLengths[command.toLowerCase()], repeatedCommand = repeatedCommands[command] || command; - if (coordsParsed.length - 1 > commandLength) { - for (var k = 1, klen = coordsParsed.length; k < klen; k += commandLength) { - result.push([ command ].concat(coordsParsed.slice(k, k + commandLength))); - command = repeatedCommand; - } - } else { - result.push(coordsParsed); - } - } - return result; - }, - _parseDimensions: function() { - var aX = [], aY = [], current, previous = null, subpathStartX = 0, subpathStartY = 0, x = 0, y = 0, controlX = 0, controlY = 0, tempX, tempY, bounds; - for (var i = 0, len = this.path.length; i < len; ++i) { - current = this.path[i]; - switch (current[0]) { - case "l": - x += current[1]; - y += current[2]; - bounds = []; - break; - - case "L": - x = current[1]; - y = current[2]; - bounds = []; - break; - - case "h": - x += current[1]; - bounds = []; - break; - - case "H": - x = current[1]; - bounds = []; - break; - - case "v": - y += current[1]; - bounds = []; - break; - - case "V": - y = current[1]; - bounds = []; - break; - - case "m": - x += current[1]; - y += current[2]; - subpathStartX = x; - subpathStartY = y; - bounds = []; - break; - - case "M": - x = current[1]; - y = current[2]; - subpathStartX = x; - subpathStartY = y; - bounds = []; - break; - - case "c": - tempX = x + current[5]; - tempY = y + current[6]; - controlX = x + current[3]; - controlY = y + current[4]; - bounds = fabric.util.getBoundsOfCurve(x, y, x + current[1], y + current[2], controlX, controlY, tempX, tempY); - x = tempX; - y = tempY; - break; - - case "C": - x = current[5]; - y = current[6]; - controlX = current[3]; - controlY = current[4]; - bounds = fabric.util.getBoundsOfCurve(x, y, current[1], current[2], controlX, controlY, x, y); - break; - - case "s": - tempX = x + current[3]; - tempY = y + current[4]; - if (previous[0].match(/[CcSs]/) === null) { - controlX = x; - controlY = y; - } else { - controlX = 2 * x - controlX; - controlY = 2 * y - controlY; - } - bounds = fabric.util.getBoundsOfCurve(x, y, controlX, controlY, x + current[1], y + current[2], tempX, tempY); - controlX = x + current[1]; - controlY = y + current[2]; - x = tempX; - y = tempY; - break; - - case "S": - tempX = current[3]; - tempY = current[4]; - if (previous[0].match(/[CcSs]/) === null) { - controlX = x; - controlY = y; - } else { - controlX = 2 * x - controlX; - controlY = 2 * y - controlY; - } - bounds = fabric.util.getBoundsOfCurve(x, y, controlX, controlY, current[1], current[2], tempX, tempY); - x = tempX; - y = tempY; - controlX = current[1]; - controlY = current[2]; - break; - - case "q": - tempX = x + current[3]; - tempY = y + current[4]; - controlX = x + current[1]; - controlY = y + current[2]; - bounds = fabric.util.getBoundsOfCurve(x, y, controlX, controlY, controlX, controlY, tempX, tempY); - x = tempX; - y = tempY; - break; - - case "Q": - controlX = current[1]; - controlY = current[2]; - bounds = fabric.util.getBoundsOfCurve(x, y, controlX, controlY, controlX, controlY, current[3], current[4]); - x = current[3]; - y = current[4]; - break; - - case "t": - tempX = x + current[1]; - tempY = y + current[2]; - if (previous[0].match(/[QqTt]/) === null) { - controlX = x; - controlY = y; - } else { - controlX = 2 * x - controlX; - controlY = 2 * y - controlY; - } - bounds = fabric.util.getBoundsOfCurve(x, y, controlX, controlY, controlX, controlY, tempX, tempY); - x = tempX; - y = tempY; - break; - - case "T": - tempX = current[1]; - tempY = current[2]; - if (previous[0].match(/[QqTt]/) === null) { - controlX = x; - controlY = y; - } else { - controlX = 2 * x - controlX; - controlY = 2 * y - controlY; - } - bounds = fabric.util.getBoundsOfCurve(x, y, controlX, controlY, controlX, controlY, tempX, tempY); - x = tempX; - y = tempY; - break; - - case "a": - bounds = fabric.util.getBoundsOfArc(x, y, current[1], current[2], current[3], current[4], current[5], current[6] + x, current[7] + y); - x += current[6]; - y += current[7]; - break; - - case "A": - bounds = fabric.util.getBoundsOfArc(x, y, current[1], current[2], current[3], current[4], current[5], current[6], current[7]); - x = current[6]; - y = current[7]; - break; - - case "z": - case "Z": - x = subpathStartX; - y = subpathStartY; - break; - } - previous = current; - bounds.forEach(function(point) { - aX.push(point.x); - aY.push(point.y); - }); - aX.push(x); - aY.push(y); - } - var minX = min(aX) || 0, minY = min(aY) || 0, maxX = max(aX) || 0, maxY = max(aY) || 0, deltaX = maxX - minX, deltaY = maxY - minY, o = { - left: minX, - top: minY, - width: deltaX, - height: deltaY - }; - return o; - } - }); - fabric.Path.fromObject = function(object, callback) { - if (typeof object.path === "string") { - fabric.loadSVGFromURL(object.path, function(elements) { - var path = elements[0], pathUrl = object.path; - delete object.path; - fabric.util.object.extend(path, object); - path.setSourcePath(pathUrl); - callback(path); - }); - } else { - callback(new fabric.Path(object.path, object)); - } - }; - 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); - callback && callback(new fabric.Path(parsedAttributes.d, extend(parsedAttributes, options))); - }; - fabric.Path.async = true; -})(typeof exports !== "undefined" ? exports : this); - -(function(global) { - "use strict"; - var fabric = global.fabric || (global.fabric = {}), extend = fabric.util.object.extend, invoke = fabric.util.array.invoke, parentToObject = fabric.Object.prototype.toObject; - if (fabric.PathGroup) { - fabric.warn("fabric.PathGroup is already defined"); - return; - } - fabric.PathGroup = fabric.util.createClass(fabric.Path, { - type: "path-group", - fill: "", - initialize: function(paths, options) { - options = options || {}; - this.paths = paths || []; - for (var i = this.paths.length; i--; ) { - this.paths[i].group = this; - } - if (options.toBeParsed) { - this.parseDimensionsFromPaths(options); - delete options.toBeParsed; - } - this.setOptions(options); - this.setCoords(); - if (options.sourcePath) { - this.setSourcePath(options.sourcePath); - } - }, - parseDimensionsFromPaths: function(options) { - var points, p, xC = [], yC = [], path, height, width, m; - for (var j = this.paths.length; j--; ) { - path = this.paths[j]; - height = path.height + path.strokeWidth; - width = path.width + path.strokeWidth; - points = [ { - x: path.left, - y: path.top - }, { - x: path.left + width, - y: path.top - }, { - x: path.left, - y: path.top + height - }, { - x: path.left + width, - y: path.top + height - } ]; - m = this.paths[j].transformMatrix; - for (var i = 0; i < points.length; i++) { - p = points[i]; - if (m) { - p = fabric.util.transformPoint(p, m, false); - } - xC.push(p.x); - yC.push(p.y); - } - } - options.width = Math.max.apply(null, xC); - options.height = Math.max.apply(null, yC); - }, - render: function(ctx) { - if (!this.visible) { - return; - } - ctx.save(); - if (this.transformMatrix) { - ctx.transform.apply(ctx, this.transformMatrix); - } - this.transform(ctx); - this._setShadow(ctx); - this.clipTo && fabric.util.clipContext(this, ctx); - ctx.translate(-this.width / 2, -this.height / 2); - for (var i = 0, l = this.paths.length; i < l; ++i) { - this.paths[i].render(ctx, true); - } - this.clipTo && ctx.restore(); - ctx.restore(); - }, - _set: function(prop, value) { - if (prop === "fill" && value && this.isSameColor()) { - var i = this.paths.length; - while (i--) { - this.paths[i]._set(prop, value); - } - } - return this.callSuper("_set", prop, value); - }, - toObject: function(propertiesToInclude) { - var o = extend(parentToObject.call(this, propertiesToInclude), { - paths: invoke(this.getObjects(), "toObject", propertiesToInclude) - }); - if (this.sourcePath) { - o.sourcePath = this.sourcePath; - } - return o; - }, - toDatalessObject: function(propertiesToInclude) { - var o = this.toObject(propertiesToInclude); - if (this.sourcePath) { - o.paths = this.sourcePath; - } - return o; - }, - toSVG: function(reviver) { - var objects = this.getObjects(), p = this.getPointByOrigin("left", "top"), translatePart = "translate(" + p.x + " " + p.y + ")", markup = this._createBaseSVGMarkup(); - markup.push("\n"); - for (var i = 0, len = objects.length; i < len; i++) { - markup.push(" ", objects[i].toSVG(reviver)); - } - markup.push("\n"); - return reviver ? reviver(markup.join("")) : markup.join(""); - }, - toString: function() { - return "#"; - }, - isSameColor: function() { - var firstPathFill = this.getObjects()[0].get("fill") || ""; - if (typeof firstPathFill !== "string") { - return false; - } - firstPathFill = firstPathFill.toLowerCase(); - return this.getObjects().every(function(path) { - var pathFill = path.get("fill") || ""; - return typeof pathFill === "string" && pathFill.toLowerCase() === firstPathFill; - }); - }, - complexity: function() { - return this.paths.reduce(function(total, path) { - return total + (path && path.complexity ? path.complexity() : 0); - }, 0); - }, - getObjects: function() { - return this.paths; - } - }); - fabric.PathGroup.fromObject = function(object, callback) { - if (typeof object.paths === "string") { - fabric.loadSVGFromURL(object.paths, function(elements) { - var pathUrl = object.paths; - delete object.paths; - var pathGroup = fabric.util.groupSVGElements(elements, object, pathUrl); - callback(pathGroup); - }); - } else { - fabric.util.enlivenObjects(object.paths, function(enlivenedObjects) { - delete object.paths; - callback(new fabric.PathGroup(enlivenedObjects, object)); - }); - } - }; - fabric.PathGroup.async = true; -})(typeof exports !== "undefined" ? exports : this); - -(function(global) { - "use strict"; - var fabric = global.fabric || (global.fabric = {}), extend = fabric.util.object.extend, min = fabric.util.array.min, max = fabric.util.array.max, invoke = fabric.util.array.invoke; - 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, - initialize: function(objects, options, isAlreadyGrouped) { - options = options || {}; - this._objects = []; - isAlreadyGrouped && this.callSuper("initialize", options); - this._objects = objects || []; - for (var i = this._objects.length; i--; ) { - this._objects[i].group = this; - } - this.originalState = {}; - if (options.originX) { - this.originX = options.originX; - } - if (options.originY) { - this.originY = options.originY; - } - if (isAlreadyGrouped) { - this._updateObjectsCoords(true); - } else { - this._calcBounds(); - this._updateObjectsCoords(); - this.callSuper("initialize", options); - } - this.setCoords(); - this.saveCoords(); - }, - _updateObjectsCoords: function(skipCoordsChange) { - for (var i = this._objects.length; i--; ) { - this._updateObjectCoords(this._objects[i], skipCoordsChange); - } - }, - _updateObjectCoords: function(object, skipCoordsChange) { - object.__origHasControls = object.hasControls; - object.hasControls = false; - if (skipCoordsChange) { - return; - } - var objectLeft = object.getLeft(), objectTop = object.getTop(), center = this.getCenterPoint(); - object.set({ - originalLeft: objectLeft, - originalTop: objectTop, - left: objectLeft - center.x, - top: objectTop - center.y - }); - object.setCoords(); - }, - toString: function() { - return "#"; - }, - addWithUpdate: function(object) { - this._restoreObjectsState(); - fabric.util.resetObjectTransform(this); - if (object) { - this._objects.push(object); - object.group = this; - object._set("canvas", this.canvas); - } - this.forEachObject(this._setObjectActive, this); - this._calcBounds(); - this._updateObjectsCoords(); - return this; - }, - _setObjectActive: function(object) { - object.set("active", true); - object.group = this; - }, - removeWithUpdate: function(object) { - this._restoreObjectsState(); - fabric.util.resetObjectTransform(this); - this.forEachObject(this._setObjectActive, this); - this.remove(object); - this._calcBounds(); - this._updateObjectsCoords(); - return this; - }, - _onObjectAdded: function(object) { - object.group = this; - object._set("canvas", this.canvas); - }, - _onObjectRemoved: function(object) { - 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") { - while (i--) { - this._objects[i].set(key, value); - } - } else { - while (i--) { - this._objects[i].setOnGroup(key, value); - } - } - this.callSuper("_set", key, value); - }, - toObject: function(propertiesToInclude) { - return extend(this.callSuper("toObject", propertiesToInclude), { - objects: invoke(this._objects, "toObject", propertiesToInclude) - }); - }, - render: function(ctx) { - if (!this.visible) { - return; - } - ctx.save(); - if (this.transformMatrix) { - ctx.transform.apply(ctx, this.transformMatrix); - } - this.transform(ctx); - this._setShadow(ctx); - this.clipTo && fabric.util.clipContext(this, ctx); - for (var i = 0, len = this._objects.length; i < len; i++) { - this._renderObject(this._objects[i], ctx); - } - this.clipTo && ctx.restore(); - ctx.restore(); - }, - _renderControls: function(ctx, noTransform) { - this.callSuper("_renderControls", ctx, noTransform); - for (var i = 0, len = this._objects.length; i < len; i++) { - this._objects[i]._renderControls(ctx); - } - }, - _renderObject: function(object, ctx) { - if (!object.visible) { - return; - } - var originalHasRotatingPoint = object.hasRotatingPoint; - object.hasRotatingPoint = false; - object.render(ctx); - object.hasRotatingPoint = originalHasRotatingPoint; - }, - _restoreObjectsState: function() { - this._objects.forEach(this._restoreObjectState, this); - return this; - }, - realizeTransform: function(object) { - var matrix = object.calcTransformMatrix(), options = fabric.util.qrDecompose(matrix), center = new fabric.Point(options.translateX, options.translateY); - object.scaleX = options.scaleX; - object.scaleY = options.scaleY; - object.skewX = options.skewX; - object.skewY = options.skewY; - object.angle = options.angle; - object.flipX = false; - object.flipY = false; - object.setPositionByOrigin(center, "center", "center"); - return object; - }, - _restoreObjectState: function(object) { - this.realizeTransform(object); - object.setCoords(); - object.hasControls = object.__origHasControls; - delete object.__origHasControls; - object.set("active", false); - delete object.group; - return this; - }, - destroy: function() { - return this._restoreObjectsState(); - }, - saveCoords: function() { - this._originalLeft = this.get("left"); - this._originalTop = this.get("top"); - return this; - }, - hasMoved: function() { - return this._originalLeft !== this.get("left") || this._originalTop !== this.get("top"); - }, - setObjectsCoords: function() { - this.forEachObject(function(object) { - object.setCoords(); - }); - return this; - }, - _calcBounds: function(onlyWidthHeight) { - var aX = [], aY = [], o, prop, props = [ "tr", "br", "bl", "tl" ], i = 0, iLen = this._objects.length, j, jLen = props.length; - for (;i < iLen; ++i) { - o = this._objects[i]; - o.setCoords(); - for (j = 0; j < jLen; j++) { - prop = props[j]; - aX.push(o.oCoords[prop].x); - aY.push(o.oCoords[prop].y); - } - } - this.set(this._getBounds(aX, aY, onlyWidthHeight)); - }, - _getBounds: function(aX, aY, onlyWidthHeight) { - var ivt = fabric.util.invertTransform(this.getViewportTransform()), minXY = fabric.util.transformPoint(new fabric.Point(min(aX), min(aY)), ivt), maxXY = fabric.util.transformPoint(new fabric.Point(max(aX), max(aY)), ivt), obj = { - width: maxXY.x - minXY.x || 0, - height: maxXY.y - minXY.y || 0 - }; - if (!onlyWidthHeight) { - obj.left = minXY.x || 0; - obj.top = minXY.y || 0; - if (this.originX === "center") { - obj.left += obj.width / 2; - } - if (this.originX === "right") { - obj.left += obj.width; - } - if (this.originY === "center") { - obj.top += obj.height / 2; - } - if (this.originY === "bottom") { - obj.top += obj.height; - } - } - return obj; - }, - toSVG: function(reviver) { - var markup = this._createBaseSVGMarkup(); - markup.push('\n'); - for (var i = 0, len = this._objects.length; i < len; i++) { - markup.push(" ", this._objects[i].toSVG(reviver)); - } - 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) { - fabric.util.enlivenObjects(object.objects, function(enlivenedObjects) { - delete object.objects; - callback && callback(new fabric.Group(enlivenedObjects, object, true)); - }); - }; - fabric.Group.async = true; -})(typeof exports !== "undefined" ? exports : this); - -(function(global) { - "use strict"; - var extend = fabric.util.object.extend; - if (!global.fabric) { - global.fabric = {}; - } - if (global.fabric.Image) { - fabric.warn("fabric.Image is already defined."); - return; - } - fabric.Image = fabric.util.createClass(fabric.Object, { - type: "image", - crossOrigin: "", - alignX: "none", - alignY: "none", - meetOrSlice: "meet", - strokeWidth: 0, - _lastScaleX: 1, - _lastScaleY: 1, - initialize: function(element, options) { - options || (options = {}); - this.filters = []; - this.resizeFilters = []; - this.callSuper("initialize", options); - this._initElement(element, options); - }, - getElement: function() { - return this._element; - }, - setElement: function(element, callback, options) { - this._element = element; - this._originalElement = element; - this._initConfig(options); - if (this.filters.length !== 0) { - this.applyFilters(callback); - } else if (callback) { - callback(); - } - return this; - }, - setCrossOrigin: function(value) { - this.crossOrigin = value; - this._element.crossOrigin = value; - return this; - }, - getOriginalSize: function() { - var element = this.getElement(); - return { - width: element.width, - height: element.height - }; - }, - _stroke: function(ctx) { - ctx.save(); - this._setStrokeStyles(ctx); - ctx.beginPath(); - ctx.strokeRect(-this.width / 2, -this.height / 2, this.width, this.height); - ctx.closePath(); - ctx.restore(); - }, - _renderDashedStroke: function(ctx) { - var x = -this.width / 2, y = -this.height / 2, w = this.width, h = this.height; - ctx.save(); - this._setStrokeStyles(ctx); - ctx.beginPath(); - fabric.util.drawDashedLine(ctx, x, y, x + w, y, this.strokeDashArray); - fabric.util.drawDashedLine(ctx, x + w, y, x + w, y + h, this.strokeDashArray); - fabric.util.drawDashedLine(ctx, x + w, y + h, x, y + h, this.strokeDashArray); - fabric.util.drawDashedLine(ctx, x, y + h, x, y, this.strokeDashArray); - ctx.closePath(); - ctx.restore(); - }, - toObject: function(propertiesToInclude) { - var filters = [], element = this._originalElement; - this.filters.forEach(function(filterObj) { - if (filterObj) { - filters.push(filterObj.toObject()); - } - }); - var object = extend(this.callSuper("toObject", propertiesToInclude), { - src: element ? element.src || element._src : "", - filters: filters, - crossOrigin: this.crossOrigin, - alignX: this.alignX, - alignY: this.alignY, - meetOrSlice: this.meetOrSlice - }); - if (this.resizeFilters.length > 0) { - object.resizeFilters = this.resizeFilters.map(function(filterObj) { - return filterObj && filterObj.toObject(); - }); - } - if (!this.includeDefaultValues) { - this._removeDefaultValues(object); - } - return object; - }, - toSVG: function(reviver) { - var markup = this._createBaseSVGMarkup(), x = -this.width / 2, y = -this.height / 2, preserveAspectRatio = "none"; - if (this.group && this.group.type === "path-group") { - x = this.left; - y = this.top; - } - if (this.alignX !== "none" && this.alignY !== "none") { - preserveAspectRatio = "x" + this.alignX + "Y" + this.alignY + " " + this.meetOrSlice; - } - markup.push('\n', '\n"); - if (this.stroke || this.strokeDashArray) { - var origFill = this.fill; - this.fill = null; - markup.push("\n'); - this.fill = origFill; - } - markup.push("\n"); - return reviver ? reviver(markup.join("")) : markup.join(""); - }, - getSrc: function() { - if (this.getElement()) { - return this.getElement().src || this.getElement()._src; - } - }, - setSrc: function(src, callback, options) { - fabric.util.loadImage(src, function(img) { - return this.setElement(img, callback, options); - }, this, options && options.crossOrigin); - }, - toString: function() { - return '#'; - }, - clone: function(callback, propertiesToInclude) { - this.constructor.fromObject(this.toObject(propertiesToInclude), callback); - }, - applyFilters: function(callback, filters, imgElement, forResizing) { - filters = filters || this.filters; - imgElement = imgElement || this._originalElement; - if (!imgElement) { - return; - } - var imgEl = imgElement, canvasEl = fabric.util.createCanvasElement(), replacement = fabric.util.createImage(), _this = this; - canvasEl.width = imgEl.width; - canvasEl.height = imgEl.height; - canvasEl.getContext("2d").drawImage(imgEl, 0, 0, imgEl.width, imgEl.height); - if (filters.length === 0) { - this._element = imgElement; - callback && callback(); - return canvasEl; - } - filters.forEach(function(filter) { - filter && filter.applyTo(canvasEl, filter.scaleX || _this.scaleX, filter.scaleY || _this.scaleY); - if (!forResizing && filter && filter.type === "Resize") { - _this.width *= filter.scaleX; - _this.height *= filter.scaleY; - } - }); - replacement.width = canvasEl.width; - replacement.height = canvasEl.height; - if (fabric.isLikelyNode) { - replacement.src = canvasEl.toBuffer(undefined, fabric.Image.pngCompression); - _this._element = replacement; - !forResizing && (_this._filteredEl = replacement); - callback && callback(); - } else { - replacement.onload = function() { - _this._element = replacement; - !forResizing && (_this._filteredEl = replacement); - callback && callback(); - replacement.onload = canvasEl = imgEl = null; - }; - replacement.src = canvasEl.toDataURL("image/png"); - } - return canvasEl; - }, - _render: function(ctx, noTransform) { - var x, y, imageMargins = this._findMargins(), elementToDraw; - x = noTransform ? this.left : -this.width / 2; - y = noTransform ? this.top : -this.height / 2; - if (this.meetOrSlice === "slice") { - ctx.beginPath(); - ctx.rect(x, y, this.width, this.height); - ctx.clip(); - } - if (this.isMoving === false && this.resizeFilters.length && this._needsResize()) { - this._lastScaleX = this.scaleX; - this._lastScaleY = this.scaleY; - elementToDraw = this.applyFilters(null, this.resizeFilters, this._filteredEl || this._originalElement, true); - } else { - elementToDraw = this._element; - } - elementToDraw && ctx.drawImage(elementToDraw, x + imageMargins.marginX, y + imageMargins.marginY, imageMargins.width, imageMargins.height); - 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); - this.set("height", element.height); - }, - _initElement: function(element, options) { - this.setElement(fabric.util.getById(element), null, options); - fabric.util.addClass(this.getElement(), fabric.Image.CSS_CANVAS); - }, - _initConfig: function(options) { - options || (options = {}); - this.setOptions(options); - this._setWidthHeight(options); - if (this._element && this.crossOrigin) { - this._element.crossOrigin = this.crossOrigin; - } - }, - _initFilters: function(filters, callback) { - if (filters && filters.length) { - fabric.util.enlivenObjects(filters, function(enlivenedObjects) { - callback && callback(enlivenedObjects); - }, "fabric.Image.filters"); - } else { - callback && callback(); - } - }, - _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; - }, - complexity: function() { - return 1; - } - }); - fabric.Image.CSS_CANVAS = "canvas-img"; - fabric.Image.prototype.getSvgSrc = fabric.Image.prototype.getSrc; - fabric.Image.fromObject = function(object, callback) { - fabric.util.loadImage(object.src, function(img) { - fabric.Image.prototype._initFilters.call(object, object.filters, function(filters) { - object.filters = filters || []; - fabric.Image.prototype._initFilters.call(object, object.resizeFilters, function(resizeFilters) { - object.resizeFilters = resizeFilters || []; - var instance = new fabric.Image(img, object); - callback && callback(instance); - }); - }); - }, null, object.crossOrigin); - }; - fabric.Image.fromURL = function(url, callback, imgOptions) { - fabric.util.loadImage(url, function(img) { - callback && callback(new fabric.Image(img, imgOptions)); - }, null, imgOptions && imgOptions.crossOrigin); - }; - fabric.Image.ATTRIBUTE_NAMES = fabric.SHARED_ATTRIBUTES.concat("x y width height preserveAspectRatio xlink:href".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); - } - 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; - if (angle > 0) { - return Math.round((angle - 1) / 90) * 90; - } - return Math.round(angle / 90) * 90; - }, - straighten: function() { - this.setAngle(this._getAngleValueForStraighten()); - return this; - }, - fxStraighten: function(callbacks) { - callbacks = callbacks || {}; - var empty = function() {}, onComplete = callbacks.onComplete || empty, onChange = callbacks.onChange || empty, _this = this; - fabric.util.animate({ - startValue: this.get("angle"), - endValue: this._getAngleValueForStraighten(), - duration: this.FX_DURATION, - onChange: function(value) { - _this.setAngle(value); - onChange(); - }, - onComplete: function() { - _this.setCoords(); - onComplete(); - }, - onStart: function() { - _this.set("active", false); - } - }); - return this; - } -}); - -fabric.util.object.extend(fabric.StaticCanvas.prototype, { - straightenObject: function(object) { - object.straighten(); - this.renderAll(); - return this; - }, - fxStraightenObject: function(object) { - object.fxStraighten({ - onChange: this.renderAll.bind(this) - }); - return this; - } -}); - -fabric.Image.filters = fabric.Image.filters || {}; - -fabric.Image.filters.BaseFilter = fabric.util.createClass({ - type: "BaseFilter", - initialize: function(options) { - if (options) { - this.setOptions(options); - } - }, - setOptions: function(options) { - for (var prop in options) { - this[prop] = options[prop]; - } - }, - toObject: function() { - return { - type: this.type - }; - }, - toJSON: function() { - return this.toObject(); - } -}); - -(function(global) { - "use strict"; - var fabric = global.fabric || (global.fabric = {}), extend = fabric.util.object.extend; - fabric.Image.filters.Brightness = fabric.util.createClass(fabric.Image.filters.BaseFilter, { - type: "Brightness", - initialize: function(options) { - options = options || {}; - this.brightness = options.brightness || 0; - }, - applyTo: function(canvasEl) { - var context = canvasEl.getContext("2d"), imageData = context.getImageData(0, 0, canvasEl.width, canvasEl.height), data = imageData.data, brightness = this.brightness; - for (var i = 0, len = data.length; i < len; i += 4) { - data[i] += brightness; - data[i + 1] += brightness; - data[i + 2] += brightness; - } - context.putImageData(imageData, 0, 0); - }, - toObject: function() { - return extend(this.callSuper("toObject"), { - brightness: this.brightness - }); - } - }); - fabric.Image.filters.Brightness.fromObject = function(object) { - return new fabric.Image.filters.Brightness(object); - }; -})(typeof exports !== "undefined" ? exports : this); - -(function(global) { - "use strict"; - var fabric = global.fabric || (global.fabric = {}), extend = fabric.util.object.extend; - fabric.Image.filters.Convolute = fabric.util.createClass(fabric.Image.filters.BaseFilter, { - type: "Convolute", - initialize: function(options) { - options = options || {}; - this.opaque = options.opaque; - this.matrix = options.matrix || [ 0, 0, 0, 0, 1, 0, 0, 0, 0 ]; - }, - applyTo: function(canvasEl) { - var weights = this.matrix, context = canvasEl.getContext("2d"), pixels = context.getImageData(0, 0, canvasEl.width, canvasEl.height), side = Math.round(Math.sqrt(weights.length)), halfSide = Math.floor(side / 2), src = pixels.data, sw = pixels.width, sh = pixels.height, output = context.createImageData(sw, sh), dst = output.data, alphaFac = this.opaque ? 1 : 0, r, g, b, a, dstOff, scx, scy, srcOff, wt; - for (var y = 0; y < sh; y++) { - for (var x = 0; x < sw; x++) { - dstOff = (y * sw + x) * 4; - r = 0; - g = 0; - b = 0; - a = 0; - for (var cy = 0; cy < side; cy++) { - for (var cx = 0; cx < side; cx++) { - scy = y + cy - halfSide; - scx = x + cx - halfSide; - if (scy < 0 || scy > sh || scx < 0 || scx > sw) { - continue; - } - srcOff = (scy * sw + scx) * 4; - wt = weights[cy * side + cx]; - r += src[srcOff] * wt; - g += src[srcOff + 1] * wt; - b += src[srcOff + 2] * wt; - a += src[srcOff + 3] * wt; - } - } - dst[dstOff] = r; - dst[dstOff + 1] = g; - dst[dstOff + 2] = b; - dst[dstOff + 3] = a + alphaFac * (255 - a); - } - } - context.putImageData(output, 0, 0); - }, - toObject: function() { - return extend(this.callSuper("toObject"), { - opaque: this.opaque, - matrix: this.matrix - }); - } - }); - fabric.Image.filters.Convolute.fromObject = function(object) { - return new fabric.Image.filters.Convolute(object); - }; -})(typeof exports !== "undefined" ? exports : this); - -(function(global) { - "use strict"; - var fabric = global.fabric || (global.fabric = {}), extend = fabric.util.object.extend; - fabric.Image.filters.GradientTransparency = fabric.util.createClass(fabric.Image.filters.BaseFilter, { - type: "GradientTransparency", - initialize: function(options) { - options = options || {}; - this.threshold = options.threshold || 100; - }, - applyTo: function(canvasEl) { - var context = canvasEl.getContext("2d"), imageData = context.getImageData(0, 0, canvasEl.width, canvasEl.height), data = imageData.data, threshold = this.threshold, total = data.length; - for (var i = 0, len = data.length; i < len; i += 4) { - data[i + 3] = threshold + 255 * (total - i) / total; - } - context.putImageData(imageData, 0, 0); - }, - toObject: function() { - return extend(this.callSuper("toObject"), { - threshold: this.threshold - }); - } - }); - fabric.Image.filters.GradientTransparency.fromObject = function(object) { - return new fabric.Image.filters.GradientTransparency(object); - }; -})(typeof exports !== "undefined" ? exports : this); - -(function(global) { - "use strict"; - var fabric = global.fabric || (global.fabric = {}); - fabric.Image.filters.Grayscale = fabric.util.createClass(fabric.Image.filters.BaseFilter, { - type: "Grayscale", - applyTo: function(canvasEl) { - var context = canvasEl.getContext("2d"), imageData = context.getImageData(0, 0, canvasEl.width, canvasEl.height), data = imageData.data, len = imageData.width * imageData.height * 4, index = 0, average; - while (index < len) { - average = (data[index] + data[index + 1] + data[index + 2]) / 3; - data[index] = average; - data[index + 1] = average; - data[index + 2] = average; - index += 4; - } - context.putImageData(imageData, 0, 0); - } - }); - fabric.Image.filters.Grayscale.fromObject = function() { - return new fabric.Image.filters.Grayscale(); - }; -})(typeof exports !== "undefined" ? exports : this); - -(function(global) { - "use strict"; - var fabric = global.fabric || (global.fabric = {}); - fabric.Image.filters.Invert = fabric.util.createClass(fabric.Image.filters.BaseFilter, { - type: "Invert", - applyTo: function(canvasEl) { - var context = canvasEl.getContext("2d"), imageData = context.getImageData(0, 0, canvasEl.width, canvasEl.height), data = imageData.data, iLen = data.length, i; - for (i = 0; i < iLen; i += 4) { - data[i] = 255 - data[i]; - data[i + 1] = 255 - data[i + 1]; - data[i + 2] = 255 - data[i + 2]; - } - context.putImageData(imageData, 0, 0); - } - }); - fabric.Image.filters.Invert.fromObject = function() { - return new fabric.Image.filters.Invert(); - }; -})(typeof exports !== "undefined" ? exports : this); - -(function(global) { - "use strict"; - var fabric = global.fabric || (global.fabric = {}), extend = fabric.util.object.extend; - fabric.Image.filters.Mask = fabric.util.createClass(fabric.Image.filters.BaseFilter, { - type: "Mask", - initialize: function(options) { - options = options || {}; - this.mask = options.mask; - this.channel = [ 0, 1, 2, 3 ].indexOf(options.channel) > -1 ? options.channel : 0; - }, - applyTo: function(canvasEl) { - if (!this.mask) { - return; - } - var context = canvasEl.getContext("2d"), imageData = context.getImageData(0, 0, canvasEl.width, canvasEl.height), data = imageData.data, maskEl = this.mask.getElement(), maskCanvasEl = fabric.util.createCanvasElement(), channel = this.channel, i, iLen = imageData.width * imageData.height * 4; - maskCanvasEl.width = canvasEl.width; - maskCanvasEl.height = canvasEl.height; - maskCanvasEl.getContext("2d").drawImage(maskEl, 0, 0, canvasEl.width, canvasEl.height); - var maskImageData = maskCanvasEl.getContext("2d").getImageData(0, 0, canvasEl.width, canvasEl.height), maskData = maskImageData.data; - for (i = 0; i < iLen; i += 4) { - data[i + 3] = maskData[i + channel]; - } - context.putImageData(imageData, 0, 0); - }, - toObject: function() { - return extend(this.callSuper("toObject"), { - mask: this.mask.toObject(), - channel: this.channel - }); - } - }); - fabric.Image.filters.Mask.fromObject = function(object, callback) { - fabric.util.loadImage(object.mask.src, function(img) { - object.mask = new fabric.Image(img, object.mask); - callback && callback(new fabric.Image.filters.Mask(object)); - }); - }; - fabric.Image.filters.Mask.async = true; -})(typeof exports !== "undefined" ? exports : this); - -(function(global) { - "use strict"; - var fabric = global.fabric || (global.fabric = {}), extend = fabric.util.object.extend; - fabric.Image.filters.Noise = fabric.util.createClass(fabric.Image.filters.BaseFilter, { - type: "Noise", - initialize: function(options) { - options = options || {}; - this.noise = options.noise || 0; - }, - applyTo: function(canvasEl) { - var context = canvasEl.getContext("2d"), imageData = context.getImageData(0, 0, canvasEl.width, canvasEl.height), data = imageData.data, noise = this.noise, rand; - for (var i = 0, len = data.length; i < len; i += 4) { - rand = (.5 - Math.random()) * noise; - data[i] += rand; - data[i + 1] += rand; - data[i + 2] += rand; - } - context.putImageData(imageData, 0, 0); - }, - toObject: function() { - return extend(this.callSuper("toObject"), { - noise: this.noise - }); - } - }); - fabric.Image.filters.Noise.fromObject = function(object) { - return new fabric.Image.filters.Noise(object); - }; -})(typeof exports !== "undefined" ? exports : this); - -(function(global) { - "use strict"; - var fabric = global.fabric || (global.fabric = {}), extend = fabric.util.object.extend; - fabric.Image.filters.Pixelate = fabric.util.createClass(fabric.Image.filters.BaseFilter, { - type: "Pixelate", - initialize: function(options) { - options = options || {}; - this.blocksize = options.blocksize || 4; - }, - applyTo: function(canvasEl) { - var context = canvasEl.getContext("2d"), imageData = context.getImageData(0, 0, canvasEl.width, canvasEl.height), data = imageData.data, iLen = imageData.height, jLen = imageData.width, index, i, j, r, g, b, a; - for (i = 0; i < iLen; i += this.blocksize) { - for (j = 0; j < jLen; j += this.blocksize) { - index = i * 4 * jLen + j * 4; - r = data[index]; - g = data[index + 1]; - b = data[index + 2]; - a = data[index + 3]; - for (var _i = i, _ilen = i + this.blocksize; _i < _ilen; _i++) { - for (var _j = j, _jlen = j + this.blocksize; _j < _jlen; _j++) { - index = _i * 4 * jLen + _j * 4; - data[index] = r; - data[index + 1] = g; - data[index + 2] = b; - data[index + 3] = a; - } - } - } - } - context.putImageData(imageData, 0, 0); - }, - toObject: function() { - return extend(this.callSuper("toObject"), { - blocksize: this.blocksize - }); - } - }); - fabric.Image.filters.Pixelate.fromObject = function(object) { - return new fabric.Image.filters.Pixelate(object); - }; -})(typeof exports !== "undefined" ? exports : this); - -(function(global) { - "use strict"; - var fabric = global.fabric || (global.fabric = {}), extend = fabric.util.object.extend; - fabric.Image.filters.RemoveWhite = fabric.util.createClass(fabric.Image.filters.BaseFilter, { - type: "RemoveWhite", - initialize: function(options) { - options = options || {}; - this.threshold = options.threshold || 30; - this.distance = options.distance || 20; - }, - applyTo: function(canvasEl) { - var context = canvasEl.getContext("2d"), imageData = context.getImageData(0, 0, canvasEl.width, canvasEl.height), data = imageData.data, threshold = this.threshold, distance = this.distance, limit = 255 - threshold, abs = Math.abs, r, g, b; - for (var i = 0, len = data.length; i < len; i += 4) { - r = data[i]; - g = data[i + 1]; - b = data[i + 2]; - if (r > limit && g > limit && b > limit && abs(r - g) < distance && abs(r - b) < distance && abs(g - b) < distance) { - data[i + 3] = 0; - } - } - context.putImageData(imageData, 0, 0); - }, - toObject: function() { - return extend(this.callSuper("toObject"), { - threshold: this.threshold, - distance: this.distance - }); - } - }); - fabric.Image.filters.RemoveWhite.fromObject = function(object) { - return new fabric.Image.filters.RemoveWhite(object); - }; -})(typeof exports !== "undefined" ? exports : this); - -(function(global) { - "use strict"; - var fabric = global.fabric || (global.fabric = {}); - fabric.Image.filters.Sepia = fabric.util.createClass(fabric.Image.filters.BaseFilter, { - type: "Sepia", - applyTo: function(canvasEl) { - var context = canvasEl.getContext("2d"), imageData = context.getImageData(0, 0, canvasEl.width, canvasEl.height), data = imageData.data, iLen = data.length, i, avg; - for (i = 0; i < iLen; i += 4) { - avg = .3 * data[i] + .59 * data[i + 1] + .11 * data[i + 2]; - data[i] = avg + 100; - data[i + 1] = avg + 50; - data[i + 2] = avg + 255; - } - context.putImageData(imageData, 0, 0); - } - }); - fabric.Image.filters.Sepia.fromObject = function() { - return new fabric.Image.filters.Sepia(); - }; -})(typeof exports !== "undefined" ? exports : this); - -(function(global) { - "use strict"; - var fabric = global.fabric || (global.fabric = {}); - fabric.Image.filters.Sepia2 = fabric.util.createClass(fabric.Image.filters.BaseFilter, { - type: "Sepia2", - applyTo: function(canvasEl) { - var context = canvasEl.getContext("2d"), imageData = context.getImageData(0, 0, canvasEl.width, canvasEl.height), data = imageData.data, iLen = data.length, i, r, g, b; - for (i = 0; i < iLen; i += 4) { - r = data[i]; - g = data[i + 1]; - b = data[i + 2]; - data[i] = (r * .393 + g * .769 + b * .189) / 1.351; - data[i + 1] = (r * .349 + g * .686 + b * .168) / 1.203; - data[i + 2] = (r * .272 + g * .534 + b * .131) / 2.14; - } - context.putImageData(imageData, 0, 0); - } - }); - fabric.Image.filters.Sepia2.fromObject = function() { - return new fabric.Image.filters.Sepia2(); - }; -})(typeof exports !== "undefined" ? exports : this); - -(function(global) { - "use strict"; - var fabric = global.fabric || (global.fabric = {}), extend = fabric.util.object.extend; - fabric.Image.filters.Tint = fabric.util.createClass(fabric.Image.filters.BaseFilter, { - type: "Tint", - initialize: function(options) { - options = options || {}; - this.color = options.color || "#000000"; - this.opacity = typeof options.opacity !== "undefined" ? options.opacity : new fabric.Color(this.color).getAlpha(); - }, - applyTo: function(canvasEl) { - var context = canvasEl.getContext("2d"), imageData = context.getImageData(0, 0, canvasEl.width, canvasEl.height), data = imageData.data, iLen = data.length, i, tintR, tintG, tintB, r, g, b, alpha1, source; - source = new fabric.Color(this.color).getSource(); - tintR = source[0] * this.opacity; - tintG = source[1] * this.opacity; - tintB = source[2] * this.opacity; - alpha1 = 1 - this.opacity; - for (i = 0; i < iLen; i += 4) { - r = data[i]; - g = data[i + 1]; - b = data[i + 2]; - data[i] = tintR + r * alpha1; - data[i + 1] = tintG + g * alpha1; - data[i + 2] = tintB + b * alpha1; - } - context.putImageData(imageData, 0, 0); - }, - toObject: function() { - return extend(this.callSuper("toObject"), { - color: this.color, - opacity: this.opacity - }); - } - }); - fabric.Image.filters.Tint.fromObject = function(object) { - return new fabric.Image.filters.Tint(object); - }; -})(typeof exports !== "undefined" ? exports : this); - -(function(global) { - "use strict"; - var fabric = global.fabric || (global.fabric = {}), extend = fabric.util.object.extend; - fabric.Image.filters.Multiply = fabric.util.createClass(fabric.Image.filters.BaseFilter, { - type: "Multiply", - initialize: function(options) { - options = options || {}; - this.color = options.color || "#000000"; - }, - applyTo: function(canvasEl) { - var context = canvasEl.getContext("2d"), imageData = context.getImageData(0, 0, canvasEl.width, canvasEl.height), data = imageData.data, iLen = data.length, i, source; - source = new fabric.Color(this.color).getSource(); - for (i = 0; i < iLen; i += 4) { - data[i] *= source[0] / 255; - data[i + 1] *= source[1] / 255; - data[i + 2] *= source[2] / 255; - } - context.putImageData(imageData, 0, 0); - }, - toObject: function() { - return extend(this.callSuper("toObject"), { - color: this.color - }); - } - }); - fabric.Image.filters.Multiply.fromObject = function(object) { - return new fabric.Image.filters.Multiply(object); - }; -})(typeof exports !== "undefined" ? exports : this); - -(function(global) { - "use strict"; - var fabric = global.fabric; - fabric.Image.filters.Blend = fabric.util.createClass({ - type: "Blend", - initialize: function(options) { - options = options || {}; - this.color = options.color || "#000"; - this.image = options.image || false; - this.mode = options.mode || "multiply"; - this.alpha = options.alpha || 1; - }, - applyTo: function(canvasEl) { - var context = canvasEl.getContext("2d"), imageData = context.getImageData(0, 0, canvasEl.width, canvasEl.height), data = imageData.data, tr, tg, tb, r, g, b, _r, _g, _b, source, isImage = false; - if (this.image) { - isImage = true; - var _el = fabric.util.createCanvasElement(); - _el.width = this.image.width; - _el.height = this.image.height; - var tmpCanvas = new fabric.StaticCanvas(_el); - tmpCanvas.add(this.image); - var context2 = tmpCanvas.getContext("2d"); - source = context2.getImageData(0, 0, tmpCanvas.width, tmpCanvas.height).data; - } else { - source = new fabric.Color(this.color).getSource(); - tr = source[0] * this.alpha; - tg = source[1] * this.alpha; - tb = source[2] * this.alpha; - } - for (var i = 0, len = data.length; i < len; i += 4) { - r = data[i]; - g = data[i + 1]; - b = data[i + 2]; - if (isImage) { - tr = source[i] * this.alpha; - tg = source[i + 1] * this.alpha; - tb = source[i + 2] * this.alpha; - } - switch (this.mode) { - case "multiply": - data[i] = r * tr / 255; - data[i + 1] = g * tg / 255; - data[i + 2] = b * tb / 255; - break; - - case "screen": - data[i] = 1 - (1 - r) * (1 - tr); - data[i + 1] = 1 - (1 - g) * (1 - tg); - data[i + 2] = 1 - (1 - b) * (1 - tb); - break; - - case "add": - data[i] = Math.min(255, r + tr); - data[i + 1] = Math.min(255, g + tg); - data[i + 2] = Math.min(255, b + tb); - break; - - case "diff": - case "difference": - data[i] = Math.abs(r - tr); - data[i + 1] = Math.abs(g - tg); - data[i + 2] = Math.abs(b - tb); - break; - - case "subtract": - _r = r - tr; - _g = g - tg; - _b = b - tb; - data[i] = _r < 0 ? 0 : _r; - data[i + 1] = _g < 0 ? 0 : _g; - data[i + 2] = _b < 0 ? 0 : _b; - break; - - case "darken": - data[i] = Math.min(r, tr); - data[i + 1] = Math.min(g, tg); - data[i + 2] = Math.min(b, tb); - break; - - case "lighten": - data[i] = Math.max(r, tr); - data[i + 1] = Math.max(g, tg); - data[i + 2] = Math.max(b, tb); - break; - } - } - context.putImageData(imageData, 0, 0); - }, - toObject: function() { - return { - color: this.color, - image: this.image, - mode: this.mode, - alpha: this.alpha - }; - } - }); - fabric.Image.filters.Blend.fromObject = function(object) { - return new fabric.Image.filters.Blend(object); - }; -})(typeof exports !== "undefined" ? exports : this); - -(function(global) { - "use strict"; - var fabric = global.fabric || (global.fabric = {}), pow = Math.pow, floor = Math.floor, sqrt = Math.sqrt, abs = Math.abs, max = Math.max, round = Math.round, sin = Math.sin, ceil = Math.ceil; - fabric.Image.filters.Resize = fabric.util.createClass(fabric.Image.filters.BaseFilter, { - type: "Resize", - resizeType: "hermite", - scaleX: 0, - scaleY: 0, - lanczosLobes: 3, - applyTo: function(canvasEl, scaleX, scaleY) { - this.rcpScaleX = 1 / scaleX; - this.rcpScaleY = 1 / scaleY; - var oW = canvasEl.width, oH = canvasEl.height, dW = round(oW * scaleX), dH = round(oH * scaleY), imageData; - if (this.resizeType === "sliceHack") { - imageData = this.sliceByTwo(canvasEl, oW, oH, dW, dH); - } - if (this.resizeType === "hermite") { - imageData = this.hermiteFastResize(canvasEl, oW, oH, dW, dH); - } - if (this.resizeType === "bilinear") { - imageData = this.bilinearFiltering(canvasEl, oW, oH, dW, dH); - } - if (this.resizeType === "lanczos") { - imageData = this.lanczosResize(canvasEl, oW, oH, dW, dH); - } - canvasEl.width = dW; - canvasEl.height = dH; - canvasEl.getContext("2d").putImageData(imageData, 0, 0); - }, - sliceByTwo: function(canvasEl, width, height, newWidth, newHeight) { - var context = canvasEl.getContext("2d"), imageData, multW = .5, multH = .5, signW = 1, signH = 1, doneW = false, doneH = false, stepW = width, stepH = height, tmpCanvas = fabric.util.createCanvasElement(), tmpCtx = tmpCanvas.getContext("2d"); - newWidth = floor(newWidth); - newHeight = floor(newHeight); - tmpCanvas.width = max(newWidth, width); - tmpCanvas.height = max(newHeight, height); - if (newWidth > width) { - multW = 2; - signW = -1; - } - if (newHeight > height) { - multH = 2; - signH = -1; - } - imageData = context.getImageData(0, 0, width, height); - canvasEl.width = max(newWidth, width); - canvasEl.height = max(newHeight, height); - context.putImageData(imageData, 0, 0); - while (!doneW || !doneH) { - width = stepW; - height = stepH; - if (newWidth * signW < floor(stepW * multW * signW)) { - stepW = floor(stepW * multW); - } else { - stepW = newWidth; - doneW = true; - } - if (newHeight * signH < floor(stepH * multH * signH)) { - stepH = floor(stepH * multH); - } else { - stepH = newHeight; - doneH = true; - } - imageData = context.getImageData(0, 0, width, height); - tmpCtx.putImageData(imageData, 0, 0); - context.clearRect(0, 0, stepW, stepH); - context.drawImage(tmpCanvas, 0, 0, width, height, 0, 0, stepW, stepH); - } - return context.getImageData(0, 0, newWidth, newHeight); - }, - lanczosResize: function(canvasEl, oW, oH, dW, dH) { - function lanczosCreate(lobes) { - return function(x) { - if (x > lobes) { - return 0; - } - x *= Math.PI; - if (abs(x) < 1e-16) { - return 1; - } - var xx = x / lobes; - return sin(x) * sin(xx) / x / xx; - }; - } - function process(u) { - var v, i, weight, idx, a, red, green, blue, alpha, fX, fY; - center.x = (u + .5) * ratioX; - icenter.x = floor(center.x); - for (v = 0; v < dH; v++) { - center.y = (v + .5) * ratioY; - icenter.y = floor(center.y); - a = 0, red = 0, green = 0, blue = 0, alpha = 0; - for (i = icenter.x - range2X; i <= icenter.x + range2X; i++) { - if (i < 0 || i >= oW) { - continue; - } - fX = floor(1e3 * abs(i - center.x)); - if (!cacheLanc[fX]) { - cacheLanc[fX] = {}; - } - for (var j = icenter.y - range2Y; j <= icenter.y + range2Y; j++) { - if (j < 0 || j >= oH) { - continue; - } - fY = floor(1e3 * abs(j - center.y)); - if (!cacheLanc[fX][fY]) { - cacheLanc[fX][fY] = lanczos(sqrt(pow(fX * rcpRatioX, 2) + pow(fY * rcpRatioY, 2)) / 1e3); - } - weight = cacheLanc[fX][fY]; - if (weight > 0) { - idx = (j * oW + i) * 4; - a += weight; - red += weight * srcData[idx]; - green += weight * srcData[idx + 1]; - blue += weight * srcData[idx + 2]; - alpha += weight * srcData[idx + 3]; - } - } - } - idx = (v * dW + u) * 4; - destData[idx] = red / a; - destData[idx + 1] = green / a; - destData[idx + 2] = blue / a; - destData[idx + 3] = alpha / a; - } - if (++u < dW) { - return process(u); - } else { - return destImg; - } - } - var context = canvasEl.getContext("2d"), srcImg = context.getImageData(0, 0, oW, oH), destImg = context.getImageData(0, 0, dW, dH), srcData = srcImg.data, destData = destImg.data, lanczos = lanczosCreate(this.lanczosLobes), ratioX = this.rcpScaleX, ratioY = this.rcpScaleY, rcpRatioX = 2 / this.rcpScaleX, rcpRatioY = 2 / this.rcpScaleY, range2X = ceil(ratioX * this.lanczosLobes / 2), range2Y = ceil(ratioY * this.lanczosLobes / 2), cacheLanc = {}, center = {}, icenter = {}; - return process(0); - }, - bilinearFiltering: function(canvasEl, w, h, w2, h2) { - var a, b, c, d, x, y, i, j, xDiff, yDiff, chnl, color, offset = 0, origPix, ratioX = this.rcpScaleX, ratioY = this.rcpScaleY, context = canvasEl.getContext("2d"), w4 = 4 * (w - 1), img = context.getImageData(0, 0, w, h), pixels = img.data, destImage = context.getImageData(0, 0, w2, h2), destPixels = destImage.data; - for (i = 0; i < h2; i++) { - for (j = 0; j < w2; j++) { - x = floor(ratioX * j); - y = floor(ratioY * i); - xDiff = ratioX * j - x; - yDiff = ratioY * i - y; - origPix = 4 * (y * w + x); - for (chnl = 0; chnl < 4; chnl++) { - a = pixels[origPix + chnl]; - b = pixels[origPix + 4 + chnl]; - c = pixels[origPix + w4 + chnl]; - d = pixels[origPix + w4 + 4 + chnl]; - color = a * (1 - xDiff) * (1 - yDiff) + b * xDiff * (1 - yDiff) + c * yDiff * (1 - xDiff) + d * xDiff * yDiff; - destPixels[offset++] = color; - } - } - } - return destImage; - }, - hermiteFastResize: function(canvasEl, oW, oH, dW, dH) { - var ratioW = this.rcpScaleX, ratioH = this.rcpScaleY, ratioWHalf = ceil(ratioW / 2), ratioHHalf = ceil(ratioH / 2), context = canvasEl.getContext("2d"), img = context.getImageData(0, 0, oW, oH), data = img.data, img2 = context.getImageData(0, 0, dW, dH), data2 = img2.data; - for (var j = 0; j < dH; j++) { - for (var i = 0; i < dW; i++) { - var x2 = (i + j * dW) * 4, weight = 0, weights = 0, weightsAlpha = 0, gxR = 0, gxG = 0, gxB = 0, gxA = 0, centerY = (j + .5) * ratioH; - for (var yy = floor(j * ratioH); yy < (j + 1) * ratioH; yy++) { - var dy = abs(centerY - (yy + .5)) / ratioHHalf, centerX = (i + .5) * ratioW, w0 = dy * dy; - for (var xx = floor(i * ratioW); xx < (i + 1) * ratioW; xx++) { - var dx = abs(centerX - (xx + .5)) / ratioWHalf, w = sqrt(w0 + dx * dx); - if (w > 1 && w < -1) { - continue; - } - weight = 2 * w * w * w - 3 * w * w + 1; - if (weight > 0) { - dx = 4 * (xx + yy * oW); - gxA += weight * data[dx + 3]; - weightsAlpha += weight; - if (data[dx + 3] < 255) { - weight = weight * data[dx + 3] / 250; - } - gxR += weight * data[dx]; - gxG += weight * data[dx + 1]; - gxB += weight * data[dx + 2]; - weights += weight; - } - } - } - data2[x2] = gxR / weights; - data2[x2 + 1] = gxG / weights; - data2[x2 + 2] = gxB / weights; - data2[x2 + 3] = gxA / weightsAlpha; - } - } - return img2; - }, - toObject: function() { - return { - type: this.type, - scaleX: this.scaleX, - scaleY: this.scaleY, - resizeType: this.resizeType, - lanczosLobes: this.lanczosLobes - }; - } - }); - fabric.Image.filters.Resize.fromObject = function(object) { - return new fabric.Image.filters.Resize(object); - }; -})(typeof exports !== "undefined" ? exports : this); - -(function(global) { - "use strict"; - var fabric = global.fabric || (global.fabric = {}), extend = fabric.util.object.extend, clone = fabric.util.object.clone, toFixed = fabric.util.toFixed, supportsLineDash = fabric.StaticCanvas.supports("setLineDash"), NUM_FRACTION_DIGITS = fabric.Object.NUM_FRACTION_DIGITS; - if (fabric.Text) { - fabric.warn("fabric.Text is already defined"); - return; - } - var stateProperties = fabric.Object.prototype.stateProperties.concat(); - stateProperties.push("fontFamily", "fontWeight", "fontSize", "text", "textDecoration", "textAlign", "fontStyle", "lineHeight", "textBackgroundColor"); - fabric.Text = fabric.util.createClass(fabric.Object, { - _dimensionAffectingProps: { - fontSize: true, - fontWeight: true, - fontFamily: true, - fontStyle: true, - lineHeight: true, - stroke: true, - strokeWidth: true, - text: true, - textAlign: true - }, - _reNewline: /\r?\n/, - _reSpacesAndTabs: /[ \t\r]+/g, - type: "text", - fontSize: 40, - fontWeight: "normal", - fontFamily: "Times New Roman", - textDecoration: "", - textAlign: "left", - fontStyle: "", - lineHeight: 1.16, - textBackgroundColor: "", - stateProperties: stateProperties, - stroke: null, - shadow: null, - _fontSizeFraction: .25, - _fontSizeMult: 1.13, - initialize: function(text, options) { - options = options || {}; - this.text = text; - this.__skipDimension = true; - this.setOptions(options); - this.__skipDimension = false; - this._initDimensions(); - }, - _initDimensions: function(ctx) { - if (this.__skipDimension) { - return; - } - if (!ctx) { - ctx = fabric.util.createCanvasElement().getContext("2d"); - this._setTextStyles(ctx); - } - this._textLines = this._splitTextIntoLines(); - this._clearCache(); - this._cacheLinesWidth = this.textAlign !== "justify"; - this.width = this._getTextWidth(ctx); - this._cacheLinesWidth = true; - this.height = this._getTextHeight(ctx); - }, - toString: function() { - return "#'; - }, - _render: function(ctx) { - this.clipTo && fabric.util.clipContext(this, ctx); - this._setOpacity(ctx); - this._setShadow(ctx); - this._setupCompositeOperation(ctx); - this._renderTextBackground(ctx); - this._setStrokeStyles(ctx); - this._setFillStyles(ctx); - this._renderText(ctx); - this._renderTextDecoration(ctx); - this.clipTo && ctx.restore(); - }, - _renderText: function(ctx) { - this._translateForTextAlign(ctx); - this._renderTextFill(ctx); - this._renderTextStroke(ctx); - this._translateForTextAlign(ctx, true); - }, - _translateForTextAlign: function(ctx, back) { - if (this.textAlign !== "left" && this.textAlign !== "justify") { - var sign = back ? -1 : 1; - ctx.translate(this.textAlign === "center" ? sign * this.width / 2 : sign * this.width, 0); - } - }, - _setTextStyles: function(ctx) { - ctx.textBaseline = "alphabetic"; - if (!this.skipTextAlign) { - ctx.textAlign = this.textAlign; - } - ctx.font = this._getFontDeclaration(); - }, - _getTextHeight: function() { - return this._textLines.length * this._getHeightOfLine(); - }, - _getTextWidth: function(ctx) { - var maxWidth = this._getLineWidth(ctx, 0); - for (var i = 1, len = this._textLines.length; i < len; i++) { - var currentLineWidth = this._getLineWidth(ctx, i); - if (currentLineWidth > maxWidth) { - maxWidth = currentLineWidth; - } - } - return maxWidth; - }, - _renderChars: function(method, ctx, chars, left, top) { - var shortM = method.slice(0, -4); - if (this[shortM].toLive) { - var offsetX = -this.width / 2 + this[shortM].offsetX || 0, offsetY = -this.height / 2 + this[shortM].offsetY || 0; - ctx.save(); - ctx.translate(offsetX, offsetY); - left -= offsetX; - top -= offsetY; - } - ctx[method](chars, left, top); - this[shortM].toLive && ctx.restore(); - }, - _renderTextLine: function(method, ctx, line, left, top, lineIndex) { - top -= this.fontSize * this._fontSizeFraction; - var lineWidth = this._getLineWidth(ctx, lineIndex); - if (this.textAlign !== "justify" || this.width < lineWidth) { - this._renderChars(method, ctx, line, left, top, lineIndex); - return; - } - var words = line.split(/\s+/), charOffset = 0, wordsWidth = this._getWidthOfWords(ctx, line, lineIndex, 0), widthDiff = this.width - wordsWidth, numSpaces = words.length - 1, spaceWidth = numSpaces > 0 ? widthDiff / numSpaces : 0, leftOffset = 0, word; - for (var i = 0, len = words.length; i < len; i++) { - while (line[charOffset] === " " && charOffset < line.length) { - charOffset++; - } - word = words[i]; - this._renderChars(method, ctx, word, left + leftOffset, top, lineIndex, charOffset); - leftOffset += this._getWidthOfWords(ctx, word, lineIndex, charOffset) + spaceWidth; - charOffset += word.length; - } - }, - _getWidthOfWords: function(ctx, line) { - return ctx.measureText(line.replace(/\s+/g, "")).width; - }, - _getLeftOffset: function() { - return -this.width / 2; - }, - _getTopOffset: function() { - return -this.height / 2; - }, - isEmptyStyles: function() { - return true; - }, - _renderTextFill: function(ctx) { - if (!this.fill && this.isEmptyStyles()) { - return; - } - var lineHeights = 0; - for (var i = 0, len = this._textLines.length; i < len; i++) { - var heightOfLine = this._getHeightOfLine(ctx, i), maxHeight = heightOfLine / this.lineHeight; - this._renderTextLine("fillText", ctx, this._textLines[i], this._getLeftOffset(), this._getTopOffset() + lineHeights + maxHeight, i); - lineHeights += heightOfLine; - } - }, - _renderTextStroke: function(ctx) { - if ((!this.stroke || this.strokeWidth === 0) && this.isEmptyStyles()) { - return; - } - var lineHeights = 0; - if (this.shadow && !this.shadow.affectStroke) { - this._removeShadow(ctx); - } - ctx.save(); - if (this.strokeDashArray) { - if (1 & this.strokeDashArray.length) { - this.strokeDashArray.push.apply(this.strokeDashArray, this.strokeDashArray); - } - supportsLineDash && ctx.setLineDash(this.strokeDashArray); - } - ctx.beginPath(); - for (var i = 0, len = this._textLines.length; i < len; i++) { - var heightOfLine = this._getHeightOfLine(ctx, i), maxHeight = heightOfLine / this.lineHeight; - this._renderTextLine("strokeText", ctx, this._textLines[i], this._getLeftOffset(), this._getTopOffset() + lineHeights + maxHeight, i); - lineHeights += heightOfLine; - } - ctx.closePath(); - ctx.restore(); - }, - _getHeightOfLine: function() { - return this.fontSize * this._fontSizeMult * this.lineHeight; - }, - _renderTextBackground: function(ctx) { - this._renderTextBoxBackground(ctx); - this._renderTextLinesBackground(ctx); - }, - _renderTextBoxBackground: function(ctx) { - if (!this.backgroundColor) { - return; - } - ctx.fillStyle = this.backgroundColor; - ctx.fillRect(this._getLeftOffset(), this._getTopOffset(), this.width, this.height); - this._removeShadow(ctx); - }, - _renderTextLinesBackground: function(ctx) { - if (!this.textBackgroundColor) { - return; - } - var lineTopOffset = 0, heightOfLine, lineWidth, lineLeftOffset; - ctx.fillStyle = this.textBackgroundColor; - for (var i = 0, len = this._textLines.length; i < len; i++) { - heightOfLine = this._getHeightOfLine(ctx, i); - if (this._textLines[i] !== "") { - lineWidth = this.textAlign === "justify" ? this.width : this._getLineWidth(ctx, i); - lineLeftOffset = this._getLineLeftOffset(lineWidth); - ctx.fillRect(this._getLeftOffset() + lineLeftOffset, this._getTopOffset() + lineTopOffset, lineWidth, heightOfLine / this.lineHeight); - } - lineTopOffset += heightOfLine; - } - this._removeShadow(ctx); - }, - _getLineLeftOffset: function(lineWidth) { - if (this.textAlign === "center") { - return (this.width - lineWidth) / 2; - } - if (this.textAlign === "right") { - return this.width - lineWidth; - } - return 0; - }, - _clearCache: function() { - this.__lineWidths = []; - this.__lineHeights = []; - }, - _shouldClearCache: function() { - var shouldClear = false; - if (this._forceClearCache) { - this._forceClearCache = false; - return true; - } - for (var prop in this._dimensionAffectingProps) { - if (this["__" + prop] !== this[prop]) { - this["__" + prop] = this[prop]; - shouldClear = true; - } - } - return shouldClear; - }, - _getLineWidth: function(ctx, lineIndex) { - if (this.__lineWidths[lineIndex]) { - return this.__lineWidths[lineIndex]; - } - var width, wordCount, line = this._textLines[lineIndex]; - if (line === "") { - width = 0; - } else if (this.textAlign === "justify" && this._cacheLinesWidth) { - wordCount = line.split(/\s+/); - if (wordCount.length > 1) { - width = this.width; - } else { - width = ctx.measureText(line).width; - } - } else { - width = ctx.measureText(line).width; - } - this._cacheLinesWidth && (this.__lineWidths[lineIndex] = width); - return width; - }, - _renderTextDecoration: function(ctx) { - if (!this.textDecoration) { - return; - } - var halfOfVerticalBox = this.height / 2, _this = this, offsets = []; - function renderLinesAtOffset(offsets) { - var i, lineHeight = 0, len, j, oLen, lineWidth, lineLeftOffset, heightOfLine; - for (i = 0, len = _this._textLines.length; i < len; i++) { - lineWidth = _this._getLineWidth(ctx, i), lineLeftOffset = _this._getLineLeftOffset(lineWidth), - heightOfLine = _this._getHeightOfLine(ctx, i); - for (j = 0, oLen = offsets.length; j < oLen; j++) { - ctx.fillRect(_this._getLeftOffset() + lineLeftOffset, lineHeight + (_this._fontSizeMult - 1 + offsets[j]) * _this.fontSize - halfOfVerticalBox, lineWidth, _this.fontSize / 15); - } - lineHeight += heightOfLine; - } - } - if (this.textDecoration.indexOf("underline") > -1) { - offsets.push(.85); - } - if (this.textDecoration.indexOf("line-through") > -1) { - offsets.push(.43); - } - if (this.textDecoration.indexOf("overline") > -1) { - offsets.push(-.12); - } - if (offsets.length > 0) { - renderLinesAtOffset(offsets); - } - }, - _getFontDeclaration: function() { - return [ fabric.isLikelyNode ? this.fontWeight : this.fontStyle, fabric.isLikelyNode ? this.fontStyle : this.fontWeight, this.fontSize + "px", fabric.isLikelyNode ? '"' + this.fontFamily + '"' : this.fontFamily ].join(" "); - }, - render: function(ctx, noTransform) { - if (!this.visible) { - return; - } - ctx.save(); - this._setTextStyles(ctx); - if (this._shouldClearCache()) { - this._initDimensions(ctx); - } - if (!noTransform) { - this.transform(ctx); - } - if (this.transformMatrix) { - ctx.transform.apply(ctx, this.transformMatrix); - } - if (this.group && this.group.type === "path-group") { - ctx.translate(this.left, this.top); - } - this._render(ctx); - ctx.restore(); - }, - _splitTextIntoLines: function() { - return this.text.split(this._reNewline); - }, - toObject: function(propertiesToInclude) { - var object = extend(this.callSuper("toObject", propertiesToInclude), { - text: this.text, - fontSize: this.fontSize, - fontWeight: this.fontWeight, - fontFamily: this.fontFamily, - fontStyle: this.fontStyle, - lineHeight: this.lineHeight, - textDecoration: this.textDecoration, - textAlign: this.textAlign, - textBackgroundColor: this.textBackgroundColor - }); - if (!this.includeDefaultValues) { - this._removeDefaultValues(object); - } - return object; - }, - toSVG: function(reviver) { - var markup = this._createBaseSVGMarkup(), offsets = this._getSVGLeftTopOffsets(this.ctx), textAndBg = this._getSVGTextAndBg(offsets.textTop, offsets.textLeft); - this._wrapSVGTextAndBg(markup, textAndBg); - return reviver ? reviver(markup.join("")) : markup.join(""); - }, - _getSVGLeftTopOffsets: function(ctx) { - var lineTop = this._getHeightOfLine(ctx, 0), textLeft = -this.width / 2, textTop = 0; - return { - textLeft: textLeft + (this.group && this.group.type === "path-group" ? this.left : 0), - textTop: textTop + (this.group && this.group.type === "path-group" ? -this.top : 0), - lineTop: lineTop - }; - }, - _wrapSVGTextAndBg: function(markup, textAndBg) { - var noShadow = true, filter = this.getSvgFilter(), style = filter === "" ? "" : ' style="' + filter + '"'; - markup.push(' \n", textAndBg.textBgRects.join(""), " \n', textAndBg.textSpans.join(""), " \n", " \n"); - }, - _getSVGTextAndBg: function(textTopOffset, textLeftOffset) { - var textSpans = [], textBgRects = [], height = 0; - this._setSVGBg(textBgRects); - for (var i = 0, len = this._textLines.length; i < len; i++) { - if (this.textBackgroundColor) { - this._setSVGTextLineBg(textBgRects, i, textLeftOffset, textTopOffset, height); - } - this._setSVGTextLineText(i, textSpans, height, textLeftOffset, textTopOffset, textBgRects); - height += this._getHeightOfLine(this.ctx, i); - } - return { - textSpans: textSpans, - textBgRects: textBgRects - }; - }, - _setSVGTextLineText: function(i, textSpans, height, textLeftOffset, textTopOffset) { - var yPos = this.fontSize * (this._fontSizeMult - this._fontSizeFraction) - textTopOffset + height - this.height / 2; - if (this.textAlign === "justify") { - this._setSVGTextLineJustifed(i, textSpans, yPos, textLeftOffset); - return; - } - textSpans.push(' ", fabric.util.string.escapeXml(this._textLines[i]), "\n"); - }, - _setSVGTextLineJustifed: function(i, textSpans, yPos, textLeftOffset) { - var ctx = fabric.util.createCanvasElement().getContext("2d"); - this._setTextStyles(ctx); - var line = this._textLines[i], words = line.split(/\s+/), wordsWidth = this._getWidthOfWords(ctx, line), widthDiff = this.width - wordsWidth, numSpaces = words.length - 1, spaceWidth = numSpaces > 0 ? widthDiff / numSpaces : 0, word, attributes = this._getFillAttributes(this.fill), len; - textLeftOffset += this._getLineLeftOffset(this._getLineWidth(ctx, i)); - for (i = 0, len = words.length; i < len; i++) { - word = words[i]; - textSpans.push(' ", fabric.util.string.escapeXml(word), "\n"); - textLeftOffset += this._getWidthOfWords(ctx, word) + spaceWidth; - } - }, - _setSVGTextLineBg: function(textBgRects, i, textLeftOffset, textTopOffset, height) { - textBgRects.push(" \n'); - }, - _setSVGBg: function(textBgRects) { - if (this.backgroundColor) { - textBgRects.push(" \n'); - } - }, - _getFillAttributes: function(value) { - var fillColor = value && typeof value === "string" ? new fabric.Color(value) : ""; - if (!fillColor || !fillColor.getSource() || fillColor.getAlpha() === 1) { - return 'fill="' + value + '"'; - } - return 'opacity="' + fillColor.getAlpha() + '" fill="' + fillColor.setAlpha(1).toRgb() + '"'; - }, - _set: function(key, value) { - this.callSuper("_set", key, value); - if (key in this._dimensionAffectingProps) { - this._initDimensions(); - this.setCoords(); - } - }, - complexity: function() { - return 1; - } - }); - 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) { - if (!element) { - return null; - } - var parsedAttributes = fabric.parseAttributes(element, fabric.Text.ATTRIBUTE_NAMES); - options = fabric.util.object.extend(options ? fabric.util.object.clone(options) : {}, parsedAttributes); - options.top = options.top || 0; - options.left = options.left || 0; - if ("dx" in parsedAttributes) { - options.left += parsedAttributes.dx; - } - if ("dy" in parsedAttributes) { - options.top += parsedAttributes.dy; - } - if (!("fontSize" in options)) { - options.fontSize = fabric.Text.DEFAULT_SVG_FONT_SIZE; - } - if (!options.originX) { - options.originX = "left"; - } - var textContent = ""; - if (!("textContent" in element)) { - if ("firstChild" in element && element.firstChild !== null) { - if ("data" in element.firstChild && element.firstChild.data !== null) { - textContent = element.firstChild.data; - } - } - } else { - textContent = element.textContent; - } - textContent = textContent.replace(/^\s+|\s+$|\n+/g, "").replace(/\s+/g, " "); - var text = new fabric.Text(textContent, options), offX = 0; - if (text.originX === "left") { - offX = text.getWidth() / 2; - } - if (text.originX === "right") { - offX = -text.getWidth() / 2; - } - text.set({ - left: text.getLeft() + offX, - top: text.getTop() - text.getHeight() / 2 + text.fontSize * (.18 + text._fontSizeFraction) - }); - return text; - }; - fabric.Text.fromObject = function(object) { - return new fabric.Text(object.text, clone(object)); - }; - fabric.util.createAccessors(fabric.Text); -})(typeof exports !== "undefined" ? exports : this); - -(function() { - var clone = fabric.util.object.clone; - fabric.IText = fabric.util.createClass(fabric.Text, fabric.Observable, { - type: "i-text", - selectionStart: 0, - selectionEnd: 0, - selectionColor: "rgba(17,119,255,0.3)", - isEditing: false, - editable: true, - editingBorderColor: "rgba(102,153,255,0.25)", - cursorWidth: 2, - cursorColor: "#333", - cursorDelay: 1e3, - cursorDuration: 600, - styles: null, - caching: true, - _reSpace: /\s|\n/, - _currentCursorOpacity: 0, - _selectionDirection: null, - _abortCursorAnimation: false, - _charWidthsCache: {}, - __widthOfSpace: [], - initialize: function(text, options) { - this.styles = options ? options.styles || {} : {}; - this.callSuper("initialize", text, options); - this.initBehavior(); - }, - _clearCache: function() { - this.callSuper("_clearCache"); - this.__widthOfSpace = []; - }, - isEmptyStyles: function() { - if (!this.styles) { - return true; - } - var obj = this.styles; - for (var p1 in obj) { - for (var p2 in obj[p1]) { - for (var p3 in obj[p1][p2]) { - return false; - } - } - } - return true; - }, - setSelectionStart: function(index) { - index = Math.max(index, 0); - if (this.selectionStart !== index) { - this.fire("selection:changed"); - this.canvas && this.canvas.fire("text:selection:changed", { - target: this - }); - this.selectionStart = index; - } - this._updateTextarea(); - }, - setSelectionEnd: function(index) { - index = Math.min(index, this.text.length); - if (this.selectionEnd !== index) { - this.fire("selection:changed"); - this.canvas && this.canvas.fire("text:selection:changed", { - target: this - }); - this.selectionEnd = index; - } - this._updateTextarea(); - }, - getSelectionStyles: function(startIndex, endIndex) { - if (arguments.length === 2) { - var styles = []; - for (var i = startIndex; i < endIndex; i++) { - styles.push(this.getSelectionStyles(i)); - } - return styles; - } - var loc = this.get2DCursorLocation(startIndex), style = this._getStyleDeclaration(loc.lineIndex, loc.charIndex); - return style || {}; - }, - setSelectionStyles: function(styles) { - if (this.selectionStart === this.selectionEnd) { - this._extendStyles(this.selectionStart, styles); - } else { - for (var i = this.selectionStart; i < this.selectionEnd; i++) { - this._extendStyles(i, styles); - } - } - this._forceClearCache = true; - return this; - }, - _extendStyles: function(index, styles) { - var loc = this.get2DCursorLocation(index); - if (!this._getLineStyle(loc.lineIndex)) { - this._setLineStyle(loc.lineIndex, {}); - } - if (!this._getStyleDeclaration(loc.lineIndex, loc.charIndex)) { - this._setStyleDeclaration(loc.lineIndex, loc.charIndex, {}); - } - fabric.util.object.extend(this._getStyleDeclaration(loc.lineIndex, loc.charIndex), styles); - }, - _render: function(ctx) { - this.callSuper("_render", ctx); - this.ctx = ctx; - this.isEditing && this.renderCursorOrSelection(); - }, - renderCursorOrSelection: function() { - if (!this.active) { - return; - } - var chars = this.text.split(""), boundaries, ctx; - if (this.canvas.contextTop) { - ctx = this.canvas.contextTop; - ctx.save(); - ctx.transform.apply(ctx, this.canvas.viewportTransform); - this.transform(ctx); - this.transformMatrix && ctx.transform.apply(ctx, this.transformMatrix); - } else { - ctx = this.ctx; - ctx.save(); - } - if (this.selectionStart === this.selectionEnd) { - boundaries = this._getCursorBoundaries(chars, "cursor"); - this.renderCursor(boundaries, ctx); - } else { - boundaries = this._getCursorBoundaries(chars, "selection"); - this.renderSelection(chars, boundaries, ctx); - } - ctx.restore(); - }, - get2DCursorLocation: function(selectionStart) { - if (typeof selectionStart === "undefined") { - selectionStart = this.selectionStart; - } - var len = this._textLines.length; - for (var i = 0; i < len; i++) { - if (selectionStart <= this._textLines[i].length) { - return { - lineIndex: i, - charIndex: selectionStart - }; - } - selectionStart -= this._textLines[i].length + 1; - } - return { - lineIndex: i - 1, - charIndex: this._textLines[i - 1].length < selectionStart ? this._textLines[i - 1].length : selectionStart - }; - }, - getCurrentCharStyle: function(lineIndex, charIndex) { - var style = this._getStyleDeclaration(lineIndex, charIndex === 0 ? 0 : charIndex - 1); - return { - fontSize: style && style.fontSize || this.fontSize, - fill: style && style.fill || this.fill, - textBackgroundColor: style && style.textBackgroundColor || this.textBackgroundColor, - textDecoration: style && style.textDecoration || this.textDecoration, - fontFamily: style && style.fontFamily || this.fontFamily, - fontWeight: style && style.fontWeight || this.fontWeight, - fontStyle: style && style.fontStyle || this.fontStyle, - stroke: style && style.stroke || this.stroke, - strokeWidth: style && style.strokeWidth || this.strokeWidth - }; - }, - getCurrentCharFontSize: function(lineIndex, charIndex) { - var style = this._getStyleDeclaration(lineIndex, charIndex === 0 ? 0 : charIndex - 1); - return style && style.fontSize ? style.fontSize : this.fontSize; - }, - getCurrentCharColor: function(lineIndex, charIndex) { - var style = this._getStyleDeclaration(lineIndex, charIndex === 0 ? 0 : charIndex - 1); - return style && style.fill ? style.fill : this.cursorColor; - }, - _getCursorBoundaries: function(chars, typeOfBoundaries) { - var left = Math.round(this._getLeftOffset()), top = this._getTopOffset(), offsets = this._getCursorBoundariesOffsets(chars, typeOfBoundaries); - return { - left: left, - top: top, - leftOffset: offsets.left + offsets.lineLeft, - topOffset: offsets.top - }; - }, - _getCursorBoundariesOffsets: function(chars, typeOfBoundaries) { - var lineLeftOffset = 0, lineIndex = 0, charIndex = 0, topOffset = 0, leftOffset = 0; - for (var i = 0; i < this.selectionStart; i++) { - if (chars[i] === "\n") { - leftOffset = 0; - topOffset += this._getHeightOfLine(this.ctx, lineIndex); - lineIndex++; - charIndex = 0; - } else { - leftOffset += this._getWidthOfChar(this.ctx, chars[i], lineIndex, charIndex); - charIndex++; - } - lineLeftOffset = this._getLineLeftOffset(this._getLineWidth(this.ctx, lineIndex)); - } - if (typeOfBoundaries === "cursor") { - topOffset += (1 - this._fontSizeFraction) * this._getHeightOfLine(this.ctx, lineIndex) / this.lineHeight - this.getCurrentCharFontSize(lineIndex, charIndex) * (1 - this._fontSizeFraction); - } - return { - top: topOffset, - left: leftOffset, - lineLeft: lineLeftOffset - }; - }, - renderCursor: function(boundaries, ctx) { - var cursorLocation = this.get2DCursorLocation(), lineIndex = cursorLocation.lineIndex, charIndex = cursorLocation.charIndex, charHeight = this.getCurrentCharFontSize(lineIndex, charIndex), leftOffset = lineIndex === 0 && charIndex === 0 ? this._getLineLeftOffset(this._getLineWidth(ctx, lineIndex)) : boundaries.leftOffset; - ctx.fillStyle = this.getCurrentCharColor(lineIndex, charIndex); - ctx.globalAlpha = this.__isMousedown ? 1 : this._currentCursorOpacity; - ctx.fillRect(boundaries.left + leftOffset, boundaries.top + boundaries.topOffset, this.cursorWidth / this.scaleX, charHeight); - }, - renderSelection: function(chars, boundaries, ctx) { - ctx.fillStyle = this.selectionColor; - var start = this.get2DCursorLocation(this.selectionStart), end = this.get2DCursorLocation(this.selectionEnd), startLine = start.lineIndex, endLine = end.lineIndex; - for (var i = startLine; i <= endLine; i++) { - var lineOffset = this._getLineLeftOffset(this._getLineWidth(ctx, i)) || 0, lineHeight = this._getHeightOfLine(this.ctx, i), boxWidth = 0, line = this._textLines[i]; - if (i === startLine) { - for (var j = 0, len = line.length; j < len; j++) { - if (j >= start.charIndex && (i !== endLine || j < end.charIndex)) { - boxWidth += this._getWidthOfChar(ctx, line[j], i, j); - } - if (j < start.charIndex) { - lineOffset += this._getWidthOfChar(ctx, line[j], i, j); - } - } - } else if (i > startLine && i < endLine) { - boxWidth += this._getLineWidth(ctx, i) || 5; - } else if (i === endLine) { - for (var j2 = 0, j2len = end.charIndex; j2 < j2len; j2++) { - boxWidth += this._getWidthOfChar(ctx, line[j2], i, j2); - } - } - ctx.fillRect(boundaries.left + lineOffset, boundaries.top + boundaries.topOffset, boxWidth, lineHeight); - boundaries.topOffset += lineHeight; - } - }, - _renderChars: function(method, ctx, line, left, top, lineIndex, charOffset) { - if (this.isEmptyStyles()) { - return this._renderCharsFast(method, ctx, line, left, top); - } - charOffset = charOffset || 0; - this.skipTextAlign = true; - left -= this.textAlign === "center" ? this.width / 2 : this.textAlign === "right" ? this.width : 0; - var lineHeight = this._getHeightOfLine(ctx, lineIndex), lineLeftOffset = this._getLineLeftOffset(this._getLineWidth(ctx, lineIndex)), prevStyle, thisStyle, charsToRender = ""; - left += lineLeftOffset || 0; - ctx.save(); - top -= lineHeight / this.lineHeight * this._fontSizeFraction; - for (var i = charOffset, len = line.length + charOffset; i <= len; i++) { - prevStyle = prevStyle || this.getCurrentCharStyle(lineIndex, i); - thisStyle = this.getCurrentCharStyle(lineIndex, i + 1); - if (this._hasStyleChanged(prevStyle, thisStyle) || i === len) { - this._renderChar(method, ctx, lineIndex, i - 1, charsToRender, left, top, lineHeight); - charsToRender = ""; - prevStyle = thisStyle; - } - charsToRender += line[i - charOffset]; - } - ctx.restore(); - }, - _renderCharsFast: function(method, ctx, line, left, top) { - this.skipTextAlign = false; - if (method === "fillText" && this.fill) { - this.callSuper("_renderChars", method, ctx, line, left, top); - } - if (method === "strokeText" && (this.stroke && this.strokeWidth > 0 || this.skipFillStrokeCheck)) { - this.callSuper("_renderChars", method, ctx, line, left, top); - } - }, - _renderChar: function(method, ctx, lineIndex, i, _char, left, top, lineHeight) { - var charWidth, charHeight, shouldFill, shouldStroke, decl = this._getStyleDeclaration(lineIndex, i), offset, textDecoration; - if (decl) { - charHeight = this._getHeightOfChar(ctx, _char, lineIndex, i); - shouldStroke = decl.stroke; - shouldFill = decl.fill; - textDecoration = decl.textDecoration; - } else { - charHeight = this.fontSize; - } - shouldStroke = (shouldStroke || this.stroke) && method === "strokeText"; - shouldFill = (shouldFill || this.fill) && method === "fillText"; - decl && ctx.save(); - charWidth = this._applyCharStylesGetWidth(ctx, _char, lineIndex, i, decl || {}); - textDecoration = textDecoration || this.textDecoration; - if (decl && decl.textBackgroundColor) { - this._removeShadow(ctx); - } - shouldFill && ctx.fillText(_char, left, top); - shouldStroke && ctx.strokeText(_char, left, top); - if (textDecoration || textDecoration !== "") { - offset = this._fontSizeFraction * lineHeight / this.lineHeight; - this._renderCharDecoration(ctx, textDecoration, left, top, offset, charWidth, charHeight); - } - decl && ctx.restore(); - ctx.translate(charWidth, 0); - }, - _hasStyleChanged: function(prevStyle, thisStyle) { - return prevStyle.fill !== thisStyle.fill || prevStyle.fontSize !== thisStyle.fontSize || prevStyle.textBackgroundColor !== thisStyle.textBackgroundColor || prevStyle.textDecoration !== thisStyle.textDecoration || prevStyle.fontFamily !== thisStyle.fontFamily || prevStyle.fontWeight !== thisStyle.fontWeight || prevStyle.fontStyle !== thisStyle.fontStyle || prevStyle.stroke !== thisStyle.stroke || prevStyle.strokeWidth !== thisStyle.strokeWidth; - }, - _renderCharDecoration: function(ctx, textDecoration, left, top, offset, charWidth, charHeight) { - if (!textDecoration) { - return; - } - var decorationWeight = charHeight / 15, positions = { - underline: top + charHeight / 10, - "line-through": top - charHeight * (this._fontSizeFraction + this._fontSizeMult - 1) + decorationWeight, - overline: top - (this._fontSizeMult - this._fontSizeFraction) * charHeight - }, decorations = [ "underline", "line-through", "overline" ], i, decoration; - for (i = 0; i < decorations.length; i++) { - decoration = decorations[i]; - if (textDecoration.indexOf(decoration) > -1) { - ctx.fillRect(left, positions[decoration], charWidth, decorationWeight); - } - } - }, - _renderTextLine: function(method, ctx, line, left, top, lineIndex) { - if (!this.isEmptyStyles()) { - top += this.fontSize * (this._fontSizeFraction + .03); - } - this.callSuper("_renderTextLine", method, ctx, line, left, top, lineIndex); - }, - _renderTextDecoration: function(ctx) { - if (this.isEmptyStyles()) { - return this.callSuper("_renderTextDecoration", ctx); - } - }, - _renderTextLinesBackground: function(ctx) { - this.callSuper("_renderTextLinesBackground", ctx); - var lineTopOffset = 0, heightOfLine, lineWidth, lineLeftOffset, leftOffset = this._getLeftOffset(), topOffset = this._getTopOffset(), line, _char, style; - for (var i = 0, len = this._textLines.length; i < len; i++) { - heightOfLine = this._getHeightOfLine(ctx, i); - line = this._textLines[i]; - if (line === "" || !this.styles || !this._getLineStyle(i)) { - lineTopOffset += heightOfLine; - continue; - } - lineWidth = this._getLineWidth(ctx, i); - lineLeftOffset = this._getLineLeftOffset(lineWidth); - for (var j = 0, jlen = line.length; j < jlen; j++) { - style = this._getStyleDeclaration(i, j); - if (!style || !style.textBackgroundColor) { - continue; - } - _char = line[j]; - ctx.fillStyle = style.textBackgroundColor; - ctx.fillRect(leftOffset + lineLeftOffset + this._getWidthOfCharsAt(ctx, i, j), topOffset + lineTopOffset, this._getWidthOfChar(ctx, _char, i, j) + 1, heightOfLine / this.lineHeight); - } - lineTopOffset += heightOfLine; - } - }, - _getCacheProp: function(_char, styleDeclaration) { - return _char + styleDeclaration.fontFamily + styleDeclaration.fontSize + styleDeclaration.fontWeight + styleDeclaration.fontStyle + styleDeclaration.shadow; - }, - _applyCharStylesGetWidth: function(ctx, _char, lineIndex, charIndex, decl) { - var charDecl = this._getStyleDeclaration(lineIndex, charIndex), styleDeclaration = decl && clone(decl) || clone(charDecl), width; - this._applyFontStyles(styleDeclaration); - var cacheProp = this._getCacheProp(_char, styleDeclaration); - if (!charDecl && this._charWidthsCache[cacheProp] && this.caching) { - return this._charWidthsCache[cacheProp]; - } - if (typeof styleDeclaration.shadow === "string") { - styleDeclaration.shadow = new fabric.Shadow(styleDeclaration.shadow); - } - var fill = styleDeclaration.fill || this.fill; - ctx.fillStyle = fill.toLive ? fill.toLive(ctx, this) : fill; - if (styleDeclaration.stroke) { - ctx.strokeStyle = styleDeclaration.stroke && styleDeclaration.stroke.toLive ? styleDeclaration.stroke.toLive(ctx, this) : styleDeclaration.stroke; - } - ctx.lineWidth = styleDeclaration.strokeWidth || this.strokeWidth; - ctx.font = this._getFontDeclaration.call(styleDeclaration); - if (styleDeclaration.shadow) { - styleDeclaration.scaleX = this.scaleX; - styleDeclaration.scaleY = this.scaleY; - styleDeclaration.canvas = this.canvas; - this._setShadow.call(styleDeclaration, ctx); - } - if (!this.caching || !this._charWidthsCache[cacheProp]) { - width = ctx.measureText(_char).width; - this.caching && (this._charWidthsCache[cacheProp] = width); - } - return this._charWidthsCache[cacheProp]; - }, - _applyFontStyles: function(styleDeclaration) { - if (!styleDeclaration.fontFamily) { - styleDeclaration.fontFamily = this.fontFamily; - } - if (!styleDeclaration.fontSize) { - styleDeclaration.fontSize = this.fontSize; - } - if (!styleDeclaration.fontWeight) { - styleDeclaration.fontWeight = this.fontWeight; - } - if (!styleDeclaration.fontStyle) { - styleDeclaration.fontStyle = this.fontStyle; - } - }, - _getStyleDeclaration: function(lineIndex, charIndex, returnCloneOrEmpty) { - if (returnCloneOrEmpty) { - return this.styles[lineIndex] && this.styles[lineIndex][charIndex] ? clone(this.styles[lineIndex][charIndex]) : {}; - } - return this.styles[lineIndex] && this.styles[lineIndex][charIndex] ? this.styles[lineIndex][charIndex] : null; - }, - _setStyleDeclaration: function(lineIndex, charIndex, style) { - this.styles[lineIndex][charIndex] = style; - }, - _deleteStyleDeclaration: function(lineIndex, charIndex) { - delete this.styles[lineIndex][charIndex]; - }, - _getLineStyle: function(lineIndex) { - return this.styles[lineIndex]; - }, - _setLineStyle: function(lineIndex, style) { - this.styles[lineIndex] = style; - }, - _deleteLineStyle: function(lineIndex) { - delete this.styles[lineIndex]; - }, - _getWidthOfChar: function(ctx, _char, lineIndex, charIndex) { - if (this.textAlign === "justify" && this._reSpacesAndTabs.test(_char)) { - return this._getWidthOfSpace(ctx, lineIndex); - } - var styleDeclaration = this._getStyleDeclaration(lineIndex, charIndex, true); - this._applyFontStyles(styleDeclaration); - var cacheProp = this._getCacheProp(_char, styleDeclaration); - if (this._charWidthsCache[cacheProp] && this.caching) { - return this._charWidthsCache[cacheProp]; - } else if (ctx) { - ctx.save(); - var width = this._applyCharStylesGetWidth(ctx, _char, lineIndex, charIndex); - ctx.restore(); - return width; - } - }, - _getHeightOfChar: function(ctx, lineIndex, charIndex) { - var style = this._getStyleDeclaration(lineIndex, charIndex); - return style && style.fontSize ? style.fontSize : this.fontSize; - }, - _getWidthOfCharsAt: function(ctx, lineIndex, charIndex) { - var width = 0, i, _char; - for (i = 0; i < charIndex; i++) { - _char = this._textLines[lineIndex][i]; - width += this._getWidthOfChar(ctx, _char, lineIndex, i); - } - return width; - }, - _getLineWidth: function(ctx, lineIndex) { - if (this.__lineWidths[lineIndex]) { - return this.__lineWidths[lineIndex]; - } - this.__lineWidths[lineIndex] = this._getWidthOfCharsAt(ctx, lineIndex, this._textLines[lineIndex].length); - return this.__lineWidths[lineIndex]; - }, - _getWidthOfSpace: function(ctx, lineIndex) { - if (this.__widthOfSpace[lineIndex]) { - return this.__widthOfSpace[lineIndex]; - } - var line = this._textLines[lineIndex], wordsWidth = this._getWidthOfWords(ctx, line, lineIndex, 0), widthDiff = this.width - wordsWidth, numSpaces = line.length - line.replace(this._reSpacesAndTabs, "").length, width = widthDiff / numSpaces; - this.__widthOfSpace[lineIndex] = width; - return width; - }, - _getWidthOfWords: function(ctx, line, lineIndex, charOffset) { - var width = 0; - for (var charIndex = 0; charIndex < line.length; charIndex++) { - var _char = line[charIndex]; - if (!_char.match(/\s/)) { - width += this._getWidthOfChar(ctx, _char, lineIndex, charIndex + charOffset); - } - } - return width; - }, - _getHeightOfLine: function(ctx, lineIndex) { - if (this.__lineHeights[lineIndex]) { - return this.__lineHeights[lineIndex]; - } - var line = this._textLines[lineIndex], maxHeight = this._getHeightOfChar(ctx, lineIndex, 0); - for (var i = 1, len = line.length; i < len; i++) { - var currentCharHeight = this._getHeightOfChar(ctx, lineIndex, i); - if (currentCharHeight > maxHeight) { - maxHeight = currentCharHeight; - } - } - this.__lineHeights[lineIndex] = maxHeight * this.lineHeight * this._fontSizeMult; - return this.__lineHeights[lineIndex]; - }, - _getTextHeight: function(ctx) { - var height = 0; - for (var i = 0, len = this._textLines.length; i < len; i++) { - height += this._getHeightOfLine(ctx, i); - } - return height; - }, - toObject: function(propertiesToInclude) { - var clonedStyles = {}, i, j, row; - for (i in this.styles) { - row = this.styles[i]; - clonedStyles[i] = {}; - for (j in row) { - clonedStyles[i][j] = clone(row[j]); - } - } - return fabric.util.object.extend(this.callSuper("toObject", propertiesToInclude), { - styles: clonedStyles - }); - } - }); - fabric.IText.fromObject = function(object) { - return new fabric.IText(object.text, clone(object)); - }; -})(); - -(function() { - var clone = fabric.util.object.clone; - fabric.util.object.extend(fabric.IText.prototype, { - initBehavior: function() { - this.initAddedHandler(); - this.initRemovedHandler(); - this.initCursorSelectionHandlers(); - this.initDoubleClickSimulation(); - }, - initSelectedHandler: function() { - this.on("selected", function() { - var _this = this; - setTimeout(function() { - _this.selected = true; - }, 100); - }); - }, - initAddedHandler: function() { - var _this = this; - this.on("added", function() { - if (this.canvas && !this.canvas._hasITextHandlers) { - this.canvas._hasITextHandlers = true; - this._initCanvasHandlers(); - } - if (_this.canvas) { - _this.canvas._iTextInstances = _this.canvas._iTextInstances || []; - _this.canvas._iTextInstances.push(_this); - } - }); - }, - initRemovedHandler: function() { - var _this = this; - this.on("removed", function() { - if (_this.canvas) { - _this.canvas._iTextInstances = _this.canvas._iTextInstances || []; - fabric.util.removeFromArray(_this.canvas._iTextInstances, _this); - } - }); - }, - _initCanvasHandlers: function() { - var _this = this; - this.canvas.on("selection:cleared", function() { - fabric.IText.prototype.exitEditingOnOthers(_this.canvas); - }); - this.canvas.on("mouse:up", function() { - if (_this.canvas._iTextInstances) { - _this.canvas._iTextInstances.forEach(function(obj) { - obj.__isMousedown = false; - }); - } - }); - this.canvas.on("object:selected", function() { - fabric.IText.prototype.exitEditingOnOthers(_this.canvas); - }); - }, - _tick: function() { - this._currentTickState = this._animateCursor(this, 1, this.cursorDuration, "_onTickComplete"); - }, - _animateCursor: function(obj, targetOpacity, duration, completeMethod) { - var tickState; - tickState = { - isAborted: false, - abort: function() { - this.isAborted = true; - } - }; - obj.animate("_currentCursorOpacity", targetOpacity, { - duration: duration, - onComplete: function() { - if (!tickState.isAborted) { - obj[completeMethod](); - } - }, - onChange: function() { - if (obj.canvas) { - obj.canvas.clearContext(obj.canvas.contextTop || obj.ctx); - obj.renderCursorOrSelection(); - } - }, - abort: function() { - return tickState.isAborted; - } - }); - return tickState; - }, - _onTickComplete: function() { - var _this = this; - if (this._cursorTimeout1) { - clearTimeout(this._cursorTimeout1); - } - this._cursorTimeout1 = setTimeout(function() { - _this._currentTickCompleteState = _this._animateCursor(_this, 0, this.cursorDuration / 2, "_tick"); - }, 100); - }, - initDelayedCursor: function(restart) { - var _this = this, delay = restart ? 0 : this.cursorDelay; - this._currentTickState && this._currentTickState.abort(); - this._currentTickCompleteState && this._currentTickCompleteState.abort(); - clearTimeout(this._cursorTimeout1); - this._currentCursorOpacity = 1; - if (this.canvas) { - this.canvas.clearContext(this.canvas.contextTop || this.ctx); - this.renderCursorOrSelection(); - } - if (this._cursorTimeout2) { - clearTimeout(this._cursorTimeout2); - } - this._cursorTimeout2 = setTimeout(function() { - _this._tick(); - }, delay); - }, - abortCursorAnimation: function() { - this._currentTickState && this._currentTickState.abort(); - this._currentTickCompleteState && this._currentTickCompleteState.abort(); - clearTimeout(this._cursorTimeout1); - clearTimeout(this._cursorTimeout2); - this._currentCursorOpacity = 0; - this.canvas && this.canvas.clearContext(this.canvas.contextTop || this.ctx); - }, - selectAll: function() { - this.setSelectionStart(0); - this.setSelectionEnd(this.text.length); - }, - getSelectedText: function() { - return this.text.slice(this.selectionStart, this.selectionEnd); - }, - findWordBoundaryLeft: function(startFrom) { - var offset = 0, index = startFrom - 1; - if (this._reSpace.test(this.text.charAt(index))) { - while (this._reSpace.test(this.text.charAt(index))) { - offset++; - index--; - } - } - while (/\S/.test(this.text.charAt(index)) && index > -1) { - offset++; - index--; - } - return startFrom - offset; - }, - findWordBoundaryRight: function(startFrom) { - var offset = 0, index = startFrom; - if (this._reSpace.test(this.text.charAt(index))) { - while (this._reSpace.test(this.text.charAt(index))) { - offset++; - index++; - } - } - while (/\S/.test(this.text.charAt(index)) && index < this.text.length) { - offset++; - index++; - } - return startFrom + offset; - }, - findLineBoundaryLeft: function(startFrom) { - var offset = 0, index = startFrom - 1; - while (!/\n/.test(this.text.charAt(index)) && index > -1) { - offset++; - index--; - } - return startFrom - offset; - }, - findLineBoundaryRight: function(startFrom) { - var offset = 0, index = startFrom; - while (!/\n/.test(this.text.charAt(index)) && index < this.text.length) { - offset++; - index++; - } - return startFrom + offset; - }, - getNumNewLinesInSelectedText: function() { - var selectedText = this.getSelectedText(), numNewLines = 0; - for (var i = 0, len = selectedText.length; i < len; i++) { - if (selectedText[i] === "\n") { - numNewLines++; - } - } - return numNewLines; - }, - searchWordBoundary: function(selectionStart, direction) { - var index = this._reSpace.test(this.text.charAt(selectionStart)) ? selectionStart - 1 : selectionStart, _char = this.text.charAt(index), reNonWord = /[ \n\.,;!\?\-]/; - while (!reNonWord.test(_char) && index > 0 && index < this.text.length) { - index += direction; - _char = this.text.charAt(index); - } - if (reNonWord.test(_char) && _char !== "\n") { - index += direction === 1 ? 0 : 1; - } - return index; - }, - selectWord: function(selectionStart) { - var newSelectionStart = this.searchWordBoundary(selectionStart, -1), newSelectionEnd = this.searchWordBoundary(selectionStart, 1); - this.setSelectionStart(newSelectionStart); - this.setSelectionEnd(newSelectionEnd); - }, - selectLine: function(selectionStart) { - var newSelectionStart = this.findLineBoundaryLeft(selectionStart), newSelectionEnd = this.findLineBoundaryRight(selectionStart); - this.setSelectionStart(newSelectionStart); - this.setSelectionEnd(newSelectionEnd); - }, - enterEditing: function(e) { - if (this.isEditing || !this.editable) { - return; - } - if (this.canvas) { - this.exitEditingOnOthers(this.canvas); - } - this.isEditing = true; - this.initHiddenTextarea(e); - this.hiddenTextarea.focus(); - this._updateTextarea(); - this._saveEditingProps(); - this._setEditingProps(); - this._tick(); - this.fire("editing:entered"); - if (!this.canvas) { - return this; - } - this.canvas.renderAll(); - this.canvas.fire("text:editing:entered", { - target: this - }); - this.initMouseMoveHandler(); - return this; - }, - exitEditingOnOthers: function(canvas) { - if (canvas._iTextInstances) { - canvas._iTextInstances.forEach(function(obj) { - obj.selected = false; - if (obj.isEditing) { - obj.exitEditing(); - } - }); - } - }, - initMouseMoveHandler: function() { - var _this = this; - this.canvas.on("mouse:move", function(options) { - if (!_this.__isMousedown || !_this.isEditing) { - return; - } - var newSelectionStart = _this.getSelectionStartFromPointer(options.e); - if (newSelectionStart >= _this.__selectionStartOnMouseDown) { - _this.setSelectionStart(_this.__selectionStartOnMouseDown); - _this.setSelectionEnd(newSelectionStart); - } else { - _this.setSelectionStart(newSelectionStart); - _this.setSelectionEnd(_this.__selectionStartOnMouseDown); - } - }); - }, - _setEditingProps: function() { - this.hoverCursor = "text"; - if (this.canvas) { - this.canvas.defaultCursor = this.canvas.moveCursor = "text"; - } - this.borderColor = this.editingBorderColor; - this.hasControls = this.selectable = false; - this.lockMovementX = this.lockMovementY = true; - }, - _updateTextarea: function() { - if (!this.hiddenTextarea || this.inCompositionMode) { - return; - } - this.hiddenTextarea.value = this.text; - this.hiddenTextarea.selectionStart = this.selectionStart; - this.hiddenTextarea.selectionEnd = this.selectionEnd; - if (this.selectionStart === this.selectionEnd) { - var p = this._calcTextareaPosition(); - this.hiddenTextarea.style.left = p.x + "px"; - this.hiddenTextarea.style.top = p.y + "px"; - } - }, - _calcTextareaPosition: function() { - var chars = this.text.split(""), boundaries = this._getCursorBoundaries(chars, "cursor"), cursorLocation = this.get2DCursorLocation(), lineIndex = cursorLocation.lineIndex, charIndex = cursorLocation.charIndex, charHeight = this.getCurrentCharFontSize(lineIndex, charIndex), leftOffset = lineIndex === 0 && charIndex === 0 ? this._getLineLeftOffset(this._getLineWidth(this.ctx, lineIndex)) : boundaries.leftOffset, m = this.calcTransformMatrix(), p = { - x: boundaries.left + leftOffset, - y: boundaries.top + boundaries.topOffset + charHeight - }; - this.hiddenTextarea.style.fontSize = charHeight + "px"; - return fabric.util.transformPoint(p, m); - }, - _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() { - if (!this._savedProps) { - return; - } - 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; - if (this.canvas) { - this.canvas.defaultCursor = this._savedProps.defaultCursor; - this.canvas.moveCursor = this._savedProps.moveCursor; - } - }, - exitEditing: function() { - this.selected = false; - this.isEditing = false; - this.selectable = true; - this.selectionEnd = this.selectionStart; - this.hiddenTextarea && this.canvas && this.hiddenTextarea.parentNode.removeChild(this.hiddenTextarea); - this.hiddenTextarea = null; - this.abortCursorAnimation(); - this._restoreEditingProps(); - this._currentCursorOpacity = 0; - this.fire("editing:exited"); - this.canvas && this.canvas.fire("text:editing:exited", { - target: this - }); - return this; - }, - _removeExtraneousStyles: function() { - for (var prop in this.styles) { - if (!this._textLines[prop]) { - delete this.styles[prop]; - } - } - }, - _removeCharsFromTo: function(start, end) { - while (end !== start) { - this._removeSingleCharAndStyle(start + 1); - end--; - } - this.setSelectionStart(start); - }, - _removeSingleCharAndStyle: function(index) { - var isBeginningOfLine = this.text[index - 1] === "\n", indexStyle = isBeginningOfLine ? index : index - 1; - this.removeStyleObject(isBeginningOfLine, indexStyle); - this.text = this.text.slice(0, index - 1) + this.text.slice(index); - this._textLines = this._splitTextIntoLines(); - }, - insertChars: function(_chars, useCopiedStyle) { - var style; - if (this.selectionEnd - this.selectionStart > 1) { - this._removeCharsFromTo(this.selectionStart, this.selectionEnd); - this.setSelectionEnd(this.selectionStart); - } - if (!useCopiedStyle && this.isEmptyStyles()) { - this.insertChar(_chars, false); - return; - } - for (var i = 0, len = _chars.length; i < len; i++) { - if (useCopiedStyle) { - style = fabric.copiedTextStyle[i]; - } - this.insertChar(_chars[i], i < len - 1, style); - } - }, - insertChar: function(_char, skipUpdate, styleObject) { - var isEndOfLine = this.text[this.selectionStart] === "\n"; - this.text = this.text.slice(0, this.selectionStart) + _char + this.text.slice(this.selectionEnd); - this._textLines = this._splitTextIntoLines(); - this.insertStyleObjects(_char, isEndOfLine, styleObject); - this.selectionStart += _char.length; - this.selectionEnd = this.selectionStart; - if (skipUpdate) { - return; - } - this._updateTextarea(); - this.canvas && this.canvas.renderAll(); - this.setCoords(); - this.fire("changed"); - this.canvas && this.canvas.fire("text:changed", { - target: this - }); - }, - insertNewlineStyleObject: function(lineIndex, charIndex, isEndOfLine) { - this.shiftLineStyles(lineIndex, +1); - if (!this.styles[lineIndex + 1]) { - this.styles[lineIndex + 1] = {}; - } - var currentCharStyle = {}, newLineStyles = {}; - if (this.styles[lineIndex] && this.styles[lineIndex][charIndex - 1]) { - currentCharStyle = this.styles[lineIndex][charIndex - 1]; - } - if (isEndOfLine) { - newLineStyles[0] = clone(currentCharStyle); - this.styles[lineIndex + 1] = newLineStyles; - } else { - for (var index in this.styles[lineIndex]) { - if (parseInt(index, 10) >= charIndex) { - newLineStyles[parseInt(index, 10) - charIndex] = this.styles[lineIndex][index]; - delete this.styles[lineIndex][index]; - } - } - this.styles[lineIndex + 1] = newLineStyles; - } - this._forceClearCache = true; - }, - insertCharStyleObject: function(lineIndex, charIndex, style) { - var currentLineStyles = this.styles[lineIndex], currentLineStylesCloned = clone(currentLineStyles); - if (charIndex === 0 && !style) { - charIndex = 1; - } - for (var index in currentLineStylesCloned) { - var numericIndex = parseInt(index, 10); - if (numericIndex >= charIndex) { - currentLineStyles[numericIndex + 1] = currentLineStylesCloned[numericIndex]; - if (!currentLineStylesCloned[numericIndex - 1]) { - delete currentLineStyles[numericIndex]; - } - } - } - this.styles[lineIndex][charIndex] = style || clone(currentLineStyles[charIndex - 1]); - this._forceClearCache = true; - }, - insertStyleObjects: function(_chars, isEndOfLine, styleObject) { - var cursorLocation = this.get2DCursorLocation(), lineIndex = cursorLocation.lineIndex, charIndex = cursorLocation.charIndex; - if (!this._getLineStyle(lineIndex)) { - this._setLineStyle(lineIndex, {}); - } - if (_chars === "\n") { - this.insertNewlineStyleObject(lineIndex, charIndex, isEndOfLine); - } else { - this.insertCharStyleObject(lineIndex, charIndex, styleObject); - } - }, - shiftLineStyles: function(lineIndex, offset) { - var clonedStyles = clone(this.styles); - for (var line in this.styles) { - var numericLine = parseInt(line, 10); - if (numericLine > lineIndex) { - this.styles[numericLine + offset] = clonedStyles[numericLine]; - if (!clonedStyles[numericLine - offset]) { - delete this.styles[numericLine]; - } - } - } - }, - removeStyleObject: function(isBeginningOfLine, index) { - var cursorLocation = this.get2DCursorLocation(index), lineIndex = cursorLocation.lineIndex, charIndex = cursorLocation.charIndex; - this._removeStyleObject(isBeginningOfLine, cursorLocation, lineIndex, charIndex); - }, - _getTextOnPreviousLine: function(lIndex) { - return this._textLines[lIndex - 1]; - }, - _removeStyleObject: function(isBeginningOfLine, cursorLocation, lineIndex, charIndex) { - if (isBeginningOfLine) { - var textOnPreviousLine = this._getTextOnPreviousLine(cursorLocation.lineIndex), newCharIndexOnPrevLine = textOnPreviousLine ? textOnPreviousLine.length : 0; - if (!this.styles[lineIndex - 1]) { - this.styles[lineIndex - 1] = {}; - } - for (charIndex in this.styles[lineIndex]) { - this.styles[lineIndex - 1][parseInt(charIndex, 10) + newCharIndexOnPrevLine] = this.styles[lineIndex][charIndex]; - } - this.shiftLineStyles(cursorLocation.lineIndex, -1); - } else { - var currentLineStyles = this.styles[lineIndex]; - if (currentLineStyles) { - delete currentLineStyles[charIndex]; - } - var currentLineStylesCloned = clone(currentLineStyles); - for (var i in currentLineStylesCloned) { - var numericIndex = parseInt(i, 10); - if (numericIndex >= charIndex && numericIndex !== 0) { - currentLineStyles[numericIndex - 1] = currentLineStylesCloned[numericIndex]; - delete currentLineStyles[numericIndex]; - } - } - } - }, - insertNewline: function() { - this.insertChars("\n"); - } - }); -})(); - -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(options) { - this.__newClickTime = +new Date(); - var newPointer = this.canvas.getPointer(options.e); - if (this.isTripleClick(newPointer)) { - 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; - 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; - }, - _stopEvent: function(e) { - e.preventDefault && e.preventDefault(); - e.stopPropagation && e.stopPropagation(); - }, - initCursorSelectionHandlers: function() { - this.initSelectedHandler(); - this.initMousedownHandler(); - this.initMouseupHandler(); - this.initClicks(); - }, - initClicks: function() { - this.on("dblclick", function(options) { - this.selectWord(this.getSelectionStartFromPointer(options.e)); - }); - this.on("tripleclick", function(options) { - this.selectLine(this.getSelectionStartFromPointer(options.e)); - }); - }, - initMousedownHandler: function() { - this.on("mousedown", function(options) { - if (!this.editable) { - return; - } - var pointer = this.canvas.getPointer(options.e); - this.__mousedownX = pointer.x; - this.__mousedownY = pointer.y; - this.__isMousedown = true; - if (this.hiddenTextarea && this.canvas) { - this.canvas.wrapperEl.appendChild(this.hiddenTextarea); - } - if (this.selected) { - this.setCursorByClick(options.e); - } - if (this.isEditing) { - this.__selectionStartOnMouseDown = this.selectionStart; - this.initDelayedCursor(true); - } - }); - }, - _isObjectMoved: function(e) { - var pointer = this.canvas.getPointer(e); - return this.__mousedownX !== pointer.x || this.__mousedownY !== pointer.y; - }, - initMouseupHandler: function() { - this.on("mouseup", function(options) { - this.__isMousedown = false; - if (!this.editable || this._isObjectMoved(options.e)) { - return; - } - if (this.__lastSelected && !this.__corner) { - this.enterEditing(options.e); - this.initDelayedCursor(true); - } - this.selected = true; - }); - }, - setCursorByClick: function(e) { - var newSelectionStart = this.getSelectionStartFromPointer(e); - if (e.shiftKey) { - if (newSelectionStart < this.selectionStart) { - this.setSelectionEnd(this.selectionStart); - this.setSelectionStart(newSelectionStart); - } else { - this.setSelectionEnd(newSelectionStart); - } - } else { - this.setSelectionStart(newSelectionStart); - this.setSelectionEnd(newSelectionStart); - } - }, - getSelectionStartFromPointer: function(e) { - var mouseOffset = this.getLocalPointer(e), prevWidth = 0, width = 0, height = 0, charIndex = 0, newSelectionStart, line; - for (var i = 0, len = this._textLines.length; i < len; i++) { - line = this._textLines[i]; - height += this._getHeightOfLine(this.ctx, i) * this.scaleY; - var widthOfLine = this._getLineWidth(this.ctx, i), lineLeftOffset = this._getLineLeftOffset(widthOfLine); - width = lineLeftOffset * this.scaleX; - for (var j = 0, jlen = line.length; j < jlen; j++) { - prevWidth = width; - width += this._getWidthOfChar(this.ctx, line[j], i, this.flipX ? jlen - j : j) * this.scaleX; - if (height <= mouseOffset.y || width <= mouseOffset.x) { - charIndex++; - continue; - } - return this._getNewSelectionStartFromOffset(mouseOffset, prevWidth, width, charIndex + i, jlen); - } - if (mouseOffset.y < height) { - return this._getNewSelectionStartFromOffset(mouseOffset, prevWidth, width, charIndex + i - 1, jlen); - } - } - if (typeof newSelectionStart === "undefined") { - return this.text.length; - } - }, - _getNewSelectionStartFromOffset: function(mouseOffset, prevWidth, width, index, jlen) { - var distanceBtwLastCharAndCursor = mouseOffset.x - prevWidth, distanceBtwNextCharAndCursor = width - mouseOffset.x, offset = distanceBtwNextCharAndCursor > distanceBtwLastCharAndCursor ? 0 : 1, newSelectionStart = index + offset; - if (this.flipX) { - newSelectionStart = jlen - newSelectionStart; - } - if (newSelectionStart > this.text.length) { - newSelectionStart = this.text.length; - } - return newSelectionStart; - } -}); - -fabric.util.object.extend(fabric.IText.prototype, { - initHiddenTextarea: function(e) { - var p; - if (e && this.canvas) { - p = this.canvas.getPointer(e); - } else { - this.oCoords || this.setCoords(); - p = this.oCoords.tl; - } - this.hiddenTextarea = fabric.document.createElement("textarea"); - this.hiddenTextarea.setAttribute("autocapitalize", "off"); - this.hiddenTextarea.style.cssText = "position: absolute; top: " + p.y + "px; left: " + p.x + "px; opacity: 0;" + " width: 0px; height: 0px; z-index: -999;"; - if (this.canvas) { - this.canvas.lowerCanvasEl.parentNode.appendChild(this.hiddenTextarea); - } else { - 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.cut.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)); - if (!this._clickHandlerInitialized && this.canvas) { - fabric.util.addListener(this.canvas.upperCanvasEl, "click", this.onClick.bind(this)); - this._clickHandlerInitialized = true; - } - }, - _keysMap: { - 8: "removeChars", - 9: "exitEditing", - 27: "exitEditing", - 13: "insertNewline", - 33: "moveCursorUp", - 34: "moveCursorDown", - 35: "moveCursorRight", - 36: "moveCursorLeft", - 37: "moveCursorLeft", - 38: "moveCursorUp", - 39: "moveCursorRight", - 40: "moveCursorDown", - 46: "forwardDelete" - }, - _ctrlKeysMap: { - 65: "selectAll", - 67: "copy", - 88: "cut" - }, - onClick: function() { - this.hiddenTextarea && this.hiddenTextarea.focus(); - }, - onKeyDown: function(e) { - if (!this.isEditing) { - return; - } - if (e.keyCode in this._keysMap) { - this[this._keysMap[e.keyCode]](e); - } else { - return; - } - e.stopImmediatePropagation(); - e.preventDefault(); - this.canvas && this.canvas.renderAll(); - }, - onKeyUp: function(e) { - if (!this.isEditing || this._copyDone) { - this._copyDone = false; - return; - } - if (e.keyCode in this._ctrlKeysMap && (e.ctrlKey || e.metaKey)) { - this[this._ctrlKeysMap[e.keyCode]](e); - } else { - return; - } - e.stopImmediatePropagation(); - e.preventDefault(); - this.canvas && this.canvas.renderAll(); - }, - onInput: function(e) { - if (!this.isEditing || this.inCompositionMode) { - return; - } - var offset = this.selectionStart || 0, offsetEnd = this.selectionEnd || 0, textLength = this.text.length, newTextLength = this.hiddenTextarea.value.length, diff, charsToInsert, start; - if (newTextLength > textLength) { - start = this._selectionDirection === "left" ? offsetEnd : offset; - diff = newTextLength - textLength; - charsToInsert = this.hiddenTextarea.value.slice(start, start + diff); - } else { - diff = newTextLength - textLength + offsetEnd - offset; - charsToInsert = this.hiddenTextarea.value.slice(offset, offset + diff); - } - this.insertChars(charsToInsert); - e.stopPropagation(); - }, - onCompositionStart: function() { - this.inCompositionMode = true; - this.prevCompositionLength = 0; - this.compositionStart = this.selectionStart; - }, - onCompositionEnd: function() { - this.inCompositionMode = false; - }, - onCompositionUpdate: function(e) { - var data = e.data; - this.selectionStart = this.compositionStart; - this.selectionEnd = this.selectionEnd === this.selectionStart ? this.compositionStart + this.prevCompositionLength : this.selectionEnd; - this.insertChars(data, false); - this.prevCompositionLength = data.length; - }, - forwardDelete: function(e) { - if (this.selectionStart === this.selectionEnd) { - if (this.selectionStart === this.text.length) { - return; - } - this.moveCursorRight(e); - } - this.removeChars(e); - }, - copy: function(e) { - if (this.selectionStart === this.selectionEnd) { - return; - } - var selectedText = this.getSelectedText(), clipboardData = this._getClipboardData(e); - if (clipboardData) { - clipboardData.setData("text", selectedText); - } - fabric.copiedText = selectedText; - fabric.copiedTextStyle = this.getSelectionStyles(this.selectionStart, this.selectionEnd); - e.stopImmediatePropagation(); - e.preventDefault(); - this._copyDone = true; - }, - paste: function(e) { - var copiedText = null, clipboardData = this._getClipboardData(e), useCopiedStyle = true; - if (clipboardData) { - copiedText = clipboardData.getData("text").replace(/\r/g, ""); - if (!fabric.copiedTextStyle || fabric.copiedText !== copiedText) { - useCopiedStyle = false; - } - } else { - copiedText = fabric.copiedText; - } - if (copiedText) { - this.insertChars(copiedText, useCopiedStyle); - } - e.stopImmediatePropagation(); - e.preventDefault(); - }, - cut: function(e) { - if (this.selectionStart === this.selectionEnd) { - return; - } - this.copy(e); - this.removeChars(e); - }, - _getClipboardData: function(e) { - return e && e.clipboardData || fabric.window.clipboardData; - }, - getDownCursorOffset: function(e, isRight) { - var selectionProp = isRight ? this.selectionEnd : this.selectionStart, cursorLocation = this.get2DCursorLocation(selectionProp), _char, lineLeftOffset, lineIndex = cursorLocation.lineIndex, textOnSameLineBeforeCursor = this._textLines[lineIndex].slice(0, cursorLocation.charIndex), textOnSameLineAfterCursor = this._textLines[lineIndex].slice(cursorLocation.charIndex), textOnNextLine = this._textLines[lineIndex + 1] || ""; - if (lineIndex === this._textLines.length - 1 || e.metaKey || e.keyCode === 34) { - return this.text.length - selectionProp; - } - var widthOfSameLineBeforeCursor = this._getLineWidth(this.ctx, lineIndex); - lineLeftOffset = this._getLineLeftOffset(widthOfSameLineBeforeCursor); - var widthOfCharsOnSameLineBeforeCursor = lineLeftOffset; - for (var i = 0, len = textOnSameLineBeforeCursor.length; i < len; i++) { - _char = textOnSameLineBeforeCursor[i]; - widthOfCharsOnSameLineBeforeCursor += this._getWidthOfChar(this.ctx, _char, lineIndex, i); - } - var indexOnNextLine = this._getIndexOnNextLine(cursorLocation, textOnNextLine, widthOfCharsOnSameLineBeforeCursor); - return textOnSameLineAfterCursor.length + 1 + indexOnNextLine; - }, - _getIndexOnNextLine: function(cursorLocation, textOnNextLine, widthOfCharsOnSameLineBeforeCursor) { - var lineIndex = cursorLocation.lineIndex + 1, widthOfNextLine = this._getLineWidth(this.ctx, lineIndex), lineLeftOffset = this._getLineLeftOffset(widthOfNextLine), widthOfCharsOnNextLine = lineLeftOffset, indexOnNextLine = 0, foundMatch; - for (var j = 0, jlen = textOnNextLine.length; j < jlen; j++) { - var _char = textOnNextLine[j], widthOfChar = this._getWidthOfChar(this.ctx, _char, lineIndex, j); - widthOfCharsOnNextLine += widthOfChar; - if (widthOfCharsOnNextLine > widthOfCharsOnSameLineBeforeCursor) { - foundMatch = true; - var leftEdge = widthOfCharsOnNextLine - widthOfChar, rightEdge = widthOfCharsOnNextLine, offsetFromLeftEdge = Math.abs(leftEdge - widthOfCharsOnSameLineBeforeCursor), offsetFromRightEdge = Math.abs(rightEdge - widthOfCharsOnSameLineBeforeCursor); - indexOnNextLine = offsetFromRightEdge < offsetFromLeftEdge ? j + 1 : j; - break; - } - } - if (!foundMatch) { - indexOnNextLine = textOnNextLine.length; - } - return indexOnNextLine; - }, - moveCursorDown: function(e) { - this.abortCursorAnimation(); - this._currentCursorOpacity = 1; - var offset = this.getDownCursorOffset(e, this._selectionDirection === "right"); - if (e.shiftKey) { - this.moveCursorDownWithShift(offset); - } else { - this.moveCursorDownWithoutShift(offset); - } - this.initDelayedCursor(); - }, - moveCursorDownWithoutShift: function(offset) { - this._selectionDirection = "right"; - this.setSelectionStart(this.selectionStart + offset); - this.setSelectionEnd(this.selectionStart); - }, - swapSelectionPoints: function() { - var swapSel = this.selectionEnd; - this.setSelectionEnd(this.selectionStart); - this.setSelectionStart(swapSel); - }, - moveCursorDownWithShift: function(offset) { - if (this.selectionEnd === this.selectionStart) { - this._selectionDirection = "right"; - } - if (this._selectionDirection === "right") { - this.setSelectionEnd(this.selectionEnd + offset); - } else { - this.setSelectionStart(this.selectionStart + offset); - } - if (this.selectionEnd < this.selectionStart && this._selectionDirection === "left") { - this.swapSelectionPoints(); - this._selectionDirection = "right"; - } - if (this.selectionEnd > this.text.length) { - this.setSelectionEnd(this.text.length); - } - }, - getUpCursorOffset: function(e, isRight) { - var selectionProp = isRight ? this.selectionEnd : this.selectionStart, cursorLocation = this.get2DCursorLocation(selectionProp), lineIndex = cursorLocation.lineIndex; - if (lineIndex === 0 || e.metaKey || e.keyCode === 33) { - return selectionProp; - } - var textOnSameLineBeforeCursor = this._textLines[lineIndex].slice(0, cursorLocation.charIndex), textOnPreviousLine = this._textLines[lineIndex - 1] || "", _char, widthOfSameLineBeforeCursor = this._getLineWidth(this.ctx, cursorLocation.lineIndex), lineLeftOffset = this._getLineLeftOffset(widthOfSameLineBeforeCursor), widthOfCharsOnSameLineBeforeCursor = lineLeftOffset; - for (var i = 0, len = textOnSameLineBeforeCursor.length; i < len; i++) { - _char = textOnSameLineBeforeCursor[i]; - widthOfCharsOnSameLineBeforeCursor += this._getWidthOfChar(this.ctx, _char, lineIndex, i); - } - var indexOnPrevLine = this._getIndexOnPrevLine(cursorLocation, textOnPreviousLine, widthOfCharsOnSameLineBeforeCursor); - return textOnPreviousLine.length - indexOnPrevLine + textOnSameLineBeforeCursor.length; - }, - _getIndexOnPrevLine: function(cursorLocation, textOnPreviousLine, widthOfCharsOnSameLineBeforeCursor) { - var lineIndex = cursorLocation.lineIndex - 1, widthOfPreviousLine = this._getLineWidth(this.ctx, lineIndex), lineLeftOffset = this._getLineLeftOffset(widthOfPreviousLine), widthOfCharsOnPreviousLine = lineLeftOffset, indexOnPrevLine = 0, foundMatch; - for (var j = 0, jlen = textOnPreviousLine.length; j < jlen; j++) { - var _char = textOnPreviousLine[j], widthOfChar = this._getWidthOfChar(this.ctx, _char, lineIndex, j); - widthOfCharsOnPreviousLine += widthOfChar; - if (widthOfCharsOnPreviousLine > widthOfCharsOnSameLineBeforeCursor) { - foundMatch = true; - var leftEdge = widthOfCharsOnPreviousLine - widthOfChar, rightEdge = widthOfCharsOnPreviousLine, offsetFromLeftEdge = Math.abs(leftEdge - widthOfCharsOnSameLineBeforeCursor), offsetFromRightEdge = Math.abs(rightEdge - widthOfCharsOnSameLineBeforeCursor); - indexOnPrevLine = offsetFromRightEdge < offsetFromLeftEdge ? j : j - 1; - break; - } - } - if (!foundMatch) { - indexOnPrevLine = textOnPreviousLine.length - 1; - } - return indexOnPrevLine; - }, - moveCursorUp: function(e) { - this.abortCursorAnimation(); - this._currentCursorOpacity = 1; - var offset = this.getUpCursorOffset(e, this._selectionDirection === "right"); - if (e.shiftKey) { - this.moveCursorUpWithShift(offset); - } else { - this.moveCursorUpWithoutShift(offset); - } - this.initDelayedCursor(); - }, - moveCursorUpWithShift: function(offset) { - if (this.selectionEnd === this.selectionStart) { - this._selectionDirection = "left"; - } - if (this._selectionDirection === "right") { - this.setSelectionEnd(this.selectionEnd - offset); - } else { - this.setSelectionStart(this.selectionStart - offset); - } - if (this.selectionEnd < this.selectionStart && this._selectionDirection === "right") { - this.swapSelectionPoints(); - this._selectionDirection = "left"; - } - }, - moveCursorUpWithoutShift: function(offset) { - if (this.selectionStart === this.selectionEnd) { - this.setSelectionStart(this.selectionStart - offset); - } - this.setSelectionEnd(this.selectionStart); - this._selectionDirection = "left"; - }, - moveCursorLeft: function(e) { - if (this.selectionStart === 0 && this.selectionEnd === 0) { - return; - } - this.abortCursorAnimation(); - this._currentCursorOpacity = 1; - if (e.shiftKey) { - this.moveCursorLeftWithShift(e); - } else { - this.moveCursorLeftWithoutShift(e); - } - this.initDelayedCursor(); - }, - _move: function(e, prop, direction) { - var propMethod = prop === "selectionStart" ? "setSelectionStart" : "setSelectionEnd"; - if (e.altKey) { - this[propMethod](this["findWordBoundary" + direction](this[prop])); - } else if (e.metaKey || e.keyCode === 35 || e.keyCode === 36) { - this[propMethod](this["findLineBoundary" + direction](this[prop])); - } else { - this[propMethod](this[prop] + (direction === "Left" ? -1 : 1)); - } - }, - _moveLeft: function(e, prop) { - this._move(e, prop, "Left"); - }, - _moveRight: function(e, prop) { - this._move(e, prop, "Right"); - }, - moveCursorLeftWithoutShift: function(e) { - this._selectionDirection = "left"; - if (this.selectionEnd === this.selectionStart) { - this._moveLeft(e, "selectionStart"); - } - this.setSelectionEnd(this.selectionStart); - }, - moveCursorLeftWithShift: function(e) { - if (this._selectionDirection === "right" && this.selectionStart !== this.selectionEnd) { - this._moveLeft(e, "selectionEnd"); - } else { - this._selectionDirection = "left"; - this._moveLeft(e, "selectionStart"); - } - }, - moveCursorRight: function(e) { - if (this.selectionStart >= this.text.length && this.selectionEnd >= this.text.length) { - return; - } - this.abortCursorAnimation(); - this._currentCursorOpacity = 1; - if (e.shiftKey) { - this.moveCursorRightWithShift(e); - } else { - this.moveCursorRightWithoutShift(e); - } - this.initDelayedCursor(); - }, - moveCursorRightWithShift: function(e) { - if (this._selectionDirection === "left" && this.selectionStart !== this.selectionEnd) { - this._moveRight(e, "selectionStart"); - } else { - this._selectionDirection = "right"; - this._moveRight(e, "selectionEnd"); - } - }, - moveCursorRightWithoutShift: function(e) { - this._selectionDirection = "right"; - if (this.selectionStart === this.selectionEnd) { - this._moveRight(e, "selectionStart"); - this.setSelectionEnd(this.selectionStart); - } else { - this.setSelectionEnd(this.selectionEnd + this.getNumNewLinesInSelectedText()); - this.setSelectionStart(this.selectionEnd); - } - }, - removeChars: function(e) { - if (this.selectionStart === this.selectionEnd) { - this._removeCharsNearCursor(e); - } else { - this._removeCharsFromTo(this.selectionStart, this.selectionEnd); - } - 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(e) { - if (this.selectionStart === 0) { - return; - } - if (e.metaKey) { - var leftLineBoundary = this.findLineBoundaryLeft(this.selectionStart); - this._removeCharsFromTo(leftLineBoundary, this.selectionStart); - this.setSelectionStart(leftLineBoundary); - } else if (e.altKey) { - var leftWordBoundary = this.findWordBoundaryLeft(this.selectionStart); - this._removeCharsFromTo(leftWordBoundary, this.selectionStart); - this.setSelectionStart(leftWordBoundary); - } else { - this._removeSingleCharAndStyle(this.selectionStart); - this.setSelectionStart(this.selectionStart - 1); - } - } -}); - -(function() { - var toFixed = fabric.util.toFixed, NUM_FRACTION_DIGITS = fabric.Object.NUM_FRACTION_DIGITS; - fabric.util.object.extend(fabric.IText.prototype, { - _setSVGTextLineText: function(lineIndex, textSpans, height, textLeftOffset, textTopOffset, textBgRects) { - if (!this._getLineStyle(lineIndex)) { - fabric.Text.prototype._setSVGTextLineText.call(this, lineIndex, textSpans, height, textLeftOffset, textTopOffset); - } else { - this._setSVGTextLineChars(lineIndex, textSpans, height, textLeftOffset, textBgRects); - } - }, - _setSVGTextLineChars: function(lineIndex, textSpans, height, textLeftOffset, textBgRects) { - var chars = this._textLines[lineIndex], charOffset = 0, lineLeftOffset = this._getLineLeftOffset(this._getLineWidth(this.ctx, lineIndex)) - this.width / 2, lineOffset = this._getSVGLineTopOffset(lineIndex), heightOfLine = this._getHeightOfLine(this.ctx, lineIndex); - for (var i = 0, len = chars.length; i < len; i++) { - var styleDecl = this._getStyleDeclaration(lineIndex, i) || {}; - textSpans.push(this._createTextCharSpan(chars[i], styleDecl, lineLeftOffset, lineOffset.lineTop + lineOffset.offset, charOffset)); - var charWidth = this._getWidthOfChar(this.ctx, chars[i], lineIndex, i); - if (styleDecl.textBackgroundColor) { - textBgRects.push(this._createTextCharBg(styleDecl, lineLeftOffset, lineOffset.lineTop, heightOfLine, charWidth, charOffset)); - } - charOffset += charWidth; - } - }, - _getSVGLineTopOffset: function(lineIndex) { - var lineTopOffset = 0, lastHeight = 0; - for (var j = 0; j < lineIndex; j++) { - lineTopOffset += this._getHeightOfLine(this.ctx, j); - } - lastHeight = this._getHeightOfLine(this.ctx, j); - return { - lineTop: lineTopOffset, - offset: (this._fontSizeMult - this._fontSizeFraction) * lastHeight / (this.lineHeight * this._fontSizeMult) - }; - }, - _createTextCharBg: function(styleDecl, lineLeftOffset, lineTopOffset, heightOfLine, charWidth, charOffset) { - return [ ' \n' ].join(""); - }, - _createTextCharSpan: function(_char, styleDecl, lineLeftOffset, lineTopOffset, charOffset) { - var fillStyles = this.getSvgStyles.call(fabric.util.object.extend({ - visible: true, - fill: this.fill, - stroke: this.stroke, - type: "text", - getSvgFilter: fabric.Object.prototype.getSvgFilter - }, styleDecl)); - return [ ' ', fabric.util.string.escapeXml(_char), "\n" ].join(""); - } - }); -})(); - -(function(global) { - "use strict"; - var fabric = global.fabric || (global.fabric = {}), clone = fabric.util.object.clone; - fabric.Textbox = fabric.util.createClass(fabric.IText, fabric.Observable, { - type: "textbox", - minWidth: 20, - dynamicMinWidth: 0, - __cachedLines: null, - initialize: function(text, options) { - this.ctx = fabric.util.createCanvasElement().getContext("2d"); - this.callSuper("initialize", text, options); - this.set({ - lockUniScaling: false, - lockScalingY: true, - lockScalingFlip: true, - hasBorders: true - }); - this.setControlsVisibility(fabric.Textbox.getTextboxControlVisibility()); - this._dimensionAffectingProps.width = true; - }, - _initDimensions: function(ctx) { - if (this.__skipDimension) { - return; - } - if (!ctx) { - ctx = fabric.util.createCanvasElement().getContext("2d"); - this._setTextStyles(ctx); - } - this.dynamicMinWidth = 0; - this._textLines = this._splitTextIntoLines(); - if (this.dynamicMinWidth > this.width) { - this._set("width", this.dynamicMinWidth); - } - this._clearCache(); - this.height = this._getTextHeight(ctx); - }, - _generateStyleMap: function() { - var realLineCount = 0, realLineCharCount = 0, charCount = 0, map = {}; - for (var i = 0; i < this._textLines.length; i++) { - if (this.text[charCount] === "\n") { - realLineCharCount = 0; - charCount++; - realLineCount++; - } else if (this.text[charCount] === " ") { - realLineCharCount++; - charCount++; - } - map[i] = { - line: realLineCount, - offset: realLineCharCount - }; - charCount += this._textLines[i].length; - realLineCharCount += this._textLines[i].length; - } - return map; - }, - _getStyleDeclaration: function(lineIndex, charIndex, returnCloneOrEmpty) { - if (this._styleMap) { - var map = this._styleMap[lineIndex]; - if (!map) { - return returnCloneOrEmpty ? {} : null; - } - lineIndex = map.line; - charIndex = map.offset + charIndex; - } - return this.callSuper("_getStyleDeclaration", lineIndex, charIndex, returnCloneOrEmpty); - }, - _setStyleDeclaration: function(lineIndex, charIndex, style) { - var map = this._styleMap[lineIndex]; - lineIndex = map.line; - charIndex = map.offset + charIndex; - this.styles[lineIndex][charIndex] = style; - }, - _deleteStyleDeclaration: function(lineIndex, charIndex) { - var map = this._styleMap[lineIndex]; - lineIndex = map.line; - charIndex = map.offset + charIndex; - delete this.styles[lineIndex][charIndex]; - }, - _getLineStyle: function(lineIndex) { - var map = this._styleMap[lineIndex]; - return this.styles[map.line]; - }, - _setLineStyle: function(lineIndex, style) { - var map = this._styleMap[lineIndex]; - this.styles[map.line] = style; - }, - _deleteLineStyle: function(lineIndex) { - var map = this._styleMap[lineIndex]; - delete this.styles[map.line]; - }, - _wrapText: function(ctx, text) { - var lines = text.split(this._reNewline), wrapped = [], i; - for (i = 0; i < lines.length; i++) { - wrapped = wrapped.concat(this._wrapLine(ctx, lines[i], i)); - } - return wrapped; - }, - _measureText: function(ctx, text, lineIndex, charOffset) { - var width = 0; - charOffset = charOffset || 0; - for (var i = 0, len = text.length; i < len; i++) { - width += this._getWidthOfChar(ctx, text[i], lineIndex, i + charOffset); - } - return width; - }, - _wrapLine: function(ctx, text, lineIndex) { - var lineWidth = 0, lines = [], line = "", words = text.split(" "), word = "", offset = 0, infix = " ", wordWidth = 0, infixWidth = 0, largestWordWidth = 0, lineJustStarted = true; - for (var i = 0; i < words.length; i++) { - word = words[i]; - wordWidth = this._measureText(ctx, word, lineIndex, offset); - offset += word.length; - lineWidth += infixWidth + wordWidth; - if (lineWidth >= this.width && !lineJustStarted) { - lines.push(line); - line = ""; - lineWidth = wordWidth; - lineJustStarted = true; - } - if (!lineJustStarted) { - line += infix; - } - line += word; - infixWidth = this._measureText(ctx, infix, lineIndex, offset); - offset++; - lineJustStarted = false; - if (wordWidth > largestWordWidth) { - largestWordWidth = wordWidth; - } - } - i && lines.push(line); - if (largestWordWidth > this.dynamicMinWidth) { - this.dynamicMinWidth = largestWordWidth; - } - return lines; - }, - _splitTextIntoLines: function() { - var originalAlign = this.textAlign; - this.ctx.save(); - this._setTextStyles(this.ctx); - this.textAlign = "left"; - var lines = this._wrapText(this.ctx, this.text); - this.textAlign = originalAlign; - this.ctx.restore(); - this._textLines = lines; - this._styleMap = this._generateStyleMap(); - return lines; - }, - 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; - } - }, - get2DCursorLocation: function(selectionStart) { - if (typeof selectionStart === "undefined") { - selectionStart = this.selectionStart; - } - var numLines = this._textLines.length, removed = 0; - for (var i = 0; i < numLines; i++) { - var line = this._textLines[i], lineLen = line.length; - if (selectionStart <= removed + lineLen) { - return { - lineIndex: i, - charIndex: selectionStart - removed - }; - } - removed += lineLen; - if (this.text[removed] === "\n" || this.text[removed] === " ") { - removed++; - } - } - return { - lineIndex: numLines - 1, - charIndex: this._textLines[numLines - 1].length - }; - }, - _getCursorBoundariesOffsets: function(chars, typeOfBoundaries) { - var topOffset = 0, leftOffset = 0, cursorLocation = this.get2DCursorLocation(), lineChars = this._textLines[cursorLocation.lineIndex].split(""), lineLeftOffset = this._getLineLeftOffset(this._getLineWidth(this.ctx, cursorLocation.lineIndex)); - for (var i = 0; i < cursorLocation.charIndex; i++) { - leftOffset += this._getWidthOfChar(this.ctx, lineChars[i], cursorLocation.lineIndex, i); - } - for (i = 0; i < cursorLocation.lineIndex; i++) { - topOffset += this._getHeightOfLine(this.ctx, i); - } - if (typeOfBoundaries === "cursor") { - topOffset += (1 - this._fontSizeFraction) * this._getHeightOfLine(this.ctx, cursorLocation.lineIndex) / this.lineHeight - this.getCurrentCharFontSize(cursorLocation.lineIndex, cursorLocation.charIndex) * (1 - this._fontSizeFraction); - } - return { - top: topOffset, - left: leftOffset, - lineLeft: lineLeftOffset - }; - }, - getMinWidth: function() { - return Math.max(this.minWidth, this.dynamicMinWidth); - }, - toObject: function(propertiesToInclude) { - return fabric.util.object.extend(this.callSuper("toObject", propertiesToInclude), { - minWidth: this.minWidth - }); - } - }); - fabric.Textbox.fromObject = function(object) { - return new fabric.Textbox(object.text, clone(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.instances = []; -})(typeof exports !== "undefined" ? exports : this); - -(function() { - 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 (w >= t.getMinWidth()) { - t.set("width", w); - return true; - } - } else { - 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; - } - } - }; - var clone = fabric.util.object.clone; - fabric.util.object.extend(fabric.Textbox.prototype, { - _removeExtraneousStyles: function() { - for (var prop in this._styleMap) { - if (!this._textLines[prop]) { - delete this.styles[this._styleMap[prop].line]; - } - } - }, - insertCharStyleObject: function(lineIndex, charIndex, style) { - var map = this._styleMap[lineIndex]; - lineIndex = map.line; - charIndex = map.offset + charIndex; - fabric.IText.prototype.insertCharStyleObject.apply(this, [ lineIndex, charIndex, style ]); - }, - insertNewlineStyleObject: function(lineIndex, charIndex, isEndOfLine) { - var map = this._styleMap[lineIndex]; - lineIndex = map.line; - charIndex = map.offset + charIndex; - fabric.IText.prototype.insertNewlineStyleObject.apply(this, [ lineIndex, charIndex, isEndOfLine ]); - }, - shiftLineStyles: function(lineIndex, offset) { - var clonedStyles = clone(this.styles), map = this._styleMap[lineIndex]; - lineIndex = map.line; - for (var line in this.styles) { - var numericLine = parseInt(line, 10); - if (numericLine > lineIndex) { - this.styles[numericLine + offset] = clonedStyles[numericLine]; - if (!clonedStyles[numericLine - offset]) { - delete this.styles[numericLine]; - } - } - } - }, - _getTextOnPreviousLine: function(lIndex) { - var textOnPreviousLine = this._textLines[lIndex - 1]; - while (this._styleMap[lIndex - 2] && this._styleMap[lIndex - 2].line === this._styleMap[lIndex - 1].line) { - textOnPreviousLine = this._textLines[lIndex - 2] + textOnPreviousLine; - lIndex--; - } - return textOnPreviousLine; - }, - removeStyleObject: function(isBeginningOfLine, index) { - var cursorLocation = this.get2DCursorLocation(index), map = this._styleMap[cursorLocation.lineIndex], lineIndex = map.line, charIndex = map.offset + cursorLocation.charIndex; - this._removeStyleObject(isBeginningOfLine, cursorLocation, lineIndex, charIndex); - } - }); -})(); - -(function() { - var override = fabric.IText.prototype._getNewSelectionStartFromOffset; - fabric.IText.prototype._getNewSelectionStartFromOffset = function(mouseOffset, prevWidth, width, index, jlen) { - index = override.call(this, mouseOffset, prevWidth, width, index, jlen); - var tmp = 0, removed = 0; - for (var i = 0; i < this._textLines.length; i++) { - tmp += this._textLines[i].length; - if (tmp + removed >= index) { - break; - } - if (this.text[tmp + removed] === "\n" || this.text[tmp + removed] === " ") { - removed++; - } - } - return index - i + removed; - }; -})(); - -(function() { - if (typeof document !== "undefined" && typeof window !== "undefined") { - return; - } - var DOMParser = require("xmldom").DOMParser, URL = require("url"), HTTP = require("http"), HTTPS = require("https"), Canvas = require("canvas"), Image = require("canvas").Image; - function request(url, encoding, callback) { - var oURL = URL.parse(url); - if (!oURL.port) { - oURL.port = oURL.protocol.indexOf("https:") === 0 ? 443 : 80; - } - var reqHandler = oURL.protocol.indexOf("https:") === 0 ? HTTPS : HTTP, req = reqHandler.request({ - hostname: oURL.hostname, - port: oURL.port, - path: oURL.path, - method: "GET" - }, function(response) { - var body = ""; - if (encoding) { - response.setEncoding(encoding); - } - response.on("end", function() { - callback(body); - }); - response.on("data", function(chunk) { - if (response.statusCode === 200) { - body += chunk; - } - }); - }); - req.on("error", function(err) { - if (err.errno === process.ECONNREFUSED) { - fabric.log("ECONNREFUSED: connection refused to " + oURL.hostname + ":" + oURL.port); - } else { - fabric.log(err.message); - } - callback(null); - }); - req.end(); - } - function requestFs(path, callback) { - var fs = require("fs"); - fs.readFile(path, function(err, data) { - if (err) { - fabric.log(err); - throw err; - } else { - callback(data); - } - }); - } - fabric.util.loadImage = function(url, callback, context) { - function createImageAndCallBack(data) { - if (data) { - img.src = new Buffer(data, "binary"); - img._src = url; - callback && callback.call(context, img); - } else { - img = null; - callback && callback.call(context, null, true); - } - } - var img = new Image(); - if (url && (url instanceof Buffer || url.indexOf("data") === 0)) { - img.src = img._src = url; - callback && callback.call(context, img); - } else if (url && url.indexOf("http") !== 0) { - requestFs(url, createImageAndCallBack); - } else if (url) { - request(url, "binary", createImageAndCallBack); - } else { - callback && callback.call(context, url); - } - }; - fabric.loadSVGFromURL = function(url, callback, reviver) { - url = url.replace(/^\n\s*/, "").replace(/\?.*$/, "").trim(); - if (url.indexOf("http") !== 0) { - requestFs(url, function(body) { - fabric.loadSVGFromString(body.toString(), callback, reviver); - }); - } else { - request(url, "", function(body) { - fabric.loadSVGFromString(body, callback, reviver); - }); - } - }; - fabric.loadSVGFromString = function(string, callback, reviver) { - var doc = new DOMParser().parseFromString(string); - fabric.parseSVGDocument(doc.documentElement, function(results, options) { - callback && callback(results, options); - }, reviver); - }; - fabric.util.getScript = function(url, callback) { - request(url, "", function(body) { - eval(body); - callback && callback(); - }); - }; - fabric.Image.fromObject = function(object, callback) { - fabric.util.loadImage(object.src, function(img) { - var oImg = new fabric.Image(img); - oImg._initConfig(object); - oImg._initFilters(object.filters, function(filters) { - oImg.filters = filters || []; - oImg._initFilters(object.resizeFilters, function(resizeFilters) { - oImg.resizeFilters = resizeFilters || []; - callback && callback(oImg); - }); - }); - }); - }; - fabric.createCanvasForNode = function(width, height, options, nodeCanvasOptions) { - nodeCanvasOptions = nodeCanvasOptions || options; - var canvasEl = fabric.document.createElement("canvas"), nodeCanvas = new Canvas(width || 600, height || 600, nodeCanvasOptions); - canvasEl.style = {}; - canvasEl.width = nodeCanvas.width; - canvasEl.height = nodeCanvas.height; - var FabricCanvas = fabric.Canvas || fabric.StaticCanvas, fabricCanvas = new FabricCanvas(canvasEl, options); - fabricCanvas.contextContainer = nodeCanvas.getContext("2d"); - fabricCanvas.nodeCanvas = nodeCanvas; - fabricCanvas.Font = Canvas.Font; - return fabricCanvas; - }; - fabric.StaticCanvas.prototype.createPNGStream = function() { - return this.nodeCanvas.createPNGStream(); - }; - fabric.StaticCanvas.prototype.createJPEGStream = function(opts) { - return this.nodeCanvas.createJPEGStream(opts); - }; - var origSetWidth = fabric.StaticCanvas.prototype.setWidth; - fabric.StaticCanvas.prototype.setWidth = function(width, options) { - origSetWidth.call(this, width, options); - this.nodeCanvas.width = width; - return this; - }; - if (fabric.Canvas) { - fabric.Canvas.prototype.setWidth = fabric.StaticCanvas.prototype.setWidth; - } - var origSetHeight = fabric.StaticCanvas.prototype.setHeight; - fabric.StaticCanvas.prototype.setHeight = function(height, options) { - origSetHeight.call(this, height, options); - this.nodeCanvas.height = height; - return this; - }; - if (fabric.Canvas) { - fabric.Canvas.prototype.setHeight = fabric.StaticCanvas.prototype.setHeight; - } -})(); - -window.fabric = fabric; - -if (typeof define === "function" && define.amd) { - define([], function() { - return fabric; - }); -} \ No newline at end of file +var fabric=fabric||{version:"1.6.1"};if(typeof exports!=="undefined"){exports.fabric=fabric}if(typeof document!=="undefined"&&typeof window!=="undefined"){fabric.document=document;fabric.window=window;window.fabric=fabric}else{fabric.document=require("jsdom").jsdom("");if(fabric.document.createWindow){fabric.window=fabric.document.createWindow()}else{fabric.window=fabric.document.parentWindow}}fabric.isTouchSupported="ontouchstart"in fabric.document.documentElement;fabric.isLikelyNode=typeof Buffer!=="undefined"&&typeof window==="undefined";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.devicePixelRatio=fabric.window.devicePixelRatio||fabric.window.webkitDevicePixelRatio||fabric.window.mozDevicePixelRatio||1;(function(){function _removeEventListener(eventName,handler){if(!this.__eventListeners[eventName]){return}var eventListener=this.__eventListeners[eventName];if(handler){eventListener[eventListener.indexOf(handler)]=false}else{fabric.util.array.fill(eventListener,false)}}function observe(eventName,handler){if(!this.__eventListeners){this.__eventListeners={}}if(arguments.length===1){for(var prop in eventName){this.on(prop,eventName[prop])}}else{if(!this.__eventListeners[eventName]){this.__eventListeners[eventName]=[]}this.__eventListeners[eventName].push(handler)}return this}function stopObserving(eventName,handler){if(!this.__eventListeners){return}if(arguments.length===0){for(eventName in this.__eventListeners){_removeEventListener.call(this,eventName)}}else if(arguments.length===1&&typeof arguments[0]==="object"){for(var prop in eventName){_removeEventListener.call(this,prop,eventName[prop])}}else{_removeEventListener.call(this,eventName,handler)}return this}function fire(eventName,options){if(!this.__eventListeners){return}var listenersForEvent=this.__eventListeners[eventName];if(!listenersForEvent){return}for(var i=0,len=listenersForEvent.length;i-1},complexity:function(){return this.getObjects().reduce(function(memo,current){memo+=current.complexity?current.complexity():0;return memo},0)}};(function(global){var sqrt=Math.sqrt,atan2=Math.atan2,pow=Math.pow,abs=Math.abs,PiBy180=Math.PI/180;fabric.util={removeFromArray:function(array,value){var idx=array.indexOf(value);if(idx!==-1){array.splice(idx,1)}return array},getRandomInt:function(min,max){return Math.floor(Math.random()*(max-min+1))+min},degreesToRadians:function(degrees){return degrees*PiBy180},radiansToDegrees:function(radians){return radians/PiBy180},rotatePoint:function(point,origin,radians){point.subtractEquals(origin);var v=fabric.util.rotateVector(point,radians);return new fabric.Point(v.x,v.y).addEquals(origin)},rotateVector:function(vector,radians){var sin=Math.sin(radians),cos=Math.cos(radians),rx=vector.x*cos-vector.y*sin,ry=vector.x*sin+vector.y*cos;return{x:rx,y:ry}},transformPoint:function(p,t,ignoreOffset){if(ignoreOffset){return new fabric.Point(t[0]*p.x+t[2]*p.y,t[1]*p.x+t[3]*p.y)}return new fabric.Point(t[0]*p.x+t[2]*p.y+t[4],t[1]*p.x+t[3]*p.y+t[5])},makeBoundingBoxFromPoints:function(points){var xPoints=[points[0].x,points[1].x,points[2].x,points[3].x],minX=fabric.util.array.min(xPoints),maxX=fabric.util.array.max(xPoints),width=Math.abs(minX-maxX),yPoints=[points[0].y,points[1].y,points[2].y,points[3].y],minY=fabric.util.array.min(yPoints),maxY=fabric.util.array.max(yPoints),height=Math.abs(minY-maxY);return{left:minX,top:minY,width:width,height:height}},invertTransform:function(t){var a=1/(t[0]*t[3]-t[1]*t[2]),r=[a*t[3],-a*t[1],-a*t[2],a*t[0]],o=fabric.util.transformPoint({x:t[4],y:t[5]},r,true);r[4]=-o.x;r[5]=-o.y;return r},toFixed:function(number,fractionDigits){return parseFloat(Number(number).toFixed(fractionDigits))},parseUnit:function(value,fontSize){var unit=/\D{0,2}$/.exec(value),number=parseFloat(value);if(!fontSize){fontSize=fabric.Text.DEFAULT_SVG_FONT_SIZE}switch(unit[0]){case"mm":return number*fabric.DPI/25.4;case"cm":return number*fabric.DPI/2.54;case"in":return number*fabric.DPI;case"pt":return number*fabric.DPI/72;case"pc":return number*fabric.DPI/72*12;case"em":return number*fontSize;default:return number}},falseFunction:function(){return false},getKlass:function(type,namespace){type=fabric.util.string.camelize(type.charAt(0).toUpperCase()+type.slice(1));return fabric.util.resolveNamespace(namespace)[type]},resolveNamespace:function(namespace){if(!namespace){return fabric}var parts=namespace.split("."),len=parts.length,obj=global||fabric.window;for(var i=0;ix){x+=da[di++%dc];if(x>len){x=len}ctx[draw?"lineTo":"moveTo"](x,0);draw=!draw}ctx.restore()},createCanvasElement:function(canvasEl){canvasEl||(canvasEl=fabric.document.createElement("canvas"));if(!canvasEl.getContext&&typeof G_vmlCanvasManager!=="undefined"){G_vmlCanvasManager.initElement(canvasEl)}return canvasEl},createImage:function(){return fabric.isLikelyNode?new(require("canvas").Image):fabric.document.createElement("img")},createAccessors:function(klass){var proto=klass.prototype;for(var i=proto.stateProperties.length;i--;){var 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();receiver.clipTo(ctx);ctx.clip()},multiplyTransformMatrices:function(a,b,is2x2){return[a[0]*b[0]+a[2]*b[1],a[1]*b[0]+a[3]*b[1],a[0]*b[2]+a[2]*b[3],a[1]*b[2]+a[3]*b[3],is2x2?0:a[0]*b[4]+a[2]*b[5]+a[4],is2x2?0:a[1]*b[4]+a[3]*b[5]+a[5]]},qrDecompose:function(a){var angle=atan2(a[1],a[0]),denom=pow(a[0],2)+pow(a[1],2),scaleX=sqrt(denom),scaleY=(a[0]*a[3]-a[2]*a[1])/scaleX,skewX=atan2(a[0]*a[2]+a[1]*a[3],denom);return{angle:angle/PiBy180,scaleX:scaleX,scaleY:scaleY,skewX:skewX/PiBy180,skewY:0,translateX:a[4],translateY:a[5]}},customTransformMatrix:function(scaleX,scaleY,skewX){var skewMatrixX=[1,0,abs(Math.tan(skewX*PiBy180)),1],scaleMatrix=[abs(scaleX),0,0,abs(scaleY)];return fabric.util.multiplyTransformMatrices(scaleMatrix,skewMatrixX,true)},resetObjectTransform:function(target){target.scaleX=1;target.scaleY=1;target.skewX=0;target.skewY=0;target.flipX=false;target.flipY=false;target.setAngle(0)},getFunctionBody:function(fn){return(String(fn).match(/function[^{]*\{([\s\S]*)\}/)||{})[1]},isTransparent:function(ctx,x,y,tolerance){if(tolerance>0){if(x>tolerance){x-=tolerance}else{x=0}if(y>tolerance){y-=tolerance}else{y=0}}var _isTransparent=true,imageData=ctx.getImageData(x,y,tolerance*2||1,tolerance*2||1);for(var i=3,l=imageData.data.length;i0){dtheta-=2*PI}else if(sweep===1&&dtheta<0){dtheta+=2*PI}var segments=Math.ceil(Math.abs(dtheta/PI*2)),result=[],mDelta=dtheta/segments,mT=8/3*Math.sin(mDelta/4)*Math.sin(mDelta/4)/Math.sin(mDelta/2),th3=mTheta+mDelta;for(var i=0;i=ta){return tb-ta}else{return 2*Math.PI-(ta-tb)}}fabric.util.drawArc=function(ctx,fx,fy,coords){var rx=coords[0],ry=coords[1],rot=coords[2],large=coords[3],sweep=coords[4],tx=coords[5],ty=coords[6],segs=[[],[],[],[]],segsNorm=arcToSegments(tx-fx,ty-fy,rx,ry,large,sweep,rot);for(var i=0,len=segsNorm.length;i0){b=6*y0-12*y1+6*y2;a=-3*y0+9*y1-9*y2+3*y3;c=3*y1-3*y0}if(abs(a)<1e-12){if(abs(b)<1e-12){continue}t=-c/b;if(0>>0;if(len===0){return-1}var n=0;if(arguments.length>0){n=Number(arguments[1]);if(n!==n){n=0}else if(n!==0&&n!==Number.POSITIVE_INFINITY&&n!==Number.NEGATIVE_INFINITY){n=(n>0||-1)*Math.floor(Math.abs(n))}}if(n>=len){return-1}var k=n>=0?n:Math.max(len-Math.abs(n),0);for(;k>>0;i>>0;i>>0;i>>0;i>>0;i>>0,i=0,rv;if(arguments.length>1){rv=arguments[1]}else{do{if(i in this){rv=this[i++];break}if(++i>=len){throw new TypeError}}while(true)}for(;i=value2})}function min(array,byProperty){return find(array,byProperty,function(value1,value2){return value1/g,">")}fabric.util.string={camelize:camelize,capitalize:capitalize,escapeXml:escapeXml}})();(function(){var slice=Array.prototype.slice,apply=Function.prototype.apply,Dummy=function(){};if(!Function.prototype.bind){Function.prototype.bind=function(thisArg){var _this=this,args=slice.call(arguments,1),bound;if(args.length){bound=function(){return apply.call(_this,this instanceof Dummy?this:thisArg,args.concat(slice.call(arguments)))}}else{bound=function(){return apply.call(_this,this instanceof Dummy?this:thisArg,arguments)}}Dummy.prototype=this.prototype;bound.prototype=new Dummy;return bound}}})();(function(){var slice=Array.prototype.slice,emptyFunction=function(){},IS_DONTENUM_BUGGY=function(){for(var p in{toString:1}){if(p==="toString"){return false}}return true}(),addMethods=function(klass,source,parent){for(var property in source){if(property in klass.prototype&&typeof klass.prototype[property]==="function"&&(source[property]+"").indexOf("callSuper")>-1){klass.prototype[property]=function(property){return function(){var superclass=this.constructor.superclass;this.constructor.superclass=parent;var returnValue=source[property].apply(this,arguments);this.constructor.superclass=superclass;if(property!=="initialize"){return returnValue}}}(property)}else{klass.prototype[property]=source[property]}if(IS_DONTENUM_BUGGY){if(source.toString!==Object.prototype.toString){klass.prototype.toString=source.toString}if(source.valueOf!==Object.prototype.valueOf){klass.prototype.valueOf=source.valueOf}}}};function Subclass(){}function callSuper(methodName){var fn=this.constructor.superclass.prototype[methodName];return arguments.length>1?fn.apply(this,slice.call(arguments,1)):fn.call(this)}function createClass(){var parent=null,properties=slice.call(arguments,0);if(typeof properties[0]==="function"){parent=properties.shift()}function klass(){this.initialize.apply(this,arguments)}klass.superclass=parent;klass.subclasses=[];if(parent){Subclass.prototype=parent.prototype;klass.prototype=new Subclass;parent.subclasses.push(klass)}for(var i=0,length=properties.length;i-1?setOpacity(element,styles.match(/opacity:\s*(\d?\.?\d*)/)[1]):element}for(var property in styles){if(property==="opacity"){setOpacity(element,styles[property])}else{var normalizedProperty=property==="float"||property==="cssFloat"?typeof elementStyle.styleFloat==="undefined"?"cssFloat":"styleFloat":property;elementStyle[normalizedProperty]=styles[property]}}return element}var parseEl=fabric.document.createElement("div"),supportsOpacity=typeof parseEl.style.opacity==="string",supportsFilters=typeof parseEl.style.filter==="string",reOpacity=/alpha\s*\(\s*opacity\s*=\s*([^\)]+)\)/,setOpacity=function(element){return element};if(supportsOpacity){setOpacity=function(element,value){element.style.opacity=value;return element}}else if(supportsFilters){setOpacity=function(element,value){var es=element.style;if(element.currentStyle&&!element.currentStyle.hasLayout){es.zoom=1}if(reOpacity.test(es.filter)){value=value>=.9999?"":"alpha(opacity="+value*100+")";es.filter=es.filter.replace(reOpacity,value)}else{es.filter+=" alpha(opacity="+value*100+")"}return element}}fabric.util.setStyle=setStyle})();(function(){var _slice=Array.prototype.slice;function getById(id){return typeof id==="string"?fabric.document.getElementById(id):id}var sliceCanConvertNodelists,toArray=function(arrayLike){return _slice.call(arrayLike,0)};try{sliceCanConvertNodelists=toArray(fabric.document.childNodes)instanceof Array}catch(err){}if(!sliceCanConvertNodelists){toArray=function(arrayLike){var arr=new Array(arrayLike.length),i=arrayLike.length;while(i--){arr[i]=arrayLike[i]}return arr}}function makeElement(tagName,attributes){var el=fabric.document.createElement(tagName);for(var prop in attributes){if(prop==="class"){el.className=attributes[prop]}else if(prop==="for"){el.htmlFor=attributes[prop]}else{el.setAttribute(prop,attributes[prop])}}return el}function addClass(element,className){if(element&&(" "+element.className+" ").indexOf(" "+className+" ")===-1){element.className+=(element.className?" ":"")+className}}function wrapElement(element,wrapper,attributes){if(typeof wrapper==="string"){wrapper=makeElement(wrapper,attributes)}if(element.parentNode){element.parentNode.replaceChild(wrapper,element)}wrapper.appendChild(element);return wrapper}function getScrollLeftTop(element){var left=0,top=0,docElement=fabric.document.documentElement,body=fabric.document.body||{scrollLeft:0,scrollTop:0};while(element&&(element.parentNode||element.host)){element=element.parentNode||element.host;if(element===fabric.document){left=body.scrollLeft||docElement.scrollLeft||0;top=body.scrollTop||docElement.scrollTop||0}else{left+=element.scrollLeft||0;top+=element.scrollTop||0}if(element.nodeType===1&&fabric.util.getElementStyle(element,"position")==="fixed"){break}}return{left:left,top:top}}function getElementOffset(element){var docElem,doc=element&&element.ownerDocument,box={left:0,top:0},offset={left:0,top:0},scrollLeftTop,offsetAttributes={borderLeftWidth:"left",borderTopWidth:"top",paddingLeft:"left",paddingTop:"top"};if(!doc){return offset}for(var attr in offsetAttributes){offset[offsetAttributes[attr]]+=parseInt(getElementStyle(element,attr),10)||0}docElem=doc.documentElement;if(typeof element.getBoundingClientRect!=="undefined"){box=element.getBoundingClientRect()}scrollLeftTop=getScrollLeftTop(element);return{left:box.left+scrollLeftTop.left-(docElem.clientLeft||0)+offset.left,top:box.top+scrollLeftTop.top-(docElem.clientTop||0)+offset.top}}var getElementStyle;if(fabric.document.defaultView&&fabric.document.defaultView.getComputedStyle){getElementStyle=function(element,attr){var style=fabric.document.defaultView.getComputedStyle(element,null);return style?style[attr]:undefined}}else{getElementStyle=function(element,attr){var value=element.style[attr];if(!value&&element.currentStyle){value=element.currentStyle[attr]}return value}}(function(){var style=fabric.document.documentElement.style,selectProp="userSelect"in style?"userSelect":"MozUserSelect"in style?"MozUserSelect":"WebkitUserSelect"in style?"WebkitUserSelect":"KhtmlUserSelect"in style?"KhtmlUserSelect":"";function makeElementUnselectable(element){if(typeof element.onselectstart!=="undefined"){element.onselectstart=fabric.util.falseFunction}if(selectProp){element.style[selectProp]="none"}else if(typeof element.unselectable==="string"){element.unselectable="on"}return element}function makeElementSelectable(element){if(typeof element.onselectstart!=="undefined"){element.onselectstart=null}if(selectProp){element.style[selectProp]=""}else if(typeof element.unselectable==="string"){element.unselectable=""}return element}fabric.util.makeElementUnselectable=makeElementUnselectable;fabric.util.makeElementSelectable=makeElementSelectable})();(function(){function getScript(url,callback){var headEl=fabric.document.getElementsByTagName("head")[0],scriptEl=fabric.document.createElement("script"),loading=true;scriptEl.onload=scriptEl.onreadystatechange=function(e){if(loading){if(typeof this.readyState==="string"&&this.readyState!=="loaded"&&this.readyState!=="complete"){return}loading=false;callback(e||fabric.window.event);scriptEl=scriptEl.onload=scriptEl.onreadystatechange=null}};scriptEl.src=url;headEl.appendChild(scriptEl)}fabric.util.getScript=getScript})();fabric.util.getById=getById;fabric.util.toArray=toArray;fabric.util.makeElement=makeElement;fabric.util.addClass=addClass;fabric.util.wrapElement=wrapElement;fabric.util.getScrollLeftTop=getScrollLeftTop;fabric.util.getElementOffset=getElementOffset;fabric.util.getElementStyle=getElementStyle})();(function(){function addParamToUrl(url,param){return url+(/\?/.test(url)?"&":"?")+param}var makeXHR=function(){var factories=[function(){return new ActiveXObject("Microsoft.XMLHTTP")},function(){return new ActiveXObject("Msxml2.XMLHTTP")},function(){return new ActiveXObject("Msxml2.XMLHTTP.3.0")},function(){return new XMLHttpRequest}];for(var i=factories.length;i--;){try{var req=factories[i]();if(req){return factories[i]}}catch(err){}}}();function emptyFn(){}function request(url,options){options||(options={});var method=options.method?options.method.toUpperCase():"GET",onComplete=options.onComplete||function(){},xhr=makeXHR(),body;xhr.onreadystatechange=function(){if(xhr.readyState===4){onComplete(xhr);xhr.onreadystatechange=emptyFn}};if(method==="GET"){body=null; +if(typeof options.parameters==="string"){url=addParamToUrl(url,options.parameters)}}xhr.open(method,url,true);if(method==="POST"||method==="PUT"){xhr.setRequestHeader("Content-Type","application/x-www-form-urlencoded")}xhr.send(body);return xhr}fabric.util.request=request})();fabric.log=function(){};fabric.warn=function(){};if(typeof console!=="undefined"){["log","warn"].forEach(function(methodName){if(typeof console[methodName]!=="undefined"&&typeof console[methodName].apply==="function"){fabric[methodName]=function(){return console[methodName].apply(console,arguments)}}})}(function(){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){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();return}onChange(easing(currentTime,startValue,byValue,duration));if(time>finish){options.onComplete&&options.onComplete();return}requestAnimFrame(tick)})(start)})}var _requestAnimFrame=fabric.window.requestAnimationFrame||fabric.window.webkitRequestAnimationFrame||fabric.window.mozRequestAnimationFrame||fabric.window.oRequestAnimationFrame||fabric.window.msRequestAnimationFrame||function(callback){fabric.window.setTimeout(callback,1e3/60)};function requestAnimFrame(){return _requestAnimFrame.apply(fabric.window,arguments)}fabric.util.animate=animate;fabric.util.requestAnimFrame=requestAnimFrame})();(function(){function normalize(a,c,p,s){if(a1){matrices.shift();combinedMatrix=fabric.util.multiplyTransformMatrices(combinedMatrix,matrices[0])}return combinedMatrix}}();function parseStyleString(style,oStyle){var attr,value;style.replace(/;\s*$/,"").split(";").forEach(function(chunk){var pair=chunk.split(":");attr=normalizeAttr(pair[0].trim().toLowerCase());value=normalizeValue(attr,pair[1].trim());oStyle[attr]=value})}function parseStyleObject(style,oStyle){var attr,value;for(var prop in style){if(typeof style[prop]==="undefined"){continue}attr=normalizeAttr(prop.toLowerCase());value=normalizeValue(attr,style[prop]);oStyle[attr]=value}}function getGlobalStylesForElement(element,svgUid){var styles={};for(var rule in fabric.cssRules[svgUid]){if(elementMatchesRule(element,rule.split(" "))){for(var property in fabric.cssRules[svgUid][rule]){styles[property]=fabric.cssRules[svgUid][rule][property]}}}return styles}function elementMatchesRule(element,selectors){var firstMatching,parentMatching=true;firstMatching=selectorMatches(element,selectors.pop());if(firstMatching&&selectors.length){parentMatching=doesSomeParentMatch(element,selectors)}return firstMatching&&parentMatching&&selectors.length===0}function doesSomeParentMatch(element,selectors){var selector,parentMatching=true;while(element.parentNode&&element.parentNode.nodeType===1&&selectors.length){if(parentMatching){selector=selectors.pop()}element=element.parentNode;parentMatching=selectorMatches(element,selector)}return selectors.length===0}function selectorMatches(element,selector){var nodeName=element.nodeName,classNames=element.getAttribute("class"),id=element.getAttribute("id"),matcher;matcher=new RegExp("^"+nodeName,"i");selector=selector.replace(matcher,"");if(id&&selector.length){matcher=new RegExp("#"+id+"(?![a-zA-Z\\-]+)","i");selector=selector.replace(matcher,"")}if(classNames&&selector.length){classNames=classNames.split(" ");for(var i=classNames.length;i--;){matcher=new RegExp("\\."+classNames[i]+"(?![a-zA-Z\\-]+)","i");selector=selector.replace(matcher,"")}}return selector.length===0}function elementById(doc,id){var el;doc.getElementById&&(el=doc.getElementById(id));if(el){return el}var node,i,nodelist=doc.getElementsByTagName("*");for(i=0;iscaleY?scaleY:scaleX}if(scaleX===1&&scaleY===1&&minX===0&&minY===0&&x===0&&y===0){return parsedDim}if(x||y){translateMatrix=" translate("+parseUnit(x)+" "+parseUnit(y)+") "}matrix=translateMatrix+" matrix("+scaleX+" 0"+" 0 "+scaleY+" "+minX*scaleX+" "+minY*scaleY+") ";if(element.tagName==="svg"){el=element.ownerDocument.createElement("g");while(element.firstChild!=null){el.appendChild(element.firstChild)}element.appendChild(el)}else{el=element;matrix=el.getAttribute("transform")+matrix}el.setAttribute("transform",matrix);return parsedDim}fabric.parseSVGDocument=function(){function hasAncestorWithNodeName(element,nodeName){while(element&&(element=element.parentNode)){if(nodeName.test(element.nodeName)&&!element.getAttribute("instantiated_by_use")){return true}}return false}return function(doc,callback,reviver){if(!doc){return}parseUseDirectives(doc);var startTime=new Date,svgUid=fabric.Object.__uid++,options=applyViewboxTransform(doc),descendants=fabric.util.toArray(doc.getElementsByTagName("*"));options.svgUid=svgUid;if(descendants.length===0&&fabric.isLikelyNode){descendants=doc.selectNodes('//*[name(.)!="svg"]');var arr=[];for(var i=0,len=descendants.length;i\n',' \n \n')}}var reFontDeclaration=new RegExp("(normal|italic)?\\s*(normal|small-caps)?\\s*"+"(normal|bold|bolder|lighter|100|200|300|400|500|600|700|800|900)?\\s*("+fabric.reNum+"(?:px|cm|mm|em|pt|pc|in)*)(?:\\/(normal|"+fabric.reNum+"))?\\s+(.*)");extend(fabric,{parseFontDeclaration:function(value,oStyle){var match=value.match(reFontDeclaration);if(!match){return}var fontStyle=match[1],fontWeight=match[3],fontSize=match[4],lineHeight=match[5],fontFamily=match[6];if(fontStyle){oStyle.fontStyle=fontStyle}if(fontWeight){oStyle.fontWeight=isNaN(parseFloat(fontWeight))?fontWeight:parseFloat(fontWeight)}if(fontSize){oStyle.fontSize=parseUnit(fontSize)}if(fontFamily){oStyle.fontFamily=fontFamily}if(lineHeight){oStyle.lineHeight=lineHeight==="normal"?1:lineHeight}},getGradientDefs:function(doc){var linearGradientEls=doc.getElementsByTagName("linearGradient"),radialGradientEls=doc.getElementsByTagName("radialGradient"),el,i,j=0,id,xlink,elList=[],gradientDefs={},idsToXlinkMap={};elList.length=linearGradientEls.length+radialGradientEls.length;i=linearGradientEls.length;while(i--){elList[j++]=linearGradientEls[i]}i=radialGradientEls.length;while(i--){elList[j++]=radialGradientEls[i]}while(j--){el=elList[j];xlink=el.getAttribute("xlink:href");id=el.getAttribute("id");if(xlink){idsToXlinkMap[id]=xlink.substr(1)}gradientDefs[id]=el}for(id in idsToXlinkMap){var el2=gradientDefs[idsToXlinkMap[id]].cloneNode(true);el=gradientDefs[id];while(el2.firstChild){el.appendChild(el2.firstChild)}}return gradientDefs},parseAttributes:function(element,attributes,svgUid){if(!element){return}var value,parentAttributes={},fontSize;if(typeof svgUid==="undefined"){svgUid=element.getAttribute("svgUid")}if(element.parentNode&&reAllowedParents.test(element.parentNode.nodeName)){parentAttributes=fabric.parseAttributes(element.parentNode,attributes,svgUid)}fontSize=parentAttributes&&parentAttributes.fontSize||element.getAttribute("font-size")||fabric.Text.DEFAULT_SVG_FONT_SIZE;var ownAttributes=attributes.reduce(function(memo,attr){value=element.getAttribute(attr);if(value){attr=normalizeAttr(attr);value=normalizeValue(attr,value,parentAttributes,fontSize);memo[attr]=value}return memo},{});ownAttributes=extend(ownAttributes,extend(getGlobalStylesForElement(element,svgUid),fabric.parseStyleAttribute(element)));if(ownAttributes.font){fabric.parseFontDeclaration(ownAttributes.font,ownAttributes)}return _setStrokeFillOpacity(extend(parentAttributes,ownAttributes))},parseElements:function(elements,callback,options,reviver){new fabric.ElementsParser(elements,callback,options,reviver).parse()},parseStyleAttribute:function(element){var oStyle={},style=element.getAttribute("style");if(!style){return oStyle}if(typeof style==="string"){parseStyleString(style,oStyle)}else{parseStyleObject(style,oStyle)}return oStyle},parsePointsAttribute:function(points){if(!points){return null}points=points.replace(/,/g," ").trim();points=points.split(/\s+/);var parsedPoints=[],i,len;i=0;len=points.length;for(;i/i,""))}if(!xml||!xml.documentElement){return}fabric.parseSVGDocument(xml.documentElement,function(results,options){svgCache.set(url,{objects:fabric.util.array.invoke(results,"toObject"),options:options});callback(results,options)},reviver)}},loadSVGFromString:function(string,callback,reviver){string=string.trim();var doc;if(typeof DOMParser!=="undefined"){var parser=new DOMParser;if(parser&&parser.parseFromString){doc=parser.parseFromString(string,"text/xml")}}else if(fabric.window.ActiveXObject){doc=new ActiveXObject("Microsoft.XMLDOM");doc.async="false";doc.loadXML(string.replace(//i,""))}fabric.parseSVGDocument(doc.documentElement,function(results,options){callback(results,options)},reviver)},createSVGFontFacesMarkup:function(objects){var markup="",fontList={},obj,fontFamily,style,row,rowIndex,char,charIndex,fontPaths=fabric.fontPaths;for(var i=0,len=objects.length;i',"","\n"].join("")}return markup},createSVGRefElementsMarkup:function(canvas){var markup=[];_createSVGPattern(markup,canvas,"backgroundColor");_createSVGPattern(markup,canvas,"overlayColor");return markup.join("")}})})(typeof exports!=="undefined"?exports:this);fabric.ElementsParser=function(elements,callback,options,reviver){this.elements=elements;this.callback=callback;this.options=options;this.reviver=reviver;this.svgUid=options&&options.svgUid||0};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 i=0,len=this.elements.length;ithat.x&&this.y>that.y},gte:function(that){return this.x>=that.x&&this.y>=that.y},lerp:function(that,t){return new Point(this.x+(that.x-this.x)*t,this.y+(that.y-this.y)*t)},distanceFrom:function(that){var dx=this.x-that.x,dy=this.y-that.y;return Math.sqrt(dx*dx+dy*dy)},midPointFrom:function(that){return new Point(this.x+(that.x-this.x)/2,this.y+(that.y-this.y)/2)},min:function(that){return new Point(Math.min(this.x,that.x),Math.min(this.y,that.y))},max:function(that){return new Point(Math.max(this.x,that.x),Math.max(this.y,that.y))},toString:function(){return this.x+","+this.y},setXY:function(x,y){this.x=x;this.y=y},setFromPoint:function(that){this.x=that.x;this.y=that.y},swap:function(that){var x=this.x,y=this.y;this.x=that.x;this.y=that.y;that.x=x;that.y=y}}})(typeof exports!=="undefined"?exports:this);(function(global){"use strict";var fabric=global.fabric||(global.fabric={});if(fabric.Intersection){fabric.warn("fabric.Intersection is already defined");return}function Intersection(status){this.status=status;this.points=[]}fabric.Intersection=Intersection;fabric.Intersection.prototype={appendPoint:function(point){this.points.push(point)},appendPoints:function(points){this.points=this.points.concat(points)}};fabric.Intersection.intersectLineLine=function(a1,a2,b1,b2){var result,uaT=(b2.x-b1.x)*(a1.y-b1.y)-(b2.y-b1.y)*(a1.x-b1.x),ubT=(a2.x-a1.x)*(a1.y-b1.y)-(a2.y-a1.y)*(a1.x-b1.x),uB=(b2.y-b1.y)*(a2.x-a1.x)-(b2.x-b1.x)*(a2.y-a1.y);if(uB!==0){var ua=uaT/uB,ub=ubT/uB;if(0<=ua&&ua<=1&&0<=ub&&ub<=1){result=new Intersection("Intersection");result.points.push(new fabric.Point(a1.x+ua*(a2.x-a1.x),a1.y+ua*(a2.y-a1.y)))}else{result=new Intersection}}else{if(uaT===0||ubT===0){result=new Intersection("Coincident")}else{result=new Intersection("Parallel")}}return result};fabric.Intersection.intersectLinePolygon=function(a1,a2,points){var result=new Intersection,length=points.length;for(var i=0;i0){result.status="Intersection"}return result};fabric.Intersection.intersectPolygonPolygon=function(points1,points2){var result=new Intersection,length=points1.length;for(var i=0;i0){result.status="Intersection"}return result};fabric.Intersection.intersectPolygonRectangle=function(points,r1,r2){var min=r1.min(r2),max=r1.max(r2),topRight=new fabric.Point(max.x,min.y),bottomLeft=new fabric.Point(min.x,max.y),inter1=Intersection.intersectLinePolygon(min,topRight,points),inter2=Intersection.intersectLinePolygon(topRight,max,points),inter3=Intersection.intersectLinePolygon(max,bottomLeft,points),inter4=Intersection.intersectLinePolygon(bottomLeft,min,points),result=new Intersection;result.appendPoints(inter1.points);result.appendPoints(inter2.points);result.appendPoints(inter3.points);result.appendPoints(inter4.points);if(result.points.length>0){result.status="Intersection"}return result}})(typeof exports!=="undefined"?exports:this);(function(global){"use strict";var fabric=global.fabric||(global.fabric={});if(fabric.Color){fabric.warn("fabric.Color is already defined.");return}function Color(color){if(!color){this.setSource([0,0,0,1])}else{this._tryParsingColor(color)}}fabric.Color=Color;fabric.Color.prototype={_tryParsingColor:function(color){var source;if(color in Color.colorNameMap){color=Color.colorNameMap[color] +}if(color==="transparent"){this.setSource([255,255,255,0]);return}source=Color.sourceFromHex(color);if(!source){source=Color.sourceFromRgb(color)}if(!source){source=Color.sourceFromHsl(color)}if(source){this.setSource(source)}},_rgbToHsl:function(r,g,b){r/=255,g/=255,b/=255;var h,s,l,max=fabric.util.array.max([r,g,b]),min=fabric.util.array.min([r,g,b]);l=(max+min)/2;if(max===min){h=s=0}else{var d=max-min;s=l>.5?d/(2-max-min):d/(max+min);switch(max){case r:h=(g-b)/d+(g1){t-=1}if(t<1/6){return p+(q-p)*6*t}if(t<1/2){return q}if(t<2/3){return p+(q-p)*(2/3-t)*6}return p}fabric.Color.fromRgb=function(color){return Color.fromSource(Color.sourceFromRgb(color))};fabric.Color.sourceFromRgb=function(color){var match=color.match(Color.reRGBa);if(match){var r=parseInt(match[1],10)/(/%$/.test(match[1])?100:1)*(/%$/.test(match[1])?255:1),g=parseInt(match[2],10)/(/%$/.test(match[2])?100:1)*(/%$/.test(match[2])?255:1),b=parseInt(match[3],10)/(/%$/.test(match[3])?100:1)*(/%$/.test(match[3])?255:1);return[parseInt(r,10),parseInt(g,10),parseInt(b,10),match[4]?parseFloat(match[4]):1]}};fabric.Color.fromRgba=Color.fromRgb;fabric.Color.fromHsl=function(color){return Color.fromSource(Color.sourceFromHsl(color))};fabric.Color.sourceFromHsl=function(color){var match=color.match(Color.reHSLa);if(!match){return}var h=(parseFloat(match[1])%360+360)%360/360,s=parseFloat(match[2])/(/%$/.test(match[2])?100:1),l=parseFloat(match[3])/(/%$/.test(match[3])?100:1),r,g,b;if(s===0){r=g=b=l}else{var q=l<=.5?l*(s+1):l+s-l*s,p=l*2-q;r=hue2rgb(p,q,h+1/3);g=hue2rgb(p,q,h);b=hue2rgb(p,q,h-1/3)}return[Math.round(r*255),Math.round(g*255),Math.round(b*255),match[4]?parseFloat(match[4]):1]};fabric.Color.fromHsla=Color.fromHsl;fabric.Color.fromHex=function(color){return Color.fromSource(Color.sourceFromHex(color))};fabric.Color.sourceFromHex=function(color){if(color.match(Color.reHex)){var value=color.slice(color.indexOf("#")+1),isShortNotation=value.length===3,r=isShortNotation?value.charAt(0)+value.charAt(0):value.substring(0,2),g=isShortNotation?value.charAt(1)+value.charAt(1):value.substring(2,4),b=isShortNotation?value.charAt(2)+value.charAt(2):value.substring(4,6);return[parseInt(r,16),parseInt(g,16),parseInt(b,16),1]}};fabric.Color.fromSource=function(source){var oColor=new Color;oColor.setSource(source);return oColor}})(typeof exports!=="undefined"?exports:this);(function(){function getColorStop(el){var style=el.getAttribute("style"),offset=el.getAttribute("offset")||0,color,colorAlpha,opacity;offset=parseFloat(offset)/(/%$/.test(offset)?100:1);offset=offset<0?0:offset>1?1:offset;if(style){var keyValuePairs=style.split(/\s*;\s*/);if(keyValuePairs[keyValuePairs.length-1]===""){keyValuePairs.pop()}for(var i=keyValuePairs.length;i--;){var split=keyValuePairs[i].split(/\s*:\s*/),key=split[0].trim(),value=split[1].trim();if(key==="stop-color"){color=value}else if(key==="stop-opacity"){opacity=value}}}if(!color){color=el.getAttribute("stop-color")||"rgb(0,0,0)"}if(!opacity){opacity=el.getAttribute("stop-opacity")}color=new fabric.Color(color);colorAlpha=color.getAlpha();opacity=isNaN(parseFloat(opacity))?1:parseFloat(opacity);opacity*=colorAlpha;return{offset:offset,color:color.toRgb(),opacity:opacity}}function getLinearCoords(el){return{x1:el.getAttribute("x1")||0,y1:el.getAttribute("y1")||0,x2:el.getAttribute("x2")||"100%",y2:el.getAttribute("y2")||0}}function getRadialCoords(el){return{x1:el.getAttribute("fx")||el.getAttribute("cx")||"50%",y1:el.getAttribute("fy")||el.getAttribute("cy")||"50%",r1:0,x2:el.getAttribute("cx")||"50%",y2:el.getAttribute("cy")||"50%",r2:el.getAttribute("r")||"50%"}}fabric.Gradient=fabric.util.createClass({offsetX:0,offsetY:0,initialize:function(options){options||(options={});var coords={};this.id=fabric.Object.__uid++;this.type=options.type||"linear";coords={x1:options.coords.x1||0,y1:options.coords.y1||0,x2:options.coords.x2||0,y2:options.coords.y2||0};if(this.type==="radial"){coords.r1=options.coords.r1||0;coords.r2=options.coords.r2||0}this.coords=coords;this.colorStops=options.colorStops.slice();if(options.gradientTransform){this.gradientTransform=options.gradientTransform}this.offsetX=options.offsetX||this.offsetX;this.offsetY=options.offsetY||this.offsetY},addColorStop:function(colorStop){for(var position in colorStop){var color=new fabric.Color(colorStop[position]);this.colorStops.push({offset:position,color:color.toRgb(),opacity:color.getAlpha()})}return this},toObject:function(){return{type:this.type,coords:this.coords,colorStops:this.colorStops,offsetX:this.offsetX,offsetY:this.offsetY,gradientTransform:this.gradientTransform?this.gradientTransform.concat():this.gradientTransform}},toSVG:function(object){var coords=fabric.util.object.clone(this.coords),markup,commonAttributes;this.colorStops.sort(function(a,b){return a.offset-b.offset});if(!(object.group&&object.group.type==="path-group")){for(var prop in coords){if(prop==="x1"||prop==="x2"||prop==="r2"){coords[prop]+=this.offsetX-object.width/2}else if(prop==="y1"||prop==="y2"){coords[prop]+=this.offsetY-object.height/2}}}commonAttributes='id="SVGID_'+this.id+'" gradientUnits="userSpaceOnUse"';if(this.gradientTransform){commonAttributes+=' gradientTransform="matrix('+this.gradientTransform.join(" ")+')" '}if(this.type==="linear"){markup=["\n']}else if(this.type==="radial"){markup=["\n']}for(var i=0;i\n')}markup.push(this.type==="linear"?"\n":"\n");return markup.join("")},toLive:function(ctx,object){var gradient,prop,coords=fabric.util.object.clone(this.coords);if(!this.type){return}if(object.group&&object.group.type==="path-group"){for(prop in coords){if(prop==="x1"||prop==="x2"){coords[prop]+=-this.offsetX+object.width/2}else if(prop==="y1"||prop==="y2"){coords[prop]+=-this.offsetY+object.height/2}}}if(this.type==="linear"){gradient=ctx.createLinearGradient(coords.x1,coords.y1,coords.x2,coords.y2)}else if(this.type==="radial"){gradient=ctx.createRadialGradient(coords.x1,coords.y1,coords.r1,coords.x2,coords.y2,coords.r2)}for(var i=0,len=this.colorStops.length;i\n'+'\n'+"\n"},toLive:function(ctx){var source=typeof this.source==="function"?this.source():this.source;if(!source){return""}if(typeof source.src!=="undefined"){if(!source.complete){return""}if(source.naturalWidth===0||source.naturalHeight===0){return""}}return ctx.createPattern(source,this.repeat)}});(function(global){"use strict";var fabric=global.fabric||(global.fabric={}),toFixed=fabric.util.toFixed;if(fabric.Shadow){fabric.warn("fabric.Shadow is already defined.");return}fabric.Shadow=fabric.util.createClass({color:"rgb(0,0,0)",blur:0,offsetX:0,offsetY:0,affectStroke:false,includeDefaultValues:true,initialize:function(options){if(typeof options==="string"){options=this._parseShadow(options)}for(var prop in options){this[prop]=options[prop]}this.id=fabric.Object.__uid++},_parseShadow:function(shadow){var shadowStr=shadow.trim(),offsetsAndBlur=fabric.Shadow.reOffsetsAndBlur.exec(shadowStr)||[],color=shadowStr.replace(fabric.Shadow.reOffsetsAndBlur,"")||"rgb(0,0,0)";return{color:color.trim(),offsetX:parseInt(offsetsAndBlur[1],10)||0,offsetY:parseInt(offsetsAndBlur[2],10)||0,blur:parseInt(offsetsAndBlur[3],10)||0}},toString:function(){return[this.offsetX,this.offsetY,this.blur,this.color].join("px ")},toSVG:function(object){var fBoxX=40,fBoxY=40,NUM_FRACTION_DIGITS=fabric.Object.NUM_FRACTION_DIGITS,offset=fabric.util.rotateVector({x:this.offsetX,y:this.offsetY},fabric.util.degreesToRadians(-object.angle)),BLUR_BOX=20;if(object.width&&object.height){fBoxX=toFixed((Math.abs(offset.x)+this.blur)/object.width,NUM_FRACTION_DIGITS)*100+BLUR_BOX;fBoxY=toFixed((Math.abs(offset.y)+this.blur)/object.height,NUM_FRACTION_DIGITS)*100+BLUR_BOX}if(object.flipX){offset.x*=-1}if(object.flipY){offset.y*=-1}return'\n"+' \n'+' \n'+' \n'+' \n'+" \n"+" \n"+' \n'+" \n"+"\n"},toObject:function(){if(this.includeDefaultValues){return{color:this.color,blur:this.blur,offsetX:this.offsetX,offsetY:this.offsetY,affectStroke:this.affectStroke}}var obj={},proto=fabric.Shadow.prototype;["color","blur","offsetX","offsetY","affectStroke"].forEach(function(prop){if(this[prop]!==proto[prop]){obj[prop]=this[prop]}},this);return obj}});fabric.Shadow.reOffsetsAndBlur=/(?:\s|^)(-?\d+(?:px)?(?:\s?|$))?(-?\d+(?:px)?(?:\s?|$))?(\d+(?:px)?)?(?:\s?|$)(?:$|\s)/})(typeof exports!=="undefined"?exports:this);(function(){"use strict";if(fabric.StaticCanvas){fabric.warn("fabric.StaticCanvas is already defined.");return}var extend=fabric.util.object.extend,getElementOffset=fabric.util.getElementOffset,removeFromArray=fabric.util.removeFromArray,toFixed=fabric.util.toFixed,CANVAS_INIT_ERROR=new Error("Could not initialize `canvas` element");fabric.StaticCanvas=fabric.util.createClass({initialize:function(el,options){options||(options={});this._initStatic(el,options)},backgroundColor:"",backgroundImage:null,overlayColor:"",overlayImage:null,includeDefaultValues:true,stateful:true,renderOnAddRemove:true,clipTo:null,controlsAboveOverlay:false,allowTouchScrolling:false,imageSmoothingEnabled:true,preserveObjectStacking:false,viewportTransform:[1,0,0,1,0,0],onBeforeScaleRotate:function(){},enableRetinaScaling:true,_initStatic:function(el,options){this._objects=[];this._createLowerCanvas(el);this._initOptions(options);this._setImageSmoothing();if(!this.interactive){this._initRetinaScaling()}if(options.overlayImage){this.setOverlayImage(options.overlayImage,this.renderAll.bind(this))}if(options.backgroundImage){this.setBackgroundImage(options.backgroundImage,this.renderAll.bind(this))}if(options.backgroundColor){this.setBackgroundColor(options.backgroundColor,this.renderAll.bind(this))}if(options.overlayColor){this.setOverlayColor(options.overlayColor,this.renderAll.bind(this))}this.calcOffset()},_isRetinaScaling:function(){return fabric.devicePixelRatio!==1&&this.enableRetinaScaling},_initRetinaScaling:function(){if(!this._isRetinaScaling()){return}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(){this._offset=getElementOffset(this.lowerCanvasEl);return this},setOverlayImage:function(image,callback,options){return this.__setBgOverlayImage("overlayImage",image,callback,options)},setBackgroundImage:function(image,callback,options){return this.__setBgOverlayImage("backgroundImage",image,callback,options)},setOverlayColor:function(overlayColor,callback){return this.__setBgOverlayColor("overlayColor",overlayColor,callback)},setBackgroundColor:function(backgroundColor,callback){return this.__setBgOverlayColor("backgroundColor",backgroundColor,callback)},_setImageSmoothing:function(){var ctx=this.getContext();ctx.imageSmoothingEnabled=ctx.imageSmoothingEnabled||ctx.webkitImageSmoothingEnabled||ctx.mozImageSmoothingEnabled||ctx.msImageSmoothingEnabled||ctx.oImageSmoothingEnabled;ctx.imageSmoothingEnabled=this.imageSmoothingEnabled},__setBgOverlayImage:function(property,image,callback,options){if(typeof image==="string"){fabric.util.loadImage(image,function(img){this[property]=new fabric.Image(img,options);callback&&callback(img)},this,options&&options.crossOrigin)}else{options&&image.setOptions(options);this[property]=image;callback&&callback(image)}return this},__setBgOverlayColor:function(property,color,callback){if(color&&color.source){var _this=this;fabric.util.loadImage(color.source,function(img){_this[property]=new fabric.Pattern({source:img,repeat:color.repeat,offsetX:color.offsetX,offsetY:color.offsetY});callback&&callback()})}else{this[property]=color;callback&&callback()}return this},_createCanvasElement:function(){var element=fabric.document.createElement("canvas");if(!element.style){element.style={}}if(!element){throw CANVAS_INIT_ERROR}this._initCanvasElement(element);return element},_initCanvasElement:function(element){fabric.util.createCanvasElement(element);if(typeof element.getContext==="undefined"){throw CANVAS_INIT_ERROR}},_initOptions:function(options){for(var prop in options){this[prop]=options[prop]}this.width=this.width||parseInt(this.lowerCanvasEl.width,10)||0;this.height=this.height||parseInt(this.lowerCanvasEl.height,10)||0;if(!this.lowerCanvasEl.style){return}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(canvasEl){this.lowerCanvasEl=fabric.util.getById(canvasEl)||this._createCanvasElement();this._initCanvasElement(this.lowerCanvasEl);fabric.util.addClass(this.lowerCanvasEl,"lower-canvas");if(this.interactive){this._applyCanvasStyle(this.lowerCanvasEl)}this.contextContainer=this.lowerCanvasEl.getContext("2d")},getWidth:function(){return this.width},getHeight:function(){return this.height},setWidth:function(value,options){return this.setDimensions({width:value},options)},setHeight:function(value,options){return this.setDimensions({height:value},options)},setDimensions:function(dimensions,options){var cssValue;options=options||{};for(var prop in dimensions){cssValue=dimensions[prop];if(!options.cssOnly){this._setBackstoreDimension(prop,dimensions[prop]);cssValue+="px"}if(!options.backstoreOnly){this._setCssDimension(prop,cssValue)}}this._initRetinaScaling();this._setImageSmoothing();this.calcOffset();if(!options.cssOnly){this.renderAll()}return this},_setBackstoreDimension:function(prop,value){this.lowerCanvasEl[prop]=value;if(this.upperCanvasEl){this.upperCanvasEl[prop]=value}if(this.cacheCanvasEl){this.cacheCanvasEl[prop]=value}this[prop]=value;return this},_setCssDimension:function(prop,value){this.lowerCanvasEl.style[prop]=value;if(this.upperCanvasEl){this.upperCanvasEl.style[prop]=value}if(this.wrapperEl){this.wrapperEl.style[prop]=value}return this},getZoom:function(){return Math.sqrt(this.viewportTransform[0]*this.viewportTransform[3])},setViewportTransform:function(vpt){var activeGroup=this.getActiveGroup();this.viewportTransform=vpt;this.renderAll();for(var i=0,len=this._objects.length;i");return markup.join("")},_setSVGPreamble:function(markup,options){if(options.suppressPreamble){return}markup.push('\n','\n')},_setSVGHeader:function(markup,options){var width=options.width||this.width,height=options.height||this.height,vpt,viewBox='viewBox="0 0 '+this.width+" "+this.height+'" ',NUM_FRACTION_DIGITS=fabric.Object.NUM_FRACTION_DIGITS;if(options.viewBox){viewBox='viewBox="'+options.viewBox.x+" "+options.viewBox.y+" "+options.viewBox.width+" "+options.viewBox.height+'" '}else{if(this.svgViewportTransformation){vpt=this.viewportTransform;viewBox='viewBox="'+toFixed(-vpt[4]/vpt[0],NUM_FRACTION_DIGITS)+" "+toFixed(-vpt[5]/vpt[3],NUM_FRACTION_DIGITS)+" "+toFixed(this.width/vpt[0],NUM_FRACTION_DIGITS)+" "+toFixed(this.height/vpt[3],NUM_FRACTION_DIGITS)+'" '}}markup.push("\n',"Created with Fabric.js ",fabric.version,"\n","",fabric.createSVGFontFacesMarkup(this.getObjects()),fabric.createSVGRefElementsMarkup(this),"\n")},_setSVGObjects:function(markup,reviver){for(var i=0,objects=this.getObjects(),len=objects.length;i\n")}else if(this[property]&&property==="overlayColor"){markup.push('\n")}},sendToBack:function(object){if(!object){return this}var activeGroup=this.getActiveGroup?this.getActiveGroup():null,i,obj,objs;if(object===activeGroup){objs=activeGroup._objects;for(i=objs.length;i--;){obj=objs[i];removeFromArray(this._objects,obj); +this._objects.unshift(obj)}}else{removeFromArray(this._objects,object);this._objects.unshift(object)}return this.renderAll&&this.renderAll()},bringToFront:function(object){if(!object){return this}var activeGroup=this.getActiveGroup?this.getActiveGroup():null,i,obj,objs;if(object===activeGroup){objs=activeGroup._objects;for(i=0;i=0;--i){var isIntersecting=object.intersectsWithObject(this._objects[i])||object.isContainedWithinObject(this._objects[i])||this._objects[i].isContainedWithinObject(object);if(isIntersecting){newIdx=i;break}}}else{newIdx=idx-1}return newIdx},bringForward:function(object,intersecting){if(!object){return this}var activeGroup=this.getActiveGroup?this.getActiveGroup():null,i,obj,idx,newIdx,objs;if(object===activeGroup){objs=activeGroup._objects;for(i=objs.length;i--;){obj=objs[i];idx=this._objects.indexOf(obj);if(idx!==this._objects.length-1){newIdx=idx+1;removeFromArray(this._objects,obj);this._objects.splice(newIdx,0,obj)}}}else{idx=this._objects.indexOf(object);if(idx!==this._objects.length-1){newIdx=this._findNewUpperIndex(object,idx,intersecting);removeFromArray(this._objects,object);this._objects.splice(newIdx,0,object)}}this.renderAll&&this.renderAll();return this},_findNewUpperIndex:function(object,idx,intersecting){var newIdx;if(intersecting){newIdx=idx;for(var i=idx+1;i"}});extend(fabric.StaticCanvas.prototype,fabric.Observable);extend(fabric.StaticCanvas.prototype,fabric.Collection);extend(fabric.StaticCanvas.prototype,fabric.DataURLExporter);extend(fabric.StaticCanvas,{EMPTY_JSON:'{"objects": [], "background": "white"}',supports:function(methodName){var el=fabric.util.createCanvasElement();if(!el||!el.getContext){return null}var ctx=el.getContext("2d");if(!ctx){return null}switch(methodName){case"getImageData":return typeof ctx.getImageData!=="undefined";case"setLineDash":return typeof ctx.setLineDash!=="undefined";case"toDataURL":return typeof el.toDataURL!=="undefined";case"toDataURLWithQuality":try{el.toDataURL("image/jpeg",0);return true}catch(e){}return false;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(options){this.shadow=new fabric.Shadow(options);return this},_setBrushStyles:function(){var ctx=this.canvas.contextTop;ctx.strokeStyle=this.color;ctx.lineWidth=this.width;ctx.lineCap=this.strokeLineCap;ctx.lineJoin=this.strokeLineJoin;if(this.strokeDashArray&&fabric.StaticCanvas.supports("setLineDash")){ctx.setLineDash(this.strokeDashArray)}},_setShadow:function(){if(!this.shadow){return}var ctx=this.canvas.contextTop;ctx.shadowColor=this.shadow.color;ctx.shadowBlur=this.shadow.blur;ctx.shadowOffsetX=this.shadow.offsetX;ctx.shadowOffsetY=this.shadow.offsetY},_resetShadow:function(){var ctx=this.canvas.contextTop;ctx.shadowColor="";ctx.shadowBlur=ctx.shadowOffsetX=ctx.shadowOffsetY=0}});(function(){fabric.PencilBrush=fabric.util.createClass(fabric.BaseBrush,{initialize:function(canvas){this.canvas=canvas;this._points=[]},onMouseDown:function(pointer){this._prepareForDrawing(pointer);this._captureDrawingPath(pointer);this._render()},onMouseMove:function(pointer){this._captureDrawingPath(pointer);this.canvas.clearContext(this.canvas.contextTop);this._render()},onMouseUp:function(){this._finalizeAndAddPath()},_prepareForDrawing:function(pointer){var p=new fabric.Point(pointer.x,pointer.y);this._reset();this._addPoint(p);this.canvas.contextTop.moveTo(p.x,p.y)},_addPoint:function(point){this._points.push(point)},_reset:function(){this._points.length=0;this._setBrushStyles();this._setShadow()},_captureDrawingPath:function(pointer){var pointerPoint=new fabric.Point(pointer.x,pointer.y);this._addPoint(pointerPoint)},_render:function(){var ctx=this.canvas.contextTop,v=this.canvas.viewportTransform,p1=this._points[0],p2=this._points[1];ctx.save();ctx.transform(v[0],v[1],v[2],v[3],v[4],v[5]);ctx.beginPath();if(this._points.length===2&&p1.x===p2.x&&p1.y===p2.y){p1.x-=.5;p2.x+=.5}ctx.moveTo(p1.x,p1.y);for(var i=1,len=this._points.length;i0?1:-1;if(by==="y"){skew=t.target.skewY;originA="top";originB="bottom";property="originY"}origins[-1]=originA;origins[1]=originB;t.target.flipX&&(flipSign*=-1);t.target.flipY&&(flipSign*=-1);if(skew===0){t.skewSign=-corner*mouseMove*flipSign;t[property]=origins[-mouseMove]}else{skew=skew>0?1:-1;t.skewSign=skew;t[property]=origins[skew*corner*flipSign]}},_skewObject:function(x,y,by){var t=this._currentTransform,target=t.target,skewed=false,lockSkewingX=target.get("lockSkewingX"),lockSkewingY=target.get("lockSkewingY");if(lockSkewingX&&by==="x"||lockSkewingY&&by==="y"){return false}var center=target.getCenterPoint(),actualMouseByCenter=target.toLocalPoint(new fabric.Point(x,y),"center","center")[by],lastMouseByCenter=target.toLocalPoint(new fabric.Point(t.lastX,t.lastY),"center","center")[by],actualMouseByOrigin,constraintPosition,dim=target._getTransformedDimensions();this._changeSkewTransformOrigin(actualMouseByCenter-lastMouseByCenter,t,by);actualMouseByOrigin=target.toLocalPoint(new fabric.Point(x,y),t.originX,t.originY)[by],constraintPosition=target.translateToOriginPoint(center,t.originX,t.originY);skewed=this._setObjectSkew(actualMouseByOrigin,t,by,dim);t.lastX=x;t.lastY=y;target.setPositionByOrigin(constraintPosition,t.originX,t.originY);return skewed},_setObjectSkew:function(localMouse,transform,by,_dim){var target=transform.target,newValue,skewed=false,skewSign=transform.skewSign,newDim,dimNoSkew,otherBy,_otherBy,_by,newDimMouse,skewX,skewY;if(by==="x"){otherBy="y";_otherBy="Y";_by="X";skewX=0;skewY=target.skewY}else{otherBy="x";_otherBy="X";_by="Y";skewX=target.skewX;skewY=0}dimNoSkew=target._getTransformedDimensions(skewX,skewY);newDimMouse=2*Math.abs(localMouse)-dimNoSkew[by];if(newDimMouse<=2){newValue=0}else{newValue=skewSign*Math.atan(newDimMouse/target["scale"+_by]/(dimNoSkew[otherBy]/target["scale"+_otherBy]));newValue=fabric.util.radiansToDegrees(newValue)}skewed=target["skew"+_by]!==newValue;target.set("skew"+_by,newValue);if(target["skew"+_otherBy]!==0){newDim=target._getTransformedDimensions();newValue=_dim[otherBy]/newDim[otherBy]*target["scale"+_otherBy];target.set("scale"+_otherBy,newValue)}return skewed},_scaleObject:function(x,y,by){var t=this._currentTransform,target=t.target,lockScalingX=target.get("lockScalingX"),lockScalingY=target.get("lockScalingY"),lockScalingFlip=target.get("lockScalingFlip");if(lockScalingX&&lockScalingY){return false}var constraintPosition=target.translateToOriginPoint(target.getCenterPoint(),t.originX,t.originY),localMouse=target.toLocalPoint(new fabric.Point(x,y),t.originX,t.originY),dim=target._getTransformedDimensions(),scaled=false;this._setLocalMouse(localMouse,t);scaled=this._setObjectScale(localMouse,t,lockScalingX,lockScalingY,by,lockScalingFlip,dim);target.setPositionByOrigin(constraintPosition,t.originX,t.originY);return scaled},_setObjectScale:function(localMouse,transform,lockScalingX,lockScalingY,by,lockScalingFlip,_dim){var target=transform.target,forbidScalingX=false,forbidScalingY=false,scaled=false,changeX,changeY,scaleX,scaleY;scaleX=localMouse.x*target.scaleX/_dim.x;scaleY=localMouse.y*target.scaleY/_dim.y;changeX=target.scaleX!==scaleX;changeY=target.scaleY!==scaleY;if(lockScalingFlip&&scaleX<=0&&scaleXtarget.padding){if(localMouse.x<0){localMouse.x+=target.padding}else{localMouse.x-=target.padding}}else{localMouse.x=0}if(abs(localMouse.y)>target.padding){if(localMouse.y<0){localMouse.y+=target.padding}else{localMouse.y-=target.padding}}else{localMouse.y=0}},_rotateObject:function(x,y){var t=this._currentTransform;if(t.target.get("lockRotation")){return false}var lastAngle=atan2(t.ey-t.top,t.ex-t.left),curAngle=atan2(y-t.top,x-t.left),angle=radiansToDegrees(curAngle-lastAngle+t.theta);if(angle<0){angle=360+angle}t.target.angle=angle%360;return true},setCursor:function(value){this.upperCanvasEl.style.cursor=value},_resetObjectTransform:function(target){target.scaleX=1;target.scaleY=1;target.skewX=0;target.skewY=0;target.setAngle(0)},_drawSelection:function(){var ctx=this.contextTop,groupSelector=this._groupSelector,left=groupSelector.left,top=groupSelector.top,aleft=abs(left),atop=abs(top);ctx.fillStyle=this.selectionColor;ctx.fillRect(groupSelector.ex-(left>0?0:-left),groupSelector.ey-(top>0?0:-top),aleft,atop);ctx.lineWidth=this.selectionLineWidth;ctx.strokeStyle=this.selectionBorderColor;if(this.selectionDashArray.length>1){var px=groupSelector.ex+STROKE_OFFSET-(left>0?0:aleft),py=groupSelector.ey+STROKE_OFFSET-(top>0?0:atop);ctx.beginPath();fabric.util.drawDashedLine(ctx,px,py,px+aleft,py,this.selectionDashArray);fabric.util.drawDashedLine(ctx,px,py+atop-1,px+aleft,py+atop-1,this.selectionDashArray);fabric.util.drawDashedLine(ctx,px,py,px,py+atop,this.selectionDashArray);fabric.util.drawDashedLine(ctx,px+aleft-1,py,px+aleft-1,py+atop,this.selectionDashArray);ctx.closePath();ctx.stroke()}else{ctx.strokeRect(groupSelector.ex+STROKE_OFFSET-(left>0?0:aleft),groupSelector.ey+STROKE_OFFSET-(top>0?0:atop),aleft,atop)}},_isLastRenderedObject:function(e){return this.controlsAboveOverlay&&this.lastRenderedObjectWithControlsAboveOverlay&&this.lastRenderedObjectWithControlsAboveOverlay.visible&&this.containsPoint(e,this.lastRenderedObjectWithControlsAboveOverlay)&&this.lastRenderedObjectWithControlsAboveOverlay._findTargetCorner(this.getPointer(e,true))},findTarget:function(e,skipGroup){if(this.skipTargetFind){return}if(this._isLastRenderedObject(e)){return this.lastRenderedObjectWithControlsAboveOverlay}var activeGroup=this.getActiveGroup();if(!skipGroup&&this._checkTarget(e,activeGroup,this.getPointer(e,true))){return activeGroup}var target=this._searchPossibleTargets(e,skipGroup);this._fireOverOutEvents(target,e);return target},_fireOverOutEvents:function(target,e){if(target){if(this._hoveredTarget!==target){if(this._hoveredTarget){this.fire("mouse:out",{target:this._hoveredTarget,e:e});this._hoveredTarget.fire("mouseout")}this.fire("mouse:over",{target:target,e:e});target.fire("mouseover");this._hoveredTarget=target}}else if(this._hoveredTarget){this.fire("mouse:out",{target:this._hoveredTarget,e:e});this._hoveredTarget.fire("mouseout");this._hoveredTarget=null}},_checkTarget:function(e,obj,pointer){if(obj&&obj.visible&&obj.evented&&this.containsPoint(e,obj)){if((this.perPixelTargetFind||obj.perPixelTargetFind)&&!obj.isEditing){var isTransparent=this.isTargetTransparent(obj,pointer.x,pointer.y);if(!isTransparent){return true}}else{return true}}},_searchPossibleTargets:function(e,skipGroup){var target,pointer=this.getPointer(e,true),i=this._objects.length;while(i--){if((!this._objects[i].group||skipGroup)&&this._checkTarget(e,this._objects[i],pointer)){this.relatedTarget=this._objects[i];target=this._objects[i];break}}return target},getPointer:function(e,ignoreZoom,upperCanvasEl){if(!upperCanvasEl){upperCanvasEl=this.upperCanvasEl}var pointer=getPointer(e),bounds=upperCanvasEl.getBoundingClientRect(),boundsWidth=bounds.width||0,boundsHeight=bounds.height||0,cssScale;if(!boundsWidth||!boundsHeight){if("top"in bounds&&"bottom"in bounds){boundsHeight=Math.abs(bounds.top-bounds.bottom)}if("right"in bounds&&"left"in bounds){boundsWidth=Math.abs(bounds.right-bounds.left)}}this.calcOffset();pointer.x=pointer.x-this._offset.left;pointer.y=pointer.y-this._offset.top;if(!ignoreZoom){pointer=fabric.util.transformPoint(pointer,fabric.util.invertTransform(this.viewportTransform))}if(boundsWidth===0||boundsHeight===0){cssScale={width:1,height:1}}else{cssScale={width:upperCanvasEl.width/boundsWidth,height:upperCanvasEl.height/boundsHeight}}return{x:pointer.x*cssScale.width,y:pointer.y*cssScale.height}},_createUpperCanvas:function(){var lowerCanvasClass=this.lowerCanvasEl.className.replace(/\s*lower-canvas\s*/,"");this.upperCanvasEl=this._createCanvasElement();fabric.util.addClass(this.upperCanvasEl,"upper-canvas "+lowerCanvasClass);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(element){var width=this.getWidth()||element.width,height=this.getHeight()||element.height;fabric.util.setStyle(element,{position:"absolute",width:width+"px",height:height+"px",left:0,top:0});element.width=width;element.height=height;fabric.util.makeElementUnselectable(element)},_copyCanvasStyle:function(fromEl,toEl){toEl.style.cssText=fromEl.style.cssText},getSelectionContext:function(){return this.contextTop},getSelectionElement:function(){return this.upperCanvasEl},_setActiveObject:function(object){if(this._activeObject){this._activeObject.set("active",false)}this._activeObject=object;object.set("active",true)},setActiveObject:function(object,e){this._setActiveObject(object);this.renderAll();this.fire("object:selected",{target:object,e:e});object.fire("selected",{e:e});return this},getActiveObject:function(){return this._activeObject},_discardActiveObject:function(){if(this._activeObject){this._activeObject.set("active",false)}this._activeObject=null},discardActiveObject:function(e){this._discardActiveObject();this.renderAll();this.fire("selection:cleared",{e:e});return this},_setActiveGroup:function(group){this._activeGroup=group;if(group){group.set("active",true)}},setActiveGroup:function(group,e){this._setActiveGroup(group);if(group){this.fire("object:selected",{target:group,e:e});group.fire("selected",{e:e})}return this},getActiveGroup:function(){return this._activeGroup},_discardActiveGroup:function(){var g=this.getActiveGroup();if(g){g.destroy()}this.setActiveGroup(null)},discardActiveGroup:function(e){this._discardActiveGroup();this.fire("selection:cleared",{e:e});return this},deactivateAll:function(){var allObjects=this.getObjects(),i=0,len=allObjects.length;for(;i1){return}var groupSelector=this._groupSelector;if(groupSelector){pointer=this.getPointer(e,true);groupSelector.left=pointer.x-groupSelector.ex;groupSelector.top=pointer.y-groupSelector.ey;this.renderTop()}else if(!this._currentTransform){target=this.findTarget(e);if(!target||target&&!target.selectable){this.setCursor(this.defaultCursor)}else{this._setCursorFromEvent(e,target)}}else{this._transformObject(e)}this.fire("mouse:move",{target:target,e:e});target&&target.fire("mousemove",{e:e})},_transformObject:function(e){var pointer=this.getPointer(e),transform=this._currentTransform;transform.reset=false,transform.target.isMoving=true;this._beforeScaleTransform(e,transform);this._performTransformAction(e,transform,pointer);this.renderAll()},_performTransformAction:function(e,transform,pointer){var x=pointer.x,y=pointer.y,target=transform.target,action=transform.action,actionPerformed=false;if(action==="rotate"){(actionPerformed=this._rotateObject(x,y))&&this._fire("rotating",target,e)}else if(action==="scale"){(actionPerformed=this._onScale(e,transform,x,y))&&this._fire("scaling",target,e)}else if(action==="scaleX"){(actionPerformed=this._scaleObject(x,y,"x"))&&this._fire("scaling",target,e)}else if(action==="scaleY"){(actionPerformed=this._scaleObject(x,y,"y"))&&this._fire("scaling",target,e)}else if(action==="skewX"){(actionPerformed=this._skewObject(x,y,"x"))&&this._fire("skewing",target,e)}else if(action==="skewY"){(actionPerformed=this._skewObject(x,y,"y"))&&this._fire("skewing",target,e)}else{(actionPerformed=this._translateObject(x,y))&&this._fire("moving",target,e);this.setCursor(this.moveCursor)}transform.actionPerformed=actionPerformed},_fire:function(eventName,target,e){this.fire("object:"+eventName,{target:target,e:e});target.fire(eventName,{e:e})},_beforeScaleTransform:function(e,transform){if(transform.action==="scale"||transform.action==="scaleX"||transform.action==="scaleY"){var centerTransform=this._shouldCenterTransform(transform.target);if(centerTransform&&(transform.originX!=="center"||transform.originY!=="center")||!centerTransform&&transform.originX==="center"&&transform.originY==="center"){this._resetCurrentTransform();transform.reset=true}}},_onScale:function(e,transform,x,y){if((e.shiftKey||this.uniScaleTransform)&&!transform.target.get("lockUniScaling")){transform.currentAction="scale";return this._scaleObject(x,y)}else{if(!transform.reset&&transform.currentAction==="scale"){this._resetCurrentTransform()}transform.currentAction="scaleEqually";return this._scaleObject(x,y,"equally")}},_setCursorFromEvent:function(e,target){if(!target||!target.selectable){this.setCursor(this.defaultCursor);return false}else{var activeGroup=this.getActiveGroup(),corner=target._findTargetCorner&&(!activeGroup||!activeGroup.contains(target))&&target._findTargetCorner(this.getPointer(e,true));if(!corner){this.setCursor(target.hoverCursor||this.hoverCursor)}else{this._setCornerCursor(corner,target,e)}}return true},_setCornerCursor:function(corner,target,e){if(corner in cursorOffset){this.setCursor(this._getRotatedCornerCursor(corner,target,e))}else if(corner==="mtr"&&target.hasRotatingPoint){this.setCursor(this.rotationCursor)}else{this.setCursor(this.defaultCursor);return false}},_getRotatedCornerCursor:function(corner,target,e){var n=Math.round(target.getAngle()%360/45);if(n<0){n+=8}n+=cursorOffset[corner];if(e.shiftKey&&cursorOffset[corner]%2===0){n+=2}n%=8;return this.cursorMap[n]}})})();(function(){var min=Math.min,max=Math.max;fabric.util.object.extend(fabric.Canvas.prototype,{_shouldGroup:function(e,target){var activeObject=this.getActiveObject();return e.shiftKey&&target&&target.selectable&&(this.getActiveGroup()||activeObject&&activeObject!==target)&&this.selection},_handleGrouping:function(e,target){if(target===this.getActiveGroup()){target=this.findTarget(e,true);if(!target||target.isType("group")){return}}if(this.getActiveGroup()){this._updateActiveGroup(target,e)}else{this._createActiveGroup(target,e)}if(this._activeGroup){this._activeGroup.saveCoords()}},_updateActiveGroup:function(target,e){var activeGroup=this.getActiveGroup();if(activeGroup.contains(target)){activeGroup.removeWithUpdate(target);target.set("active",false);if(activeGroup.size()===1){this.discardActiveGroup(e);this.setActiveObject(activeGroup.item(0));return}}else{activeGroup.addWithUpdate(target)}this.fire("selection:created",{target:activeGroup,e:e});activeGroup.set("active",true)},_createActiveGroup:function(target,e){if(this._activeObject&&target!==this._activeObject){var group=this._createGroup(target);group.addWithUpdate();this.setActiveGroup(group);this._activeObject=null;this.fire("selection:created",{target:group,e:e})}target.set("active",true)},_createGroup:function(target){var objects=this.getObjects(),isActiveLower=objects.indexOf(this._activeObject)1){group=new fabric.Group(group.reverse(),{canvas:this});group.addWithUpdate();this.setActiveGroup(group,e);group.saveCoords();this.fire("selection:created",{target:group});this.renderAll()}},_collectObjects:function(){var group=[],currentObject,x1=this._groupSelector.ex,y1=this._groupSelector.ey,x2=x1+this._groupSelector.left,y2=y1+this._groupSelector.top,selectionX1Y1=new fabric.Point(min(x1,x2),min(y1,y2)),selectionX2Y2=new fabric.Point(max(x1,x2),max(y1,y2)),isClick=x1===x2&&y1===y2;for(var i=this._objects.length;i--;){currentObject=this._objects[i];if(!currentObject||!currentObject.selectable||!currentObject.visible){continue}if(currentObject.intersectsWithRect(selectionX1Y1,selectionX2Y2)||currentObject.isContainedWithinRect(selectionX1Y1,selectionX2Y2)||currentObject.containsPoint(selectionX1Y1)||currentObject.containsPoint(selectionX2Y2)){currentObject.set("active",true);group.push(currentObject);if(isClick){break}}}return group},_maybeGroupObjects:function(e){if(this.selection&&this._groupSelector){this._groupSelectedObjects(e)}var activeGroup=this.getActiveGroup();if(activeGroup){activeGroup.setObjectsCoords().setCoords();activeGroup.isMoving=false;this.setCursor(this.defaultCursor)}this._groupSelector=null;this._currentTransform=null}})})();fabric.util.object.extend(fabric.StaticCanvas.prototype,{toDataURL:function(options){options||(options={});var format=options.format||"png",quality=options.quality||1,multiplier=options.multiplier||1,cropping={left:options.left,top:options.top,width:options.width,height:options.height};if(this._isRetinaScaling()){multiplier*=fabric.devicePixelRatio}if(multiplier!==1){return this.__toDataURLWithMultiplier(format,quality,cropping,multiplier)}else{return this.__toDataURL(format,quality,cropping)}},__toDataURL:function(format,quality,cropping){this.renderAll();var canvasEl=this.contextContainer.canvas,croppedCanvasEl=this.__getCroppedCanvas(canvasEl,cropping);if(format==="jpg"){format="jpeg"}var data=fabric.StaticCanvas.supports("toDataURLWithQuality")?(croppedCanvasEl||canvasEl).toDataURL("image/"+format,quality):(croppedCanvasEl||canvasEl).toDataURL("image/"+format);if(croppedCanvasEl){croppedCanvasEl=null}return data},__getCroppedCanvas:function(canvasEl,cropping){var croppedCanvasEl,croppedCtx,shouldCrop="left"in cropping||"top"in cropping||"width"in cropping||"height"in cropping;if(shouldCrop){croppedCanvasEl=fabric.util.createCanvasElement();croppedCtx=croppedCanvasEl.getContext("2d");croppedCanvasEl.width=cropping.width||this.width;croppedCanvasEl.height=cropping.height||this.height;croppedCtx.drawImage(canvasEl,-cropping.left||0,-cropping.top||0)}return croppedCanvasEl},__toDataURLWithMultiplier:function(format,quality,cropping,multiplier){var origWidth=this.getWidth(),origHeight=this.getHeight(),scaledWidth=origWidth*multiplier,scaledHeight=origHeight*multiplier,activeObject=this.getActiveObject(),activeGroup=this.getActiveGroup(),ctx=this.contextContainer;if(multiplier>1){this.setDimensions({width:scaledWidth,height:scaledHeight})}ctx.save();ctx.scale(multiplier/fabric.devicePixelRatio,multiplier/fabric.devicePixelRatio);if(cropping.left){cropping.left*=multiplier}if(cropping.top){cropping.top*=multiplier}if(cropping.width){cropping.width*=multiplier}else if(multiplier<1){cropping.width=scaledWidth}if(cropping.height){cropping.height*=multiplier}else if(multiplier<1){cropping.height=scaledHeight}if(activeGroup){this._tempRemoveBordersControlsFromGroup(activeGroup)}else if(activeObject&&this.deactivateAll){this.deactivateAll()}var data=this.__toDataURL(format,quality,cropping);this.width=origWidth;this.height=origHeight;this.setDimensions({width:origWidth,height:origHeight});if(activeGroup){this._restoreBordersControlsOnGroup(activeGroup)}else if(activeObject&&this.setActiveObject){this.setActiveObject(activeObject)}this.contextTop&&this.clearContext(this.contextTop);this.renderAll();return data},toDataURLWithMultiplier:function(format,multiplier,quality){return this.toDataURL({format:format,multiplier:multiplier,quality:quality})},_tempRemoveBordersControlsFromGroup:function(group){group.origHasControls=group.hasControls;group.origBorderColor=group.borderColor;group.hasControls=true;group.borderColor="rgba(0,0,0,0)";group.forEachObject(function(o){o.origBorderColor=o.borderColor;o.borderColor="rgba(0,0,0,0)"})},_restoreBordersControlsOnGroup:function(group){group.hideControls=group.origHideControls;group.borderColor=group.origBorderColor;group.forEachObject(function(o){o.borderColor=o.origBorderColor;delete o.origBorderColor})}});fabric.util.object.extend(fabric.StaticCanvas.prototype,{loadFromDatalessJSON:function(json,callback,reviver){return this.loadFromJSON(json,callback,reviver)},loadFromJSON:function(json,callback,reviver){if(!json){return}var serialized=typeof json==="string"?JSON.parse(json):json;this.clear();var _this=this;this._enlivenObjects(serialized.objects,function(){_this._setBgOverlay(serialized,callback)},reviver);return this},_setBgOverlay:function(serialized,callback){var _this=this,loaded={backgroundColor:false,overlayColor:false,backgroundImage:false,overlayImage:false};if(!serialized.backgroundImage&&!serialized.overlayImage&&!serialized.background&&!serialized.overlay){callback&&callback();return}var cbIfLoaded=function(){if(loaded.backgroundImage&&loaded.overlayImage&&loaded.backgroundColor&&loaded.overlayColor){_this.renderAll();callback&&callback()}};this.__setBgOverlay("backgroundImage",serialized.backgroundImage,loaded,cbIfLoaded);this.__setBgOverlay("overlayImage",serialized.overlayImage,loaded,cbIfLoaded);this.__setBgOverlay("backgroundColor",serialized.background,loaded,cbIfLoaded);this.__setBgOverlay("overlayColor",serialized.overlay,loaded,cbIfLoaded);cbIfLoaded()},__setBgOverlay:function(property,value,loaded,callback){var _this=this;if(!value){loaded[property]=true;return}if(property==="backgroundImage"||property==="overlayImage"){fabric.Image.fromObject(value,function(img){_this[property]=img;loaded[property]=true;callback&&callback()})}else{this["set"+fabric.util.string.capitalize(property,true)](value,function(){loaded[property]=true;callback&&callback()})}},_enlivenObjects:function(objects,callback,reviver){var _this=this;if(!objects||objects.length===0){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,true)});_this.renderOnAddRemove=renderOnAddRemove;callback&&callback()},null,reviver)},_toDataURL:function(format,callback){this.clone(function(clone){callback(clone.toDataURL(format))})},_toDataURLWithMultiplier:function(format,multiplier,callback){this.clone(function(clone){callback(clone.toDataURLWithMultiplier(format,multiplier))})},clone:function(callback,properties){var data=JSON.stringify(this.toJSON(properties));this.cloneWithoutData(function(clone){clone.loadFromJSON(data,function(){callback&&callback(clone)})})},cloneWithoutData:function(callback){var el=fabric.document.createElement("canvas");el.width=this.getWidth();el.height=this.getHeight();var clone=new fabric.Canvas(el);clone.clipTo=this.clipTo;if(this.backgroundImage){clone.setBackgroundImage(this.backgroundImage.src,function(){clone.renderAll();callback&&callback(clone)});clone.backgroundImageOpacity=this.backgroundImageOpacity;clone.backgroundImageStretch=this.backgroundImageStretch}else{callback&&callback(clone)}}});(function(global){"use strict";var fabric=global.fabric||(global.fabric={}),extend=fabric.util.object.extend,toFixed=fabric.util.toFixed,capitalize=fabric.util.string.capitalize,degreesToRadians=fabric.util.degreesToRadians,supportsLineDash=fabric.StaticCanvas.supports("setLineDash");if(fabric.Object){return}fabric.Object=fabric.util.createClass({type:"object",originX:"left",originY:"top",top:0,left:0,width:0,height:0,scaleX:1,scaleY:1,flipX:false,flipY:false,opacity:1,angle:0,skewX:0,skewY:0,cornerSize:12,transparentCorners:true,hoverCursor:null,padding:0,borderColor:"rgba(102,153,255,0.75)",cornerColor:"rgba(102,153,255,0.5)",centeredScaling:false,centeredRotation:true,fill:"rgb(0,0,0)",fillRule:"nonzero",globalCompositeOperation:"source-over",backgroundColor:"",stroke:null,strokeWidth:1,strokeDashArray:null,strokeLineCap:"butt",strokeLineJoin:"miter",strokeMiterLimit:10,shadow:null,borderOpacityWhenMoving:.4,borderScaleFactor:1,transformMatrix:null,minScaleLimit:.01,selectable:true,evented:true,visible:true,hasControls:true,hasBorders:true,hasRotatingPoint:true,rotatingPointOffset:40,perPixelTargetFind:false,includeDefaultValues:true,clipTo:null,lockMovementX:false,lockMovementY:false,lockRotation:false,lockScalingX:false,lockScalingY:false,lockUniScaling:false,lockSkewingX:false,lockSkewingY:false,lockScalingFlip: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 "+"alignX alignY meetOrSlice skewX skewY").split(" "),initialize:function(options){if(options){this.setOptions(options)}},_initGradient:function(options){if(options.fill&&options.fill.colorStops&&!(options.fill instanceof fabric.Gradient)){this.set("fill",new fabric.Gradient(options.fill))}if(options.stroke&&options.stroke.colorStops&&!(options.stroke instanceof fabric.Gradient)){this.set("stroke",new fabric.Gradient(options.stroke))}},_initPattern:function(options){if(options.fill&&options.fill.source&&!(options.fill instanceof fabric.Pattern)){this.set("fill",new fabric.Pattern(options.fill))}if(options.stroke&&options.stroke.source&&!(options.stroke instanceof fabric.Pattern)){this.set("stroke",new fabric.Pattern(options.stroke))}},_initClipping:function(options){if(!options.clipTo||typeof options.clipTo!=="string"){return}var functionBody=fabric.util.getFunctionBody(options.clipTo);if(typeof functionBody!=="undefined"){this.clipTo=new Function("ctx",functionBody)}},setOptions:function(options){for(var prop in options){this.set(prop,options[prop])}this._initGradient(options);this._initPattern(options);this._initClipping(options)},transform:function(ctx,fromLeft){if(this.group&&this.canvas.preserveObjectStacking&&this.group===this.canvas._activeGroup){this.group.transform(ctx)}var center=fromLeft?this._getLeftTopCoords():this.getCenterPoint();ctx.translate(center.x,center.y);ctx.rotate(degreesToRadians(this.angle));ctx.scale(this.scaleX*(this.flipX?-1:1),this.scaleY*(this.flipY?-1:1));ctx.transform(1,0,Math.tan(degreesToRadians(this.skewX)),1,0,0);ctx.transform(1,Math.tan(degreesToRadians(this.skewY)),0,1,0,0)},toObject:function(propertiesToInclude){var NUM_FRACTION_DIGITS=fabric.Object.NUM_FRACTION_DIGITS,object={type:this.type,originX:this.originX,originY:this.originY,left:toFixed(this.left,NUM_FRACTION_DIGITS),top:toFixed(this.top,NUM_FRACTION_DIGITS),width:toFixed(this.width,NUM_FRACTION_DIGITS),height:toFixed(this.height,NUM_FRACTION_DIGITS),fill:this.fill&&this.fill.toObject?this.fill.toObject():this.fill,stroke:this.stroke&&this.stroke.toObject?this.stroke.toObject():this.stroke,strokeWidth:toFixed(this.strokeWidth,NUM_FRACTION_DIGITS),strokeDashArray:this.strokeDashArray?this.strokeDashArray.concat():this.strokeDashArray,strokeLineCap:this.strokeLineCap,strokeLineJoin:this.strokeLineJoin,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),flipX:this.flipX,flipY:this.flipY,opacity:toFixed(this.opacity,NUM_FRACTION_DIGITS),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():this.transformMatrix,skewX:toFixed(this.skewX,NUM_FRACTION_DIGITS),skewY:toFixed(this.skewY,NUM_FRACTION_DIGITS)};if(!this.includeDefaultValues){object=this._removeDefaultValues(object)}fabric.util.populateWithProperties(this,object,propertiesToInclude);return object},toDatalessObject:function(propertiesToInclude){return this.toObject(propertiesToInclude)},_removeDefaultValues:function(object){var prototype=fabric.util.getKlass(object.type).prototype,stateProperties=prototype.stateProperties;stateProperties.forEach(function(prop){if(object[prop]===prototype[prop]){delete object[prop]}var isArray=Object.prototype.toString.call(object[prop])==="[object Array]"&&Object.prototype.toString.call(prototype[prop])==="[object Array]";if(isArray&&object[prop].length===0&&prototype[prop].length===0){delete object[prop]}});return object},toString:function(){return"#"},get:function(property){return this[property]},_setObject:function(obj){for(var prop in obj){this._set(prop,obj[prop])}},set:function(key,value){if(typeof key==="object"){this._setObject(key)}else{if(typeof value==="function"&&key!=="clipTo"){this._set(key,value(this.get(key)))}else{this._set(key,value)}}return this},_set:function(key,value){var shouldConstrainValue=key==="scaleX"||key==="scaleY";if(shouldConstrainValue){value=this._constrainScale(value)}if(key==="scaleX"&&value<0){this.flipX=!this.flipX;value*=-1}else if(key==="scaleY"&&value<0){this.flipY=!this.flipY;value*=-1}else if(key==="width"||key==="height"){this.minScaleLimit=toFixed(Math.min(.1,1/Math.max(this.width,this.height)),2)}else if(key==="shadow"&&value&&!(value instanceof fabric.Shadow)){value=new fabric.Shadow(value)}this[key]=value;return this},setOnGroup:function(){},toggle:function(property){var value=this.get(property);if(typeof value==="boolean"){this.set(property,!value)}return this},setSourcePath:function(value){this.sourcePath=value;return this},getViewportTransform:function(){if(this.canvas&&this.canvas.viewportTransform){return this.canvas.viewportTransform}return[1,0,0,1,0,0]},render:function(ctx,noTransform){if(this.width===0&&this.height===0||!this.visible){return}ctx.save();this._setupCompositeOperation(ctx);if(!noTransform){this.transform(ctx)}this._setStrokeStyles(ctx);this._setFillStyles(ctx);if(this.transformMatrix){ctx.transform.apply(ctx,this.transformMatrix)}this._setOpacity(ctx);this._setShadow(ctx);this.clipTo&&fabric.util.clipContext(this,ctx);this._render(ctx,noTransform);this.clipTo&&ctx.restore();ctx.restore()},_setOpacity:function(ctx){if(this.group){this.group._setOpacity(ctx)}ctx.globalAlpha*=this.opacity},_setStrokeStyles:function(ctx){if(this.stroke){ctx.lineWidth=this.strokeWidth;ctx.lineCap=this.strokeLineCap;ctx.lineJoin=this.strokeLineJoin;ctx.miterLimit=this.strokeMiterLimit;ctx.strokeStyle=this.stroke.toLive?this.stroke.toLive(ctx,this):this.stroke}},_setFillStyles:function(ctx){if(this.fill){ctx.fillStyle=this.fill.toLive?this.fill.toLive(ctx,this):this.fill}},_renderControls:function(ctx,noTransform){if(!this.active||noTransform||this.group&&this.group!==this.canvas.getActiveGroup()){return}var vpt=this.getViewportTransform(),matrix=this.calcTransformMatrix(),options;matrix=fabric.util.multiplyTransformMatrices(vpt,matrix);options=fabric.util.qrDecompose(matrix);ctx.save();ctx.translate(options.translateX,options.translateY);if(this.group&&this.group===this.canvas.getActiveGroup()){ctx.rotate(degreesToRadians(options.angle));this.drawBordersInGroup(ctx,options)}else{ctx.rotate(degreesToRadians(this.angle));this.drawBorders(ctx)}this.drawControls(ctx);ctx.restore()},_setShadow:function(ctx){if(!this.shadow){return}var multX=this.canvas&&this.canvas.viewportTransform[0]||1,multY=this.canvas&&this.canvas.viewportTransform[3]||1;if(this.canvas&&this.canvas._isRetinaScaling()){multX*=fabric.devicePixelRatio;multY*=fabric.devicePixelRatio}ctx.shadowColor=this.shadow.color;ctx.shadowBlur=this.shadow.blur*(multX+multY)*(this.scaleX+this.scaleY)/4;ctx.shadowOffsetX=this.shadow.offsetX*multX*this.scaleX;ctx.shadowOffsetY=this.shadow.offsetY*multY*this.scaleY},_removeShadow:function(ctx){if(!this.shadow){return}ctx.shadowColor="";ctx.shadowBlur=ctx.shadowOffsetX=ctx.shadowOffsetY=0},_renderFill:function(ctx){if(!this.fill){return}ctx.save();if(this.fill.gradientTransform){var g=this.fill.gradientTransform;ctx.transform.apply(ctx,g)}if(this.fill.toLive){ctx.translate(-this.width/2+this.fill.offsetX||0,-this.height/2+this.fill.offsetY||0)}if(this.fillRule==="evenodd"){ctx.fill("evenodd")}else{ctx.fill()}ctx.restore()},_renderStroke:function(ctx){if(!this.stroke||this.strokeWidth===0){return}if(this.shadow&&!this.shadow.affectStroke){this._removeShadow(ctx)}ctx.save();if(this.strokeDashArray){if(1&this.strokeDashArray.length){this.strokeDashArray.push.apply(this.strokeDashArray,this.strokeDashArray)}if(supportsLineDash){ctx.setLineDash(this.strokeDashArray);this._stroke&&this._stroke(ctx)}else{this._renderDashedStroke&&this._renderDashedStroke(ctx)}ctx.stroke()}else{if(this.stroke.gradientTransform){var g=this.stroke.gradientTransform;ctx.transform.apply(ctx,g)}this._stroke?this._stroke(ctx):ctx.stroke()}ctx.restore()},clone:function(callback,propertiesToInclude){if(this.constructor.fromObject){return this.constructor.fromObject(this.toObject(propertiesToInclude),callback)}return new fabric.Object(this.toObject(propertiesToInclude))},cloneAsImage:function(callback){var dataUrl=this.toDataURL();fabric.util.loadImage(dataUrl,function(img){if(callback){callback(new fabric.Image(img)) +}});return this},toDataURL:function(options){options||(options={});var el=fabric.util.createCanvasElement(),boundingRect=this.getBoundingRect();el.width=boundingRect.width;el.height=boundingRect.height;fabric.util.wrapElement(el,"div");var canvas=new fabric.StaticCanvas(el);if(options.format==="jpg"){options.format="jpeg"}if(options.format==="jpeg"){canvas.backgroundColor="#fff"}var origParams={active:this.get("active"),left:this.getLeft(),top:this.getTop()};this.set("active",false);this.setPositionByOrigin(new fabric.Point(el.width/2,el.height/2),"center","center");var originalCanvas=this.canvas;canvas.add(this);var data=canvas.toDataURL(options);this.set(origParams).setCoords();this.canvas=originalCanvas;canvas.dispose();canvas=null;return data},isType:function(type){return this.type===type},complexity:function(){return 0},toJSON:function(propertiesToInclude){return this.toObject(propertiesToInclude)},setGradient:function(property,options){options||(options={});var gradient={colorStops:[]};gradient.type=options.type||(options.r1||options.r2?"radial":"linear");gradient.coords={x1:options.x1,y1:options.y1,x2:options.x2,y2:options.y2};if(options.r1||options.r2){gradient.coords.r1=options.r1;gradient.coords.r2=options.r2}options.gradientTransform&&(gradient.gradientTransform=options.gradientTransform);for(var position in options.colorStops){var color=new fabric.Color(options.colorStops[position]);gradient.colorStops.push({offset:position,color:color.toRgb(),opacity:color.getAlpha()})}return this.set(property,fabric.Gradient.forObject(this,gradient))},setPatternFill:function(options){return this.set("fill",new fabric.Pattern(options))},setShadow:function(options){return this.set("shadow",options?new fabric.Shadow(options):null)},setColor:function(color){this.set("fill",color);return this},setAngle:function(angle){var shouldCenterOrigin=(this.originX!=="center"||this.originY!=="center")&&this.centeredRotation;if(shouldCenterOrigin){this._setOriginToCenter()}this.set("angle",angle);if(shouldCenterOrigin){this._resetOrigin()}return this},centerH:function(){this.canvas.centerObjectH(this);return this},centerV:function(){this.canvas.centerObjectV(this);return this},center:function(){this.canvas.centerObject(this);return this},remove:function(){this.canvas.remove(this);return this},getLocalPointer:function(e,pointer){pointer=pointer||this.canvas.getPointer(e);var pClicked=new fabric.Point(pointer.x,pointer.y),objectLeftTop=this._getLeftTopCoords();if(this.angle){pClicked=fabric.util.rotatePoint(pClicked,objectLeftTop,fabric.util.degreesToRadians(-this.angle))}return{x:pClicked.x-objectLeftTop.x,y:pClicked.y-objectLeftTop.y}},_setupCompositeOperation:function(ctx){if(this.globalCompositeOperation){ctx.globalCompositeOperation=this.globalCompositeOperation}}});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.__uid=0})(typeof exports!=="undefined"?exports:this);(function(){var degreesToRadians=fabric.util.degreesToRadians,originXOffset={left:-.5,center:0,right:.5},originYOffset={top:-.5,center:0,bottom:.5};fabric.util.object.extend(fabric.Object.prototype,{translateToGivenOrigin:function(point,fromOriginX,fromOriginY,toOriginX,toOriginY){var x=point.x,y=point.y,offsetX=originXOffset[toOriginX]-originXOffset[fromOriginX],offsetY=originYOffset[toOriginY]-originYOffset[fromOriginY],dim;if(offsetX||offsetY){dim=this._getTransformedDimensions();x=point.x+offsetX*dim.x;y=point.y+offsetY*dim.y}return new fabric.Point(x,y)},translateToCenterPoint:function(point,originX,originY){var p=this.translateToGivenOrigin(point,originX,originY,"center","center");if(this.angle){return fabric.util.rotatePoint(p,point,degreesToRadians(this.angle))}return p},translateToOriginPoint:function(center,originX,originY){var p=this.translateToGivenOrigin(center,"center","center",originX,originY);if(this.angle){return fabric.util.rotatePoint(p,center,degreesToRadians(this.angle))}return p},getCenterPoint:function(){var leftTop=new fabric.Point(this.left,this.top);return this.translateToCenterPoint(leftTop,this.originX,this.originY)},getPointByOrigin:function(originX,originY){var center=this.getCenterPoint();return this.translateToOriginPoint(center,originX,originY)},toLocalPoint:function(point,originX,originY){var center=this.getCenterPoint(),p,p2;if(originX&&originY){p=this.translateToGivenOrigin(center,"center","center",originX,originY)}else{p=new fabric.Point(this.left,this.top)}p2=new fabric.Point(point.x,point.y);if(this.angle){p2=fabric.util.rotatePoint(p2,center,-degreesToRadians(this.angle))}return p2.subtractEquals(p)},setPositionByOrigin:function(pos,originX,originY){var center=this.translateToCenterPoint(pos,originX,originY),position=this.translateToOriginPoint(center,this.originX,this.originY);this.set("left",position.x);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;this.left+=xFull*(originXOffset[to]-originXOffset[this.originX]);this.top+=yFull*(originXOffset[to]-originXOffset[this.originX]);this.setCoords();this.originX=to},_setOriginToCenter:function(){this._originalOriginX=this.originX;this._originalOriginY=this.originY;var center=this.getCenterPoint();this.originX="center";this.originY="center";this.left=center.x;this.top=center.y},_resetOrigin:function(){var originPoint=this.translateToOriginPoint(this.getCenterPoint(),this._originalOriginX,this._originalOriginY);this.originX=this._originalOriginX;this.originY=this._originalOriginY;this.left=originPoint.x;this.top=originPoint.y;this._originalOriginX=null;this._originalOriginY=null},_getLeftTopCoords:function(){return this.translateToOriginPoint(this.getCenterPoint(),"left","top")}})})();(function(){function getCoords(oCoords){return[new fabric.Point(oCoords.tl.x,oCoords.tl.y),new fabric.Point(oCoords.tr.x,oCoords.tr.y),new fabric.Point(oCoords.br.x,oCoords.br.y),new fabric.Point(oCoords.bl.x,oCoords.bl.y)]}var degreesToRadians=fabric.util.degreesToRadians,multiplyMatrices=fabric.util.multiplyTransformMatrices;fabric.util.object.extend(fabric.Object.prototype,{oCoords:null,intersectsWithRect:function(pointTL,pointBR){var oCoords=getCoords(this.oCoords),intersection=fabric.Intersection.intersectPolygonRectangle(oCoords,pointTL,pointBR);return intersection.status==="Intersection"},intersectsWithObject:function(other){var intersection=fabric.Intersection.intersectPolygonPolygon(getCoords(this.oCoords),getCoords(other.oCoords));return intersection.status==="Intersection"},isContainedWithinObject:function(other){var boundingRect=other.getBoundingRect(),point1=new fabric.Point(boundingRect.left,boundingRect.top),point2=new fabric.Point(boundingRect.left+boundingRect.width,boundingRect.top+boundingRect.height);return this.isContainedWithinRect(point1,point2)},isContainedWithinRect:function(pointTL,pointBR){var boundingRect=this.getBoundingRect();return boundingRect.left>=pointTL.x&&boundingRect.left+boundingRect.width<=pointBR.x&&boundingRect.top>=pointTL.y&&boundingRect.top+boundingRect.height<=pointBR.y},containsPoint:function(point){var lines=this._getImageLines(this.oCoords),xPoints=this._findCrossPoints(point,lines);return xPoints!==0&&xPoints%2===1},_getImageLines:function(oCoords){return{topline:{o:oCoords.tl,d:oCoords.tr},rightline:{o:oCoords.tr,d:oCoords.br},bottomline:{o:oCoords.br,d:oCoords.bl},leftline:{o:oCoords.bl,d:oCoords.tl}}},_findCrossPoints:function(point,oCoords){var b1,b2,a1,a2,xi,yi,xcount=0,iLine;for(var lineKey in oCoords){iLine=oCoords[lineKey];if(iLine.o.y=point.y&&iLine.d.y>=point.y){continue}if(iLine.o.x===iLine.d.x&&iLine.o.x>=point.x){xi=iLine.o.x;yi=point.y}else{b1=0;b2=(iLine.d.y-iLine.o.y)/(iLine.d.x-iLine.o.x);a1=point.y-b1*point.x;a2=iLine.o.y-b2*iLine.o.x;xi=-(a1-a2)/(b1-b2);yi=a1+b1*xi}if(xi>=point.x){xcount+=1}if(xcount===2){break}}return xcount},getBoundingRectWidth:function(){return this.getBoundingRect().width},getBoundingRectHeight:function(){return this.getBoundingRect().height},getBoundingRect:function(){this.oCoords||this.setCoords();return fabric.util.makeBoundingBoxFromPoints([this.oCoords.tl,this.oCoords.tr,this.oCoords.br,this.oCoords.bl])},getWidth:function(){return this._getTransformedDimensions().x},getHeight:function(){return this._getTransformedDimensions().y},_constrainScale:function(value){if(Math.abs(value)0?Math.atan(currentHeight/currentWidth):0,_hypotenuse=currentWidth/Math.cos(_angle)/2,offsetX=Math.cos(_angle+theta)*_hypotenuse,offsetY=Math.sin(_angle+theta)*_hypotenuse,coords=fabric.util.transformPoint(this.getCenterPoint(),vpt),tl=new fabric.Point(coords.x-offsetX,coords.y-offsetY),tr=new fabric.Point(tl.x+currentWidth*cosTh,tl.y+currentWidth*sinTh),bl=new fabric.Point(tl.x-currentHeight*sinTh,tl.y+currentHeight*cosTh),br=new fabric.Point(coords.x+offsetX,coords.y+offsetY),ml=new fabric.Point((tl.x+bl.x)/2,(tl.y+bl.y)/2),mt=new fabric.Point((tr.x+tl.x)/2,(tr.y+tl.y)/2),mr=new fabric.Point((br.x+tr.x)/2,(br.y+tr.y)/2),mb=new fabric.Point((br.x+bl.x)/2,(br.y+bl.y)/2),mtr=new fabric.Point(mt.x+sinTh*this.rotatingPointOffset,mt.y-cosTh*this.rotatingPointOffset);this.oCoords={tl:tl,tr:tr,br:br,bl:bl,ml:ml,mt:mt,mr:mr,mb:mb,mtr:mtr};this._setCornerCoords&&this._setCornerCoords();return this},_calcRotateMatrix:function(){if(this.angle){var theta=degreesToRadians(this.angle),cos=Math.cos(theta),sin=Math.sin(theta);return[cos,sin,-sin,cos,0,0]}return[1,0,0,1,0,0]},calcTransformMatrix:function(){var center=this.getCenterPoint(),translateMatrix=[1,0,0,1,center.x,center.y],rotateMatrix=this._calcRotateMatrix(),dimensionMatrix=this._calcDimensionsTransformMatrix(this.skewX,this.skewY,true),matrix=this.group?this.group.calcTransformMatrix():[1,0,0,1,0,0];matrix=multiplyMatrices(matrix,translateMatrix);matrix=multiplyMatrices(matrix,rotateMatrix);matrix=multiplyMatrices(matrix,dimensionMatrix);return matrix},_calcDimensionsTransformMatrix:function(skewX,skewY,flipping){var skewMatrixX=[1,0,Math.tan(degreesToRadians(skewX)),1],skewMatrixY=[1,Math.tan(degreesToRadians(skewY)),0,1],scaleX=this.scaleX*(flipping&&this.flipX?-1:1),scaleY=this.scaleY*(flipping&&this.flipY?-1:1),scaleMatrix=[scaleX,0,0,scaleY],m=multiplyMatrices(scaleMatrix,skewMatrixX,true);return multiplyMatrices(m,skewMatrixY,true)}})})();fabric.util.object.extend(fabric.Object.prototype,{sendToBack:function(){if(this.group){fabric.StaticCanvas.prototype.sendToBack.call(this.group,this)}else{this.canvas.sendToBack(this)}return this},bringToFront:function(){if(this.group){fabric.StaticCanvas.prototype.bringToFront.call(this.group,this)}else{this.canvas.bringToFront(this)}return this},sendBackwards:function(intersecting){if(this.group){fabric.StaticCanvas.prototype.sendBackwards.call(this.group,this,intersecting)}else{this.canvas.sendBackwards(this,intersecting)}return this},bringForward:function(intersecting){if(this.group){fabric.StaticCanvas.prototype.bringForward.call(this.group,this,intersecting)}else{this.canvas.bringForward(this,intersecting)}return this},moveTo:function(index){if(this.group){fabric.StaticCanvas.prototype.moveTo.call(this.group,this,index)}else{this.canvas.moveTo(this,index)}return this}});fabric.util.object.extend(fabric.Object.prototype,{getSvgStyles:function(skipShadow){var fill=this.fill?this.fill.toLive?"url(#SVGID_"+this.fill.id+")":this.fill:"none",fillRule=this.fillRule,stroke=this.stroke?this.stroke.toLive?"url(#SVGID_"+this.stroke.id+")":this.stroke:"none",strokeWidth=this.strokeWidth?this.strokeWidth:"0",strokeDashArray=this.strokeDashArray?this.strokeDashArray.join(" "):"none",strokeLineCap=this.strokeLineCap?this.strokeLineCap:"butt",strokeLineJoin=this.strokeLineJoin?this.strokeLineJoin:"miter",strokeMiterLimit=this.strokeMiterLimit?this.strokeMiterLimit:"4",opacity=typeof this.opacity!=="undefined"?this.opacity:"1",visibility=this.visible?"":" visibility: hidden;",filter=skipShadow?"":this.getSvgFilter();return["stroke: ",stroke,"; ","stroke-width: ",strokeWidth,"; ","stroke-dasharray: ",strokeDashArray,"; ","stroke-linecap: ",strokeLineCap,"; ","stroke-linejoin: ",strokeLineJoin,"; ","stroke-miterlimit: ",strokeMiterLimit,"; ","fill: ",fill,"; ","fill-rule: ",fillRule,"; ","opacity: ",opacity,";",filter,visibility].join("")},getSvgFilter:function(){return this.shadow?"filter: url(#SVGID_"+this.shadow.id+");":""},getSvgTransform:function(){if(this.group&&this.group.type==="path-group"){return""}var toFixed=fabric.util.toFixed,angle=this.getAngle(),skewX=this.getSkewX()%360,skewY=this.getSkewY()%360,center=this.getCenterPoint(),NUM_FRACTION_DIGITS=fabric.Object.NUM_FRACTION_DIGITS,translatePart=this.type==="path-group"?"":"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)+")":"",addTranslateX=this.type==="path-group"?this.width:0,flipXPart=this.flipX?" matrix(-1 0 0 1 "+addTranslateX+" 0) ":"",addTranslateY=this.type==="path-group"?this.height:0,flipYPart=this.flipY?" matrix(1 0 0 -1 0 "+addTranslateY+")":"";return[translatePart,anglePart,scalePart,flipXPart,flipYPart,skewXPart,skewYPart].join("")},getSvgTransformMatrix:function(){return this.transformMatrix?" matrix("+this.transformMatrix.join(" ")+") ":""},_createBaseSVGMarkup:function(){var markup=[];if(this.fill&&this.fill.toLive){markup.push(this.fill.toSVG(this,false))}if(this.stroke&&this.stroke.toLive){markup.push(this.stroke.toSVG(this,false))}if(this.shadow){markup.push(this.shadow.toSVG(this))}return markup}});fabric.util.object.extend(fabric.Object.prototype,{hasStateChanged:function(){return this.stateProperties.some(function(prop){return this.get(prop)!==this.originalState[prop]},this)},saveState:function(options){this.stateProperties.forEach(function(prop){this.originalState[prop]=this.get(prop)},this);if(options&&options.stateProperties){options.stateProperties.forEach(function(prop){this.originalState[prop]=this.get(prop)},this)}return this},setupState:function(){this.originalState={};this.saveState();return this}});(function(){var degreesToRadians=fabric.util.degreesToRadians,isVML=function(){return typeof G_vmlCanvasManager!=="undefined"};fabric.util.object.extend(fabric.Object.prototype,{_controlsVisibility:null,_findTargetCorner:function(pointer){if(!this.hasControls||!this.active){return false}var ex=pointer.x,ey=pointer.y,xPoints,lines;this.__corner=0;for(var i in this.oCoords){if(!this.isControlVisible(i)){continue}if(i==="mtr"&&!this.hasRotatingPoint){continue}if(this.get("lockUniScaling")&&(i==="mt"||i==="mr"||i==="mb"||i==="ml")){continue}lines=this._getImageLines(this.oCoords[i].corner);xPoints=this._findCrossPoints({x:ex,y:ey},lines);if(xPoints!==0&&xPoints%2===1){this.__corner=i;return i}}return false},_setCornerCoords:function(){var coords=this.oCoords,newTheta=degreesToRadians(45-this.angle),cornerHypotenuse=this.cornerSize*.707106,cosHalfOffset=cornerHypotenuse*Math.cos(newTheta),sinHalfOffset=cornerHypotenuse*Math.sin(newTheta),x,y;for(var point in coords){x=coords[point].x;y=coords[point].y;coords[point].corner={tl:{x:x-sinHalfOffset,y:y-cosHalfOffset},tr:{x:x+cosHalfOffset,y:y-sinHalfOffset},bl:{x:x-cosHalfOffset,y:y+sinHalfOffset},br:{x:x+sinHalfOffset,y:y+cosHalfOffset}}}},_getNonTransformedDimensions:function(){var strokeWidth=this.strokeWidth,w=this.width,h=this.height,addStrokeToW=true,addStrokeToH=true;if(this.type==="line"&&this.strokeLineCap==="butt"){addStrokeToH=w;addStrokeToW=h}if(addStrokeToH){h+=h<0?-strokeWidth:strokeWidth}if(addStrokeToW){w+=w<0?-strokeWidth:strokeWidth}return{x:w,y:h}},_getTransformedDimensions:function(skewX,skewY){if(typeof skewX==="undefined"){skewX=this.skewX}if(typeof skewY==="undefined"){skewY=this.skewY}var dimensions=this._getNonTransformedDimensions(),dimX=dimensions.x/2,dimY=dimensions.y/2,points=[{x:-dimX,y:-dimY},{x:dimX,y:-dimY},{x:-dimX,y:dimY},{x:dimX,y:dimY}],i,transformMatrix=this._calcDimensionsTransformMatrix(skewX,skewY,false),bbox;for(i=0;i\n');return reviver?reviver(markup.join("")):markup.join("")},complexity:function(){return 1}});fabric.Line.ATTRIBUTE_NAMES=fabric.SHARED_ATTRIBUTES.concat("x1 y1 x2 y2".split(" "));fabric.Line.fromElement=function(element,options){var parsedAttributes=fabric.parseAttributes(element,fabric.Line.ATTRIBUTE_NAMES),points=[parsedAttributes.x1||0,parsedAttributes.y1||0,parsedAttributes.x2||0,parsedAttributes.y2||0];return new fabric.Line(points,extend(parsedAttributes,options))};fabric.Line.fromObject=function(object){var points=[object.x1,object.y1,object.x2,object.y2];return new fabric.Line(points,object)};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;return function(){switch(this.get(origin)){case nearest:return Math.min(this.get(axis1),this.get(axis2));case center:return Math.min(this.get(axis1),this.get(axis2))+.5*this.get(dimension);case farthest:return Math.max(this.get(axis1),this.get(axis2))}}}})(typeof exports!=="undefined"?exports:this);(function(global){"use strict";var fabric=global.fabric||(global.fabric={}),pi=Math.PI,extend=fabric.util.object.extend;if(fabric.Circle){fabric.warn("fabric.Circle is already defined.");return}fabric.Circle=fabric.util.createClass(fabric.Object,{type:"circle",radius:0,startAngle:0,endAngle:pi*2,initialize:function(options){options=options||{};this.callSuper("initialize",options);this.set("radius",options.radius||0);this.startAngle=options.startAngle||this.startAngle;this.endAngle=options.endAngle||this.endAngle},_set:function(key,value){this.callSuper("_set",key,value);if(key==="radius"){this.setRadius(value)}return this},toObject:function(propertiesToInclude){return extend(this.callSuper("toObject",propertiesToInclude),{radius:this.get("radius"),startAngle:this.startAngle,endAngle:this.endAngle})},toSVG:function(reviver){var markup=this._createBaseSVGMarkup(),x=0,y=0,angle=(this.endAngle-this.startAngle)%(2*pi);if(angle===0){if(this.group&&this.group.type==="path-group"){x=this.left+this.radius;y=this.top+this.radius}markup.push("\n')}else{var startX=Math.cos(this.startAngle)*this.radius,startY=Math.sin(this.startAngle)*this.radius,endX=Math.cos(this.endAngle)*this.radius,endY=Math.sin(this.endAngle)*this.radius,largeFlag=angle>pi?"1":"0";markup.push('\n')}return reviver?reviver(markup.join("")):markup.join("")},_render:function(ctx,noTransform){ctx.beginPath();ctx.arc(noTransform?this.left+this.radius:0,noTransform?this.top+this.radius:0,this.radius,this.startAngle,this.endAngle,false);this._renderFill(ctx);this._renderStroke(ctx)},getRadiusX:function(){return this.get("radius")*this.get("scaleX")},getRadiusY:function(){return this.get("radius")*this.get("scaleY")},setRadius:function(value){this.radius=value;return this.set("width",value*2).set("height",value*2)},complexity:function(){return 1}});fabric.Circle.ATTRIBUTE_NAMES=fabric.SHARED_ATTRIBUTES.concat("cx cy r".split(" "));fabric.Circle.fromElement=function(element,options){options||(options={});var parsedAttributes=fabric.parseAttributes(element,fabric.Circle.ATTRIBUTE_NAMES);if(!isValidRadius(parsedAttributes)){throw new Error("value of `r` attribute is required and can not be negative")}parsedAttributes.left=parsedAttributes.left||0;parsedAttributes.top=parsedAttributes.top||0;var obj=new fabric.Circle(extend(parsedAttributes,options));obj.left-=obj.radius;obj.top-=obj.radius;return obj};function isValidRadius(attributes){return"radius"in attributes&&attributes.radius>=0}fabric.Circle.fromObject=function(object){return new fabric.Circle(object)}})(typeof exports!=="undefined"?exports:this);(function(global){"use strict";var fabric=global.fabric||(global.fabric={});if(fabric.Triangle){fabric.warn("fabric.Triangle is already defined");return}fabric.Triangle=fabric.util.createClass(fabric.Object,{type:"triangle",initialize:function(options){options=options||{};this.callSuper("initialize",options);this.set("width",options.width||100).set("height",options.height||100)},_render:function(ctx){var widthBy2=this.width/2,heightBy2=this.height/2;ctx.beginPath();ctx.moveTo(-widthBy2,heightBy2);ctx.lineTo(0,-heightBy2);ctx.lineTo(widthBy2,heightBy2);ctx.closePath();this._renderFill(ctx);this._renderStroke(ctx)},_renderDashedStroke:function(ctx){var widthBy2=this.width/2,heightBy2=this.height/2;ctx.beginPath();fabric.util.drawDashedLine(ctx,-widthBy2,heightBy2,0,-heightBy2,this.strokeDashArray);fabric.util.drawDashedLine(ctx,0,-heightBy2,widthBy2,heightBy2,this.strokeDashArray);fabric.util.drawDashedLine(ctx,widthBy2,heightBy2,-widthBy2,heightBy2,this.strokeDashArray);ctx.closePath()},toSVG:function(reviver){var markup=this._createBaseSVGMarkup(),widthBy2=this.width/2,heightBy2=this.height/2,points=[-widthBy2+" "+heightBy2,"0 "+-heightBy2,widthBy2+" "+heightBy2].join(",");markup.push("');return reviver?reviver(markup.join("")):markup.join("")},complexity:function(){return 1}});fabric.Triangle.fromObject=function(object){return new fabric.Triangle(object)}})(typeof exports!=="undefined"?exports:this);(function(global){"use strict";var fabric=global.fabric||(global.fabric={}),piBy2=Math.PI*2,extend=fabric.util.object.extend;if(fabric.Ellipse){fabric.warn("fabric.Ellipse is already defined."); +return}fabric.Ellipse=fabric.util.createClass(fabric.Object,{type:"ellipse",rx:0,ry:0,initialize:function(options){options=options||{};this.callSuper("initialize",options);this.set("rx",options.rx||0);this.set("ry",options.ry||0)},_set:function(key,value){this.callSuper("_set",key,value);switch(key){case"rx":this.rx=value;this.set("width",value*2);break;case"ry":this.ry=value;this.set("height",value*2);break}return this},getRx:function(){return this.get("rx")*this.get("scaleX")},getRy:function(){return this.get("ry")*this.get("scaleY")},toObject:function(propertiesToInclude){return extend(this.callSuper("toObject",propertiesToInclude),{rx:this.get("rx"),ry:this.get("ry")})},toSVG:function(reviver){var markup=this._createBaseSVGMarkup(),x=0,y=0;if(this.group&&this.group.type==="path-group"){x=this.left+this.rx;y=this.top+this.ry}markup.push("\n');return reviver?reviver(markup.join("")):markup.join("")},_render:function(ctx,noTransform){ctx.beginPath();ctx.save();ctx.transform(1,0,0,this.ry/this.rx,0,0);ctx.arc(noTransform?this.left+this.rx:0,noTransform?(this.top+this.ry)*this.rx/this.ry:0,this.rx,0,piBy2,false);ctx.restore();this._renderFill(ctx);this._renderStroke(ctx)},complexity:function(){return 1}});fabric.Ellipse.ATTRIBUTE_NAMES=fabric.SHARED_ATTRIBUTES.concat("cx cy rx ry".split(" "));fabric.Ellipse.fromElement=function(element,options){options||(options={});var parsedAttributes=fabric.parseAttributes(element,fabric.Ellipse.ATTRIBUTE_NAMES);parsedAttributes.left=parsedAttributes.left||0;parsedAttributes.top=parsedAttributes.top||0;var ellipse=new fabric.Ellipse(extend(parsedAttributes,options));ellipse.top-=ellipse.ry;ellipse.left-=ellipse.rx;return ellipse};fabric.Ellipse.fromObject=function(object){return new fabric.Ellipse(object)}})(typeof exports!=="undefined"?exports:this);(function(global){"use strict";var fabric=global.fabric||(global.fabric={}),extend=fabric.util.object.extend;if(fabric.Rect){fabric.warn("fabric.Rect is already defined");return}var stateProperties=fabric.Object.prototype.stateProperties.concat();stateProperties.push("rx","ry","x","y");fabric.Rect=fabric.util.createClass(fabric.Object,{stateProperties:stateProperties,type:"rect",rx:0,ry:0,strokeDashArray:null,initialize:function(options){options=options||{};this.callSuper("initialize",options);this._initRxRy()},_initRxRy:function(){if(this.rx&&!this.ry){this.ry=this.rx}else if(this.ry&&!this.rx){this.rx=this.ry}},_render:function(ctx,noTransform){if(this.width===1&&this.height===1){ctx.fillRect(-.5,-.5,1,1);return}var rx=this.rx?Math.min(this.rx,this.width/2):0,ry=this.ry?Math.min(this.ry,this.height/2):0,w=this.width,h=this.height,x=noTransform?this.left:-this.width/2,y=noTransform?this.top:-this.height/2,isRounded=rx!==0||ry!==0,k=1-.5522847498;ctx.beginPath();ctx.moveTo(x+rx,y);ctx.lineTo(x+w-rx,y);isRounded&&ctx.bezierCurveTo(x+w-k*rx,y,x+w,y+k*ry,x+w,y+ry);ctx.lineTo(x+w,y+h-ry);isRounded&&ctx.bezierCurveTo(x+w,y+h-k*ry,x+w-k*rx,y+h,x+w-rx,y+h);ctx.lineTo(x+rx,y+h);isRounded&&ctx.bezierCurveTo(x+k*rx,y+h,x,y+h-k*ry,x,y+h-ry);ctx.lineTo(x,y+ry);isRounded&&ctx.bezierCurveTo(x,y+k*ry,x+k*rx,y,x+rx,y);ctx.closePath();this._renderFill(ctx);this._renderStroke(ctx)},_renderDashedStroke:function(ctx){var x=-this.width/2,y=-this.height/2,w=this.width,h=this.height;ctx.beginPath();fabric.util.drawDashedLine(ctx,x,y,x+w,y,this.strokeDashArray);fabric.util.drawDashedLine(ctx,x+w,y,x+w,y+h,this.strokeDashArray);fabric.util.drawDashedLine(ctx,x+w,y+h,x,y+h,this.strokeDashArray);fabric.util.drawDashedLine(ctx,x,y+h,x,y,this.strokeDashArray);ctx.closePath()},toObject:function(propertiesToInclude){var object=extend(this.callSuper("toObject",propertiesToInclude),{rx:this.get("rx")||0,ry:this.get("ry")||0});if(!this.includeDefaultValues){this._removeDefaultValues(object)}return object},toSVG:function(reviver){var markup=this._createBaseSVGMarkup(),x=this.left,y=this.top;if(!(this.group&&this.group.type==="path-group")){x=-this.width/2;y=-this.height/2}markup.push("\n');return reviver?reviver(markup.join("")):markup.join("")},complexity:function(){return 1}});fabric.Rect.ATTRIBUTE_NAMES=fabric.SHARED_ATTRIBUTES.concat("x y rx ry width height".split(" "));fabric.Rect.fromElement=function(element,options){if(!element){return null}options=options||{};var parsedAttributes=fabric.parseAttributes(element,fabric.Rect.ATTRIBUTE_NAMES);parsedAttributes.left=parsedAttributes.left||0;parsedAttributes.top=parsedAttributes.top||0;var rect=new fabric.Rect(extend(options?fabric.util.object.clone(options):{},parsedAttributes));rect.visible=rect.width>0&&rect.height>0;return rect};fabric.Rect.fromObject=function(object){return new fabric.Rect(object)}})(typeof exports!=="undefined"?exports:this);(function(global){"use strict";var fabric=global.fabric||(global.fabric={});if(fabric.Polyline){fabric.warn("fabric.Polyline is already defined");return}fabric.Polyline=fabric.util.createClass(fabric.Object,{type:"polyline",points:null,minX:0,minY:0,initialize:function(points,options){return fabric.Polygon.prototype.initialize.call(this,points,options)},_calcDimensions:function(){return fabric.Polygon.prototype._calcDimensions.call(this)},_applyPointOffset:function(){return fabric.Polygon.prototype._applyPointOffset.call(this)},toObject:function(propertiesToInclude){return fabric.Polygon.prototype.toObject.call(this,propertiesToInclude)},toSVG:function(reviver){return fabric.Polygon.prototype.toSVG.call(this,reviver)},_render:function(ctx,noTransform){if(!fabric.Polygon.prototype.commonRender.call(this,ctx,noTransform)){return}this._renderFill(ctx);this._renderStroke(ctx)},_renderDashedStroke:function(ctx){var p1,p2;ctx.beginPath();for(var i=0,len=this.points.length;i\n');return reviver?reviver(markup.join("")):markup.join("")},_render:function(ctx,noTransform){if(!this.commonRender(ctx,noTransform)){return}this._renderFill(ctx);if(this.stroke||this.strokeDashArray){ctx.closePath();this._renderStroke(ctx)}},commonRender:function(ctx,noTransform){var point,len=this.points.length;if(!len||isNaN(this.points[len-1].y)){return false}noTransform||ctx.translate(-this.pathOffset.x,-this.pathOffset.y);ctx.beginPath();ctx.moveTo(this.points[0].x,this.points[0].y);for(var i=0;i"},toObject:function(propertiesToInclude){var o=extend(this.callSuper("toObject",propertiesToInclude),{path:this.path.map(function(item){return item.slice()}),pathOffset:this.pathOffset});if(this.sourcePath){o.sourcePath=this.sourcePath}if(this.transformMatrix){o.transformMatrix=this.transformMatrix}return o},toDatalessObject:function(propertiesToInclude){var o=this.toObject(propertiesToInclude);if(this.sourcePath){o.path=this.sourcePath}delete o.sourcePath;return o},toSVG:function(reviver){var chunks=[],markup=this._createBaseSVGMarkup(),addTransform="";for(var i=0,len=this.path.length;i\n");return reviver?reviver(markup.join("")):markup.join("")},complexity:function(){return this.path.length},_parsePath:function(){var result=[],coords=[],currentPath,parsed,re=/([-+]?((\d+\.\d+)|((\d+)|(\.\d+)))(?:e[-+]?\d+)?)/gi,match,coordsStr;for(var i=0,coordsParsed,len=this.path.length;icommandLength){for(var k=1,klen=coordsParsed.length;k\n");for(var i=0,len=objects.length;i\n");return reviver?reviver(markup.join("")):markup.join("")},toString:function(){return"#"},isSameColor:function(){var firstPathFill=this.getObjects()[0].get("fill")||"";if(typeof firstPathFill!=="string"){return false}firstPathFill=firstPathFill.toLowerCase();return this.getObjects().every(function(path){var pathFill=path.get("fill")||"";return typeof pathFill==="string"&&pathFill.toLowerCase()===firstPathFill})},complexity:function(){return this.paths.reduce(function(total,path){return total+(path&&path.complexity?path.complexity():0)},0)},getObjects:function(){return this.paths}});fabric.PathGroup.fromObject=function(object,callback){if(typeof object.paths==="string"){fabric.loadSVGFromURL(object.paths,function(elements){var pathUrl=object.paths;delete object.paths;var pathGroup=fabric.util.groupSVGElements(elements,object,pathUrl);callback(pathGroup)})}else{fabric.util.enlivenObjects(object.paths,function(enlivenedObjects){delete object.paths;callback(new fabric.PathGroup(enlivenedObjects,object))})}};fabric.PathGroup.async=true})(typeof exports!=="undefined"?exports:this);(function(global){"use strict";var fabric=global.fabric||(global.fabric={}),extend=fabric.util.object.extend,min=fabric.util.array.min,max=fabric.util.array.max,invoke=fabric.util.array.invoke;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,initialize:function(objects,options,isAlreadyGrouped){options=options||{};this._objects=[];isAlreadyGrouped&&this.callSuper("initialize",options);this._objects=objects||[];for(var i=this._objects.length;i--;){this._objects[i].group=this}this.originalState={};if(options.originX){this.originX=options.originX}if(options.originY){this.originY=options.originY}if(isAlreadyGrouped){this._updateObjectsCoords(true)}else{this._calcBounds();this._updateObjectsCoords();this.callSuper("initialize",options)}this.setCoords();this.saveCoords()},_updateObjectsCoords:function(skipCoordsChange){for(var i=this._objects.length;i--;){this._updateObjectCoords(this._objects[i],skipCoordsChange)}},_updateObjectCoords:function(object,skipCoordsChange){object.__origHasControls=object.hasControls;object.hasControls=false;if(skipCoordsChange){return}var objectLeft=object.getLeft(),objectTop=object.getTop(),center=this.getCenterPoint();object.set({originalLeft:objectLeft,originalTop:objectTop,left:objectLeft-center.x,top:objectTop-center.y});object.setCoords()},toString:function(){return"#"},addWithUpdate:function(object){this._restoreObjectsState();fabric.util.resetObjectTransform(this);if(object){this._objects.push(object);object.group=this;object._set("canvas",this.canvas)}this.forEachObject(this._setObjectActive,this);this._calcBounds();this._updateObjectsCoords();return this},_setObjectActive:function(object){object.set("active",true);object.group=this},removeWithUpdate:function(object){this._restoreObjectsState();fabric.util.resetObjectTransform(this);this.forEachObject(this._setObjectActive,this);this.remove(object);this._calcBounds();this._updateObjectsCoords();return this},_onObjectAdded:function(object){object.group=this;object._set("canvas",this.canvas)},_onObjectRemoved:function(object){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"){while(i--){this._objects[i].set(key,value)}}else{while(i--){this._objects[i].setOnGroup(key,value)}}this.callSuper("_set",key,value)},toObject:function(propertiesToInclude){return extend(this.callSuper("toObject",propertiesToInclude),{objects:invoke(this._objects,"toObject",propertiesToInclude)})},render:function(ctx){if(!this.visible){return}ctx.save();if(this.transformMatrix){ctx.transform.apply(ctx,this.transformMatrix)}this.transform(ctx);this._setShadow(ctx);this.clipTo&&fabric.util.clipContext(this,ctx);for(var i=0,len=this._objects.length;i\n');for(var i=0,len=this._objects.length;i\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;i0){object.resizeFilters=this.resizeFilters.map(function(filterObj){return filterObj&&filterObj.toObject()})}if(!this.includeDefaultValues){this._removeDefaultValues(object)}return object},toSVG:function(reviver){var markup=this._createBaseSVGMarkup(),x=-this.width/2,y=-this.height/2,preserveAspectRatio="none";if(this.group&&this.group.type==="path-group"){x=this.left;y=this.top}if(this.alignX!=="none"&&this.alignY!=="none"){preserveAspectRatio="x"+this.alignX+"Y"+this.alignY+" "+this.meetOrSlice}markup.push('\n','\n");if(this.stroke||this.strokeDashArray){var origFill=this.fill;this.fill=null;markup.push("\n');this.fill=origFill}markup.push("\n");return reviver?reviver(markup.join("")):markup.join("")},getSrc:function(){if(this.getElement()){return this.getElement().src||this.getElement()._src}},setSrc:function(src,callback,options){fabric.util.loadImage(src,function(img){return this.setElement(img,callback,options)},this,options&&options.crossOrigin)},toString:function(){return'#'},clone:function(callback,propertiesToInclude){this.constructor.fromObject(this.toObject(propertiesToInclude),callback)},applyFilters:function(callback,filters,imgElement,forResizing){filters=filters||this.filters;imgElement=imgElement||this._originalElement;if(!imgElement){return}var imgEl=imgElement,canvasEl=fabric.util.createCanvasElement(),replacement=fabric.util.createImage(),_this=this;canvasEl.width=imgEl.width;canvasEl.height=imgEl.height;canvasEl.getContext("2d").drawImage(imgEl,0,0,imgEl.width,imgEl.height);if(filters.length===0){this._element=imgElement;callback&&callback();return canvasEl}filters.forEach(function(filter){filter&&filter.applyTo(canvasEl,filter.scaleX||_this.scaleX,filter.scaleY||_this.scaleY);if(!forResizing&&filter&&filter.type==="Resize"){_this.width*=filter.scaleX;_this.height*=filter.scaleY}});replacement.width=canvasEl.width;replacement.height=canvasEl.height;if(fabric.isLikelyNode){replacement.src=canvasEl.toBuffer(undefined,fabric.Image.pngCompression);_this._element=replacement;!forResizing&&(_this._filteredEl=replacement);callback&&callback()}else{replacement.onload=function(){_this._element=replacement;!forResizing&&(_this._filteredEl=replacement);callback&&callback();replacement.onload=canvasEl=imgEl=null};replacement.src=canvasEl.toDataURL("image/png")}return canvasEl},_render:function(ctx,noTransform){var x,y,imageMargins=this._findMargins(),elementToDraw;x=noTransform?this.left:-this.width/2;y=noTransform?this.top:-this.height/2;if(this.meetOrSlice==="slice"){ctx.beginPath();ctx.rect(x,y,this.width,this.height);ctx.clip()}if(this.isMoving===false&&this.resizeFilters.length&&this._needsResize()){this._lastScaleX=this.scaleX;this._lastScaleY=this.scaleY;elementToDraw=this.applyFilters(null,this.resizeFilters,this._filteredEl||this._originalElement,true)}else{elementToDraw=this._element}elementToDraw&&ctx.drawImage(elementToDraw,x+imageMargins.marginX,y+imageMargins.marginY,imageMargins.width,imageMargins.height);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);this.set("height",element.height)},_initElement:function(element,options){this.setElement(fabric.util.getById(element),null,options);fabric.util.addClass(this.getElement(),fabric.Image.CSS_CANVAS)},_initConfig:function(options){options||(options={});this.setOptions(options);this._setWidthHeight(options);if(this._element&&this.crossOrigin){this._element.crossOrigin=this.crossOrigin}},_initFilters:function(filters,callback){if(filters&&filters.length){fabric.util.enlivenObjects(filters,function(enlivenedObjects){callback&&callback(enlivenedObjects)},"fabric.Image.filters")}else{callback&&callback()}},_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},complexity:function(){return 1}});fabric.Image.CSS_CANVAS="canvas-img";fabric.Image.prototype.getSvgSrc=fabric.Image.prototype.getSrc;fabric.Image.fromObject=function(object,callback){fabric.util.loadImage(object.src,function(img){fabric.Image.prototype._initFilters.call(object,object.filters,function(filters){object.filters=filters||[];fabric.Image.prototype._initFilters.call(object,object.resizeFilters,function(resizeFilters){object.resizeFilters=resizeFilters||[];var instance=new fabric.Image(img,object);callback&&callback(instance)})})},null,object.crossOrigin)};fabric.Image.fromURL=function(url,callback,imgOptions){fabric.util.loadImage(url,function(img){callback&&callback(new fabric.Image(img,imgOptions))},null,imgOptions&&imgOptions.crossOrigin)};fabric.Image.ATTRIBUTE_NAMES=fabric.SHARED_ATTRIBUTES.concat("x y width height preserveAspectRatio xlink:href".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)}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;if(angle>0){return Math.round((angle-1)/90)*90}return Math.round(angle/90)*90},straighten:function(){this.setAngle(this._getAngleValueForStraighten());return this},fxStraighten:function(callbacks){callbacks=callbacks||{};var empty=function(){},onComplete=callbacks.onComplete||empty,onChange=callbacks.onChange||empty,_this=this;fabric.util.animate({startValue:this.get("angle"),endValue:this._getAngleValueForStraighten(),duration:this.FX_DURATION,onChange:function(value){_this.setAngle(value);onChange()},onComplete:function(){_this.setCoords();onComplete()},onStart:function(){_this.set("active",false)}});return this}});fabric.util.object.extend(fabric.StaticCanvas.prototype,{straightenObject:function(object){object.straighten();this.renderAll();return this},fxStraightenObject:function(object){object.fxStraighten({onChange:this.renderAll.bind(this)});return this}});fabric.Image.filters=fabric.Image.filters||{};fabric.Image.filters.BaseFilter=fabric.util.createClass({type:"BaseFilter",initialize:function(options){if(options){this.setOptions(options)}},setOptions:function(options){for(var prop in options){this[prop]=options[prop]}},toObject:function(){return{type:this.type}},toJSON:function(){return this.toObject()}});(function(global){"use strict";var fabric=global.fabric||(global.fabric={}),extend=fabric.util.object.extend;fabric.Image.filters.Brightness=fabric.util.createClass(fabric.Image.filters.BaseFilter,{type:"Brightness",initialize:function(options){options=options||{};this.brightness=options.brightness||0},applyTo:function(canvasEl){var context=canvasEl.getContext("2d"),imageData=context.getImageData(0,0,canvasEl.width,canvasEl.height),data=imageData.data,brightness=this.brightness;for(var i=0,len=data.length;ish||scx<0||scx>sw){continue}srcOff=(scy*sw+scx)*4;wt=weights[cy*side+cx];r+=src[srcOff]*wt;g+=src[srcOff+1]*wt;b+=src[srcOff+2]*wt;a+=src[srcOff+3]*wt}}dst[dstOff]=r;dst[dstOff+1]=g;dst[dstOff+2]=b;dst[dstOff+3]=a+alphaFac*(255-a)}}context.putImageData(output,0,0)},toObject:function(){return extend(this.callSuper("toObject"),{opaque:this.opaque,matrix:this.matrix})}});fabric.Image.filters.Convolute.fromObject=function(object){return new fabric.Image.filters.Convolute(object)}})(typeof exports!=="undefined"?exports:this);(function(global){"use strict";var fabric=global.fabric||(global.fabric={}),extend=fabric.util.object.extend;fabric.Image.filters.GradientTransparency=fabric.util.createClass(fabric.Image.filters.BaseFilter,{type:"GradientTransparency",initialize:function(options){options=options||{};this.threshold=options.threshold||100},applyTo:function(canvasEl){var context=canvasEl.getContext("2d"),imageData=context.getImageData(0,0,canvasEl.width,canvasEl.height),data=imageData.data,threshold=this.threshold,total=data.length;for(var i=0,len=data.length;i-1?options.channel:0},applyTo:function(canvasEl){if(!this.mask){return}var context=canvasEl.getContext("2d"),imageData=context.getImageData(0,0,canvasEl.width,canvasEl.height),data=imageData.data,maskEl=this.mask.getElement(),maskCanvasEl=fabric.util.createCanvasElement(),channel=this.channel,i,iLen=imageData.width*imageData.height*4;maskCanvasEl.width=canvasEl.width;maskCanvasEl.height=canvasEl.height;maskCanvasEl.getContext("2d").drawImage(maskEl,0,0,canvasEl.width,canvasEl.height);var maskImageData=maskCanvasEl.getContext("2d").getImageData(0,0,canvasEl.width,canvasEl.height),maskData=maskImageData.data;for(i=0;ilimit&&g>limit&&b>limit&&abs(r-g)width){multW=2;signW=-1}if(newHeight>height){multH=2;signH=-1}imageData=context.getImageData(0,0,width,height);canvasEl.width=max(newWidth,width);canvasEl.height=max(newHeight,height);context.putImageData(imageData,0,0);while(!doneW||!doneH){width=stepW;height=stepH;if(newWidth*signWlobes){return 0}x*=Math.PI;if(abs(x)<1e-16){return 1}var xx=x/lobes;return sin(x)*sin(xx)/x/xx}}function process(u){var v,i,weight,idx,a,red,green,blue,alpha,fX,fY;center.x=(u+.5)*ratioX;icenter.x=floor(center.x);for(v=0;v=oW){continue}fX=floor(1e3*abs(i-center.x));if(!cacheLanc[fX]){cacheLanc[fX]={}}for(var j=icenter.y-range2Y;j<=icenter.y+range2Y;j++){if(j<0||j>=oH){continue}fY=floor(1e3*abs(j-center.y));if(!cacheLanc[fX][fY]){cacheLanc[fX][fY]=lanczos(sqrt(pow(fX*rcpRatioX,2)+pow(fY*rcpRatioY,2))/1e3)}weight=cacheLanc[fX][fY];if(weight>0){idx=(j*oW+i)*4;a+=weight;red+=weight*srcData[idx];green+=weight*srcData[idx+1];blue+=weight*srcData[idx+2];alpha+=weight*srcData[idx+3]}}}idx=(v*dW+u)*4;destData[idx]=red/a;destData[idx+1]=green/a;destData[idx+2]=blue/a;destData[idx+3]=alpha/a}if(++u1&&w<-1){continue}weight=2*w*w*w-3*w*w+1;if(weight>0){dx=4*(xx+yy*oW);gxA+=weight*data[dx+3];weightsAlpha+=weight;if(data[dx+3]<255){weight=weight*data[dx+3]/250}gxR+=weight*data[dx];gxG+=weight*data[dx+1];gxB+=weight*data[dx+2];weights+=weight}}}data2[x2]=gxR/weights;data2[x2+1]=gxG/weights;data2[x2+2]=gxB/weights;data2[x2+3]=gxA/weightsAlpha}}return img2},toObject:function(){return{type:this.type,scaleX:this.scaleX,scaleY:this.scaleY,resizeType:this.resizeType,lanczosLobes:this.lanczosLobes}}});fabric.Image.filters.Resize.fromObject=function(object){return new fabric.Image.filters.Resize(object)}})(typeof exports!=="undefined"?exports:this);(function(global){"use strict";var fabric=global.fabric||(global.fabric={}),extend=fabric.util.object.extend,clone=fabric.util.object.clone,toFixed=fabric.util.toFixed,supportsLineDash=fabric.StaticCanvas.supports("setLineDash"),NUM_FRACTION_DIGITS=fabric.Object.NUM_FRACTION_DIGITS;if(fabric.Text){fabric.warn("fabric.Text is already defined");return}var stateProperties=fabric.Object.prototype.stateProperties.concat();stateProperties.push("fontFamily","fontWeight","fontSize","text","textDecoration","textAlign","fontStyle","lineHeight","textBackgroundColor");fabric.Text=fabric.util.createClass(fabric.Object,{_dimensionAffectingProps:{fontSize:true,fontWeight:true,fontFamily:true,fontStyle:true,lineHeight:true,stroke:true,strokeWidth:true,text:true,textAlign:true},_reNewline:/\r?\n/,_reSpacesAndTabs:/[ \t\r]+/g,type:"text",fontSize:40,fontWeight:"normal",fontFamily:"Times New Roman",textDecoration:"",textAlign:"left",fontStyle:"",lineHeight:1.16,textBackgroundColor:"",stateProperties:stateProperties,stroke:null,shadow:null,_fontSizeFraction:.25,_fontSizeMult:1.13,initialize:function(text,options){options=options||{};this.text=text;this.__skipDimension=true;this.setOptions(options);this.__skipDimension=false;this._initDimensions()},_initDimensions:function(ctx){if(this.__skipDimension){return}if(!ctx){ctx=fabric.util.createCanvasElement().getContext("2d");this._setTextStyles(ctx)}this._textLines=this._splitTextIntoLines();this._clearCache();this._cacheLinesWidth=this.textAlign!=="justify";this.width=this._getTextWidth(ctx);this._cacheLinesWidth=true;this.height=this._getTextHeight(ctx)},toString:function(){return"#'},_render:function(ctx){this.clipTo&&fabric.util.clipContext(this,ctx);this._setOpacity(ctx);this._setShadow(ctx);this._setupCompositeOperation(ctx);this._renderTextBackground(ctx);this._setStrokeStyles(ctx);this._setFillStyles(ctx);this._renderText(ctx);this._renderTextDecoration(ctx);this.clipTo&&ctx.restore()},_renderText:function(ctx){this._translateForTextAlign(ctx);this._renderTextFill(ctx);this._renderTextStroke(ctx);this._translateForTextAlign(ctx,true)},_translateForTextAlign:function(ctx,back){if(this.textAlign!=="left"&&this.textAlign!=="justify"){var sign=back?-1:1;ctx.translate(this.textAlign==="center"?sign*this.width/2:sign*this.width,0)}},_setTextStyles:function(ctx){ctx.textBaseline="alphabetic";if(!this.skipTextAlign){ctx.textAlign=this.textAlign}ctx.font=this._getFontDeclaration()},_getTextHeight:function(){return this._textLines.length*this._getHeightOfLine()},_getTextWidth:function(ctx){var maxWidth=this._getLineWidth(ctx,0);for(var i=1,len=this._textLines.length;imaxWidth){maxWidth=currentLineWidth}}return maxWidth},_renderChars:function(method,ctx,chars,left,top){var shortM=method.slice(0,-4);if(this[shortM].toLive){var offsetX=-this.width/2+this[shortM].offsetX||0,offsetY=-this.height/2+this[shortM].offsetY||0;ctx.save();ctx.translate(offsetX,offsetY);left-=offsetX;top-=offsetY}ctx[method](chars,left,top);this[shortM].toLive&&ctx.restore()},_renderTextLine:function(method,ctx,line,left,top,lineIndex){top-=this.fontSize*this._fontSizeFraction;var lineWidth=this._getLineWidth(ctx,lineIndex);if(this.textAlign!=="justify"||this.width0?widthDiff/numSpaces:0,leftOffset=0,word; +for(var i=0,len=words.length;i1){width=this.width}else{width=ctx.measureText(line).width}}else{width=ctx.measureText(line).width}this._cacheLinesWidth&&(this.__lineWidths[lineIndex]=width);return width},_renderTextDecoration:function(ctx){if(!this.textDecoration){return}var halfOfVerticalBox=this.height/2,_this=this,offsets=[];function renderLinesAtOffset(offsets){var i,lineHeight=0,len,j,oLen,lineWidth,lineLeftOffset,heightOfLine;for(i=0,len=_this._textLines.length;i-1){offsets.push(.85)}if(this.textDecoration.indexOf("line-through")>-1){offsets.push(.43)}if(this.textDecoration.indexOf("overline")>-1){offsets.push(-.12)}if(offsets.length>0){renderLinesAtOffset(offsets)}},_getFontDeclaration:function(){return[fabric.isLikelyNode?this.fontWeight:this.fontStyle,fabric.isLikelyNode?this.fontStyle:this.fontWeight,this.fontSize+"px",fabric.isLikelyNode?'"'+this.fontFamily+'"':this.fontFamily].join(" ")},render:function(ctx,noTransform){if(!this.visible){return}ctx.save();this._setTextStyles(ctx);if(this._shouldClearCache()){this._initDimensions(ctx)}if(!noTransform){this.transform(ctx)}if(this.transformMatrix){ctx.transform.apply(ctx,this.transformMatrix)}if(this.group&&this.group.type==="path-group"){ctx.translate(this.left,this.top)}this._render(ctx);ctx.restore()},_splitTextIntoLines:function(){return this.text.split(this._reNewline)},toObject:function(propertiesToInclude){var object=extend(this.callSuper("toObject",propertiesToInclude),{text:this.text,fontSize:this.fontSize,fontWeight:this.fontWeight,fontFamily:this.fontFamily,fontStyle:this.fontStyle,lineHeight:this.lineHeight,textDecoration:this.textDecoration,textAlign:this.textAlign,textBackgroundColor:this.textBackgroundColor});if(!this.includeDefaultValues){this._removeDefaultValues(object)}return object},toSVG:function(reviver){var markup=this._createBaseSVGMarkup(),offsets=this._getSVGLeftTopOffsets(this.ctx),textAndBg=this._getSVGTextAndBg(offsets.textTop,offsets.textLeft);this._wrapSVGTextAndBg(markup,textAndBg);return reviver?reviver(markup.join("")):markup.join("")},_getSVGLeftTopOffsets:function(ctx){var lineTop=this._getHeightOfLine(ctx,0),textLeft=-this.width/2,textTop=0;return{textLeft:textLeft+(this.group&&this.group.type==="path-group"?this.left:0),textTop:textTop+(this.group&&this.group.type==="path-group"?-this.top:0),lineTop:lineTop}},_wrapSVGTextAndBg:function(markup,textAndBg){var noShadow=true,filter=this.getSvgFilter(),style=filter===""?"":' style="'+filter+'"';markup.push(' \n",textAndBg.textBgRects.join("")," \n',textAndBg.textSpans.join("")," \n"," \n")},_getSVGTextAndBg:function(textTopOffset,textLeftOffset){var textSpans=[],textBgRects=[],height=0;this._setSVGBg(textBgRects);for(var i=0,len=this._textLines.length;i",fabric.util.string.escapeXml(this._textLines[i]),"\n")},_setSVGTextLineJustifed:function(i,textSpans,yPos,textLeftOffset){var ctx=fabric.util.createCanvasElement().getContext("2d");this._setTextStyles(ctx);var line=this._textLines[i],words=line.split(/\s+/),wordsWidth=this._getWidthOfWords(ctx,line),widthDiff=this.width-wordsWidth,numSpaces=words.length-1,spaceWidth=numSpaces>0?widthDiff/numSpaces:0,word,attributes=this._getFillAttributes(this.fill),len;textLeftOffset+=this._getLineLeftOffset(this._getLineWidth(ctx,i));for(i=0,len=words.length;i",fabric.util.string.escapeXml(word),"\n");textLeftOffset+=this._getWidthOfWords(ctx,word)+spaceWidth}},_setSVGTextLineBg:function(textBgRects,i,textLeftOffset,textTopOffset,height){textBgRects.push(" \n')},_setSVGBg:function(textBgRects){if(this.backgroundColor){textBgRects.push(" \n')}},_getFillAttributes:function(value){var fillColor=value&&typeof value==="string"?new fabric.Color(value):"";if(!fillColor||!fillColor.getSource()||fillColor.getAlpha()===1){return'fill="'+value+'"'}return'opacity="'+fillColor.getAlpha()+'" fill="'+fillColor.setAlpha(1).toRgb()+'"'},_set:function(key,value){this.callSuper("_set",key,value);if(key in this._dimensionAffectingProps){this._initDimensions();this.setCoords()}},complexity:function(){return 1}});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){if(!element){return null}var parsedAttributes=fabric.parseAttributes(element,fabric.Text.ATTRIBUTE_NAMES);options=fabric.util.object.extend(options?fabric.util.object.clone(options):{},parsedAttributes);options.top=options.top||0;options.left=options.left||0;if("dx"in parsedAttributes){options.left+=parsedAttributes.dx}if("dy"in parsedAttributes){options.top+=parsedAttributes.dy}if(!("fontSize"in options)){options.fontSize=fabric.Text.DEFAULT_SVG_FONT_SIZE}if(!options.originX){options.originX="left"}var textContent="";if(!("textContent"in element)){if("firstChild"in element&&element.firstChild!==null){if("data"in element.firstChild&&element.firstChild.data!==null){textContent=element.firstChild.data}}}else{textContent=element.textContent}textContent=textContent.replace(/^\s+|\s+$|\n+/g,"").replace(/\s+/g," ");var text=new fabric.Text(textContent,options),offX=0;if(text.originX==="left"){offX=text.getWidth()/2}if(text.originX==="right"){offX=-text.getWidth()/2}text.set({left:text.getLeft()+offX,top:text.getTop()-text.getHeight()/2+text.fontSize*(.18+text._fontSizeFraction)});return text};fabric.Text.fromObject=function(object){return new fabric.Text(object.text,clone(object))};fabric.util.createAccessors(fabric.Text)})(typeof exports!=="undefined"?exports:this);(function(){var clone=fabric.util.object.clone;fabric.IText=fabric.util.createClass(fabric.Text,fabric.Observable,{type:"i-text",selectionStart:0,selectionEnd:0,selectionColor:"rgba(17,119,255,0.3)",isEditing:false,editable:true,editingBorderColor:"rgba(102,153,255,0.25)",cursorWidth:2,cursorColor:"#333",cursorDelay:1e3,cursorDuration:600,styles:null,caching:true,_reSpace:/\s|\n/,_currentCursorOpacity:0,_selectionDirection:null,_abortCursorAnimation:false,_charWidthsCache:{},__widthOfSpace:[],initialize:function(text,options){this.styles=options?options.styles||{}:{};this.callSuper("initialize",text,options);this.initBehavior()},_clearCache:function(){this.callSuper("_clearCache");this.__widthOfSpace=[]},isEmptyStyles:function(){if(!this.styles){return true}var obj=this.styles;for(var p1 in obj){for(var p2 in obj[p1]){for(var p3 in obj[p1][p2]){return false}}}return true},setSelectionStart:function(index){index=Math.max(index,0);if(this.selectionStart!==index){this.fire("selection:changed");this.canvas&&this.canvas.fire("text:selection:changed",{target:this});this.selectionStart=index}this._updateTextarea()},setSelectionEnd:function(index){index=Math.min(index,this.text.length);if(this.selectionEnd!==index){this.fire("selection:changed");this.canvas&&this.canvas.fire("text:selection:changed",{target:this});this.selectionEnd=index}this._updateTextarea()},getSelectionStyles:function(startIndex,endIndex){if(arguments.length===2){var styles=[];for(var i=startIndex;i=start.charIndex&&(i!==endLine||jstartLine&&i0||this.skipFillStrokeCheck)){this.callSuper("_renderChars",method,ctx,line,left,top)}},_renderChar:function(method,ctx,lineIndex,i,_char,left,top,lineHeight){var charWidth,charHeight,shouldFill,shouldStroke,decl=this._getStyleDeclaration(lineIndex,i),offset,textDecoration;if(decl){charHeight=this._getHeightOfChar(ctx,_char,lineIndex,i);shouldStroke=decl.stroke;shouldFill=decl.fill;textDecoration=decl.textDecoration}else{charHeight=this.fontSize}shouldStroke=(shouldStroke||this.stroke)&&method==="strokeText";shouldFill=(shouldFill||this.fill)&&method==="fillText";decl&&ctx.save();charWidth=this._applyCharStylesGetWidth(ctx,_char,lineIndex,i,decl||{});textDecoration=textDecoration||this.textDecoration;if(decl&&decl.textBackgroundColor){this._removeShadow(ctx)}shouldFill&&ctx.fillText(_char,left,top);shouldStroke&&ctx.strokeText(_char,left,top);if(textDecoration||textDecoration!==""){offset=this._fontSizeFraction*lineHeight/this.lineHeight;this._renderCharDecoration(ctx,textDecoration,left,top,offset,charWidth,charHeight)}decl&&ctx.restore();ctx.translate(charWidth,0)},_hasStyleChanged:function(prevStyle,thisStyle){return prevStyle.fill!==thisStyle.fill||prevStyle.fontSize!==thisStyle.fontSize||prevStyle.textBackgroundColor!==thisStyle.textBackgroundColor||prevStyle.textDecoration!==thisStyle.textDecoration||prevStyle.fontFamily!==thisStyle.fontFamily||prevStyle.fontWeight!==thisStyle.fontWeight||prevStyle.fontStyle!==thisStyle.fontStyle||prevStyle.stroke!==thisStyle.stroke||prevStyle.strokeWidth!==thisStyle.strokeWidth},_renderCharDecoration:function(ctx,textDecoration,left,top,offset,charWidth,charHeight){if(!textDecoration){return}var decorationWeight=charHeight/15,positions={underline:top+charHeight/10,"line-through":top-charHeight*(this._fontSizeFraction+this._fontSizeMult-1)+decorationWeight,overline:top-(this._fontSizeMult-this._fontSizeFraction)*charHeight},decorations=["underline","line-through","overline"],i,decoration;for(i=0;i-1){ctx.fillRect(left,positions[decoration],charWidth,decorationWeight)}}},_renderTextLine:function(method,ctx,line,left,top,lineIndex){if(!this.isEmptyStyles()){top+=this.fontSize*(this._fontSizeFraction+.03)}this.callSuper("_renderTextLine",method,ctx,line,left,top,lineIndex)},_renderTextDecoration:function(ctx){if(this.isEmptyStyles()){return this.callSuper("_renderTextDecoration",ctx)}},_renderTextLinesBackground:function(ctx){this.callSuper("_renderTextLinesBackground",ctx);var lineTopOffset=0,heightOfLine,lineWidth,lineLeftOffset,leftOffset=this._getLeftOffset(),topOffset=this._getTopOffset(),line,_char,style;for(var i=0,len=this._textLines.length;imaxHeight){maxHeight=currentCharHeight}}this.__lineHeights[lineIndex]=maxHeight*this.lineHeight*this._fontSizeMult;return this.__lineHeights[lineIndex]},_getTextHeight:function(ctx){var height=0;for(var i=0,len=this._textLines.length;i-1){offset++;index--}return startFrom-offset},findWordBoundaryRight:function(startFrom){var offset=0,index=startFrom;if(this._reSpace.test(this.text.charAt(index))){while(this._reSpace.test(this.text.charAt(index))){offset++;index++}}while(/\S/.test(this.text.charAt(index))&&index-1){offset++; +index--}return startFrom-offset},findLineBoundaryRight:function(startFrom){var offset=0,index=startFrom;while(!/\n/.test(this.text.charAt(index))&&index0&&index=_this.__selectionStartOnMouseDown){_this.setSelectionStart(_this.__selectionStartOnMouseDown);_this.setSelectionEnd(newSelectionStart)}else{_this.setSelectionStart(newSelectionStart);_this.setSelectionEnd(_this.__selectionStartOnMouseDown)}})},_setEditingProps:function(){this.hoverCursor="text";if(this.canvas){this.canvas.defaultCursor=this.canvas.moveCursor="text"}this.borderColor=this.editingBorderColor;this.hasControls=this.selectable=false;this.lockMovementX=this.lockMovementY=true},_updateTextarea:function(){if(!this.hiddenTextarea||this.inCompositionMode){return}this.hiddenTextarea.value=this.text;this.hiddenTextarea.selectionStart=this.selectionStart;this.hiddenTextarea.selectionEnd=this.selectionEnd;if(this.selectionStart===this.selectionEnd){var p=this._calcTextareaPosition();this.hiddenTextarea.style.left=p.x+"px";this.hiddenTextarea.style.top=p.y+"px"}},_calcTextareaPosition:function(){var chars=this.text.split(""),boundaries=this._getCursorBoundaries(chars,"cursor"),cursorLocation=this.get2DCursorLocation(),lineIndex=cursorLocation.lineIndex,charIndex=cursorLocation.charIndex,charHeight=this.getCurrentCharFontSize(lineIndex,charIndex),leftOffset=lineIndex===0&&charIndex===0?this._getLineLeftOffset(this._getLineWidth(this.ctx,lineIndex)):boundaries.leftOffset,m=this.calcTransformMatrix(),p={x:boundaries.left+leftOffset,y:boundaries.top+boundaries.topOffset+charHeight};this.hiddenTextarea.style.fontSize=charHeight+"px";return fabric.util.transformPoint(p,m)},_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(){if(!this._savedProps){return}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;if(this.canvas){this.canvas.defaultCursor=this._savedProps.defaultCursor;this.canvas.moveCursor=this._savedProps.moveCursor}},exitEditing:function(){this.selected=false;this.isEditing=false;this.selectable=true;this.selectionEnd=this.selectionStart;this.hiddenTextarea&&this.canvas&&this.hiddenTextarea.parentNode.removeChild(this.hiddenTextarea);this.hiddenTextarea=null;this.abortCursorAnimation();this._restoreEditingProps();this._currentCursorOpacity=0;this.fire("editing:exited");this.canvas&&this.canvas.fire("text:editing:exited",{target:this});return this},_removeExtraneousStyles:function(){for(var prop in this.styles){if(!this._textLines[prop]){delete this.styles[prop]}}},_removeCharsFromTo:function(start,end){while(end!==start){this._removeSingleCharAndStyle(start+1);end--}this.setSelectionStart(start)},_removeSingleCharAndStyle:function(index){var isBeginningOfLine=this.text[index-1]==="\n",indexStyle=isBeginningOfLine?index:index-1;this.removeStyleObject(isBeginningOfLine,indexStyle);this.text=this.text.slice(0,index-1)+this.text.slice(index);this._textLines=this._splitTextIntoLines()},insertChars:function(_chars,useCopiedStyle){var style;if(this.selectionEnd-this.selectionStart>1){this._removeCharsFromTo(this.selectionStart,this.selectionEnd);this.setSelectionEnd(this.selectionStart)}if(!useCopiedStyle&&this.isEmptyStyles()){this.insertChar(_chars,false);return}for(var i=0,len=_chars.length;i=charIndex){newLineStyles[parseInt(index,10)-charIndex]=this.styles[lineIndex][index];delete this.styles[lineIndex][index]}}this.styles[lineIndex+1]=newLineStyles}this._forceClearCache=true},insertCharStyleObject:function(lineIndex,charIndex,style){var currentLineStyles=this.styles[lineIndex],currentLineStylesCloned=clone(currentLineStyles);if(charIndex===0&&!style){charIndex=1}for(var index in currentLineStylesCloned){var numericIndex=parseInt(index,10);if(numericIndex>=charIndex){currentLineStyles[numericIndex+1]=currentLineStylesCloned[numericIndex];if(!currentLineStylesCloned[numericIndex-1]){delete currentLineStyles[numericIndex]}}}this.styles[lineIndex][charIndex]=style||clone(currentLineStyles[charIndex-1]);this._forceClearCache=true},insertStyleObjects:function(_chars,isEndOfLine,styleObject){var cursorLocation=this.get2DCursorLocation(),lineIndex=cursorLocation.lineIndex,charIndex=cursorLocation.charIndex;if(!this._getLineStyle(lineIndex)){this._setLineStyle(lineIndex,{})}if(_chars==="\n"){this.insertNewlineStyleObject(lineIndex,charIndex,isEndOfLine)}else{this.insertCharStyleObject(lineIndex,charIndex,styleObject)}},shiftLineStyles:function(lineIndex,offset){var clonedStyles=clone(this.styles);for(var line in this.styles){var numericLine=parseInt(line,10);if(numericLine>lineIndex){this.styles[numericLine+offset]=clonedStyles[numericLine];if(!clonedStyles[numericLine-offset]){delete this.styles[numericLine]}}}},removeStyleObject:function(isBeginningOfLine,index){var cursorLocation=this.get2DCursorLocation(index),lineIndex=cursorLocation.lineIndex,charIndex=cursorLocation.charIndex;this._removeStyleObject(isBeginningOfLine,cursorLocation,lineIndex,charIndex)},_getTextOnPreviousLine:function(lIndex){return this._textLines[lIndex-1]},_removeStyleObject:function(isBeginningOfLine,cursorLocation,lineIndex,charIndex){if(isBeginningOfLine){var textOnPreviousLine=this._getTextOnPreviousLine(cursorLocation.lineIndex),newCharIndexOnPrevLine=textOnPreviousLine?textOnPreviousLine.length:0;if(!this.styles[lineIndex-1]){this.styles[lineIndex-1]={}}for(charIndex in this.styles[lineIndex]){this.styles[lineIndex-1][parseInt(charIndex,10)+newCharIndexOnPrevLine]=this.styles[lineIndex][charIndex]}this.shiftLineStyles(cursorLocation.lineIndex,-1)}else{var currentLineStyles=this.styles[lineIndex];if(currentLineStyles){delete currentLineStyles[charIndex]}var currentLineStylesCloned=clone(currentLineStyles);for(var i in currentLineStylesCloned){var numericIndex=parseInt(i,10);if(numericIndex>=charIndex&&numericIndex!==0){currentLineStyles[numericIndex-1]=currentLineStylesCloned[numericIndex];delete currentLineStyles[numericIndex]}}}},insertNewline:function(){this.insertChars("\n")}})})();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(options){this.__newClickTime=+new Date;var newPointer=this.canvas.getPointer(options.e);if(this.isTripleClick(newPointer)){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;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},_stopEvent:function(e){e.preventDefault&&e.preventDefault();e.stopPropagation&&e.stopPropagation()},initCursorSelectionHandlers:function(){this.initSelectedHandler();this.initMousedownHandler();this.initMouseupHandler();this.initClicks()},initClicks:function(){this.on("dblclick",function(options){this.selectWord(this.getSelectionStartFromPointer(options.e))});this.on("tripleclick",function(options){this.selectLine(this.getSelectionStartFromPointer(options.e))})},initMousedownHandler:function(){this.on("mousedown",function(options){if(!this.editable){return}var pointer=this.canvas.getPointer(options.e);this.__mousedownX=pointer.x;this.__mousedownY=pointer.y;this.__isMousedown=true;if(this.hiddenTextarea&&this.canvas){this.canvas.wrapperEl.appendChild(this.hiddenTextarea)}if(this.selected){this.setCursorByClick(options.e)}if(this.isEditing){this.__selectionStartOnMouseDown=this.selectionStart;this.initDelayedCursor(true)}})},_isObjectMoved:function(e){var pointer=this.canvas.getPointer(e);return this.__mousedownX!==pointer.x||this.__mousedownY!==pointer.y},initMouseupHandler:function(){this.on("mouseup",function(options){this.__isMousedown=false;if(!this.editable||this._isObjectMoved(options.e)){return}if(this.__lastSelected&&!this.__corner){this.enterEditing(options.e);this.initDelayedCursor(true)}this.selected=true})},setCursorByClick:function(e){var newSelectionStart=this.getSelectionStartFromPointer(e);if(e.shiftKey){if(newSelectionStartdistanceBtwLastCharAndCursor?0:1,newSelectionStart=index+offset;if(this.flipX){newSelectionStart=jlen-newSelectionStart}if(newSelectionStart>this.text.length){newSelectionStart=this.text.length}return newSelectionStart}});fabric.util.object.extend(fabric.IText.prototype,{initHiddenTextarea:function(e){var p;if(e&&this.canvas){p=this.canvas.getPointer(e)}else{this.oCoords||this.setCoords();p=this.oCoords.tl}this.hiddenTextarea=fabric.document.createElement("textarea");this.hiddenTextarea.setAttribute("autocapitalize","off");this.hiddenTextarea.style.cssText="position: absolute; top: "+p.y+"px; left: "+p.x+"px; opacity: 0;"+" width: 0px; height: 0px; z-index: -999;";if(this.canvas){this.canvas.lowerCanvasEl.parentNode.appendChild(this.hiddenTextarea)}else{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.cut.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));if(!this._clickHandlerInitialized&&this.canvas){fabric.util.addListener(this.canvas.upperCanvasEl,"click",this.onClick.bind(this));this._clickHandlerInitialized=true}},_keysMap:{8:"removeChars",9:"exitEditing",27:"exitEditing",13:"insertNewline",33:"moveCursorUp",34:"moveCursorDown",35:"moveCursorRight",36:"moveCursorLeft",37:"moveCursorLeft",38:"moveCursorUp",39:"moveCursorRight",40:"moveCursorDown",46:"forwardDelete"},_ctrlKeysMap:{65:"selectAll",67:"copy",88:"cut"},onClick:function(){this.hiddenTextarea&&this.hiddenTextarea.focus()},onKeyDown:function(e){if(!this.isEditing){return}if(e.keyCode in this._keysMap){this[this._keysMap[e.keyCode]](e)}else{return}e.stopImmediatePropagation();e.preventDefault();this.canvas&&this.canvas.renderAll()},onKeyUp:function(e){if(!this.isEditing||this._copyDone){this._copyDone=false;return}if(e.keyCode in this._ctrlKeysMap&&(e.ctrlKey||e.metaKey)){this[this._ctrlKeysMap[e.keyCode]](e)}else{return}e.stopImmediatePropagation();e.preventDefault();this.canvas&&this.canvas.renderAll()},onInput:function(e){if(!this.isEditing||this.inCompositionMode){return}var offset=this.selectionStart||0,offsetEnd=this.selectionEnd||0,textLength=this.text.length,newTextLength=this.hiddenTextarea.value.length,diff,charsToInsert,start;if(newTextLength>textLength){start=this._selectionDirection==="left"?offsetEnd:offset;diff=newTextLength-textLength;charsToInsert=this.hiddenTextarea.value.slice(start,start+diff)}else{diff=newTextLength-textLength+offsetEnd-offset;charsToInsert=this.hiddenTextarea.value.slice(offset,offset+diff)}this.insertChars(charsToInsert);e.stopPropagation()},onCompositionStart:function(){this.inCompositionMode=true;this.prevCompositionLength=0;this.compositionStart=this.selectionStart},onCompositionEnd:function(){this.inCompositionMode=false},onCompositionUpdate:function(e){var data=e.data;this.selectionStart=this.compositionStart;this.selectionEnd=this.selectionEnd===this.selectionStart?this.compositionStart+this.prevCompositionLength:this.selectionEnd;this.insertChars(data,false);this.prevCompositionLength=data.length},forwardDelete:function(e){if(this.selectionStart===this.selectionEnd){if(this.selectionStart===this.text.length){return}this.moveCursorRight(e)}this.removeChars(e)},copy:function(e){if(this.selectionStart===this.selectionEnd){return}var selectedText=this.getSelectedText(),clipboardData=this._getClipboardData(e);if(clipboardData){clipboardData.setData("text",selectedText)}fabric.copiedText=selectedText;fabric.copiedTextStyle=this.getSelectionStyles(this.selectionStart,this.selectionEnd);e.stopImmediatePropagation();e.preventDefault();this._copyDone=true},paste:function(e){var copiedText=null,clipboardData=this._getClipboardData(e),useCopiedStyle=true;if(clipboardData){copiedText=clipboardData.getData("text").replace(/\r/g,"");if(!fabric.copiedTextStyle||fabric.copiedText!==copiedText){useCopiedStyle=false}}else{copiedText=fabric.copiedText}if(copiedText){this.insertChars(copiedText,useCopiedStyle)}e.stopImmediatePropagation();e.preventDefault()},cut:function(e){if(this.selectionStart===this.selectionEnd){return}this.copy(e);this.removeChars(e)},_getClipboardData:function(e){return e&&e.clipboardData||fabric.window.clipboardData},getDownCursorOffset:function(e,isRight){var selectionProp=isRight?this.selectionEnd:this.selectionStart,cursorLocation=this.get2DCursorLocation(selectionProp),_char,lineLeftOffset,lineIndex=cursorLocation.lineIndex,textOnSameLineBeforeCursor=this._textLines[lineIndex].slice(0,cursorLocation.charIndex),textOnSameLineAfterCursor=this._textLines[lineIndex].slice(cursorLocation.charIndex),textOnNextLine=this._textLines[lineIndex+1]||"";if(lineIndex===this._textLines.length-1||e.metaKey||e.keyCode===34){return this.text.length-selectionProp}var widthOfSameLineBeforeCursor=this._getLineWidth(this.ctx,lineIndex);lineLeftOffset=this._getLineLeftOffset(widthOfSameLineBeforeCursor);var widthOfCharsOnSameLineBeforeCursor=lineLeftOffset;for(var i=0,len=textOnSameLineBeforeCursor.length;iwidthOfCharsOnSameLineBeforeCursor){foundMatch=true;var leftEdge=widthOfCharsOnNextLine-widthOfChar,rightEdge=widthOfCharsOnNextLine,offsetFromLeftEdge=Math.abs(leftEdge-widthOfCharsOnSameLineBeforeCursor),offsetFromRightEdge=Math.abs(rightEdge-widthOfCharsOnSameLineBeforeCursor);indexOnNextLine=offsetFromRightEdgethis.text.length){this.setSelectionEnd(this.text.length)}},getUpCursorOffset:function(e,isRight){var selectionProp=isRight?this.selectionEnd:this.selectionStart,cursorLocation=this.get2DCursorLocation(selectionProp),lineIndex=cursorLocation.lineIndex;if(lineIndex===0||e.metaKey||e.keyCode===33){return selectionProp}var textOnSameLineBeforeCursor=this._textLines[lineIndex].slice(0,cursorLocation.charIndex),textOnPreviousLine=this._textLines[lineIndex-1]||"",_char,widthOfSameLineBeforeCursor=this._getLineWidth(this.ctx,cursorLocation.lineIndex),lineLeftOffset=this._getLineLeftOffset(widthOfSameLineBeforeCursor),widthOfCharsOnSameLineBeforeCursor=lineLeftOffset;for(var i=0,len=textOnSameLineBeforeCursor.length;iwidthOfCharsOnSameLineBeforeCursor){foundMatch=true;var leftEdge=widthOfCharsOnPreviousLine-widthOfChar,rightEdge=widthOfCharsOnPreviousLine,offsetFromLeftEdge=Math.abs(leftEdge-widthOfCharsOnSameLineBeforeCursor),offsetFromRightEdge=Math.abs(rightEdge-widthOfCharsOnSameLineBeforeCursor);indexOnPrevLine=offsetFromRightEdge=this.text.length&&this.selectionEnd>=this.text.length){return}this.abortCursorAnimation();this._currentCursorOpacity=1;if(e.shiftKey){this.moveCursorRightWithShift(e)}else{this.moveCursorRightWithoutShift(e)}this.initDelayedCursor()},moveCursorRightWithShift:function(e){if(this._selectionDirection==="left"&&this.selectionStart!==this.selectionEnd){this._moveRight(e,"selectionStart")}else{this._selectionDirection="right";this._moveRight(e,"selectionEnd")}},moveCursorRightWithoutShift:function(e){this._selectionDirection="right";if(this.selectionStart===this.selectionEnd){this._moveRight(e,"selectionStart");this.setSelectionEnd(this.selectionStart)}else{this.setSelectionEnd(this.selectionEnd+this.getNumNewLinesInSelectedText());this.setSelectionStart(this.selectionEnd)}},removeChars:function(e){if(this.selectionStart===this.selectionEnd){this._removeCharsNearCursor(e)}else{this._removeCharsFromTo(this.selectionStart,this.selectionEnd)}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(e){if(this.selectionStart===0){return}if(e.metaKey){var leftLineBoundary=this.findLineBoundaryLeft(this.selectionStart);this._removeCharsFromTo(leftLineBoundary,this.selectionStart);this.setSelectionStart(leftLineBoundary)}else if(e.altKey){var leftWordBoundary=this.findWordBoundaryLeft(this.selectionStart);this._removeCharsFromTo(leftWordBoundary,this.selectionStart);this.setSelectionStart(leftWordBoundary)}else{this._removeSingleCharAndStyle(this.selectionStart);this.setSelectionStart(this.selectionStart-1)}}});(function(){var toFixed=fabric.util.toFixed,NUM_FRACTION_DIGITS=fabric.Object.NUM_FRACTION_DIGITS;fabric.util.object.extend(fabric.IText.prototype,{_setSVGTextLineText:function(lineIndex,textSpans,height,textLeftOffset,textTopOffset,textBgRects){if(!this._getLineStyle(lineIndex)){fabric.Text.prototype._setSVGTextLineText.call(this,lineIndex,textSpans,height,textLeftOffset,textTopOffset)}else{this._setSVGTextLineChars(lineIndex,textSpans,height,textLeftOffset,textBgRects)}},_setSVGTextLineChars:function(lineIndex,textSpans,height,textLeftOffset,textBgRects){var chars=this._textLines[lineIndex],charOffset=0,lineLeftOffset=this._getLineLeftOffset(this._getLineWidth(this.ctx,lineIndex))-this.width/2,lineOffset=this._getSVGLineTopOffset(lineIndex),heightOfLine=this._getHeightOfLine(this.ctx,lineIndex);for(var i=0,len=chars.length;i\n'].join("")},_createTextCharSpan:function(_char,styleDecl,lineLeftOffset,lineTopOffset,charOffset){var fillStyles=this.getSvgStyles.call(fabric.util.object.extend({visible:true,fill:this.fill,stroke:this.stroke,type:"text",getSvgFilter:fabric.Object.prototype.getSvgFilter},styleDecl));return[' ',fabric.util.string.escapeXml(_char),"\n"].join("")}})})();(function(global){"use strict";var fabric=global.fabric||(global.fabric={}),clone=fabric.util.object.clone;fabric.Textbox=fabric.util.createClass(fabric.IText,fabric.Observable,{type:"textbox",minWidth:20,dynamicMinWidth:0,__cachedLines:null,initialize:function(text,options){this.ctx=fabric.util.createCanvasElement().getContext("2d");this.callSuper("initialize",text,options);this.set({lockUniScaling:false,lockScalingY:true,lockScalingFlip:true,hasBorders:true});this.setControlsVisibility(fabric.Textbox.getTextboxControlVisibility());this._dimensionAffectingProps.width=true},_initDimensions:function(ctx){if(this.__skipDimension){return}if(!ctx){ctx=fabric.util.createCanvasElement().getContext("2d");this._setTextStyles(ctx)}this.dynamicMinWidth=0;this._textLines=this._splitTextIntoLines();if(this.dynamicMinWidth>this.width){this._set("width",this.dynamicMinWidth)}this._clearCache();this.height=this._getTextHeight(ctx)},_generateStyleMap:function(){var realLineCount=0,realLineCharCount=0,charCount=0,map={};for(var i=0;i=this.width&&!lineJustStarted){lines.push(line);line="";lineWidth=wordWidth;lineJustStarted=true}if(!lineJustStarted){line+=infix}line+=word;infixWidth=this._measureText(ctx,infix,lineIndex,offset);offset++;lineJustStarted=false;if(wordWidth>largestWordWidth){largestWordWidth=wordWidth}}i&&lines.push(line);if(largestWordWidth>this.dynamicMinWidth){this.dynamicMinWidth=largestWordWidth}return lines},_splitTextIntoLines:function(){var originalAlign=this.textAlign;this.ctx.save();this._setTextStyles(this.ctx);this.textAlign="left";var lines=this._wrapText(this.ctx,this.text);this.textAlign=originalAlign;this.ctx.restore();this._textLines=lines;this._styleMap=this._generateStyleMap();return lines},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}},get2DCursorLocation:function(selectionStart){if(typeof selectionStart==="undefined"){selectionStart=this.selectionStart}var numLines=this._textLines.length,removed=0;for(var i=0;i=t.getMinWidth()){t.set("width",w);return true}}else{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}}};var clone=fabric.util.object.clone;fabric.util.object.extend(fabric.Textbox.prototype,{_removeExtraneousStyles:function(){for(var prop in this._styleMap){if(!this._textLines[prop]){delete this.styles[this._styleMap[prop].line]}}},insertCharStyleObject:function(lineIndex,charIndex,style){var map=this._styleMap[lineIndex];lineIndex=map.line;charIndex=map.offset+charIndex;fabric.IText.prototype.insertCharStyleObject.apply(this,[lineIndex,charIndex,style])},insertNewlineStyleObject:function(lineIndex,charIndex,isEndOfLine){var map=this._styleMap[lineIndex];lineIndex=map.line;charIndex=map.offset+charIndex;fabric.IText.prototype.insertNewlineStyleObject.apply(this,[lineIndex,charIndex,isEndOfLine])},shiftLineStyles:function(lineIndex,offset){var clonedStyles=clone(this.styles),map=this._styleMap[lineIndex];lineIndex=map.line;for(var line in this.styles){var numericLine=parseInt(line,10);if(numericLine>lineIndex){this.styles[numericLine+offset]=clonedStyles[numericLine];if(!clonedStyles[numericLine-offset]){delete this.styles[numericLine]}}}},_getTextOnPreviousLine:function(lIndex){var textOnPreviousLine=this._textLines[lIndex-1];while(this._styleMap[lIndex-2]&&this._styleMap[lIndex-2].line===this._styleMap[lIndex-1].line){textOnPreviousLine=this._textLines[lIndex-2]+textOnPreviousLine;lIndex--}return textOnPreviousLine},removeStyleObject:function(isBeginningOfLine,index){var cursorLocation=this.get2DCursorLocation(index),map=this._styleMap[cursorLocation.lineIndex],lineIndex=map.line,charIndex=map.offset+cursorLocation.charIndex;this._removeStyleObject(isBeginningOfLine,cursorLocation,lineIndex,charIndex)}})})();(function(){var override=fabric.IText.prototype._getNewSelectionStartFromOffset;fabric.IText.prototype._getNewSelectionStartFromOffset=function(mouseOffset,prevWidth,width,index,jlen){index=override.call(this,mouseOffset,prevWidth,width,index,jlen);var tmp=0,removed=0;for(var i=0;i=index){break}if(this.text[tmp+removed]==="\n"||this.text[tmp+removed]===" "){removed++}}return index-i+removed}})();(function(){if(typeof document!=="undefined"&&typeof window!=="undefined"){return}var DOMParser=require("xmldom").DOMParser,URL=require("url"),HTTP=require("http"),HTTPS=require("https"),Canvas=require("canvas"),Image=require("canvas").Image;function request(url,encoding,callback){var oURL=URL.parse(url);if(!oURL.port){oURL.port=oURL.protocol.indexOf("https:")===0?443:80}var reqHandler=oURL.protocol.indexOf("https:")===0?HTTPS:HTTP,req=reqHandler.request({hostname:oURL.hostname,port:oURL.port,path:oURL.path,method:"GET"},function(response){var body="";if(encoding){response.setEncoding(encoding)}response.on("end",function(){callback(body)});response.on("data",function(chunk){if(response.statusCode===200){body+=chunk}})});req.on("error",function(err){if(err.errno===process.ECONNREFUSED){fabric.log("ECONNREFUSED: connection refused to "+oURL.hostname+":"+oURL.port)}else{fabric.log(err.message)}callback(null)});req.end()}function requestFs(path,callback){var fs=require("fs");fs.readFile(path,function(err,data){if(err){fabric.log(err);throw err}else{callback(data)}})}fabric.util.loadImage=function(url,callback,context){function createImageAndCallBack(data){if(data){img.src=new Buffer(data,"binary");img._src=url;callback&&callback.call(context,img)}else{img=null;callback&&callback.call(context,null,true)}}var img=new Image;if(url&&(url instanceof Buffer||url.indexOf("data")===0)){img.src=img._src=url;callback&&callback.call(context,img)}else if(url&&url.indexOf("http")!==0){requestFs(url,createImageAndCallBack)}else if(url){request(url,"binary",createImageAndCallBack)}else{callback&&callback.call(context,url)}};fabric.loadSVGFromURL=function(url,callback,reviver){url=url.replace(/^\n\s*/,"").replace(/\?.*$/,"").trim();if(url.indexOf("http")!==0){requestFs(url,function(body){fabric.loadSVGFromString(body.toString(),callback,reviver)})}else{request(url,"",function(body){fabric.loadSVGFromString(body,callback,reviver)})}};fabric.loadSVGFromString=function(string,callback,reviver){var doc=(new DOMParser).parseFromString(string);fabric.parseSVGDocument(doc.documentElement,function(results,options){callback&&callback(results,options)},reviver)};fabric.util.getScript=function(url,callback){request(url,"",function(body){eval(body);callback&&callback()})};fabric.Image.fromObject=function(object,callback){fabric.util.loadImage(object.src,function(img){var oImg=new fabric.Image(img);oImg._initConfig(object);oImg._initFilters(object.filters,function(filters){oImg.filters=filters||[];oImg._initFilters(object.resizeFilters,function(resizeFilters){oImg.resizeFilters=resizeFilters||[];callback&&callback(oImg)})})})};fabric.createCanvasForNode=function(width,height,options,nodeCanvasOptions){nodeCanvasOptions=nodeCanvasOptions||options;var canvasEl=fabric.document.createElement("canvas"),nodeCanvas=new Canvas(width||600,height||600,nodeCanvasOptions);canvasEl.style={};canvasEl.width=nodeCanvas.width;canvasEl.height=nodeCanvas.height;var FabricCanvas=fabric.Canvas||fabric.StaticCanvas,fabricCanvas=new FabricCanvas(canvasEl,options);fabricCanvas.contextContainer=nodeCanvas.getContext("2d");fabricCanvas.nodeCanvas=nodeCanvas;fabricCanvas.Font=Canvas.Font;return fabricCanvas};fabric.StaticCanvas.prototype.createPNGStream=function(){return this.nodeCanvas.createPNGStream()};fabric.StaticCanvas.prototype.createJPEGStream=function(opts){return this.nodeCanvas.createJPEGStream(opts)};var origSetWidth=fabric.StaticCanvas.prototype.setWidth;fabric.StaticCanvas.prototype.setWidth=function(width,options){origSetWidth.call(this,width,options);this.nodeCanvas.width=width;return this};if(fabric.Canvas){fabric.Canvas.prototype.setWidth=fabric.StaticCanvas.prototype.setWidth}var origSetHeight=fabric.StaticCanvas.prototype.setHeight;fabric.StaticCanvas.prototype.setHeight=function(height,options){origSetHeight.call(this,height,options);this.nodeCanvas.height=height;return this};if(fabric.Canvas){fabric.Canvas.prototype.setHeight=fabric.StaticCanvas.prototype.setHeight}})();window.fabric=fabric;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 db645007..f8eaf7fe 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": "1.6.0", + "version": "1.6.1", "author": "Juriy Zaytsev ", "keywords": [ "canvas",