From 77013208de79491e65bd6c07115e939688d3462b Mon Sep 17 00:00:00 2001 From: kangax Date: Thu, 30 May 2013 21:59:58 +0200 Subject: [PATCH] Fix build.js, build distribution --- build.js | 5 +- dist/all.js | 2875 +++++++++++++++++++++++++------------------- dist/all.min.js | 12 +- dist/all.min.js.gz | Bin 48674 -> 49365 bytes 4 files changed, 1647 insertions(+), 1245 deletions(-) diff --git a/build.js b/build.js index a282d404..888e20f9 100644 --- a/build.js +++ b/build.js @@ -106,7 +106,7 @@ var filesToInclude = [ ifSpecifiedDependencyInclude('text', 'cufon', 'lib/cufon.js'), ifSpecifiedDependencyInclude('serialization', 'json', 'lib/json2.js'), - ifSpecifiedDependencyInclude('gestures', 'interaction', 'lib/event.js'), + ifSpecifiedDependencyInclude('gestures', 'lib/event.js'), 'src/log.js', 'src/mixins/observable.mixin.js', @@ -154,7 +154,6 @@ var filesToInclude = [ 'src/shapes/object.class.js', 'src/mixins/object_origin.mixin.js', 'src/mixins/object_geometry.mixin.js', - 'src/mixins/stateful.mixin.js', ifSpecifiedInclude('interaction', 'src/mixins/object_interactivity.mixin.js'), @@ -185,7 +184,7 @@ var filesToInclude = [ ifSpecifiedInclude('image_filters', 'src/filters/sepia2_filter.class.js'), ifSpecifiedInclude('image_filters', 'src/filters/tint_filter.class.js'), - ifSpecifiedInclude('text', 'src/text.class.js'), + ifSpecifiedInclude('text', 'src/shapes/text.class.js'), ifSpecifiedInclude('node', 'src/node.js') ]; diff --git a/dist/all.js b/dist/all.js index 709d3508..e9be4a9a 100644 --- a/dist/all.js +++ b/dist/all.js @@ -29,6 +29,7 @@ fabric.isTouchSupported = "ontouchstart" in fabric.document.documentElement; */ fabric.isLikelyNode = typeof Buffer !== 'undefined' && typeof window === 'undefined'; + /*! * Copyright (c) 2009 Simo Kinnunen. * Licensed under the MIT license. @@ -1256,6 +1257,7 @@ if (typeof exports != 'undefined') { exports.Cufon = Cufon; } + /* json2.js 2011-10-19 @@ -1747,6 +1749,7 @@ if (!JSON) { }; } }()); + /** * Wrapper around `console.log` (when available) * @param {Any} values Values to log @@ -1772,6 +1775,7 @@ if (typeof console !== 'undefined') { } } + (function(){ /** @@ -1856,6 +1860,7 @@ if (typeof console !== 'undefined') { }; })(); + /** * @namespace fabric.Collection */ @@ -1994,6 +1999,7 @@ fabric.Collection = { } }; + (function() { var sqrt = Math.sqrt, @@ -2458,6 +2464,7 @@ fabric.Collection = { })(); + (function() { var slice = Array.prototype.slice; @@ -2715,6 +2722,7 @@ fabric.Collection = { })(); + (function(){ /** @@ -2750,6 +2758,7 @@ fabric.Collection = { })(); + (function() { /* _ES5_COMPAT_START_ */ @@ -2813,6 +2822,7 @@ fabric.util.string = { }; }()); + /* _ES5_COMPAT_START_ */ (function() { @@ -2851,6 +2861,7 @@ fabric.util.string = { })(); /* _ES5_COMPAT_END_ */ + (function() { var slice = Array.prototype.slice, emptyFunction = function() { }; @@ -2948,6 +2959,7 @@ fabric.util.string = { fabric.util.createClass = createClass; })(); + (function () { /* EVENT HANDLING */ @@ -3137,9 +3149,9 @@ fabric.util.string = { while (element && element.parentNode && !firstFixedAncestor) { element = element.parentNode; - if (element !== fabric.document && fabric.util.getElementPosition(element) === 'fixed') firstFixedAncestor = element; + if (element !== fabric.document && fabric.util.getElementStyle(element, 'position') === 'fixed') firstFixedAncestor = element; - if (element !== fabric.document && orgElement !== upperCanvasEl && fabric.util.getElementPosition(element) === 'absolute') { + if (element !== fabric.document && orgElement !== upperCanvasEl && fabric.util.getElementStyle(element, 'position') === 'absolute') { scrollLeft = 0; scrollTop = 0; } @@ -3191,6 +3203,7 @@ fabric.util.string = { })(); + (function () { /** @@ -3262,6 +3275,7 @@ fabric.util.string = { })(); + (function() { var _slice = Array.prototype.slice; @@ -3366,10 +3380,23 @@ fabric.util.string = { function getElementOffset(element) { var docElem, win, box = {left: 0, top: 0}, - doc = element && element.ownerDocument; + doc = element && element.ownerDocument, + offset = {left: 0, top: 0}, + offsetAttributes = { + 'borderLeftWidth': 'left', + 'borderTopWidth': 'top', + 'paddingLeft': 'left', + 'paddingTop': 'top' + }; + if (!doc){ return {left: 0, top: 0}; } + + 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(); @@ -3380,31 +3407,31 @@ fabric.util.string = { win = doc.nodeType === 9 && doc.defaultView; } return { - left: box.left + win.pageXOffset - (docElem.clientLeft || 0), - top: box.top + win.pageYOffset - (docElem.clientTop || 0) + left: box.left + win.pageXOffset - (docElem.clientLeft || 0) + offset.left, + top: box.top + win.pageYOffset - (docElem.clientTop || 0) + offset.top }; } /** - * Returns position of a given element - * @function + * Returns style attribute value of a given element * @memberOf fabric.util - * @param {HTMLElement} element Element to get offset for - * @return {Object} position of the given element. + * @param {HTMLElement} element Element to get style attribute for + * @param {String} attr Style attribute to get for element + * @return {String} Style attribute value of the given element. */ - var getElementPosition; - if (fabric.document.defaultView && fabric.document.defaultView.getComputedStyle) { - getElementPosition = function (element) { - return fabric.document.defaultView.getComputedStyle(element, null).position; - }; - } - else { - /** @ignore */ - getElementPosition = function (element) { - var value = element.style.position; - if (!value && element.currentStyle) value = element.currentStyle.position; + function getElementStyle(element, attr) { + if (!element.style) { + element.style = { }; + } + + if (fabric.document.defaultView && fabric.document.defaultView.getComputedStyle) { + return fabric.document.defaultView.getComputedStyle(element, null)[attr]; + } + else { + var value = element.style[attr]; + if (!value && element.currentStyle) value = element.currentStyle[attr]; return value; - }; + } } (function () { @@ -3501,10 +3528,11 @@ fabric.util.string = { fabric.util.addClass = addClass; fabric.util.wrapElement = wrapElement; fabric.util.getElementOffset = getElementOffset; - fabric.util.getElementPosition = getElementPosition; + fabric.util.getElementStyle = getElementStyle; })(); + (function(){ function addParamToUrl(url, param) { @@ -3577,6 +3605,7 @@ fabric.util.string = { fabric.util.request = request; })(); + (function() { /** @@ -3909,6 +3938,7 @@ fabric.util.string = { }()); + (function(global) { "use strict"; @@ -3922,34 +3952,41 @@ fabric.util.string = { extend = fabric.util.object.extend, capitalize = fabric.util.string.capitalize, clone = fabric.util.object.clone, + toFixed = fabric.util.toFixed, multiplyTransformMatrices = fabric.util.multiplyTransformMatrices; fabric.SHARED_ATTRIBUTES = [ "transform", - "fill", "fill-rule", "fill-opacity", + "fill", "fill-opacity", "fill-rule", "opacity", - "stroke", "stroke-dasharray", "stroke-linecap", "stroke-linejoin", "stroke-miterlimit", "stroke-width" + "stroke", "stroke-dasharray", "stroke-linecap", "stroke-linejoin", "stroke-miterlimit", "stroke-opacity", "stroke-width" ]; var attributesMap = { + 'fill-opacity': 'fillOpacity', + 'fill-rule': 'fillRule', + 'font-family': 'fontFamily', + 'font-size': 'fontSize', + 'font-style': 'fontStyle', + 'font-weight': 'fontWeight', 'cx': 'left', 'x': 'left', - 'cy': 'top', - 'y': 'top', 'r': 'radius', - 'fill-opacity': 'opacity', - 'fill-rule': 'fillRule', - 'stroke-width': 'strokeWidth', 'stroke-dasharray': 'strokeDashArray', 'stroke-linecap': 'strokeLineCap', 'stroke-linejoin': 'strokeLineJoin', 'stroke-miterlimit':'strokeMiterLimit', - 'transform': 'transformMatrix', + 'stroke-opacity': 'strokeOpacity', + 'stroke-width': 'strokeWidth', 'text-decoration': 'textDecoration', - 'font-size': 'fontSize', - 'font-weight': 'fontWeight', - 'font-style': 'fontStyle', - 'font-family': 'fontFamily' + 'cy': 'top', + 'y': 'top', + 'transform': 'transformMatrix' + }; + + var colorAttributes = { + 'stroke': 'strokeOpacity', + 'fill': 'fillOpacity' }; function normalizeAttr(attr) { @@ -3988,6 +4025,22 @@ fabric.util.string = { return (!isArray && isNaN(parsed) ? value : parsed); } + /** + * @private + * @param {Object} attributes Array of attributes to parse + */ + function _setStrokeFillOpacity(attributes) { + for (var attr in colorAttributes) { + if (!attributes[attr] || typeof attributes[colorAttributes[attr]] === 'undefined') continue; + + var color = new fabric.Color(attributes[attr]); + attributes[attr] = color.setAlpha(toFixed(color.getAlpha() * attributes[colorAttributes[attr]], 2)).toRgba(); + + delete attributes[colorAttributes[attr]]; + } + return attributes; + } + /** * Returns an object of attributes' name/value, given element and an array of attribute names; * Parses parent "g" nodes recursively upwards. @@ -4027,7 +4080,7 @@ fabric.util.string = { ownAttributes = extend(ownAttributes, extend(getGlobalStylesForElement(element), fabric.parseStyleAttribute(element))); - return extend(parentAttributes, ownAttributes); + return _setStrokeFillOpacity(extend(parentAttributes, ownAttributes)); } /** @@ -4710,379 +4763,6 @@ fabric.util.string = { return markup; } - extend(fabric, { - - parseAttributes: parseAttributes, - parseElements: parseElements, - parseStyleAttribute: parseStyleAttribute, - parsePointsAttribute: parsePointsAttribute, - getCSSRules: getCSSRules, - - loadSVGFromURL: loadSVGFromURL, - loadSVGFromString: loadSVGFromString, - - createSVGFontFacesMarkup: createSVGFontFacesMarkup, - createSVGRefElementsMarkup: createSVGRefElementsMarkup - }); - -})(typeof exports !== 'undefined' ? exports : this); - -(function() { - - function getColorStop(el) { - var style = el.getAttribute('style'), - offset = el.getAttribute('offset'), - color, opacity; - - // convert percents to absolute values - offset = parseFloat(offset) / (/%$/.test(offset) ? 100 : 1); - - 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'); - } - if (!opacity) { - opacity = el.getAttribute('stop-opacity'); - } - - // convert rgba color to rgb color - alpha value has no affect in svg - color = new fabric.Color(color).toRgb(); - - return { - offset: offset, - color: color, - opacity: opacity - }; - } - - /** - * Gradient class - * @class fabric.Gradient - */ - fabric.Gradient = fabric.util.createClass(/** @lends fabric.Gradient.prototype */ { - - /** - * Constructor - * @param {Object} [options] Options object with type, coords, gradientUnits and colorStops - * @return {fabric.Gradient} thisArg - */ - 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.gradientUnits = options.gradientUnits || 'objectBoundingBox'; - this.colorStops = options.colorStops.slice(); - }, - - /** - * Adds another colorStop - * @param {Object} colorStop Object with offset and color - * @return {fabric.Gradient} thisArg - */ - 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; - }, - - /** - * Returns object representation of a gradient - * @return {Object} - */ - toObject: function() { - return { - type: this.type, - coords: this.coords, - gradientUnits: this.gradientUnits, - colorStops: this.colorStops - }; - }, - - /* _TO_SVG_START_ */ - /** - * Returns SVG representation of an gradient - * @param {Object} object Object to create a gradient for - * @param {Boolean} normalize Whether coords should be normalized - * @return {String} SVG representation of an gradient (linear/radial) - */ - toSVG: function(object, normalize) { - var coords = fabric.util.object.clone(this.coords), - markup; - - // colorStops must be sorted ascending - this.colorStops.sort(function(a, b) { - return a.offset - b.offset; - }); - - if (normalize && this.gradientUnits === 'userSpaceOnUse') { - coords.x1 += object.width / 2; - coords.y1 += object.height / 2; - coords.x2 += object.width / 2; - coords.y2 += object.height / 2; - } - else if (this.gradientUnits === 'objectBoundingBox') { - _convertValuesToPercentUnits(object, coords); - } - - if (this.type === 'linear') { - markup = [ - '' - ]; - } - else if (this.type === 'radial') { - markup = [ - '' - ]; - } - - for (var i = 0; i < this.colorStops.length; i++) { - markup.push( - '' - ); - } - - markup.push((this.type === 'linear' ? '' : '')); - - return markup.join(''); - }, - /* _TO_SVG_END_ */ - - /** - * Returns an instance of CanvasGradient - * @param ctx - * @return {CanvasGradient} - */ - toLive: function(ctx) { - var gradient; - - if (!this.type) return; - - if (this.type === 'linear') { - gradient = ctx.createLinearGradient( - this.coords.x1, this.coords.y1, this.coords.x2 || ctx.canvas.width, this.coords.y2); - } - else if (this.type === 'radial') { - gradient = ctx.createRadialGradient( - this.coords.x1, this.coords.y1, this.coords.r1, this.coords.x2, this.coords.y2, this.coords.r2); - } - - for (var i = 0; i < this.colorStops.length; i++) { - var color = this.colorStops[i].color, - opacity = this.colorStops[i].opacity, - offset = this.colorStops[i].offset; - - if (opacity) { - color = new fabric.Color(color).setAlpha(opacity).toRgba(); - } - gradient.addColorStop(parseFloat(offset), color); - } - - return gradient; - } - }); - - fabric.util.object.extend(fabric.Gradient, { - - /** - * Returns {@link fabric.Gradient} instance from an SVG element - * @static - * @memberof fabric.Gradient - * @see http://www.w3.org/TR/SVG/pservers.html#LinearGradientElement - * @see http://www.w3.org/TR/SVG/pservers.html#RadialGradientElement - */ - fromElement: function(el, instance) { - - /** - * @example: - * - * - * - * - * - * - * OR - * - * - * - * - * - * - * OR - * - * - * - * - * - * - * - * OR - * - * - * - * - * - * - * - */ - - var colorStopEls = el.getElementsByTagName('stop'), - type = (el.nodeName === 'linearGradient' ? 'linear' : 'radial'), - gradientUnits = el.getAttribute('gradientUnits') || 'objectBoundingBox', - colorStops = [], - coords = { }; - - if (type === 'linear') { - coords = { - x1: el.getAttribute('x1') || 0, - y1: el.getAttribute('y1') || 0, - x2: el.getAttribute('x2') || '100%', - y2: el.getAttribute('y2') || 0 - }; - } - else if (type === 'radial') { - coords = { - 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%' - }; - } - - for (var i = colorStopEls.length; i--; ) { - colorStops.push(getColorStop(colorStopEls[i])); - } - - _convertPercentUnitsToValues(instance, coords); - - return new fabric.Gradient({ - type: type, - coords: coords, - gradientUnits: gradientUnits, - colorStops: colorStops - }); - }, - - /** - * Returns {@link fabric.Gradient} instance from its object representation - * @static - * @param {Object} obj - * @param {Object} [options] Options object - * @memberof fabric.Gradient - */ - forObject: function(obj, options) { - options || (options = { }); - _convertPercentUnitsToValues(obj, options); - return new fabric.Gradient(options); - } - }); - - /** - * @private - */ - function _convertPercentUnitsToValues(object, options) { - for (var prop in options) { - if (typeof options[prop] === 'string' && /^\d+%$/.test(options[prop])) { - var percents = parseFloat(options[prop], 10); - if (prop === 'x1' || prop === 'x2' || prop === 'r2') { - options[prop] = fabric.util.toFixed(object.width * percents / 100, 2); - } - else if (prop === 'y1' || prop === 'y2') { - options[prop] = fabric.util.toFixed(object.height * percents / 100, 2); - } - } - // normalize rendering point (should be from top/left corner rather than center of the shape) - if (prop === 'x1' || prop === 'x2') { - options[prop] -= fabric.util.toFixed(object.width / 2, 2); - } - else if (prop === 'y1' || prop === 'y2') { - options[prop] -= fabric.util.toFixed(object.height / 2, 2); - } - } - } - - /** - * @private - */ - function _convertValuesToPercentUnits(object, options) { - for (var prop in options) { - // normalize rendering point (should be from center rather than top/left corner of the shape) - if (prop === 'x1' || prop === 'x2') { - options[prop] += fabric.util.toFixed(object.width / 2, 2); - } - else if (prop === 'y1' || prop === 'y2') { - options[prop] += fabric.util.toFixed(object.height / 2, 2); - } - // convert to percent units - if (prop === 'x1' || prop === 'x2' || prop === 'r2') { - options[prop] = fabric.util.toFixed(options[prop] / object.width * 100, 2) + '%'; - } - else if (prop === 'y1' || prop === 'y2') { - options[prop] = fabric.util.toFixed(options[prop] / object.height * 100, 2) + '%'; - } - } - } - /** * Parses an SVG document, returning all of the gradient declarations found in it * @static @@ -5112,163 +4792,25 @@ fabric.util.string = { return gradientDefs; } - fabric.getGradientDefs = getGradientDefs; + extend(fabric, { -})(); + parseAttributes: parseAttributes, + parseElements: parseElements, + parseStyleAttribute: parseStyleAttribute, + parsePointsAttribute: parsePointsAttribute, + getCSSRules: getCSSRules, -/** - * Pattern class - * @class fabric.Pattern - */ -fabric.Pattern = fabric.util.createClass(/** @lends fabric.Pattern.prototype */ { + loadSVGFromURL: loadSVGFromURL, + loadSVGFromString: loadSVGFromString, - /** - * Repeat property of a pattern (one of repeat, repeat-x, repeat-y) - * @type String - */ - repeat: 'repeat', + createSVGFontFacesMarkup: createSVGFontFacesMarkup, + createSVGRefElementsMarkup: createSVGRefElementsMarkup, - /** - * Pattern horizontal offset from object's left/top corner - * @type Number - */ - offsetX: 0, + getGradientDefs: getGradientDefs + }); - /** - * Pattern vertical offset from object's left/top corner - * @type Number - */ - offsetY: 0, +})(typeof exports !== 'undefined' ? exports : this); - /** - * Constructor - * @param {Object} [options] - * @return {fabric.Pattern} thisArg - */ - initialize: function(options) { - options || (options = { }); - - if (options.source) { - this.source = typeof options.source === 'string' - ? new Function(options.source) - : options.source; - } - if (options.repeat) { - this.repeat = options.repeat; - } - if (options.offsetX) { - this.offsetX = options.offsetX; - } - if (options.offsetY) { - this.offsetY = options.offsetY; - } - }, - - /** - * Returns object representation of a pattern - * @return {Object} - */ - toObject: function() { - - var source; - - // callback - if (typeof this.source === 'function') { - source = String(this.source) - .match(/function\s+\w*\s*\(.*\)\s+\{([\s\S]*)\}/)[1]; - } - // element - else if (typeof this.source.src === 'string') { - source = this.source.src; - } - - return { - source: source, - repeat: this.repeat, - offsetX: this.offsetX, - offsetY: this.offsetY - }; - }, - - /** - * Returns an instance of CanvasPattern - * @param ctx - * @return {CanvasPattern} - */ - toLive: function(ctx) { - var source = typeof this.source === 'function' ? this.source() : this.source; - return ctx.createPattern(source, this.repeat); - } -}); - -/** - * Shadow class - * @class fabric.Shadow - */ -fabric.Shadow = fabric.util.createClass(/** @lends fabric.Shadow.prototype */ { - - /** - * Shadow color - * @type String - */ - color: 'rgb(0,0,0)', - - /** - * Shadow blur - * @type Number - */ - blur: 0, - - /** - * Shadow horizontal offset - * @type Number - */ - offsetX: 0, - - /** - * Shadow vertical offset - * @type Number - */ - offsetY: 0, - - /** - * Whether the shadow should affect stroke operations - * @type Boolean - */ - affectStroke: false, - - /** - * Constructor - * @param [options] Options object with any of color, blur, offsetX, offsetX properties - * @return {fabric.Shadow} thisArg - */ - initialize: function(options) { - for (var prop in options) { - this[prop] = options[prop]; - } - }, - - /** - * Returns object representation of a shadow - * @return {Object} - */ - toObject: function() { - return { - color: this.color, - blur: this.blur, - offsetX: this.offsetX, - offsetY: this.offsetY - }; - }, - - /** - * Returns SVG representation of a shadow - * @return {String} - */ - toSVG: function() { - - } -}); (function(global) { @@ -5570,6 +5112,530 @@ fabric.Shadow = fabric.util.createClass(/** @lends fabric.Shadow.prototype */ { })(typeof exports !== 'undefined' ? exports : this); + +(function() { + + /* _FROM_SVG_START_ */ + function getColorStop(el) { + var style = el.getAttribute('style'), + offset = el.getAttribute('offset'), + color, opacity; + + // convert percents to absolute values + offset = parseFloat(offset) / (/%$/.test(offset) ? 100 : 1); + + 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'); + } + if (!opacity) { + opacity = el.getAttribute('stop-opacity'); + } + + // convert rgba color to rgb color - alpha value has no affect in svg + color = new fabric.Color(color).toRgb(); + + return { + offset: offset, + color: color, + opacity: opacity + }; + } + /* _FROM_SVG_END_ */ + + /** + * Gradient class + * @class fabric.Gradient + */ + fabric.Gradient = fabric.util.createClass(/** @lends fabric.Gradient.prototype */ { + + /** + * Constructor + * @param {Object} [options] Options object with type, coords, gradientUnits and colorStops + * @return {fabric.Gradient} thisArg + */ + 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.gradientUnits = options.gradientUnits || 'objectBoundingBox'; + this.colorStops = options.colorStops.slice(); + }, + + /** + * Adds another colorStop + * @param {Object} colorStop Object with offset and color + * @return {fabric.Gradient} thisArg + */ + 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; + }, + + /** + * Returns object representation of a gradient + * @return {Object} + */ + toObject: function() { + return { + type: this.type, + coords: this.coords, + gradientUnits: this.gradientUnits, + colorStops: this.colorStops + }; + }, + + /* _TO_SVG_START_ */ + /** + * Returns SVG representation of an gradient + * @param {Object} object Object to create a gradient for + * @param {Boolean} normalize Whether coords should be normalized + * @return {String} SVG representation of an gradient (linear/radial) + */ + toSVG: function(object, normalize) { + var coords = fabric.util.object.clone(this.coords), + markup; + + // colorStops must be sorted ascending + this.colorStops.sort(function(a, b) { + return a.offset - b.offset; + }); + + if (normalize && this.gradientUnits === 'userSpaceOnUse') { + coords.x1 += object.width / 2; + coords.y1 += object.height / 2; + coords.x2 += object.width / 2; + coords.y2 += object.height / 2; + } + else if (this.gradientUnits === 'objectBoundingBox') { + _convertValuesToPercentUnits(object, coords); + } + + if (this.type === 'linear') { + markup = [ + '' + ]; + } + else if (this.type === 'radial') { + markup = [ + '' + ]; + } + + for (var i = 0; i < this.colorStops.length; i++) { + markup.push( + '' + ); + } + + markup.push((this.type === 'linear' ? '' : '')); + + return markup.join(''); + }, + /* _TO_SVG_END_ */ + + /** + * Returns an instance of CanvasGradient + * @param ctx + * @return {CanvasGradient} + */ + toLive: function(ctx) { + var gradient; + + if (!this.type) return; + + if (this.type === 'linear') { + gradient = ctx.createLinearGradient( + this.coords.x1, this.coords.y1, this.coords.x2 || ctx.canvas.width, this.coords.y2); + } + else if (this.type === 'radial') { + gradient = ctx.createRadialGradient( + this.coords.x1, this.coords.y1, this.coords.r1, this.coords.x2, this.coords.y2, this.coords.r2); + } + + for (var i = 0; i < this.colorStops.length; i++) { + var color = this.colorStops[i].color, + opacity = this.colorStops[i].opacity, + offset = this.colorStops[i].offset; + + if (opacity) { + color = new fabric.Color(color).setAlpha(opacity).toRgba(); + } + gradient.addColorStop(parseFloat(offset), color); + } + + return gradient; + } + }); + + fabric.util.object.extend(fabric.Gradient, { + + /* _FROM_SVG_START_ */ + /** + * Returns {@link fabric.Gradient} instance from an SVG element + * @static + * @memberof fabric.Gradient + * @see http://www.w3.org/TR/SVG/pservers.html#LinearGradientElement + * @see http://www.w3.org/TR/SVG/pservers.html#RadialGradientElement + */ + fromElement: function(el, instance) { + + /** + * @example: + * + * + * + * + * + * + * OR + * + * + * + * + * + * + * OR + * + * + * + * + * + * + * + * OR + * + * + * + * + * + * + * + */ + + var colorStopEls = el.getElementsByTagName('stop'), + type = (el.nodeName === 'linearGradient' ? 'linear' : 'radial'), + gradientUnits = el.getAttribute('gradientUnits') || 'objectBoundingBox', + colorStops = [], + coords = { }; + + if (type === 'linear') { + coords = { + x1: el.getAttribute('x1') || 0, + y1: el.getAttribute('y1') || 0, + x2: el.getAttribute('x2') || '100%', + y2: el.getAttribute('y2') || 0 + }; + } + else if (type === 'radial') { + coords = { + 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%' + }; + } + + for (var i = colorStopEls.length; i--; ) { + colorStops.push(getColorStop(colorStopEls[i])); + } + + _convertPercentUnitsToValues(instance, coords); + + return new fabric.Gradient({ + type: type, + coords: coords, + gradientUnits: gradientUnits, + colorStops: colorStops + }); + }, + /* _FROM_SVG_END_ */ + + /** + * Returns {@link fabric.Gradient} instance from its object representation + * @static + * @param {Object} obj + * @param {Object} [options] Options object + * @memberof fabric.Gradient + */ + forObject: function(obj, options) { + options || (options = { }); + _convertPercentUnitsToValues(obj, options); + return new fabric.Gradient(options); + } + }); + + /** + * @private + */ + function _convertPercentUnitsToValues(object, options) { + for (var prop in options) { + if (typeof options[prop] === 'string' && /^\d+%$/.test(options[prop])) { + var percents = parseFloat(options[prop], 10); + if (prop === 'x1' || prop === 'x2' || prop === 'r2') { + options[prop] = fabric.util.toFixed(object.width * percents / 100, 2); + } + else if (prop === 'y1' || prop === 'y2') { + options[prop] = fabric.util.toFixed(object.height * percents / 100, 2); + } + } + // normalize rendering point (should be from top/left corner rather than center of the shape) + if (prop === 'x1' || prop === 'x2') { + options[prop] -= fabric.util.toFixed(object.width / 2, 2); + } + else if (prop === 'y1' || prop === 'y2') { + options[prop] -= fabric.util.toFixed(object.height / 2, 2); + } + } + } + + /* _TO_SVG_START_ */ + /** + * @private + */ + function _convertValuesToPercentUnits(object, options) { + for (var prop in options) { + // normalize rendering point (should be from center rather than top/left corner of the shape) + if (prop === 'x1' || prop === 'x2') { + options[prop] += fabric.util.toFixed(object.width / 2, 2); + } + else if (prop === 'y1' || prop === 'y2') { + options[prop] += fabric.util.toFixed(object.height / 2, 2); + } + // convert to percent units + if (prop === 'x1' || prop === 'x2' || prop === 'r2') { + options[prop] = fabric.util.toFixed(options[prop] / object.width * 100, 2) + '%'; + } + else if (prop === 'y1' || prop === 'y2') { + options[prop] = fabric.util.toFixed(options[prop] / object.height * 100, 2) + '%'; + } + } + } + /* _TO_SVG_END_ */ + +})(); + + +/** + * Pattern class + * @class fabric.Pattern + */ +fabric.Pattern = fabric.util.createClass(/** @lends fabric.Pattern.prototype */ { + + /** + * Repeat property of a pattern (one of repeat, repeat-x, repeat-y) + * @type String + */ + repeat: 'repeat', + + /** + * Pattern horizontal offset from object's left/top corner + * @type Number + */ + offsetX: 0, + + /** + * Pattern vertical offset from object's left/top corner + * @type Number + */ + offsetY: 0, + + /** + * Constructor + * @param {Object} [options] + * @return {fabric.Pattern} thisArg + */ + initialize: function(options) { + options || (options = { }); + + if (options.source) { + this.source = typeof options.source === 'string' + ? new Function(options.source) + : options.source; + } + if (options.repeat) { + this.repeat = options.repeat; + } + if (options.offsetX) { + this.offsetX = options.offsetX; + } + if (options.offsetY) { + this.offsetY = options.offsetY; + } + }, + + /** + * Returns object representation of a pattern + * @return {Object} + */ + toObject: function() { + + var source; + + // callback + if (typeof this.source === 'function') { + source = String(this.source) + .match(/function\s+\w*\s*\(.*\)\s+\{([\s\S]*)\}/)[1]; + } + // element + else if (typeof this.source.src === 'string') { + source = this.source.src; + } + + return { + source: source, + repeat: this.repeat, + offsetX: this.offsetX, + offsetY: this.offsetY + }; + }, + + /** + * Returns an instance of CanvasPattern + * @param ctx + * @return {CanvasPattern} + */ + toLive: function(ctx) { + var source = typeof this.source === 'function' ? this.source() : this.source; + return ctx.createPattern(source, this.repeat); + } +}); + + +/** + * Shadow class + * @class fabric.Shadow + */ +fabric.Shadow = fabric.util.createClass(/** @lends fabric.Shadow.prototype */ { + + /** + * Shadow color + * @type String + */ + color: 'rgb(0,0,0)', + + /** + * Shadow blur + * @type Number + */ + blur: 0, + + /** + * Shadow horizontal offset + * @type Number + */ + offsetX: 0, + + /** + * Shadow vertical offset + * @type Number + */ + offsetY: 0, + + /** + * Whether the shadow should affect stroke operations + * @type Boolean + */ + affectStroke: false, + + /** + * Constructor + * @param [options] Options object with any of color, blur, offsetX, offsetX properties + * @return {fabric.Shadow} thisArg + */ + initialize: function(options) { + for (var prop in options) { + this[prop] = options[prop]; + } + }, + + /** + * Returns object representation of a shadow + * @return {Object} + */ + toObject: function() { + return { + color: this.color, + blur: this.blur, + offsetX: this.offsetX, + offsetY: this.offsetY + }; + }, + + /* _TO_SVG_START_ */ + /** + * Returns SVG representation of a shadow + * @return {String} + */ + toSVG: function() { + + } + /* _TO_SVG_END_ */ +}); + + (function(global) { "use strict"; @@ -5742,6 +5808,7 @@ fabric.Shadow = fabric.util.createClass(/** @lends fabric.Shadow.prototype */ { })(typeof exports !== 'undefined' ? exports : this); + (function(global) { "use strict"; @@ -5777,6 +5844,7 @@ fabric.Shadow = fabric.util.createClass(/** @lends fabric.Shadow.prototype */ { /** * @private + * @param {String|Array} color Color value to parse */ _tryParsingColor: function(color) { var source; @@ -5790,11 +5858,58 @@ fabric.Shadow = fabric.util.createClass(/** @lends fabric.Shadow.prototype */ { if (!source) { source = Color.sourceFromRgb(color); } + if (!source) { + source = Color.sourceFromHsl(color); + } if (source) { this.setSource(source); } }, + /** + * Adapted from https://github.com/mjijackson + * @private + * @param {Number} r Red color value + * @param {Number} g Green color value + * @param {Number} b Blue color value + * @return {Array} Hsl color + */ + _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; // achromatic + } + else { + var d = max - min; + s = l > 0.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) + ]; + }, + /** * Returns source of this color (where source is an array representation; ex: [200, 200, 100, 1]) * @return {Array} @@ -5829,6 +5944,28 @@ fabric.Shadow = fabric.util.createClass(/** @lends fabric.Shadow.prototype */ { return 'rgba(' + source[0] + ',' + source[1] + ',' + source[2] + ',' + source[3] + ')'; }, + /** + * Returns color represenation in HSL format + * @return {String} ex: hsl(0-360,0%-100%,0%-100%) + */ + toHsl: function() { + var source = this.getSource(), + hsl = this._rgbToHsl(source[0], source[1], source[2]); + + return 'hsl(' + hsl[0] + ',' + hsl[1] + '%,' + hsl[2] + '%)'; + }, + + /** + * Returns color represenation in HSLA format + * @return {String} ex: hsla(0-360,0%-100%,0%-100%,0-1) + */ + 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] + ')'; + }, + /** * Returns color represenation in HEX format * @return {String} ex: FF5555 @@ -5858,7 +5995,7 @@ fabric.Shadow = fabric.util.createClass(/** @lends fabric.Shadow.prototype */ { /** * Sets value of alpha channel for this color - * @param {Number} 0-1 + * @param {Number} alpha 0-1 * @return {fabric.Color} thisArg */ setAlpha: function(alpha) { @@ -5882,6 +6019,7 @@ fabric.Shadow = fabric.util.createClass(/** @lends fabric.Shadow.prototype */ { /** * Transforms color to its black and white representation + * @param {Number} threshold * @return {fabric.Color} thisArg */ toBlackWhite: function(threshold) { @@ -5923,11 +6061,18 @@ fabric.Shadow = fabric.util.createClass(/** @lends fabric.Shadow.prototype */ { }; /** - * Regex matching color in RGB or RGBA formats (ex: rgb(0, 0, 0), rgb(255, 100, 10, 0.5), rgb(1,1,1)) + * Regex matching color in RGB or RGBA formats (ex: rgb(0, 0, 0), rgba(255, 100, 10, 0.5), rgba( 255 , 100 , 10 , 0.5 ), rgb(1,1,1), rgba(100%, 60%, 10%, 0.5)) * @static * @field */ - fabric.Color.reRGBa = /^rgba?\((\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})(?:\s*,\s*(\d+(?:\.\d+)?))?\)$/; + fabric.Color.reRGBa = /^rgba?\(\s*(\d{1,3}\%?)\s*,\s*(\d{1,3}\%?)\s*,\s*(\d{1,3}\%?)\s*(?:\s*,\s*(\d+(?:\.\d+)?)\s*)?\)$/; + + /** + * Regex matching color in HSL or HSLA formats (ex: hsl(200, 80%, 10%), hsla(300, 50%, 80%, 0.5), hsla( 300 , 50% , 80% , 0.5 )) + * @static + * @field + */ + fabric.Color.reHSLa = /^hsla?\(\s*(\d{1,3})\s*,\s*(\d{1,3}\%)\s*,\s*(\d{1,3}\%)\s*(?:\s*,\s*(\d+(?:\.\d+)?)\s*)?\)$/; /** * Regex matching color in HEX format (ex: #FF5555, 010155, aff) @@ -5960,6 +6105,22 @@ fabric.Shadow = fabric.util.createClass(/** @lends fabric.Shadow.prototype */ { 'yellow': '#FFFF00' }; + /** + * @private + * @param {Number} p + * @param {Number} q + * @param {Number} t + * @return {Number} + */ + 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; + } + /** * Returns new color object, when given a color in RGB format * @param {String} color ex: rgb(0-255,0-255,0-255) @@ -5971,16 +6132,20 @@ fabric.Shadow = fabric.util.createClass(/** @lends fabric.Shadow.prototype */ { /** * Returns array represenatation (ex: [100, 100, 200, 1]) of a color that's in RGB or RGBA format - * @param {String} color ex: rgb(0-255,0-255,0-255) + * @param {String} color ex: rgb(0-255,0-255,0-255), rgb(0%-100%,0%-100%,0%-100%) * @return {Array} source */ 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(match[1], 10), - parseInt(match[2], 10), - parseInt(match[3], 10), + parseInt(r, 10), + parseInt(g, 10), + parseInt(b, 10), match[4] ? parseFloat(match[4]) : 1 ]; } @@ -5995,6 +6160,60 @@ fabric.Shadow = fabric.util.createClass(/** @lends fabric.Shadow.prototype */ { */ fabric.Color.fromRgba = Color.fromRgb; + /** + * Returns new color object, when given a color in HSL format + * @param {String} color ex: hsl(0-260,0%-100%,0%-100%) + * @return {fabric.Color} + */ + fabric.Color.fromHsl = function(color) { + return Color.fromSource(Color.sourceFromHsl(color)); + }; + + /** + * Returns array represenatation (ex: [100, 100, 200, 1]) of a color that's in HSL or HSLA format. + * Adapted from https://github.com/mjijackson + * @param {String} color ex: hsl(0-360,0%-100%,0%-100%) or hsla(0-360,0%-100%,0%-100%, 0-1) + * @return {Array} source + * @see http://http://www.w3.org/TR/css3-color/#hsl-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 <= 0.5 ? l * (s + 1) : l + s - l * s; + var 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 + ]; + }; + + /** + * Returns new color object, when given a color in HSLA format + * @static + * @function + * @param {String} color + * @return {fabric.Color} + */ + fabric.Color.fromHsla = Color.fromHsl; + /** * Returns new color object, when given a color in HEX format * @static @@ -6030,6 +6249,7 @@ fabric.Shadow = fabric.util.createClass(/** @lends fabric.Shadow.prototype */ { /** * Returns new color object, when given color in array representation (ex: [200, 100, 100, 0.5]) * @static + * @param {Array} source * @return {fabric.Color} */ fabric.Color.fromSource = function(source) { @@ -6040,6 +6260,7 @@ fabric.Shadow = fabric.util.createClass(/** @lends fabric.Shadow.prototype */ { })(typeof exports !== 'undefined' ? exports : this); + (function () { "use strict"; @@ -7255,6 +7476,7 @@ fabric.Shadow = fabric.util.createClass(/** @lends fabric.Shadow.prototype */ { })(); + /** * BaseBrush class * @class fabric.BaseBrush @@ -7352,6 +7574,7 @@ fabric.BaseBrush = fabric.util.createClass(/** @lends fabric.BaseBrush.prototype } }); + (function() { var utilMin = fabric.util.array.min, @@ -7617,6 +7840,7 @@ fabric.BaseBrush = fabric.util.createClass(/** @lends fabric.BaseBrush.prototype }); })(); + /** * CircleBrush class * @class fabric.CircleBrush @@ -7717,6 +7941,7 @@ fabric.CircleBrush = fabric.util.createClass( fabric.BaseBrush, /** @lends fabri } }); + /** * SprayBrush class * @class fabric.SprayBrush @@ -7875,6 +8100,7 @@ fabric.SprayBrush = fabric.util.createClass( fabric.BaseBrush, /** @lends fabric } }); + /** * PatternBrush class * @class fabric.PatternBrush @@ -7933,6 +8159,7 @@ fabric.PatternBrush = fabric.util.createClass(fabric.PencilBrush, /** @lends fab } }); + (function() { var extend = fabric.util.object.extend, @@ -8681,11 +8908,14 @@ fabric.PatternBrush = fabric.util.createClass(fabric.PencilBrush, /** @lends fab * @throws {CANVAS_INIT_ERROR} If canvas can not be initialized */ _createUpperCanvas: function () { + var lowerCanvasClass = this.lowerCanvasEl.className.replace(/\s*lower-canvas\s*/, ''); + this.upperCanvasEl = this._createCanvasElement(); - this.upperCanvasEl.className = 'upper-canvas'; + 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'); }, @@ -8737,6 +8967,16 @@ fabric.PatternBrush = fabric.util.createClass(fabric.PencilBrush, /** @lends fab fabric.util.makeElementUnselectable(element); }, + /** + * Copys the the entire inline style from one element (fromEl) to another (toEl) + * @private + * @param {Element} fromEl Element style is copied from + * @param {Element} toEl Element copied style is applied to + */ + _copyCanvasStyle: function (fromEl, toEl) { + toEl.style.cssText = fromEl.style.cssText; + }, + /** * Returns context of canvas where object selection is drawn * @return {CanvasRenderingContext2D} @@ -8887,6 +9127,7 @@ fabric.PatternBrush = fabric.util.createClass(fabric.PencilBrush, /** @lends fab fabric.Element = fabric.Canvas; })(); + (function(){ var cursorMap = { @@ -9306,6 +9547,7 @@ fabric.PatternBrush = fabric.util.createClass(fabric.PencilBrush, /** @lends fab }); })(); + fabric.util.object.extend(fabric.StaticCanvas.prototype, /** @lends fabric.StaticCanvas.prototype */ { /** @@ -9417,6 +9659,7 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, /** @lends fabric.Stati } }); + fabric.util.object.extend(fabric.StaticCanvas.prototype, /** @lends fabric.StaticCanvas.prototype */ { /** @@ -9731,6 +9974,7 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, /** @lends fabric.Stati } }); + (function(global) { "use strict"; @@ -9900,7 +10144,7 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, /** @lends fabric.Stati overlayFill: null, /** - * When `true`, an object is rendered via stroke and this property specifies its color + * When defined, an object is rendered via stroke and this property specifies its color * @type String * @default */ @@ -10146,7 +10390,7 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, /** @lends fabric.Stati /** * Transforms context when rendering an object * @param {CanvasRenderingContext2D} ctx Context - * @param {Boolean} when true, context is transformed to object's top/left corner. This is used when rendering text on Node + * @param {Boolean} fromLeft When true, context is transformed to object's top/left corner. This is used when rendering text on Node */ transform: function(ctx, fromLeft) { ctx.globalAlpha = this.opacity; @@ -10162,8 +10406,8 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, /** @lends fabric.Stati /** * Returns an object representation of an instance - * @param {Array} propertiesToInclude - * @return {Object} object representation of an instance + * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output + * @return {Object} Object representation of an instance */ toObject: function(propertiesToInclude) { @@ -10211,14 +10455,15 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, /** @lends fabric.Stati /** * Returns (dataless) object representation of an instance - * @param {Array} [propertiesToInclude] - * @return {Object} object representation of an instance + * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output + * @return {Object} Object representation of an instance */ toDatalessObject: function(propertiesToInclude) { // will be overwritten by subclasses return this.toObject(propertiesToInclude); }, + /* _TO_SVG_START_ */ /** * Returns styles-string for svg-export * @return {String} @@ -10270,9 +10515,11 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, /** @lends fabric.Stati return [ translatePart, anglePart, scalePart, flipXPart, flipYPart ].join(''); }, + /* _TO_SVG_END_ */ /** * @private + * @param {Object} object */ _removeDefaultValues: function(object) { var defaultOptions = fabric.Object.prototype.options; @@ -10305,7 +10552,7 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, /** @lends fabric.Stati /** * Sets property to a given value. When changing position/dimension -related properties (left, top, scale, angle, etc.) `set` does not update position of object's borders/controls. If you need to update those, call `setCoords()`. - * @param {String} name + * @param {String|Object} key (if object, iterate over the object properties) * @param {Object|Function} value (if function, the value is passed into it and its return value is used as a new one) * @return {fabric.Object} thisArg * @chainable @@ -10329,8 +10576,9 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, /** @lends fabric.Stati /** * @private - * @param key - * @param value + * @param {String} key + * @param {Any} value + * @return {fabric.Object} thisArg */ _set: function(key, value) { var shouldConstrainValue = (key === 'scaleX' || key === 'scaleY'); @@ -10400,7 +10648,6 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, /** @lends fabric.Stati this.transform(ctx); } - ctx.save(); if (this.stroke) { ctx.lineWidth = this.strokeWidth; ctx.lineCap = this.strokeLineCap; @@ -10430,7 +10677,6 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, /** @lends fabric.Stati this._render(ctx, noTransform); this.clipTo && ctx.restore(); this._removeShadow(ctx); - ctx.restore(); if (this.active && !noTransform) { this.drawBorders(ctx); @@ -10490,6 +10736,7 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, /** @lends fabric.Stati _renderStroke: function(ctx) { if (!this.stroke) return; + ctx.save(); if (this.strokeDashArray) { // Spec requires the concatenation of two copies the dash list when the number of elements is odd if (1 & this.strokeDashArray.length) { @@ -10509,12 +10756,13 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, /** @lends fabric.Stati this._stroke ? this._stroke(ctx) : ctx.stroke(); } this._removeShadow(ctx); + ctx.restore(); }, /** * Clones an instance * @param {Function} callback Callback is invoked with a clone as a first argument - * @param {Array} propertiesToInclude + * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the outpu * @return {fabric.Object} clone of an instance */ clone: function(callback, propertiesToInclude) { @@ -10541,7 +10789,7 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, /** @lends fabric.Stati /** * Converts an object into a data-url-like string - * @param {Object} options + * @param {Object} options Options object * * `format` the format of the output image. Either "jpeg" or "png". * `quality` quality level (0..1) @@ -10609,7 +10857,7 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, /** @lends fabric.Stati /** * Returns complexity of an instance - * @return {Number} complexity + * @return {Number} complexity of this instance */ complexity: function() { return 0; @@ -10617,7 +10865,7 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, /** @lends fabric.Stati /** * Returns a JSON representation of an instance - * @param {Array} propertiesToInclude Any properties that you might want to additionally include in the output + * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output * @return {Object} JSON */ toJSON: function(propertiesToInclude) { @@ -10915,6 +11163,7 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, /** @lends fabric.Stati })(typeof exports !== 'undefined' ? exports : this); + (function() { var degreesToRadians = fabric.util.degreesToRadians; @@ -11133,6 +11382,7 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, /** @lends fabric.Stati })(); + (function() { var degreesToRadians = fabric.util.degreesToRadians; @@ -11518,13 +11768,14 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, /** @lends fabric.Stati }; // set coordinates of the draggable boxes in the corners used to scale/rotate the image - this._setCornerCoords(); + this._setCornerCoords && this._setCornerCoords(); return this; } }); })(); + /* Depends on `stateProperties` */ @@ -11571,6 +11822,7 @@ fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prot } }); + (function(){ var getPointer = fabric.util.getPointer, @@ -11986,6 +12238,7 @@ fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prot }); })(); + (function(global) { "use strict"; @@ -12166,6 +12419,7 @@ fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prot } }); + /* _FROM_SVG_START_ */ /** * List of attribute names to account for when parsing SVG element (used by {@link fabric.Line.fromElement}) * @static @@ -12190,6 +12444,7 @@ fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prot ]; return new fabric.Line(points, extend(parsedAttributes, options)); }; + /* _FROM_SVG_END_ */ /** * Returns fabric.Line instance from an object representation @@ -12204,6 +12459,7 @@ fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prot })(typeof exports !== 'undefined' ? exports : this); + (function(global) { "use strict"; @@ -12334,6 +12590,7 @@ fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prot } }); + /* _FROM_SVG_START_ */ /** * List of attribute names to account for when parsing SVG element (used by {@link fabric.Circle.fromElement}) * @static @@ -12375,6 +12632,7 @@ fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prot function isValidRadius(attributes) { return (('radius' in attributes) && (attributes.radius > 0)); } + /* _FROM_SVG_END_ */ /** * Returns {@link fabric.Circle} instance from an object representation @@ -12388,6 +12646,7 @@ fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prot })(typeof exports !== 'undefined' ? exports : this); + (function(global) { "use strict"; @@ -12517,6 +12776,7 @@ fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prot })(typeof exports !== 'undefined' ? exports : this); + (function(global){ "use strict"; @@ -12655,6 +12915,7 @@ fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prot } }); + /* _FROM_SVG_START_ */ /** * List of attribute names to account for when parsing SVG element (used by {@link fabric.Ellipse.fromElement}) * @static @@ -12690,6 +12951,7 @@ fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prot return ellipse; }; + /* _FROM_SVG_END_ */ /** * Returns {@link fabric.Ellipse} instance from an object representation @@ -12703,6 +12965,7 @@ fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prot })(typeof exports !== 'undefined' ? exports : this); + (function(global) { "use strict"; @@ -12914,6 +13177,7 @@ fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prot } }); + /* _FROM_SVG_START_ */ /** * List of attribute names to account for when parsing SVG element (used by `fabric.Rect.fromElement`) * @static @@ -12949,6 +13213,7 @@ fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prot return rect; }; + /* _FROM_SVG_END_ */ /** * Returns {@link fabric.Rect} instance from an object representation @@ -12962,6 +13227,7 @@ fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prot })(typeof exports !== 'undefined' ? exports : this); + (function(global) { "use strict"; @@ -13093,6 +13359,7 @@ fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prot } }); + /* _FROM_SVG_START_ */ /** * List of attribute names to account for when parsing SVG element (used by {@link fabric.Polyline.fromElement}) * @static @@ -13129,6 +13396,7 @@ fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prot return new fabric.Polyline(points, fabric.util.object.extend(parsedAttributes, options), true); }; + /* _FROM_SVG_END_ */ /** * Returns fabric.Polyline instance from an object representation @@ -13143,6 +13411,7 @@ fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prot })(typeof exports !== 'undefined' ? exports : this); + (function(global) { "use strict"; @@ -13303,6 +13572,7 @@ fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prot } }); + /* _FROM_SVG_START_ */ /** * List of attribute names to account for when parsing SVG element (used by `fabric.Polygon.fromElement`) * @static @@ -13339,6 +13609,7 @@ fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prot return new fabric.Polygon(points, extend(parsedAttributes, options), true); }; + /* _FROM_SVG_END_ */ /** * Returns fabric.Polygon instance from an object representation @@ -13352,6 +13623,7 @@ fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prot })(typeof exports !== 'undefined' ? exports : this); + (function(global) { var commandLengths = { @@ -13526,6 +13798,7 @@ fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prot * Constructor * @param {Array|String} path Path data (sequence of coordinates and corresponding "command" tokens) * @param {Object} [options] Options object + * @return {fabric.Path} thisArg */ initialize: function(path, options) { options = options || { }; @@ -13557,6 +13830,7 @@ fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prot /** * @private + * @param {Object} [options] Options object */ _initializePath: function (options) { var isWidthSet = 'width' in options, @@ -13586,6 +13860,7 @@ fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prot /** * @private + * @param {Boolean} positionSet When false, path offset is returned otherwise 0 */ _calculatePathOffset: function (positionSet) { return { @@ -13596,6 +13871,7 @@ fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prot /** * @private + * @param {CanvasRenderingContext2D} ctx context to render path on */ _render: function(ctx) { var current, // current instruction @@ -13894,7 +14170,6 @@ fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prot } // ctx.globalCompositeOperation = this.fillRule; - ctx.save(); if (this.overlayFill) { ctx.fillStyle = this.overlayFill; } @@ -13923,7 +14198,6 @@ fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prot this._renderStroke(ctx); this.clipTo && ctx.restore(); this._removeShadow(ctx); - ctx.restore(); if (!noTransform && this.active) { this.drawBorders(ctx); @@ -13943,7 +14217,7 @@ fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prot /** * Returns object representation of an instance - * @param {Array} propertiesToInclude + * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output * @return {Object} object representation of an instance */ toObject: function(propertiesToInclude) { @@ -13961,7 +14235,7 @@ fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prot /** * Returns dataless object representation of an instance - * @param {Array} propertiesToInclude + * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output * @return {Object} object representation of an instance */ toDatalessObject: function(propertiesToInclude) { @@ -14011,7 +14285,7 @@ fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prot /** * Returns number representation of an instance complexity - * @return {Number} complexity + * @return {Number} complexity of this instance */ complexity: function() { return this.path.length; @@ -14145,6 +14419,7 @@ fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prot return new fabric.Path(object.path, object); }; + /* _FROM_SVG_START_ */ /** * List of attribute names to account for when parsing SVG element (used by `fabric.Path.fromElement`) * @static @@ -14163,9 +14438,11 @@ fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prot var parsedAttributes = fabric.parseAttributes(element, fabric.Path.ATTRIBUTE_NAMES); return new fabric.Path(parsedAttributes.d, extend(parsedAttributes, options)); }; + /* _FROM_SVG_END_ */ })(typeof exports !== 'undefined' ? exports : this); + (function(global) { "use strict"; @@ -14401,6 +14678,7 @@ fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prot })(typeof exports !== 'undefined' ? exports : this); + (function(global){ "use strict"; @@ -14856,6 +15134,7 @@ fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prot })(typeof exports !== 'undefined' ? exports : this); + (function(global) { "use strict"; @@ -14889,7 +15168,7 @@ fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prot * Constructor * @param {HTMLImageElement | String} element Image element * @param {Object} [options] Options object - * @return {fabric.Image} + * @return {fabric.Image} thisArg */ initialize: function(element, options) { options || (options = { }); @@ -14909,7 +15188,7 @@ fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prot /** * Returns image element which this instance if based on - * @return {HTMLImageElement} image element + * @return {HTMLImageElement} Image element */ getElement: function() { return this._element; @@ -14994,9 +15273,10 @@ fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prot ctx.strokeStyle = this.stroke.toLive ? this.stroke.toLive(ctx) : this.stroke; + ctx.beginPath(); ctx.strokeRect(-this.width / 2, -this.height / 2, this.width, this.height); - ctx.beginPath(); + ctx.closePath(); ctx.restore(); }, @@ -15010,6 +15290,7 @@ fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prot w = this.width, h = this.height; + ctx.save(); ctx.lineWidth = this.strokeWidth; ctx.lineCap = this.strokeLineCap; ctx.lineJoin = this.strokeLineJoin; @@ -15017,12 +15298,14 @@ fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prot ctx.strokeStyle = this.stroke.toLive ? this.stroke.toLive(ctx) : this.stroke; + 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(); }, /** @@ -15230,7 +15513,7 @@ fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prot /** * Returns complexity of an instance - * @return {Number} complexity + * @return {Number} complexity of this instance */ complexity: function() { return 1; @@ -15300,6 +15583,7 @@ fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prot }); }; + /* _FROM_SVG_START_ */ /** * List of attribute names to account for when parsing SVG element (used by {@link fabric.Image.fromElement}) * @static @@ -15313,7 +15597,7 @@ fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prot * @param {SVGElement} element Element to parse * @param {Function} callback Callback to execute when fabric.Image object is created * @param {Object} [options] Options object - * @return {fabric.Image} + * @return {fabric.Image} Instance of fabric.Image */ fabric.Image.fromElement = function(element, callback, options) { var parsedAttributes = fabric.parseAttributes(element, fabric.Image.ATTRIBUTE_NAMES); @@ -15321,6 +15605,7 @@ fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prot fabric.Image.fromURL(parsedAttributes['xlink:href'], callback, extend((options ? fabric.util.object.clone(options) : { }), parsedAttributes)); }; + /* _FROM_SVG_END_ */ /** * Indicates that instances of this type are async @@ -15331,6 +15616,7 @@ fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prot })(typeof exports !== 'undefined' ? exports : this); + fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prototype */ { /** @@ -15421,316 +15707,26 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, /** @lends fabric.Stati } }); + /** * @namespace fabric.Image.filters * @memberOf fabric.Image */ -fabric.Image.filters = { }; - -/** - * Grayscale image filter class - * @class fabric.Image.filters.Grayscale - * @memberOf fabric.Image.filters - */ -fabric.Image.filters.Grayscale = fabric.util.createClass( /** @lends fabric.Image.filters.Grayscale.prototype */ { - - /** - * Filter type - * @param {String} type - */ - type: "Grayscale", - - /** - * Applies filter to canvas element - * @memberOf fabric.Image.filters.Grayscale.prototype - * @param {Object} canvasEl Canvas element to apply filter to - */ - 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); - }, - - /** - * Returns json representation of filter - * @return {Object} JSON representation of filter - */ - toJSON: function() { - return { type: this.type }; - } -}); - -/** - * Returns filter instance from an object representation - * @static - * @return {fabric.Image.filters.Grayscale} - */ -fabric.Image.filters.Grayscale.fromObject = function() { - return new fabric.Image.filters.Grayscale(); -}; - -/** - * Remove white filter class - * @class fabric.Image.filters.RemoveWhite - * @memberOf fabric.Image.filters - */ -fabric.Image.filters.RemoveWhite = fabric.util.createClass( /** @lends fabric.Image.filters.RemoveWhite.prototype */ { - - /** - * Filter type - * @param {String} type - */ - type: "RemoveWhite", - - /** - * Constructor - * @memberOf fabric.Image.filters.RemoveWhite.prototype - * @param {Object} [options] Options object - */ - initialize: function(options) { - options || (options = { }); - this.threshold = options.threshold || 30; - this.distance = options.distance || 20; - }, - - /** - * Applies filter to canvas element - * @param {Object} canvasEl Canvas element to apply filter to - */ - 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] = 1; - } - } - - context.putImageData(imageData, 0, 0); - }, - - /** - * Returns json representation of filter - * @return {Object} JSON representation of filter - */ - toJSON: function() { - return { - type: this.type, - threshold: this.threshold, - distance: this.distance - }; - } -}); - -/** - * Returns filter instance from an object representation - * @static - * @return {fabric.Image.filters.RemoveWhite} - */ -fabric.Image.filters.RemoveWhite.fromObject = function(object) { - return new fabric.Image.filters.RemoveWhite(object); -}; - -/** - * Invert filter class - * @class fabric.Image.filters.Invert - * @memberOf fabric.Image.filters - */ -fabric.Image.filters.Invert = fabric.util.createClass( /** @lends fabric.Image.filters.Invert.prototype */ { - - /** - * Filter type - * @param {String} type - */ - type: "Invert", - - /** - * Applies filter to canvas element - * @memberOf fabric.Image.filters.Invert.prototype - * @param {Object} canvasEl Canvas element to apply filter to - */ - 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); - }, - - /** - * Returns json representation of filter - * @return {String} json representation of filter - */ - toJSON: function() { - return { type: this.type }; - } -}); - -/** - * Returns filter instance from an object representation - * @static - * @return {fabric.Image.filters.Invert} - */ -fabric.Image.filters.Invert.fromObject = function() { - return new fabric.Image.filters.Invert(); -}; - -/** - * Sepia filter class - * @class fabric.Image.filters.Sepia - * @memberOf fabric.Image.filters - */ -fabric.Image.filters.Sepia = fabric.util.createClass( /** @lends fabric.Image.filters.Sepia.prototype */ { - - /** - * Filter type - * @param {String} type - */ - type: "Sepia", - - /** - * Applies filter to canvas element - * @memberOf fabric.Image.filters.Sepia.prototype - * @param {Object} canvasEl Canvas element to apply filter to - */ - 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 = 0.3 * data[i] + 0.59 * data[i + 1] + 0.11 * data[i + 2]; - data[i] = avg + 100; - data[i + 1] = avg + 50; - data[i + 2] = avg + 255; - } - - context.putImageData(imageData, 0, 0); - }, - - /** - * Returns json representation of filter - * @return {String} json representation of filter - */ - toJSON: function() { - return { type: this.type }; - } -}); - -/** - * Returns filter instance from an object representation - * @static - * @return {fabric.Image.filters.Sepia} - */ -fabric.Image.filters.Sepia.fromObject = function() { - return new fabric.Image.filters.Sepia(); -}; - -/** - * Sepia2 filter class - * @class fabric.Image.filters.Sepia2 - * @memberOf fabric.Image.filters - */ -fabric.Image.filters.Sepia2 = fabric.util.createClass( /** @lends fabric.Image.filters.Sepia2.prototype */ { - - /** - * Filter type - * @param {String} type - */ - type: "Sepia2", - - /** - * Applies filter to canvas element - * @memberOf fabric.Image.filters.Sepia.prototype - * @param {Object} canvasEl Canvas element to apply filter to - */ - 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 * 0.393 + g * 0.769 + b * 0.189 ) / 1.351; - data[i + 1] = (r * 0.349 + g * 0.686 + b * 0.168 ) / 1.203; - data[i + 2] = (r * 0.272 + g * 0.534 + b * 0.131 ) / 2.140; - } - - context.putImageData(imageData, 0, 0); - }, - - /** - * Returns json representation of filter - * @return {String} json representation of filter - */ - toJSON: function() { - return { type: this.type }; - } -}); - -/** - * Returns filter instance from an object representation - * @static - * @return {fabric.Image.filters.Sepia2} - */ -fabric.Image.filters.Sepia2.fromObject = function() { - return new fabric.Image.filters.Sepia2(); -}; +fabric.Image.filters = fabric.Image.filters || { }; /** * Brightness filter class * @class fabric.Image.filters.Brightness * @memberOf fabric.Image.filters */ -fabric.Image.filters.Brightness = fabric.util.createClass( /** @lends fabric.Image.filters.Brightness.prototype */ { +fabric.Image.filters.Brightness = fabric.util.createClass(/** @lends fabric.Image.filters.Brightness.prototype */ { /** * Filter type * @param {String} type + * @default */ - type: "Brightness", + type: 'Brightness', /** * Constructor @@ -15738,7 +15734,7 @@ fabric.Image.filters.Brightness = fabric.util.createClass( /** @lends fabric.Ima * @param {Object} [options] Options object */ initialize: function(options) { - options || (options = { }); + options = options || { }; this.brightness = options.brightness || 100; }, @@ -15776,214 +15772,19 @@ fabric.Image.filters.Brightness = fabric.util.createClass( /** @lends fabric.Ima /** * Returns filter instance from an object representation * @static - * @return {fabric.Image.filters.Brightness} + * @param {Object} object Object to create an instance from + * @return {fabric.Image.filters.Brightness} Instance of fabric.Image.filters.Brightness */ fabric.Image.filters.Brightness.fromObject = function(object) { return new fabric.Image.filters.Brightness(object); }; -/** - * Noise filter class - * @class fabric.Image.filters.Noise - * @memberOf fabric.Image.filters - */ -fabric.Image.filters.Noise = fabric.util.createClass( /** @lends fabric.Image.filters.Noise.prototype */ { - - /** - * Filter type - * @param {String} type - */ - type: "Noise", - - /** - * Constructor - * @memberOf fabric.Image.filters.Noise.prototype - * @param {Object} [options] Options object - */ - initialize: function(options) { - options || (options = { }); - this.noise = options.noise || 100; - }, - - /** - * Applies filter to canvas element - * @param {Object} canvasEl Canvas element to apply filter to - */ - 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 = (0.5 - Math.random()) * noise; - - data[i] += rand; - data[i + 1] += rand; - data[i + 2] += rand; - } - - context.putImageData(imageData, 0, 0); - }, - - /** - * Returns json representation of filter - * @return {String} json representation of filter - */ - toJSON: function() { - return { - type: this.type, - noise: this.noise - }; - } -}); /** - * Returns filter instance from an object representation - * @static - * @return {fabric.Image.filters.Noise} + * @namespace fabric.Image.filters + * @memberOf fabric.Image */ -fabric.Image.filters.Noise.fromObject = function(object) { - return new fabric.Image.filters.Noise(object); -}; - -/** - * GradientTransparency filter class - * @class fabric.Image.filters.GradientTransparency - * @memberOf fabric.Image.filters - */ -fabric.Image.filters.GradientTransparency = fabric.util.createClass( /** @lends fabric.Image.filters.GradientTransparency.prototype */ { - - /** - * Filter type - * @param {String} type - */ - type: "GradientTransparency", - - /** - * Constructor - * @memberOf fabric.Image.filters.GradientTransparency - * @param {Object} [options] Options object - */ - initialize: function(options) { - options || (options = { }); - this.threshold = options.threshold || 100; - }, - - /** - * Applies filter to canvas element - * @param {Object} canvasEl Canvas element to apply filter to - */ - 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); - }, - - /** - * Returns json representation of filter - * @return {String} json representation of filter - */ - toJSON: function() { - return { - type: this.type, - threshold: this.threshold - }; - } -}); - -/** - * Returns filter instance from an object representation - * @static - * @return {fabric.Image.filters.GradientTransparency} - */ -fabric.Image.filters.GradientTransparency.fromObject = function(object) { - return new fabric.Image.filters.GradientTransparency(object); -}; - -/** - * Tint filter class - * @class fabric.Image.filters.Tint - * @memberOf fabric.Image.filters - */ -fabric.Image.filters.Tint = fabric.util.createClass( /** @lends fabric.Image.filters.Tint.prototype */ { - - /** - * Filter type - * @param {String} type - */ - type: "Tint", - - /** - * Constructor - * @memberOf fabric.Image.filters.Tint.prototype - * @param {Object} [options] Options object - */ - initialize: function(options) { - options || (options = { }); - this.color = options.color || 0; - }, - - /** - * Applies filter to canvas element - * @param {Object} canvasEl Canvas element to apply filter to - */ - applyTo: function(canvasEl) { - - var context = canvasEl.getContext('2d'), - imageData = context.getImageData(0, 0, canvasEl.width, canvasEl.height), - data = imageData.data, - iLen = data.length, i, a; - - var rgb = parseInt(this.color, 10).toString(16); - - var cr = parseInt('0x' + rgb.substr(0, 2), 16); - var cg = parseInt('0x' + rgb.substr(2, 2), 16); - var cb = parseInt('0x' + rgb.substr(4, 2), 16); - - for (i = 0; i < iLen; i+=4) { - - a = data[i+3]; - - if (a > 0){ - data[i] = cr; - data[i+1] = cg; - data[i+2] = cb; - } - } - - context.putImageData(imageData, 0, 0); - }, - - /** - * Returns json representation of filter - * @return {String} json representation of filter - */ - toJSON: function() { - return { - type: this.type, - color: this.color - }; - } -}); - -/** - * Returns filter instance from an object representation - * @static - * @return {fabric.Image.filters.Tint} - */ -fabric.Image.filters.Tint.fromObject = function(object) { - return new fabric.Image.filters.Tint(object); -}; +fabric.Image.filters = fabric.Image.filters || { }; /** * Adapted from html5rocks article @@ -15995,6 +15796,7 @@ fabric.Image.filters.Convolute = fabric.util.createClass(/** @lends fabric.Image /** * Filter type * @param {String} type + * @default */ type: 'Convolute', @@ -16004,12 +15806,12 @@ fabric.Image.filters.Convolute = fabric.util.createClass(/** @lends fabric.Image * @param {Object} [options] Options object */ initialize: function(options) { - options || (options = { }); + options = options || { }; this.opaque = options.opaque; this.matrix = options.matrix || [ 0, 0, 0, - 0, 1, 0, - 0, 0, 0 ]; + 0, 1, 0, + 0, 0, 0 ]; var canvasEl = fabric.util.createCanvasElement(); this.tmpCtx = canvasEl.getContext('2d'); @@ -16027,7 +15829,6 @@ fabric.Image.filters.Convolute = fabric.util.createClass(/** @lends fabric.Image * @param {Object} canvasEl Canvas element to apply filter to */ applyTo: function(canvasEl) { - var weights = this.matrix; var context = canvasEl.getContext('2d'); var pixels = context.getImageData(0, 0, canvasEl.width, canvasEl.height); @@ -16086,6 +15887,7 @@ fabric.Image.filters.Convolute = fabric.util.createClass(/** @lends fabric.Image toJSON: function() { return { type: this.type, + opaque: this.opaque, matrix: this.matrix }; } @@ -16094,12 +15896,288 @@ fabric.Image.filters.Convolute = fabric.util.createClass(/** @lends fabric.Image /** * Returns filter instance from an object representation * @static - * @return {fabric.Image.filters.Convolute} + * @param {Object} object Object to create an instance from + * @return {fabric.Image.filters.Convolute} Instance of fabric.Image.filters.Convolute */ fabric.Image.filters.Convolute.fromObject = function(object) { - return new fabric.Image.filters.Convolute(object); + return new fabric.Image.filters.Convolute(object); }; + +/** + * @namespace fabric.Image.filters + * @memberOf fabric.Image + */ +fabric.Image.filters = fabric.Image.filters || { }; + +/** + * GradientTransparency filter class + * @class fabric.Image.filters.GradientTransparency + * @memberOf fabric.Image.filters + */ +fabric.Image.filters.GradientTransparency = fabric.util.createClass(/** @lends fabric.Image.filters.GradientTransparency.prototype */ { + + /** + * Filter type + * @param {String} type + * @default + */ + type: 'GradientTransparency', + + /** + * Constructor + * @memberOf fabric.Image.filters.GradientTransparency + * @param {Object} [options] Options object + */ + initialize: function(options) { + options = options || { }; + this.threshold = options.threshold || 100; + }, + + /** + * Applies filter to canvas element + * @param {Object} canvasEl Canvas element to apply filter to + */ + 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); + }, + + /** + * Returns json representation of filter + * @return {String} json representation of filter + */ + toJSON: function() { + return { + type: this.type, + threshold: this.threshold + }; + } +}); + +/** + * Returns filter instance from an object representation + * @static + * @param {Object} object Object to create an instance from + * @return {fabric.Image.filters.GradientTransparency} Instance of fabric.Image.filters.GradientTransparency + */ +fabric.Image.filters.GradientTransparency.fromObject = function(object) { + return new fabric.Image.filters.GradientTransparency(object); +}; + + +/** + * @namespace fabric.Image.filters + * @memberOf fabric.Image + */ +fabric.Image.filters = fabric.Image.filters || { }; + +/** + * Grayscale image filter class + * @class fabric.Image.filters.Grayscale + * @memberOf fabric.Image.filters + */ +fabric.Image.filters.Grayscale = fabric.util.createClass(/** @lends fabric.Image.filters.Grayscale.prototype */ { + + /** + * Filter type + * @param {String} type + * @default + */ + type: 'Grayscale', + + /** + * Applies filter to canvas element + * @memberOf fabric.Image.filters.Grayscale.prototype + * @param {Object} canvasEl Canvas element to apply filter to + */ + 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); + }, + + /** + * Returns json representation of filter + * @return {Object} JSON representation of filter + */ + toJSON: function() { + return { type: this.type }; + } +}); + +/** + * Returns filter instance from an object representation + * @static + * @return {fabric.Image.filters.Grayscale} Instance of fabric.Image.filters.Grayscale + */ +fabric.Image.filters.Grayscale.fromObject = function() { + return new fabric.Image.filters.Grayscale(); +}; + + +/** + * @namespace fabric.Image.filters + * @memberOf fabric.Image + */ +fabric.Image.filters = fabric.Image.filters || { }; + +/** + * Invert filter class + * @class fabric.Image.filters.Invert + * @memberOf fabric.Image.filters + */ +fabric.Image.filters.Invert = fabric.util.createClass(/** @lends fabric.Image.filters.Invert.prototype */ { + + /** + * Filter type + * @param {String} type + * @default + */ + type: 'Invert', + + /** + * Applies filter to canvas element + * @memberOf fabric.Image.filters.Invert.prototype + * @param {Object} canvasEl Canvas element to apply filter to + */ + 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); + }, + + /** + * Returns json representation of filter + * @return {String} json representation of filter + */ + toJSON: function() { + return { type: this.type }; + } +}); + +/** + * Returns filter instance from an object representation + * @static + * @return {fabric.Image.filters.Invert} Instance of fabric.Image.filters.Invert + */ +fabric.Image.filters.Invert.fromObject = function() { + return new fabric.Image.filters.Invert(); +}; + + +/** + * @namespace fabric.Image.filters + * @memberOf fabric.Image + */ +fabric.Image.filters = fabric.Image.filters || { }; + +/** + * Noise filter class + * @class fabric.Image.filters.Noise + * @memberOf fabric.Image.filters + */ +fabric.Image.filters.Noise = fabric.util.createClass(/** @lends fabric.Image.filters.Noise.prototype */ { + + /** + * Filter type + * @param {String} type + * @default + */ + type: 'Noise', + + /** + * Constructor + * @memberOf fabric.Image.filters.Noise.prototype + * @param {Object} [options] Options object + */ + initialize: function(options) { + options = options || { }; + this.noise = options.noise || 100; + }, + + /** + * Applies filter to canvas element + * @param {Object} canvasEl Canvas element to apply filter to + */ + 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 = (0.5 - Math.random()) * noise; + + data[i] += rand; + data[i + 1] += rand; + data[i + 2] += rand; + } + + context.putImageData(imageData, 0, 0); + }, + + /** + * Returns json representation of filter + * @return {String} json representation of filter + */ + toJSON: function() { + return { + type: this.type, + noise: this.noise + }; + } +}); + +/** + * Returns filter instance from an object representation + * @static + * @param {Object} object Object to create an instance from + * @return {fabric.Image.filters.Noise} Instance of fabric.Image.filters.Noise + */ +fabric.Image.filters.Noise.fromObject = function(object) { + return new fabric.Image.filters.Noise(object); +}; + + +/** + * @namespace fabric.Image.filters + * @memberOf fabric.Image + */ +fabric.Image.filters = fabric.Image.filters || { }; + /** * Pixelate filter class * @class fabric.Image.filters.Pixelate @@ -16110,6 +16188,7 @@ fabric.Image.filters.Pixelate = fabric.util.createClass(/** @lends fabric.Image. /** * Filter type * @param {String} type + * @default */ type: 'Pixelate', @@ -16119,7 +16198,7 @@ fabric.Image.filters.Pixelate = fabric.util.createClass(/** @lends fabric.Image. * @param {Object} [options] Options object */ initialize: function(options) { - options || (options = { }); + options = options || { }; this.blocksize = options.blocksize || 4; }, @@ -16128,7 +16207,6 @@ fabric.Image.filters.Pixelate = fabric.util.createClass(/** @lends fabric.Image. * @param {Object} canvasEl Canvas element to apply filter to */ applyTo: function(canvasEl) { - var context = canvasEl.getContext('2d'), imageData = context.getImageData(0, 0, canvasEl.width, canvasEl.height), data = imageData.data, @@ -16147,14 +16225,14 @@ fabric.Image.filters.Pixelate = fabric.util.createClass(/** @lends fabric.Image. a = data[index+3]; /* - blocksize: 4 + blocksize: 4 - [1,x,x,x,1] - [x,x,x,x,1] - [x,x,x,x,1] - [x,x,x,x,1] - [1,1,1,1,1] - */ + [1,x,x,x,1] + [x,x,x,x,1] + [x,x,x,x,1] + [x,x,x,x,1] + [1,1,1,1,1] + */ for (var _i = i, _ilen = i + this.blocksize; _i < _ilen; _i++) { for (var _j = j, _jlen = j + this.blocksize; _j < _jlen; _j++) { @@ -16186,12 +16264,307 @@ fabric.Image.filters.Pixelate = fabric.util.createClass(/** @lends fabric.Image. /** * Returns filter instance from an object representation * @static - * @return {fabric.Image.filters.Pixelate} + * @param {Object} object Object to create an instance from + * @return {fabric.Image.filters.Pixelate} Instance of fabric.Image.filters.Pixelate */ fabric.Image.filters.Pixelate.fromObject = function(object) { return new fabric.Image.filters.Pixelate(object); }; + +/** + * @namespace fabric.Image.filters + * @memberOf fabric.Image + */ +fabric.Image.filters = fabric.Image.filters || { }; + +/** + * Remove white filter class + * @class fabric.Image.filters.RemoveWhite + * @memberOf fabric.Image.filters + */ +fabric.Image.filters.RemoveWhite = fabric.util.createClass(/** @lends fabric.Image.filters.RemoveWhite.prototype */ { + + /** + * Filter type + * @param {String} type + * @default + */ + type: 'RemoveWhite', + + /** + * Constructor + * @memberOf fabric.Image.filters.RemoveWhite.prototype + * @param {Object} [options] Options object + */ + initialize: function(options) { + options = options || { }; + this.threshold = options.threshold || 30; + this.distance = options.distance || 20; + }, + + /** + * Applies filter to canvas element + * @param {Object} canvasEl Canvas element to apply filter to + */ + 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] = 1; + } + } + + context.putImageData(imageData, 0, 0); + }, + + /** + * Returns json representation of filter + * @return {Object} JSON representation of filter + */ + toJSON: function() { + return { + type: this.type, + threshold: this.threshold, + distance: this.distance + }; + } +}); + +/** + * Returns filter instance from an object representation + * @static + * @param {Object} object Object to create an instance from + * @return {fabric.Image.filters.RemoveWhite} Instance of fabric.Image.filters.RemoveWhite + */ +fabric.Image.filters.RemoveWhite.fromObject = function(object) { + return new fabric.Image.filters.RemoveWhite(object); +}; + + +/** + * @namespace fabric.Image.filters + * @memberOf fabric.Image + */ +fabric.Image.filters = fabric.Image.filters || { }; + +/** + * Sepia filter class + * @class fabric.Image.filters.Sepia + * @memberOf fabric.Image.filters + */ +fabric.Image.filters.Sepia = fabric.util.createClass(/** @lends fabric.Image.filters.Sepia.prototype */ { + + /** + * Filter type + * @param {String} type + * @default + */ + type: 'Sepia', + + /** + * Applies filter to canvas element + * @memberOf fabric.Image.filters.Sepia.prototype + * @param {Object} canvasEl Canvas element to apply filter to + */ + 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 = 0.3 * data[i] + 0.59 * data[i + 1] + 0.11 * data[i + 2]; + data[i] = avg + 100; + data[i + 1] = avg + 50; + data[i + 2] = avg + 255; + } + + context.putImageData(imageData, 0, 0); + }, + + /** + * Returns json representation of filter + * @return {String} json representation of filter + */ + toJSON: function() { + return { type: this.type }; + } +}); + +/** + * Returns filter instance from an object representation + * @static + * @return {fabric.Image.filters.Sepia} Instance of fabric.Image.filters.Sepia + */ +fabric.Image.filters.Sepia.fromObject = function() { + return new fabric.Image.filters.Sepia(); +}; + + +/** + * @namespace fabric.Image.filters + * @memberOf fabric.Image + */ +fabric.Image.filters = fabric.Image.filters || { }; + +/** + * Sepia2 filter class + * @class fabric.Image.filters.Sepia2 + * @memberOf fabric.Image.filters + */ +fabric.Image.filters.Sepia2 = fabric.util.createClass(/** @lends fabric.Image.filters.Sepia2.prototype */ { + + /** + * Filter type + * @param {String} type + * @default + */ + type: 'Sepia2', + + /** + * Applies filter to canvas element + * @memberOf fabric.Image.filters.Sepia.prototype + * @param {Object} canvasEl Canvas element to apply filter to + */ + 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 * 0.393 + g * 0.769 + b * 0.189 ) / 1.351; + data[i + 1] = (r * 0.349 + g * 0.686 + b * 0.168 ) / 1.203; + data[i + 2] = (r * 0.272 + g * 0.534 + b * 0.131 ) / 2.140; + } + + context.putImageData(imageData, 0, 0); + }, + + /** + * Returns json representation of filter + * @return {String} json representation of filter + */ + toJSON: function() { + return { type: this.type }; + } +}); + +/** + * Returns filter instance from an object representation + * @static + * @return {fabric.Image.filters.Sepia2} Instance of fabric.Image.filters.Sepia2 + */ +fabric.Image.filters.Sepia2.fromObject = function() { + return new fabric.Image.filters.Sepia2(); +}; + + +/** + * @namespace fabric.Image.filters + * @memberOf fabric.Image + */ +fabric.Image.filters = fabric.Image.filters || { }; + +/** + * Tint filter class + * @class fabric.Image.filters.Tint + * @memberOf fabric.Image.filters + */ +fabric.Image.filters.Tint = fabric.util.createClass(/** @lends fabric.Image.filters.Tint.prototype */ { + + /** + * Filter type + * @param {String} type + * @default + */ + type: 'Tint', + + /** + * Constructor + * @memberOf fabric.Image.filters.Tint.prototype + * @param {Object} [options] Options object + */ + initialize: function(options) { + options = options || { }; + this.color = options.color || 0; + }, + + /** + * Applies filter to canvas element + * @param {Object} canvasEl Canvas element to apply filter to + */ + applyTo: function(canvasEl) { + var context = canvasEl.getContext('2d'), + imageData = context.getImageData(0, 0, canvasEl.width, canvasEl.height), + data = imageData.data, + iLen = data.length, i, a; + + var rgb = parseInt(this.color, 10).toString(16); + + var cr = parseInt('0x' + rgb.substr(0, 2), 16); + var cg = parseInt('0x' + rgb.substr(2, 2), 16); + var cb = parseInt('0x' + rgb.substr(4, 2), 16); + + for (i = 0; i < iLen; i+=4) { + a = data[i+3]; + + if (a > 0){ + data[i] = cr; + data[i+1] = cg; + data[i+2] = cb; + } + } + + context.putImageData(imageData, 0, 0); + }, + + /** + * Returns json representation of filter + * @return {Object} json representation of filter + */ + toJSON: function() { + return { + type: this.type, + color: this.color + }; + } +}); + +/** + * Returns filter instance from an object representation + * @static + * @param {Object} object Object to create an instance from + * @return {fabric.Image.filters.Tint} Instance of fabric.Image.filters.Tint + */ +fabric.Image.filters.Tint.fromObject = function(object) { + return new fabric.Image.filters.Tint(object); +}; + + (function(global) { "use strict"; @@ -16231,8 +16604,6 @@ fabric.Image.filters.Pixelate.fromObject = function(object) { 'textAlign', 'fontStyle', 'lineHeight', - 'stroke', - 'strokeWidth', 'backgroundColor', 'textBackgroundColor', 'useNative' @@ -16246,6 +16617,14 @@ fabric.Image.filters.Pixelate.fromObject = function(object) { */ fabric.Text = fabric.util.createClass(fabric.Object, /** @lends fabric.Text.prototype */ { + + /** + * Type of an object + * @type String + * @default + */ + type: 'text', + /** * Font size (in pixels) * @type Number @@ -16268,7 +16647,7 @@ fabric.Image.filters.Pixelate.fromObject = function(object) { fontFamily: 'Times New Roman', /** - * Text decoration (e.g. underline, overline) + * Text decoration Possible values: "", "underline", "overline" or "line-through". * @type String * @default */ @@ -16289,7 +16668,7 @@ fabric.Image.filters.Pixelate.fromObject = function(object) { textAlign: 'left', /** - * Font style (e.g. italic) + * Font style . Possible values: "", "normal", "italic" or "oblique". * @type String * @default */ @@ -16302,20 +16681,6 @@ fabric.Image.filters.Pixelate.fromObject = function(object) { */ lineHeight: 1.3, - /** - * Stroke style. When specified, text is rendered with stroke - * @type String - * @default - */ - stroke: '', - - /** - * Stroke width - * @type Number - * @default - */ - strokeWidth: 1, - /** * Background color of an entire text box * @type String @@ -16337,13 +16702,6 @@ fabric.Image.filters.Pixelate.fromObject = function(object) { */ path: null, - /** - * Type of an object - * @type String - * @default - */ - type: 'text', - /** * Indicates whether canvas native text methods should be used to render text (otherwise, Cufon is used) * @type Boolean @@ -16360,8 +16718,8 @@ fabric.Image.filters.Pixelate.fromObject = function(object) { /** * Constructor - * @param {String} text - * @param {Object} [options] + * @param {String} text Text string + * @param {Object} [options] Options object * @return {fabric.Text} thisArg */ initialize: function(text, options) { @@ -16418,6 +16776,7 @@ fabric.Image.filters.Pixelate.fromObject = function(object) { /** * @private + * @param {CanvasRenderingContext2D} ctx Context to render on */ _renderViaCufon: function(ctx) { var o = Cufon.textOptions || (Cufon.textOptions = { }); @@ -16510,6 +16869,8 @@ fabric.Image.filters.Pixelate.fromObject = function(object) { /** * @private + * @param {CanvasRenderingContext2D} ctx Context to render on + * @param {Array} textLines Array of all text lines */ _setBoundaries: function(ctx, textLines) { this._boundaries = [ ]; @@ -16529,6 +16890,7 @@ fabric.Image.filters.Pixelate.fromObject = function(object) { /** * @private + * @param {CanvasRenderingContext2D} ctx Context to render on */ _setTextStyles: function(ctx) { if (this.fill) { @@ -16552,6 +16914,9 @@ fabric.Image.filters.Pixelate.fromObject = function(object) { /** * @private + * @param {CanvasRenderingContext2D} ctx Context to render on + * @param {Array} textLines Array of all text lines + * @return {Number} Height of fabric.Text object */ _getTextHeight: function(ctx, textLines) { return this.fontSize * textLines.length * this.lineHeight; @@ -16559,6 +16924,9 @@ fabric.Image.filters.Pixelate.fromObject = function(object) { /** * @private + * @param {CanvasRenderingContext2D} ctx Context to render on + * @param {Array} textLines Array of all text lines + * @return {Number} Maximum width of fabric.Text object */ _getTextWidth: function(ctx, textLines) { var maxWidth = ctx.measureText(textLines[0]).width; @@ -16574,46 +16942,46 @@ fabric.Image.filters.Pixelate.fromObject = function(object) { /** * @private + * @param {CanvasRenderingContext2D} ctx Context to render on */ _setTextShadow: function(ctx) { - if (this.textShadow) { + if (!this.textShadow) return; - // "rgba(0,0,0,0.2) 2px 2px 10px" - // "rgb(0, 100, 0) 0 0 5px" - // "red 2px 2px 1px" - // "#f55 123 345 567" - var reOffsetsAndBlur = /\s+(-?\d+)(?:px)?\s+(-?\d+)(?:px)?\s+(\d+)(?:px)?\s*/; + // "rgba(0,0,0,0.2) 2px 2px 10px" + // "rgb(0, 100, 0) 0 0 5px" + // "red 2px 2px 1px" + // "#f55 123 345 567" + var reOffsetsAndBlur = /\s+(-?\d+)(?:px)?\s+(-?\d+)(?:px)?\s+(\d+)(?:px)?\s*/; - var shadowDeclaration = this.textShadow; - var offsetsAndBlur = reOffsetsAndBlur.exec(this.textShadow); - var shadowColor = shadowDeclaration.replace(reOffsetsAndBlur, ''); + var shadowDeclaration = this.textShadow; + var offsetsAndBlur = reOffsetsAndBlur.exec(this.textShadow); + var shadowColor = shadowDeclaration.replace(reOffsetsAndBlur, ''); - ctx.save(); - ctx.shadowColor = shadowColor; - ctx.shadowOffsetX = parseInt(offsetsAndBlur[1], 10); - ctx.shadowOffsetY = parseInt(offsetsAndBlur[2], 10); - ctx.shadowBlur = parseInt(offsetsAndBlur[3], 10); + ctx.save(); + ctx.shadowColor = shadowColor; + ctx.shadowOffsetX = parseInt(offsetsAndBlur[1], 10); + ctx.shadowOffsetY = parseInt(offsetsAndBlur[2], 10); + ctx.shadowBlur = parseInt(offsetsAndBlur[3], 10); - this._shadows = [{ - blur: ctx.shadowBlur, - color: ctx.shadowColor, - offX: ctx.shadowOffsetX, - offY: ctx.shadowOffsetY - }]; + this._shadows = [{ + blur: ctx.shadowBlur, + color: ctx.shadowColor, + offX: ctx.shadowOffsetX, + offY: ctx.shadowOffsetY + }]; - this._shadowOffsets = [[ - parseInt(ctx.shadowOffsetX, 10), parseInt(ctx.shadowOffsetY, 10) - ]]; - } + this._shadowOffsets = [[ + parseInt(ctx.shadowOffsetX, 10), parseInt(ctx.shadowOffsetY, 10) + ]]; }, /** * @private - * @param method - * @param ctx - * @param line - * @param left - * param top + * @param {String} method Method name ("fillText" or "strokeText") + * @param {CanvasRenderingContext2D} ctx Context to render on + * @param {String} line Text to render + * @param {Number} left Left position of text + * @param {Number} top Top position of text */ _drawTextLine: function(method, ctx, line, left, top) { @@ -16646,6 +17014,10 @@ fabric.Image.filters.Pixelate.fromObject = function(object) { } }, + /** + * @private + * @return {Number} Left offset + */ _getLeftOffset: function() { if (fabric.isLikelyNode && (this.originX === 'left' || this.originX === 'center')) { return 0; @@ -16653,6 +17025,10 @@ fabric.Image.filters.Pixelate.fromObject = function(object) { return -this.width / 2; }, + /** + * @private + * @return {Number} Top offset + */ _getTopOffset: function() { if (fabric.isLikelyNode && (this.originY === 'top' || this.originY === 'center')) { return 0; @@ -16662,51 +17038,59 @@ fabric.Image.filters.Pixelate.fromObject = function(object) { /** * @private + * @param {CanvasRenderingContext2D} ctx Context to render on + * @param {Array} textLines Array of all text lines */ _renderTextFill: function(ctx, textLines) { - if (this.fill) { - this._boundaries = [ ]; - for (var i = 0, len = textLines.length; i < len; i++) { - this._drawTextLine( - 'fillText', - ctx, - textLines[i], - this._getLeftOffset(), - this._getTopOffset() + ((i + 1) * this.fontSize * this.lineHeight) - ); - } + if (!this.fill) return; + + this._boundaries = [ ]; + for (var i = 0, len = textLines.length; i < len; i++) { + this._drawTextLine( + 'fillText', + ctx, + textLines[i], + this._getLeftOffset(), + this._getTopOffset() + ((i + 1) * this.fontSize * this.lineHeight) + ); } }, /** * @private + * @param {CanvasRenderingContext2D} ctx Context to render on + * @param {Array} textLines Array of all text lines */ _renderTextStroke: function(ctx, textLines) { - if (this.stroke) { - if (this.strokeDashArray) { - // Spec requires the concatenation of two copies the dash list when the number of elements is odd - if (1 & this.strokeDashArray.length) { - this.strokeDashArray.push.apply(this.strokeDashArray, this.strokeDashArray); - } - supportsLineDash && ctx.setLineDash(this.strokeDashArray); - } + if (!this.stroke) return; - ctx.beginPath(); - for (var i = 0, len = textLines.length; i < len; i++) { - this._drawTextLine( - 'strokeText', - ctx, - textLines[i], - this._getLeftOffset(), - this._getTopOffset() + ((i + 1) * this.fontSize * this.lineHeight) - ); + ctx.save(); + if (this.strokeDashArray) { + // Spec requires the concatenation of two copies the dash list when the number of elements is odd + if (1 & this.strokeDashArray.length) { + this.strokeDashArray.push.apply(this.strokeDashArray, this.strokeDashArray); } - ctx.closePath(); + supportsLineDash && ctx.setLineDash(this.strokeDashArray); } + + ctx.beginPath(); + for (var i = 0, len = textLines.length; i < len; i++) { + this._drawTextLine( + 'strokeText', + ctx, + textLines[i], + this._getLeftOffset(), + this._getTopOffset() + ((i + 1) * this.fontSize * this.lineHeight) + ); + } + ctx.closePath(); + ctx.restore(); }, /** * @private + * @param {CanvasRenderingContext2D} ctx Context to render on + * @param {Array} textLines Array of all text lines */ _renderTextBackground: function(ctx, textLines) { this._renderTextBoxBackground(ctx); @@ -16715,52 +17099,57 @@ fabric.Image.filters.Pixelate.fromObject = function(object) { /** * @private + * @param {CanvasRenderingContext2D} ctx Context to render on */ _renderTextBoxBackground: function(ctx) { - if (this.backgroundColor) { - ctx.save(); - ctx.fillStyle = this.backgroundColor; + if (!this.backgroundColor) return; - ctx.fillRect( - this._getLeftOffset(), - this._getTopOffset(), - this.width, - this.height - ); + ctx.save(); + ctx.fillStyle = this.backgroundColor; - ctx.restore(); - } + ctx.fillRect( + this._getLeftOffset(), + this._getTopOffset(), + this.width, + this.height + ); + + ctx.restore(); }, /** * @private + * @param {CanvasRenderingContext2D} ctx Context to render on + * @param {Array} textLines Array of all text lines */ _renderTextLinesBackground: function(ctx, textLines) { - if (this.textBackgroundColor) { - ctx.save(); - ctx.fillStyle = this.textBackgroundColor; + if (!this.textBackgroundColor) return; - for (var i = 0, len = textLines.length; i < len; i++) { + ctx.save(); + ctx.fillStyle = this.textBackgroundColor; - if (textLines[i] !== '') { + for (var i = 0, len = textLines.length; i < len; i++) { - var lineWidth = this._getLineWidth(ctx, textLines[i]); - var lineLeftOffset = this._getLineLeftOffset(lineWidth); + if (textLines[i] !== '') { - ctx.fillRect( - this._getLeftOffset() + lineLeftOffset, - this._getTopOffset() + (i * this.fontSize * this.lineHeight), - lineWidth, - this.fontSize * this.lineHeight - ); - } + var lineWidth = this._getLineWidth(ctx, textLines[i]); + var lineLeftOffset = this._getLineLeftOffset(lineWidth); + + ctx.fillRect( + this._getLeftOffset() + lineLeftOffset, + this._getTopOffset() + (i * this.fontSize * this.lineHeight), + lineWidth, + this.fontSize * this.lineHeight + ); } - ctx.restore(); } + ctx.restore(); }, /** * @private + * @param {Number} lineWidth Width of text line + * @return {Number} Line left offset */ _getLineLeftOffset: function(lineWidth) { if (this.textAlign === 'center') { @@ -16774,8 +17163,9 @@ fabric.Image.filters.Pixelate.fromObject = function(object) { /** * @private - * @param ctx - * @param line + * @param {CanvasRenderingContext2D} ctx Context to render on + * @param {String} line Text line + * @return {Number} Line width */ _getLineWidth: function(ctx, line) { return this.textAlign === 'justify' @@ -16785,8 +17175,11 @@ fabric.Image.filters.Pixelate.fromObject = function(object) { /** * @private + * @param {CanvasRenderingContext2D} ctx Context to render on + * @param {Array} textLines Array of all text lines */ _renderTextDecoration: function(ctx, textLines) { + if (!this.textDecoration) return; var halfOfVerticalBox = this.originY === 'top' ? 0 : this._getTextHeight(ctx, textLines) / 2; var _this = this; @@ -16858,7 +17251,7 @@ fabric.Image.filters.Pixelate.fromObject = function(object) { /** * Renders text instance on a specified context - * @param ctx {CanvasRenderingContext2D} context to render on + * @param {CanvasRenderingContext2D} ctx Context to render on * @param {Boolean} [noTransform] When true, context is not transformed */ render: function(ctx, noTransform) { @@ -16876,8 +17269,8 @@ fabric.Image.filters.Pixelate.fromObject = function(object) { /** * Returns object representation of an instance - * @param {Array} propertiesToInclude - * @return {Object} object representation of an instance + * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output + * @return {Object} Object representation of an instance */ toObject: function(propertiesToInclude) { return extend(this.callSuper('toObject', propertiesToInclude), { @@ -16891,8 +17284,6 @@ fabric.Image.filters.Pixelate.fromObject = function(object) { textShadow: this.textShadow, textAlign: this.textAlign, path: this.path, - stroke: this.stroke, - strokeWidth: this.strokeWidth, backgroundColor: this.backgroundColor, textBackgroundColor: this.textBackgroundColor, useNative: this.useNative @@ -16943,6 +17334,9 @@ fabric.Image.filters.Pixelate.fromObject = function(object) { /** * @private + * @param {Number} lineTopOffset Line top offset + * @param {Array} textLines Array of all text lines + * @return {Array} */ _getSVGShadows: function(lineTopOffset, textLines) { var shadowSpans = [], j, i, jlen, ilen, lineTopOffsetMultiplier = 1; @@ -16979,6 +17373,10 @@ fabric.Image.filters.Pixelate.fromObject = function(object) { /** * @private + * @param {Number} lineTopOffset Line top offset + * @param {Number} textLeftOffset Text left offset + * @param {Array} textLines Array of all text lines + * @return {Object} */ _getSVGTextAndBg: function(lineTopOffset, textLeftOffset, textLines) { var textSpans = [ ], textBgRects = [ ], i, lineLeftOffset, len, lineTopOffsetMultiplier = 1; @@ -17048,6 +17446,8 @@ fabric.Image.filters.Pixelate.fromObject = function(object) { * we work around it by "moving" alpha channel into opacity attribute and setting fill's alpha to 1 * * @private + * @param {Any} value + * @return {String} */ _getFillAttributes: function(value) { var fillColor = (value && typeof value === 'string') ? new fabric.Color(value) : ''; @@ -17105,6 +17505,7 @@ fabric.Image.filters.Pixelate.fromObject = function(object) { } }); + /* _FROM_SVG_START_ */ /** * List of attribute names to account for when parsing SVG element (used by {@link fabric.Text.fromElement}) * @static @@ -17112,22 +17513,12 @@ fabric.Image.filters.Pixelate.fromObject = function(object) { fabric.Text.ATTRIBUTE_NAMES = fabric.SHARED_ATTRIBUTES.concat( 'x y font-family font-style font-weight font-size text-decoration'.split(' ')); - /** - * Returns fabric.Text instance from an object representation - * @static - * @param {Object} object to create an instance from - * @return {fabric.Text} an instance - */ - fabric.Text.fromObject = function(object) { - return new fabric.Text(object.text, clone(object)); - }; - /** * Returns fabric.Text instance from an SVG element (not yet implemented) * @static - * @param element - * @param options - * @return {fabric.Text} an instance + * @param {SVGElement} element Element to parse + * @param {Object} [options] Options object + * @return {fabric.Text} Instance of fabric.Text */ fabric.Text.fromElement = function(element, options) { @@ -17153,11 +17544,23 @@ fabric.Image.filters.Pixelate.fromObject = function(object) { return text; }; + /* _FROM_SVG_END_ */ + + /** + * Returns fabric.Text instance from an object representation + * @static + * @param object {Object} object Object to create an instance from + * @return {fabric.Text} Instance of fabric.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() { if (typeof document !== 'undefined' && typeof window !== 'undefined') { diff --git a/dist/all.min.js b/dist/all.min.js index 5b2d8452..53eacce6 100644 --- a/dist/all.min.js +++ b/dist/all.min.js @@ -1,6 +1,6 @@ -/* build: `node build.js modules=ALL exclude=gestures` *//*! Fabric.js Copyright 2008-2013, Printio (Juriy Zaytsev, Maxim Chernyak) */var fabric=fabric||{version:"1.1.16"};typeof exports!="undefined"&&(exports.fabric=fabric),typeof document!="undefined"&&typeof window!="undefined"?(fabric.document=document,fabric.window=window):(fabric.document=require("jsdom").jsdom(""),fabric.window=fabric.document.createWindow()),fabric.isTouchSupported="ontouchstart"in fabric.document.documentElement,fabric.isLikelyNode=typeof Buffer!="undefined"&&typeof window=="undefined";var Cufon=function(){function r(e){var t=this.face=e.face;this.glyphs=e.glyphs,this.w=e.w,this.baseSize=parseInt(t["units-per-em"],10),this.family=t["font-family"].toLowerCase(),this.weight=t["font-weight"],this.style=t["font-style"]||"normal",this.viewBox=function(){var e=t.bbox.split(/\s+/),n={minX:parseInt(e[0],10),minY:parseInt(e[1],10),maxX:parseInt(e[2],10),maxY:parseInt(e[3],10)};return n.width=n.maxX-n.minX,n.height=n.maxY-n.minY,n.toString=function(){return[this.minX,this.minY,this.width,this.height].join(" ")},n}(),this.ascent=-parseInt(t.ascent,10),this.descent=-parseInt(t.descent,10),this.height=-this.ascent+this.descent}function i(){var e={},t={oblique:"italic",italic:"oblique"};this.add=function(t){(e[t.style]||(e[t.style]={}))[t.weight]=t},this.get=function(n,r){var i=e[n]||e[t[n]]||e.normal||e.italic||e.oblique;if(!i)return null;r={normal:400,bold:700}[r]||parseInt(r,10);if(i[r])return i[r];var s={1:1,99:0}[r%100],o=[],u,a;s===undefined&&(s=r>400),r==500&&(r=400);for(var f in i){f=parseInt(f,10);if(!u||fa)a=f;o.push(f)}return ra&&(r=a),o.sort(function(e,t){return(s?e>r&&t>r?et:et:e=i.length+e?r():setTimeout(arguments.callee,10)}),function(t){e?t():n.push(t)}}(),supports:function(e,t){var n=fabric.document.createElement("span").style;return n[e]===undefined?!1:(n[e]=t,n[e]===t)},textAlign:function(e,t,n,r){return t.get("textAlign")=="right"?n>0&&(e=" "+e):nk&&(k=N),A.push(N),N=0;continue}var O=t.glyphs[T[b]]||t.missingGlyph;if(!O)continue;N+=C=Number(O.w||t.w)+h}A.push(N),N=Math.max(k,N);var M=[];for(var b=A.length;b--;)M[b]=N-A[b];if(C===null)return null;d+=l.width-C,m+=l.minX;var _,D;if(f)_=u,D=u.firstChild;else{_=fabric.document.createElement("span"),_.className="cufon cufon-canvas",_.alt=n,D=fabric.document.createElement("canvas"),_.appendChild(D);if(i.printable){var P=fabric.document.createElement("span");P.className="cufon-alt",P.appendChild(fabric.document.createTextNode(n)),_.appendChild(P)}}var H=_.style,B=D.style||{},j=c.convert(l.height-p+v),F=Math.ceil(j),I=F/j;D.width=Math.ceil(c.convert(N+d-m)*I),D.height=F,p+=l.minY,B.top=Math.round(c.convert(p-t.ascent))+"px",B.left=Math.round(c.convert(m))+"px";var q=Math.ceil(c.convert(N*I)),R=q+"px",U=c.convert(t.height),z=(i.lineHeight-1)*c.convert(-t.ascent/5)*(L-1);Cufon.textOptions.width=q,Cufon.textOptions.height=U*L+z,Cufon.textOptions.lines=L,Cufon.textOptions.totalLineHeight=z,e?(H.width=R,H.height=U+"px"):(H.paddingLeft=R,H.paddingBottom=U-1+"px");var W=Cufon.textOptions.context||D.getContext("2d"),X=F/l.height;Cufon.textOptions.fontAscent=t.ascent*X,Cufon.textOptions.boundaries=null;for(var V=Cufon.textOptions.shadowOffsets,b=y.length;b--;)V[b]=[y[b][0]*X,y[b][1]*X];W.save(),W.scale(X,X),W.translate(-m-1/X*D.width/2+(Cufon.fonts[t.family].offsetLeft||0),-p-Cufon.textOptions.height/X/2+(Cufon.fonts[t.family].offsetTop||0)),W.lineWidth=t.face["underline-thickness"],W.save();var J=Cufon.getTextDecoration(i),K=i.fontStyle==="italic";W.save(),Q();if(g)for(var b=0,w=g.length;b.cufon-vml-canvas{text-indent:0}@media screen{cvml\\:shape,cvml\\:shadow{behavior:url(#default#VML);display:block;antialias:true;position:absolute}.cufon-vml-canvas{position:absolute;text-align:left}.cufon-vml{display:inline-block;position:relative;vertical-align:middle}.cufon-vml .cufon-alt{position:absolute;left:-10000in;font-size:1px}a .cufon-vml{cursor:pointer}}@media print{.cufon-vml *{display:none}.cufon-vml .cufon-alt{display:inline}}'),function(e,t,i,s,o,u,a){var f=t===null;f&&(t=o.alt);var l=e.viewBox,c=i.computedFontSize||(i.computedFontSize=new Cufon.CSS.Size(n(u,i.get("fontSize"))+"px",e.baseSize)),h=i.computedLSpacing;h==undefined&&(h=i.get("letterSpacing"),i.computedLSpacing=h=h=="normal"?0:~~c.convertFrom(r(u,h)));var p,d;if(f)p=o,d=o.firstChild;else{p=fabric.document.createElement("span"),p.className="cufon cufon-vml",p.alt=t,d=fabric.document.createElement("span"),d.className="cufon-vml-canvas",p.appendChild(d);if(s.printable){var v=fabric.document.createElement("span");v.className="cufon-alt",v.appendChild(fabric.document.createTextNode(t)),p.appendChild(v)}a||p.appendChild(fabric.document.createElement("cvml:shape"))}var m=p.style,g=d.style,y=c.convert(l.height),b=Math.ceil(y),w=b/y,E=l.minX,S=l.minY;g.height=b,g.top=Math.round(c.convert(S-e.ascent)),g.left=Math.round(c.convert(E)),m.height=c.convert(e.height)+"px";var x=Cufon.getTextDecoration(s),T=i.get("color"),N=Cufon.CSS.textTransform(t,i).split(""),C=0,k=0,L=null,A,O,M=s.textShadow;for(var _=0,D=0,P=N.length;_-1},complexity:function(){return this.getObjects().reduce(function(e,t){return e+=t.complexity?t.complexity():0,e},0)},toGrayscale:function(){return this.forEachObject(function(e){e.toGrayscale()})}},function(){function n(e,t){var n=e.indexOf(t);return n!==-1&&e.splice(n,1),e}function r(e,t){return Math.floor(Math.random()*(t-e+1))+e}function s(e){return e*i}function o(e){return e/i}function u(e,t,n){var r=Math.sin(n),i=Math.cos(n);e.subtractEquals(t);var s=e.x*i-e.y*r,o=e.x*r+e.y*i;return(new fabric.Point(s,o)).addEquals(t)}function a(e,t){return parseFloat(Number(e).toFixed(t))}function f(){return!1}function l(e){e||(e={});var t=+(new Date),n=e.duration||500,r=t+n,i,s=e.onChange||function(){},o=e.abort||function(){return!1},u=e.easing||function(e,t,n,r){return-n*Math.cos(e/r*(Math.PI/2))+n+t},a="startValue"in e?e.startValue:0,f="endValue"in e?e.endValue:100,l=e.byValue||f-a;e.onStart&&e.onStart(),function c(){i=+(new Date);var f=i>r?n:i-t;s(u(f,a,l,n));if(i>r||o()){e.onComplete&&e.onComplete();return}h(c)}()}function p(e,t,n){if(e){var r=fabric.util.createImage();r.onload=function(){t&&t.call(n,r),r=r.onload=null},r.src=e}else t&&t.call(n,e)}function d(e,t){function n(e){return fabric[fabric.util.string.camelize(fabric.util.string.capitalize(e))]}function r(){++s===o&&t&&t(i)}var i=[],s=0,o=e.length;e.forEach(function(e,t){if(!e.type)return;var s=n(e.type);s.async?s.fromObject(e,function(e,n){n||(i[t]=e),r()}):(i[t]=s.fromObject(e),r())})}function v(e,t,n){var r;return e.length>1?r=new fabric.PathGroup(e,t):r=e[0],typeof n!="undefined"&&r.setSourcePath(n),r}function m(e,t,n){if(n&&Object.prototype.toString.call(n)==="[object Array]")for(var r=0,i=n.length;rr)r+=u[p++%h],r>l&&(r=l),n[d?"lineTo":"moveTo"](r,0),d=!d;n.restore()}function y(e){return e||(e=fabric.document.createElement("canvas")),!e.getContext&&typeof G_vmlCanvasManager!="undefined"&&G_vmlCanvasManager.initElement(e),e}function b(){return fabric.isLikelyNode?new(require("canvas").Image):fabric.document.createElement("img")}function w(e){var t=e.prototype;for(var n=t.stateProperties.length;n--;){var r=t.stateProperties[n],i=r.charAt(0).toUpperCase()+r.slice(1),s="set"+i,o="get"+i;t[o]||(t[o]=function(e){return new Function('return this.get("'+e+'")')}(r)),t[s]||(t[s]=function(e){return new Function("value",'return this.set("'+e+'", value)')}(r))}}function E(e,t){t.save(),t.beginPath(),e.clipTo(t),t.clip()}function S(e,t){var n=[[e[0],e[2],e[4]],[e[1],e[3],e[5]],[0,0,1]],r=[[t[0],t[2],t[4]],[t[1],t[3],t[5]],[0,0,1]],i=[];for(var s=0;s<3;s++){i[s]=[];for(var o=0;o<3;o++){var u=0;for(var a=0;a<3;a++)u+=n[s][a]*r[a][o];i[s][o]=u}}return[i[0][0],i[1][0],i[0][1],i[1][1],i[0][2],i[1][2]]}var e=Math.sqrt,t=Math.atan2;fabric.util={};var i=Math.PI/180,c=fabric.window.requestAnimationFrame||fabric.window.webkitRequestAnimationFrame||fabric.window.mozRequestAnimationFrame||fabric.window.oRequestAnimationFrame||fabric.window.msRequestAnimationFrame||function(e){fabric.window.setTimeout(e,1e3/60)},h=function(){return c.apply(fabric.window,arguments)};fabric.util.removeFromArray=n,fabric.util.degreesToRadians=s,fabric.util.radiansToDegrees=o,fabric.util.rotatePoint=u,fabric.util.toFixed=a,fabric.util.getRandomInt=r,fabric.util.falseFunction=f,fabric.util.animate=l,fabric.util.requestAnimFrame=h,fabric.util.loadImage=p,fabric.util.enlivenObjects=d,fabric.util.groupSVGElements=v,fabric.util.populateWithProperties=m,fabric.util.drawDashedLine=g,fabric.util.createCanvasElement=y,fabric.util.createImage=b,fabric.util.createAccessors=w,fabric.util.clipContext=E,fabric.util.multiplyTransformMatrices=S}(),function(){function t(t,n){var r=e.call(arguments,2),i=[];for(var s=0,o=t.length;s=r&&(r=e[n][t]);else while(n--)e[n]>=r&&(r=e[n]);return r}function r(e,t){if(!e||e.length===0)return undefined;var n=e.length-1,r=t?e[n][t]:e[n];if(t)while(n--)e[n][t]>>0;if(n===0)return-1;var r=0;arguments.length>0&&(r=Number(arguments[1]),r!==r?r=0:r!==0&&r!==Number.POSITIVE_INFINITY&&r!==Number.NEGATIVE_INFINITY&&(r=(r>0||-1)*Math.floor(Math.abs(r))));if(r>=n)return-1;var i=r>=0?r:Math.max(n-Math.abs(r),0);for(;i>>0;n>>0;r>>0;n>>0;n>>0;i>>0,n=0,r;if(arguments.length>1)r=arguments[1];else do{if(n in this){r=this[n++];break}if(++n>=t)throw new TypeError}while(!0);for(;n/g,">")}String.prototype.trim||(String.prototype.trim=function(){return this.replace(/^[\s\xA0]+/,"").replace(/[\s\xA0]+$/,"")}),fabric.util.string={camelize:e,capitalize:t,escapeXml:n}}(),function(){var e=Array.prototype.slice,t=Function.prototype.apply,n=function(){};Function.prototype.bind||(Function.prototype.bind=function(r){var i=this,s=e.call(arguments,1),o;return s.length?o=function(){return t.call(i,this instanceof n?this:r,s.concat(e.call(arguments)))}:o=function(){return t.call(i,this instanceof n?this:r,arguments)},n.prototype=this.prototype,o.prototype=new n,o})}(),function(){function i(){}function s(t){var n=this.constructor.superclass.prototype[t];return arguments.length>1?n.apply(this,e.call(arguments,1)):n.call(this)}function o(){function u(){this.initialize.apply(this,arguments)}var n=null,o=e.call(arguments,0);typeof o[0]=="function"&&(n=o.shift()),u.superclass=n,u.subclasses=[],n&&(i.prototype=n.prototype,u.prototype=new i,n.subclasses.push(u));for(var a=0,f=o.length;a-1?e.prototype[i]=function(e){return function(){var n=this.constructor.superclass;this.constructor.superclass=r;var i=t[e].apply(this,arguments);this.constructor.superclass=n;if(e!=="initialize")return i}}(i):e.prototype[i]=t[i],n&&(t.toString!==Object.prototype.toString&&(e.prototype.toString=t.toString),t.valueOf!==Object.prototype.valueOf&&(e.prototype.valueOf=t.valueOf))};fabric.util.createClass=o}(),function(){function e(e){var t=Array.prototype.slice.call(arguments,1),n,r,i=t.length;for(r=0;r-1?s(e,t.match(/opacity:\s*(\d?\.?\d*)/)[1]):e;for(var r in t)if(r==="opacity")s(e,t[r]);else{var i=r==="float"||r==="cssFloat"?typeof n.styleFloat=="undefined"?"cssFloat":"styleFloat":r;n[i]=t[r]}return e}var t=fabric.document.createElement("div"),n=typeof t.style.opacity=="string",r=typeof t.style.filter=="string",i=/alpha\s*\(\s*opacity\s*=\s*([^\)]+)\)/,s=function(e){return e};n?s=function(e,t){return e.style.opacity=t,e}:r&&(s=function(e,t){var n=e.style;return e.currentStyle&&!e.currentStyle.hasLayout&&(n.zoom=1),i.test(n.filter)?(t=t>=.9999?"":"alpha(opacity="+t*100+")",n.filter=n.filter.replace(i,t)):n.filter+=" alpha(opacity="+t*100+")",e}),fabric.util.setStyle=e}(),function(){function t(e){return typeof e=="string"?fabric.document.getElementById(e):e}function s(e,t){var n=fabric.document.createElement(e);for(var r in t)r==="class"?n.className=t[r]:r==="for"?n.htmlFor=t[r]:n.setAttribute(r,t[r]);return n}function o(e,t){(" "+e.className+" ").indexOf(" "+t+" ")===-1&&(e.className+=(e.className?" ":"")+t)}function u(e,t,n){return typeof t=="string"&&(t=s(t,n)),e.parentNode&&e.parentNode.replaceChild(t,e),t.appendChild(e),t}function a(e){var t,n,r={left:0,top:0},i=e&&e.ownerDocument;return i?(t=i.documentElement,typeof e.getBoundingClientRect!="undefined"&&(r=e.getBoundingClientRect()),i!=null&&i===i.window?n=i:n=i.nodeType===9&&i.defaultView,{left:r.left+n.pageXOffset-(t.clientLeft||0),top:r.top+n.pageYOffset-(t.clientTop||0)}):{left:0,top:0}}var e=Array.prototype.slice,n=function(t){return e.call(t,0)},r;try{r=n(fabric.document.childNodes)instanceof Array}catch(i){}r||(n=function(e){var t=new Array(e.length),n=e.length;while(n--)t[n]=e[n];return t});var f;fabric.document.defaultView&&fabric.document.defaultView.getComputedStyle?f=function(e){return fabric.document.defaultView.getComputedStyle(e,null).position}:f=function(e){var t=e.style.position;return!t&&e.currentStyle&&(t=e.currentStyle.position),t},function(){function n(e){return typeof e.onselectstart!="undefined"&&(e.onselectstart=fabric.util.falseFunction),t?e.style[t]="none":typeof e.unselectable=="string"&&(e.unselectable="on"),e}function r(e){return typeof e.onselectstart!="undefined"&&(e.onselectstart=null),t?e.style[t]="":typeof e.unselectable=="string"&&(e.unselectable=""),e}var e=fabric.document.documentElement.style,t="userSelect"in e?"userSelect":"MozUserSelect"in e?"MozUserSelect":"WebkitUserSelect"in e?"WebkitUserSelect":"KhtmlUserSelect"in e?"KhtmlUserSelect":"";fabric.util.makeElementUnselectable=n,fabric.util.makeElementSelectable=r}(),function(){function e(e,t){var n=fabric.document.getElementsByTagName("head")[0],r=fabric.document.createElement("script"),i=!0;r.onload=r.onreadystatechange=function(e){if(i){if(typeof this.readyState=="string"&&this.readyState!=="loaded"&&this.readyState!=="complete")return;i=!1,t(e||fabric.window.event),r=r.onload=r.onreadystatechange=null}},r.src=e,n.appendChild(r)}fabric.util.getScript=e}(),fabric.util.getById=t,fabric.util.toArray=n,fabric.util.makeElement=s,fabric.util.addClass=o,fabric.util.wrapElement=u,fabric.util.getElementOffset=a,fabric.util.getElementPosition=f}(),function(){function e(e,t){return e+(/\?/.test(e)?"&":"?")+t}function n(){}function r(r,i){i||(i={});var s=i.method?i.method.toUpperCase():"GET",o=i.onComplete||function(){},u=t(),a;return u.onreadystatechange=function(){u.readyState===4&&(o(u),u.onreadystatechange=n)},s==="GET"&&(a=null,typeof i.parameters=="string"&&(r=e(r,i.parameters))),u.open(s,r,!0),(s==="POST"||s==="PUT")&&u.setRequestHeader("Content-Type","application/x-www-form-urlencoded"),u.send(a),u}var t=function(){var e=[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 t=e.length;t--;)try{var n=e[t]();if(n)return e[t]}catch(r){}}();fabric.util.request=r}(),function(){function e(e,t,n,r){return n*(e/=r)*e+t}function t(e,t,n,r){return-n*(e/=r)*(e-2)+t}function n(e,t,n,r){return e/=r/2,e<1?n/2*e*e+t:-n/2*(--e*(e-2)-1)+t}function r(e,t,n,r){return n*(e/=r)*e*e+t}function i(e,t,n,r){return n*((e=e/r-1)*e*e+1)+t}function s(e,t,n,r){return e/=r/2,e<1?n/2*e*e*e+t:n/2*((e-=2)*e*e+2)+t}function o(e,t,n,r){return n*(e/=r)*e*e*e+t}function u(e,t,n,r){return-n*((e=e/r-1)*e*e*e-1)+t}function a(e,t,n,r){return e/=r/2,e<1?n/2*e*e*e*e+t:-n/2*((e-=2)*e*e*e-2)+t}function f(e,t,n,r){return n*(e/=r)*e*e*e*e+t}function l(e,t,n,r){return n*((e=e/r-1)*e*e*e*e+1)+t}function c(e,t,n,r){return e/=r/2,e<1?n/2*e*e*e*e*e+t:n/2*((e-=2)*e*e*e*e+2)+t}function h(e,t,n,r){return-n*Math.cos(e/r*(Math.PI/2))+n+t}function p(e,t,n,r){return n*Math.sin(e/r*(Math.PI/2))+t}function d(e,t,n,r){return-n/2*(Math.cos(Math.PI*e/r)-1)+t}function v(e,t,n,r){return e===0?t:n*Math.pow(2,10*(e/r-1))+t}function m(e,t,n,r){return e===r?t+n:n*(-Math.pow(2,-10*e/r)+1)+t}function g(e,t,n,r){return e===0?t:e===r?t+n:(e/=r/2,e<1?n/2*Math.pow(2,10*(e-1))+t:n/2*(-Math.pow(2,-10*--e)+2)+t)}function y(e,t,n,r){return-n*(Math.sqrt(1-(e/=r)*e)-1)+t}function b(e,t,n,r){return n*Math.sqrt(1-(e=e/r-1)*e)+t}function w(e,t,n,r){return e/=r/2,e<1?-n/2*(Math.sqrt(1-e*e)-1)+t:n/2*(Math.sqrt(1-(e-=2)*e)+1)+t}function E(e,t,n,r){var i=1.70158,s=0,o=n;return e===0?t:(e/=r,e===1?t+n:(s||(s=r*.3),o-1;e=e.split(/\s+/);var n=[],r,i;if(t){r=0,i=e.length;for(;r/i,"")));if(!s.documentElement)return;t.parseSVGDocument(s.documentElement,function(r,i){g.set(e,{objects:t.util.array.invoke(r,"toObject"),options:i}),n(r,i)},r)}e=e.replace(/^\n\s*/,"").trim(),g.has(e,function(r){r?g.get(e,function(e){var t=b(e);n(t.objects,t.options)}):new t.util.request(e,{method:"get",onComplete:i})})}function b(e){var n=e.objects,i=e.options;return n=n.map(function(e){return t[r(e.type)].fromObject(e)}),{objects:n,options:i}}function w(e,n,r){e=e.trim();var i;if(typeof DOMParser!="undefined"){var s=new DOMParser;s&&s.parseFromString&&(i=s.parseFromString(e,"text/xml"))}else t.window.ActiveXObject&&(i=new ActiveXObject("Microsoft.XMLDOM"),i.async="false",i.loadXML(e.replace(//i,"")));t.parseSVGDocument(i.documentElement,function(e,t){n(e,t)},r)}function E(e){var t="";for(var n=0,r=e.length;n',"",""].join("")),t}function S(e){var t="";return e.backgroundColor&&e.backgroundColor.source&&(t=['',''].join("")),t}var t=e.fabric||(e.fabric={}),n=t.util.object.extend,r=t.util.string.capitalize,i=t.util.object.clone,s=t.util.multiplyTransformMatrices;t.SHARED_ATTRIBUTES=["transform","fill","fill-rule","fill-opacity","opacity","stroke","stroke-dasharray","stroke-linecap","stroke-linejoin","stroke-miterlimit","stroke-width"];var o={cx:"left",x:"left",cy:"top",y:"top",r:"radius","fill-opacity":"opacity","fill-rule":"fillRule","stroke-width":"strokeWidth","stroke-dasharray":"strokeDashArray","stroke-linecap":"strokeLineCap","stroke-linejoin":"strokeLineJoin","stroke-miterlimit":"strokeMiterLimit",transform:"transformMatrix","text-decoration":"textDecoration","font-size":"fontSize","font-weight":"fontWeight","font-style":"fontStyle","font-family":"fontFamily"};t.parseTransformAttribute=function(){function e(e,t){var n=t[0];e[0]=Math.cos(n),e[1]=Math.sin(n),e[2]=-Math.sin(n),e[3]=Math.cos(n)}function n(e,t){var n=t[0],r=t.length===2?t[1]:t[0];e[0]=n,e[3]=r}function r(e,t){e[2]=t[0]}function i(e,t){e[1]=t[0]}function s(e,t){e[4]=t[0],t.length===2&&(e[5]=t[1])}var o=[1,0,0,1,0,0],u="(?:[-+]?\\d+(?:\\.\\d+)?(?:e[-+]?\\d+)?)",a="(?:\\s+,?\\s*|,\\s*)",f="(?:(skewX)\\s*\\(\\s*("+u+")\\s*\\))",l="(?:(skewY)\\s*\\(\\s*("+u+")\\s*\\))",c="(?:(rotate)\\s*\\(\\s*("+u+")(?:"+a+"("+u+")"+a+"("+u+"))?\\s*\\))",h="(?:(scale)\\s*\\(\\s*("+u+")(?:"+a+"("+u+"))?\\s*\\))",p="(?:(translate)\\s*\\(\\s*("+u+")(?:"+a+"("+u+"))?\\s*\\))",d="(?:(matrix)\\s*\\(\\s*("+u+")"+a+"("+u+")"+a+"("+u+")"+a+"("+u+")"+a+"("+u+")"+a+"("+u+")"+"\\s*\\))",v="(?:"+d+"|"+p+"|"+h+"|"+c+"|"+f+"|"+l+")",m="(?:"+v+"(?:"+a+v+")*"+")",g="^\\s*(?:"+m+"?)\\s*$",y=new RegExp(g),b=new RegExp(v,"g");return function(u){var a=o.concat(),f=[];if(!u||u&&!y.test(u))return a;u.replace(b,function(t){var u=(new RegExp(v)).exec(t).filter(function(e){return e!==""&&e!=null}),l=u[1],c=u.slice(2).map(parseFloat);switch(l){case"translate":s(a,c);break;case"rotate":e(a,c);break;case"scale":n(a,c);break;case"skewX":r(a,c);break;case"skewY":i(a,c);break;case"matrix":a=c}f.push(a.concat()),a=o.concat()});var l=f[0];while(f.length>1)f.shift(),l=t.util.multiplyTransformMatrices(l,f[0]);return l}}(),t.parseSVGDocument=function(){function s(e,t){while(e&&(e=e.parentNode))if(t.test(e.nodeName))return!0;return!1}var e=/^(path|circle|polygon|polyline|ellipse|rect|line|image|text)$/,n="(?:[-+]?\\d+(?:\\.\\d+)?(?:e[-+]?\\d+)?)",r=new RegExp("^\\s*("+n+"+)\\s*,?"+"\\s*("+n+"+)\\s*,?"+"\\s*("+n+"+)\\s*,?"+"\\s*("+n+"+)\\s*"+"$");return function(n,o,u){if(!n)return;var a=new Date,f=t.util.toArray(n.getElementsByTagName("*"));if(f.length===0){f=n.selectNodes("//*[name(.)!='svg']");var l=[];for(var c=0,h=f.length;c']:this.type==="radial"&&(i=["']);for(var s=0;s');return i.push(this.type==="linear"?"":""),i.join("")},toLive:function(e){var t;if(!this.type)return;this.type==="linear"?t=e.createLinearGradient(this.coords.x1,this.coords.y1,this.coords.x2||e.canvas.width,this.coords.y2):this.type==="radial"&&(t=e.createRadialGradient(this.coords.x1,this.coords.y1,this.coords.r1,this.coords.x2,this.coords.y2,this.coords.r2));for(var n=0;n0&&this.init(e,t)}var t=e.fabric||(e.fabric={});if(t.Point){t.warn("fabric.Point is already defined");return}t.Point=n,n.prototype={constructor:n,init:function(e,t){this.x=e,this.y=t},add:function(e){return new n(this.x+e.x,this.y+e.y)},addEquals:function(e){return this.x+=e.x,this.y+=e.y,this},scalarAdd:function(e){return new n(this.x+e,this.y+e)},scalarAddEquals:function(e){return this.x+=e,this.y+=e,this},subtract:function(e){return new n(this.x-e.x,this.y-e.y)},subtractEquals:function(e){return this.x-=e.x,this.y-=e.y,this},scalarSubtract:function(e){return new n(this.x-e,this.y-e)},scalarSubtractEquals:function(e){return this.x-=e,this.y-=e,this},multiply:function(e){return new n(this.x*e,this.y*e)},multiplyEquals:function(e){return this.x*=e,this.y*=e,this},divide:function(e){return new n(this.x/e,this.y/e)},divideEquals:function(e){return this.x/=e,this.y/=e,this},eq:function(e){return this.x===e.x&&this.y===e.y},lt:function(e){return this.xe.x&&this.y>e.y},gte:function(e){return this.x>=e.x&&this.y>=e.y},lerp:function(e,t){return new n(this.x+(e.x-this.x)*t,this.y+(e.y-this.y)*t)},distanceFrom:function(e){var t=this.x-e.x,n=this.y-e.y;return Math.sqrt(t*t+n*n)},midPointFrom:function(e){return new n(this.x+(e.x-this.x)/2,this.y+(e.y-this.y)/2)},min:function(e){return new n(Math.min(this.x,e.x),Math.min(this.y,e.y))},max:function(e){return new n(Math.max(this.x,e.x),Math.max(this.y,e.y))},toString:function(){return this.x+","+this.y},setXY:function(e,t){this.x=e,this.y=t},setFromPoint:function(e){this.x=e.x,this.y=e.y},swap:function(e){var t=this.x,n=this.y;this.x=e.x,this.y=e.y,e.x=t,e.y=n}}}(typeof exports!="undefined"?exports:this),function(e){"use strict";function n(e){arguments.length>0&&this.init(e)}var t=e.fabric||(e.fabric={});if(t.Intersection){t.warn("fabric.Intersection is already defined");return}t.Intersection=n,t.Intersection.prototype={init:function(e){this.status=e,this.points=[]},appendPoint:function(e){this.points.push(e)},appendPoints:function(e){this.points=this.points.concat(e)}},t.Intersection.intersectLineLine=function(e,r,i,s){var o,u=(s.x-i.x)*(e.y-i.y)-(s.y-i.y)*(e.x-i.x),a=(r.x-e.x)*(e.y-i.y)-(r.y-e.y)*(e.x-i.x),f=(s.y-i.y)*(r.x-e.x)-(s.x-i.x)*(r.y-e.y);if(f!==0){var l=u/f,c=a/f;0<=l&&l<=1&&0<=c&&c<=1?(o=new n("Intersection"),o.points.push(new t.Point(e.x+l*(r.x-e.x),e.y+l*(r.y-e.y)))):o=new n("No Intersection")}else u===0||a===0?o=new n("Coincident"):o=new n("Parallel");return o},t.Intersection.intersectLinePolygon=function(e,t,r){var i=new n("No Intersection"),s=r.length;for(var o=0;o0&&(i.status="Intersection"),i},t.Intersection.intersectPolygonPolygon=function(e,t){var r=new n("No Intersection"),i=e.length;for(var s=0;s0&&(r.status="Intersection"),r},t.Intersection.intersectPolygonRectangle=function(e,r,i){var s=r.min(i),o=r.max(i),u=new t.Point(o.x,s.y),a=new t.Point(s.x,o.y),f=n.intersectLinePolygon(s,u,e),l=n.intersectLinePolygon(u,o,e),c=n.intersectLinePolygon(o,a,e),h=n.intersectLinePolygon(a,s,e),p=new n("No Intersection");return p.appendPoints(f.points),p.appendPoints(l.points),p.appendPoints(c.points),p.appendPoints(h.points),p.points.length>0&&(p.status="Intersection"),p}}(typeof exports!="undefined"?exports:this),function(e){"use strict";function n(e){e?this._tryParsingColor(e):this.setSource([0,0,0,1])}var t=e.fabric||(e.fabric={});if(t.Color){t.warn("fabric.Color is already defined.");return}t.Color=n,t.Color.prototype={_tryParsingColor:function(e){var t;e in n.colorNameMap&&(e=n.colorNameMap[e]),t=n.sourceFromHex(e),t||(t=n.sourceFromRgb(e)),t&&this.setSource(t)},getSource:function(){return this._source},setSource:function(e){this._source=e},toRgb:function(){var e=this.getSource();return"rgb("+e[0]+","+e[1]+","+e[2]+")"},toRgba:function(){var e=this.getSource();return"rgba("+e[0]+","+e[1]+","+e[2]+","+e[3]+")"},toHex:function(){var e=this.getSource(),t=e[0].toString(16);t=t.length===1?"0"+t:t;var n=e[1].toString(16);n=n.length===1?"0"+n:n;var r=e[2].toString(16);return r=r.length===1?"0"+r:r,t.toUpperCase()+n.toUpperCase()+r.toUpperCase()},getAlpha:function(){return this.getSource()[3]},setAlpha:function(e){var t=this.getSource();return t[3]=e,this.setSource(t),this},toGrayscale:function(){var e=this.getSource(),t=parseInt((e[0]*.3+e[1]*.59+e[2]*.11).toFixed(0),10),n=e[3];return this.setSource([t,t,t,n]),this},toBlackWhite:function(e){var t=this.getSource(),n=(t[0]*.3+t[1]*.59+t[2]*.11).toFixed(0),r=t[3];return e=e||127,n=Number(n)',''),t.push("',"Created with Fabric.js ",fabric.version,"","",fabric.createSVGFontFacesMarkup(this.getObjects()),fabric.createSVGRefElementsMarkup(this),""),this.backgroundColor&&this.backgroundColor.source&&t.push('"),this.backgroundImage&&t.push(''),this.overlayImage&&t.push('');for(var n=0,r=this.getObjects(),i=r.length;n"),t.join("")},remove:function(e){return this.getActiveObject()===e&&(this.fire("before:selection:cleared",{target:e}),this.discardActiveObject(),this.fire("selection:cleared")),fabric.Collection.remove.call(this,e)},sendToBack:function(e){return n(this._objects,e),this._objects.unshift(e),this.renderAll&&this.renderAll()},bringToFront:function(e){return n(this._objects,e),this._objects.push(e),this.renderAll&&this.renderAll()},sendBackwards:function(e){var t=this._objects.indexOf(e),r=t;if(t!==0){for(var i=t-1;i>=0;--i){var s=e.intersectsWithObject(this._objects[i])||e.isContainedWithinObject(this._objects[i])||this._objects[i].isContainedWithinObject(e);if(s){r=i;break}}n(this._objects,e),this._objects.splice(r,0,e)}return this.renderAll&&this.renderAll()},bringForward:function(e){var t=this.getObjects(),r=t.indexOf(e),i=r;if(r!==t.length-1){for(var s=r+1,o=this._objects.length;s"},e(fabric.StaticCanvas,{EMPTY_JSON:'{"objects": [], "background": "white"}',toGrayscale:function(e){var t=e.getContext("2d"),n=t.getImageData(0,0,e.width,e.height),r=n.data,i=n.width,s=n.height,o,u,a,f;for(a=0;a0&&(t>this.targetFindTolerance?t-=this.targetFindTolerance:t=0,n>this.targetFindTolerance?n-=this.targetFindTolerance:n=0);var o=!0,u=r.getImageData(t,n,this.targetFindTolerance*2||1,this.targetFindTolerance*2||1);for(var a=3,f=u.data.length;a0?0:-n),t.ey-(r>0?0:-r),i,o),e.lineWidth=this.selectionLineWidth,e.strokeStyle=this.selectionBorderColor;if(this.selectionDashArray.length>1){var u=t.ex+a-(n>0?0:i),f=t.ey+a-(r>0?0:o);e.beginPath(),fabric.util.drawDashedLine(e,u,f,u+i,f,this.selectionDashArray),fabric.util.drawDashedLine(e,u,f+o-1,u+i,f+o-1,this.selectionDashArray),fabric.util.drawDashedLine(e,u,f,u,f+o,this.selectionDashArray),fabric.util.drawDashedLine(e,u+i-1,f,u+i-1,f+o,this.selectionDashArray),e.closePath(),e.stroke()}else e.strokeRect(t.ex+a-(n>0?0:i),t.ey+a-(r>0?0:o),i,o)},_findSelectedObjects:function(e){var t=[],n=this._groupSelector.ex,r=this._groupSelector.ey,i=n+this._groupSelector.left,s=r+this._groupSelector.top,a,f=new fabric.Point(o(n,i),o(r,s)),l=new fabric.Point(u(n,i),u(r,s));for(var c=0,h=this._objects.length;c1&&(t=new fabric.Group(t),this.setActiveGroup(t),t.saveCoords(),this.fire("selection:created",{target:t}),this.renderAll())},findTarget:function(e,t){var n,r=this.getPointer(e);if(this.controlsAboveOverlay&&this.lastRenderedObjectWithControlsAboveOverlay&&this.lastRenderedObjectWithControlsAboveOverlay.visible&&this.containsPoint(e,this.lastRenderedObjectWithControlsAboveOverlay)&&this.lastRenderedObjectWithControlsAboveOverlay._findTargetCorner(e,this._offset))return n=this.lastRenderedObjectWithControlsAboveOverlay,n;var i=this.getActiveGroup();if(i&&!t&&this.containsPoint(e,i))return n=i,n;var s=[];for(var o=this._objects.length;o--;)if(this._objects[o]&&this._objects[o].visible&&this.containsPoint(e,this._objects[o])){if(!this.perPixelTargetFind&&!this._objects[o].perPixelTargetFind){n=this._objects[o],this.relatedTarget=n;break}s[s.length]=this._objects[o]}for(var u=0,a=s.length;u"},get:function(e){return this[e]},set:function(e,t){if(typeof e=="object")for(var n in e)this._set(n,e[n]);else typeof t=="function"?this._set(e,t(this.get(e))):this._set(e,t);return this},_set:function(e,t){var n=e==="scaleX"||e==="scaleY";n&&(t=this._constrainScale(t));if(e==="scaleX"&&t<0)this.flipX=!this.flipX,t*=-1;else if(e==="scaleY"&&t<0)this.flipY=!this.flipY,t*=-1;else if(e==="width"||e==="height")this.minScaleLimit=r(Math.min(.1,1/Math.max(this.width,this.height)),2);return this[e]=t,this},toggle:function(e){var t=this.get(e);return typeof t=="boolean"&&this.set(e,!t),this},setSourcePath:function(e){return this.sourcePath=e,this},render:function(e,n){if(this.width===0||this.height===0||!this.visible)return;e.save();var r=this.transformMatrix;r&&!this.group&&e.setTransform(r[0],r[1],r[2],r[3],r[4],r[5]),n||this.transform(e),e.save(),this.stroke&&(e.lineWidth=this.strokeWidth,e.lineCap=this.strokeLineCap,e.lineJoin=this.strokeLineJoin,e.miterLimit=this.strokeMiterLimit,e.strokeStyle=this.stroke.toLive?this.stroke.toLive(e):this.stroke),this.overlayFill?e.fillStyle=this.overlayFill:this.fill&&(e.fillStyle=this.fill.toLive?this.fill.toLive(e):this.fill),r&&this.group&&(e.translate(-this.group.width/2,-this.group.height/2),e.transform(r[0],r[1],r[2],r[3],r[4],r[5])),this._setShadow(e),this.clipTo&&t.util.clipContext(this,e),this._render(e,n),this.clipTo&&e.restore(),this._removeShadow(e),e.restore(),this.active&&!n&&(this.drawBorders(e),this.drawControls(e)),e.restore()},_setShadow:function(e){if(!this.shadow)return;e.shadowColor=this.shadow.color,e.shadowBlur=this.shadow.blur,e.shadowOffsetX=this.shadow.offsetX,e.shadowOffsetY=this.shadow.offsetY},_removeShadow:function(e){e.shadowColor="",e.shadowBlur=e.shadowOffsetX=e.shadowOffsetY=0},_renderFill:function(e){if(!this.fill)return;this.fill.toLive&&(e.save(),e.translate(-this.width/2+this.fill.offsetX||0,-this.height/2+this.fill.offsetY||0)),e.fill(),this.fill.toLive&&e.restore(),this.shadow&&!this.shadow.affectStroke&&this._removeShadow(e)},_renderStroke:function(e){if(!this.stroke)return;this.strokeDashArray?(1&this.strokeDashArray.length&&this.strokeDashArray.push.apply(this.strokeDashArray,this.strokeDashArray),o?(e.setLineDash(this.strokeDashArray),this._stroke&&this._stroke(e)):this._renderDashedStroke&&this._renderDashedStroke(e),e.stroke()):this._stroke?this._stroke(e):e.stroke(),this._removeShadow(e)},clone:function(e,n){return this.constructor.fromObject?this.constructor.fromObject(this.toObject(n),e):new t.Object(this.toObject(n))},cloneAsImage:function(e){var n=this.toDataURL();return t.util.loadImage(n,function(n){e&&e(new t.Image(n))}),this},toDataURL:function(e){e||(e={});var n=t.util.createCanvasElement();n.width=this.getBoundingRectWidth(),n.height=this.getBoundingRectHeight(),t.util.wrapElement(n,"div");var r=new t.Canvas(n);e.format==="jpeg"&&(r.backgroundColor="#fff");var i={active:this.get("active"),left:this.getLeft(),top:this.getTop()};this.set({active:!1,left:n.width/2,top:n.height/2}),r.add(this);var s=r.toDataURL(e);return this.set(i).setCoords(),r.dispose(),r=null,s},isType:function(e){return this.type===e},toGrayscale:function(){var e=this.get("fill");return e&&this.set("overlayFill",(new t.Color(e)).toGrayscale().toRgb()),this},complexity:function(){return 0},toJSON:function(e){return this.toObject(e)},setGradient:function(e,n){n||(n={});var r={colorStops:[]};r.type=n.type||(n.r1||n.r2?"radial":"linear"),r.coords={x1:n.x1,y1:n.y1,x2:n.x2,y2:n.y2};if(n.r1||n.r2)r.coords.r1=n.r1,r.coords.r2=n.r2;for(var i in n.colorStops){var s=new t.Color(n.colorStops[i]);r.colorStops.push({offset:i,color:s.toRgb(),opacity:s.getAlpha()})}this.set(e,t.Gradient.forObject(this,r))},setPatternFill:function(e){return this.set("fill",new t.Pattern(e))},setShadow:function(e){return this.set("shadow",new t.Shadow(e))},animate:function(){if(arguments[0]&&typeof arguments[0]=="object"){var e=[],t,n;for(t in arguments[0])e.push(t);for(var r=0,i=e.length;re.x&&n.left+n.widthe.y&&n.top+n.height=e.y&&f.d.y>=e.y)continue;f.o.x===f.d.x&&f.o.x>=e.x?(o=f.o.x,u=e.y):(n=0,r=(f.d.y-f.o.y)/(f.d.x-f.o.x),i=e.y-n*e.x,s=f.o.y-r*f.o.x,o=-(i-s)/(n-r),u=i+n*o),o>=e.x&&(a+=1);if(a===2)break}return a},getBoundingRectWidth:function(){return this.getBoundingRect().width},getBoundingRectHeight:function(){return this.getBoundingRect().height},getBoundingRect:function(){this.oCoords||this.setCoords();var e=[this.oCoords.tl.x,this.oCoords.tr.x,this.oCoords.br.x,this.oCoords.bl.x],t=fabric.util.array.min(e),n=fabric.util.array.max(e),r=Math.abs(t-n),i=[this.oCoords.tl.y,this.oCoords.tr.y,this.oCoords.br.y,this.oCoords.bl.y],s=fabric.util.array.min(i),o=fabric.util.array.max(i),u=Math.abs(s-o);return{left:t,top:s,width:r,height:u}},getWidth:function(){return this.width*this.scaleX},getHeight:function(){return this.height*this.scaleY},_constrainScale:function(e){return Math.abs(e)1?this.strokeWidth:0,n=this.padding,r=e(this.angle);this.currentWidth=(this.width+t)*this.scaleX+n*2,this.currentHeight=(this.height+t)*this.scaleY+n*2,this.currentWidth<0&&(this.currentWidth=Math.abs(this.currentWidth));var i=Math.sqrt(Math.pow(this.currentWidth/2,2)+Math.pow(this.currentHeight/2,2)),s=Math.atan(isFinite(this.currentHeight/this.currentWidth)?this.currentHeight/this.currentWidth:0),o=Math.cos(s+r)*i,u=Math.sin(s+r)*i,a=Math.sin(r),f=Math.cos(r),l=this.getCenterPoint(),c={x:l.x-o,y:l.y-u},h={x:c.x+this.currentWidth*f,y:c.y+this.currentWidth*a},p={x:h.x-this.currentHeight*a,y:h.y+this.currentHeight*f},d={x:c.x-this.currentHeight*a,y:c.y+this.currentHeight*f},v={x:c.x-this.currentHeight/2*a,y:c.y+this.currentHeight/2*f},m={x:c.x+this.currentWidth/2*f,y:c.y+this.currentWidth/2*a},g={x:h.x-this.currentHeight/2*a,y:h.y+this.currentHeight/2*f},y={x:d.x+this.currentWidth/2*f,y:d.y+this.currentWidth/2*a},b={x:m.x,y:m.y};return this.oCoords={tl:c,tr:h,br:p,bl:d,ml:v,mt:m,mr:g,mb:y,mtr:b},this._setCornerCoords(),this}})}(),fabric.util.object.extend(fabric.Object.prototype,{hasStateChanged:function(){return this.stateProperties.some(function(e){return this[e]!==this.originalState[e]},this)},saveState:function(e){return this.stateProperties.forEach(function(e){this.originalState[e]=this.get(e)},this),e&&e.stateProperties&&e.stateProperties.forEach(function(e){this.originalState[e]=this.get(e)},this),this},setupState:function(){return this.originalState={},this.saveState(),this}}),function(){var e=fabric.util.getPointer,t=fabric.util.degreesToRadians;fabric.util.object.extend(fabric.Object.prototype,{_findTargetCorner:function(t,n){if(!this.hasControls||!this.active)return!1;var r=e(t,this.canvas.upperCanvasEl),i=r.x-n.left,s=r.y-n.top,o,u;for(var a in this.oCoords){if(a==="mtr"&&!this.hasRotatingPoint)continue;if(!(!this.get("lockUniScaling")||a!=="mt"&&a!=="mr"&&a!=="mb"&&a!=="ml"))continue;u=this._getImageLines(this.oCoords[a].corner),o=this._findCrossPoints({x:i,y:s},u);if(o!==0&&o%2===1)return this.__corner=a,a}return!1},_setCornerCoords:function(){var e=this.oCoords,n=t(this.angle),r=t(45-this.angle),i=Math.sqrt(2*Math.pow(this.cornerSize,2))/2,s=i*Math.cos(r),o=i*Math.sin(r),u=Math.sin(n),a=Math.cos(n);e.tl.corner={tl:{x:e.tl.x-o,y:e.tl.y-s},tr:{x:e.tl.x+s,y:e.tl.y-o},bl:{x:e.tl.x-s,y:e.tl.y+o},br:{x:e.tl.x+o,y:e.tl.y+s}},e.tr.corner={tl:{x:e.tr.x-o,y:e.tr.y-s},tr:{x:e.tr.x+s,y:e.tr.y-o},br:{x:e.tr.x+o,y:e.tr.y+s},bl:{x:e.tr.x-s,y:e.tr.y+o}},e.bl.corner={tl:{x:e.bl.x-o,y:e.bl.y-s},bl:{x:e.bl.x-s,y:e.bl.y+o},br:{x:e.bl.x+o,y:e.bl.y+s},tr:{x:e.bl.x+s,y:e.bl.y-o}},e.br.corner={tr:{x:e.br.x+s,y:e.br.y-o},bl:{x:e.br.x-s,y:e.br.y+o},br:{x:e.br.x+o,y:e.br.y+s},tl:{x:e.br.x-o,y:e.br.y-s}},e.ml.corner={tl:{x:e.ml.x-o,y:e.ml.y-s},tr:{x:e.ml.x+s,y:e.ml.y-o},bl:{x:e.ml.x-s,y:e.ml.y+o},br:{x:e.ml.x+o,y:e.ml.y+s}},e.mt.corner={tl:{x:e.mt.x-o,y:e.mt.y-s},tr:{x:e.mt.x+s,y:e.mt.y-o},bl:{x:e.mt.x-s,y:e.mt.y+o},br:{x:e.mt.x+o,y:e.mt.y+s}},e.mr.corner={tl:{x:e.mr.x-o,y:e.mr.y-s},tr:{x:e.mr.x+s,y:e.mr.y-o},bl:{x:e.mr.x-s,y:e.mr.y+o},br:{x:e.mr.x+o,y:e.mr.y+s}},e.mb.corner={tl:{x:e.mb.x-o,y:e.mb.y-s},tr:{x:e.mb.x+s,y:e.mb.y-o},bl:{x:e.mb.x-s,y:e.mb.y+o},br:{x:e.mb.x+o,y:e.mb.y+s}},e.mtr.corner={tl:{x:e.mtr.x-o+u*this.rotatingPointOffset,y:e.mtr.y-s-a*this.rotatingPointOffset},tr:{x:e.mtr.x+s+u*this.rotatingPointOffset,y:e.mtr.y-o-a*this.rotatingPointOffset},bl:{x:e.mtr.x-s+u*this.rotatingPointOffset,y:e.mtr.y+o-a*this.rotatingPointOffset},br:{x:e.mtr.x+o+u*this.rotatingPointOffset,y:e.mtr.y+s-a*this.rotatingPointOffset}}},drawBorders:function(e){if(!this.hasBorders)return this;var t=this.padding,n=t*2,r=this.strokeWidth>1?this.strokeWidth:0;e.save(),e.globalAlpha=this.isMoving?this.borderOpacityWhenMoving:1,e.strokeStyle=this.borderColor;var i=1/this._constrainScale(this.scaleX),s=1/this._constrainScale(this.scaleY);e.lineWidth=1/this.borderScaleFactor,e.scale(i,s);var o=this.getWidth(),u=this.getHeight();e.strokeRect(~~(-(o/2)-t-r/2*this.scaleX)+.5,~~(-(u/2)-t-r/2*this.scaleY)+.5,~~(o+n+r*this.scaleX),~~(u+n+r*this.scaleY));if(this.hasRotatingPoint&&!this.get("lockRotation")&&this.hasControls){var a=(this.flipY?u+r*this.scaleY+t*2:-u-r*this.scaleY-t*2)/2;e.beginPath(),e.moveTo(0,a),e.lineTo(0,a+(this.flipY?this.rotatingPointOffset:-this.rotatingPointOffset)),e.closePath(),e.stroke()}return e.restore(),this},drawControls:function(e){if(!this.hasControls)return this;var t=this.cornerSize,n=t/2,r=this.strokeWidth/2,i=-(this.width/2),s=-(this.height/2),o,u,a=t/this.scaleX,f=t/this.scaleY,l=this.padding/this.scaleX,c=this.padding/this.scaleY,h=n/this.scaleY,p=n/this.scaleX,d=(n-t)/this.scaleX,v=(n-t)/this.scaleY,m=this.height,g=this.width,y=this.transparentCorners?"strokeRect":"fillRect",b=typeof G_vmlCanvasManager!="undefined";return e.save(),e.lineWidth=1/Math.max(this.scaleX,this.scaleY),e.globalAlpha=this.isMoving?this.borderOpacityWhenMoving:1,e.strokeStyle=e.fillStyle=this.cornerColor,o=i-p-r-l,u=s-h-r-c,b||e.clearRect(o,u,a,f),e[y](o,u,a,f),o=i+g-p+r+l,u=s-h-r-c,b||e.clearRect(o,u,a,f),e[y](o,u,a,f),o=i-p-r-l,u=s+m+v+r+c,b||e.clearRect(o,u,a,f),e[y](o,u,a,f),o=i+g+d+r+l,u=s+m+v+r+c,b||e.clearRect(o,u,a,f),e[y](o,u,a,f),this.get("lockUniScaling")||(o=i+g/2-p,u=s-h-r-c,b||e.clearRect(o,u,a,f),e[y](o,u,a,f),o=i+g/2-p,u=s+m+v+r+c,b||e.clearRect(o,u,a,f),e[y](o,u,a,f),o=i+g+d+r+l,u=s+m/2-h,b||e.clearRect(o,u,a,f),e[y](o,u,a,f),o=i-p-r-l,u=s+m/2-h,b||e.clearRect(o,u,a,f),e[y](o,u,a,f)),this.hasRotatingPoint&&(o=i+g/2-p,u=this.flipY?s+m+this.rotatingPointOffset/this.scaleY-f/2+r+c:s-this.rotatingPointOffset/this.scaleY-f/2-r-c,b||e.clearRect(o,u,a,f),e[y](o,u,a,f)),e.restore(),this}})}(),function(e){"use strict";var t=e.fabric||(e.fabric={}),n=t.util.object.extend,r={x1:1,x2:1,y1:1,y2:1},i=t.StaticCanvas.supports("setLineDash");if(t.Line){t.warn("fabric.Line is already defined");return}t.Line=t.util.createClass(t.Object,{type:"line",initialize:function(e,t){t=t||{},e||(e=[0,0,0,0]),this.callSuper("initialize",t),this.set("x1",e[0]),this.set("y1",e[1]),this.set("x2",e[2]),this.set("y2",e[3]),this._setWidthHeight(t)},_setWidthHeight:function(e){e||(e={}),this.set("width",Math.abs(this.x2-this.x1)||1),this.set("height",Math.abs(this.y2-this.y1)||1),this.set("left","left"in e?e.left:Math.min(this.x1,this.x2)+this.width/2),this.set("top","top"in e?e.top:Math.min(this.y1,this.y2)+this.height/2)},_set:function(e,t){return this[e]=t,e in r&&this._setWidthHeight(),this},_render:function(e){e.beginPath();var t=this.group&&this.group.type!=="group";t&&!this.transformMatrix&&e.translate(-this.group.width/2+this.left,-this.group.height/2+this.top);if(!this.strokeDashArray||this.strokeDashArray&&i){var n=this.x1<=this.x2?-1:1,r=this.y1<=this.y2?-1:1;e.moveTo(this.width===1?0:n*this.width/2,this.height===1?0:r*this.height/2),e.lineTo(this.width===1?0:n*-1*this.width/2,this.height===1?0:r*-1*this.height/2)}e.lineWidth=this.strokeWidth;var s=e.strokeStyle;e.strokeStyle=this.stroke||e.fillStyle,this._renderStroke(e),e.strokeStyle=s},_renderDashedStroke:function(e){var n=this.width===1?0:-this.width/2,r=this.height===1?0:-this.height/2;e.beginPath(),t.util.drawDashedLine(e,n,r,-n,-r,this.strokeDashArray),e.closePath()},toObject:function(e){return n(this.callSuper("toObject",e),{x1:this.get("x1"),y1:this.get("y1"),x2:this.get("x2"),y2:this.get("y2")})},toSVG:function(){var e=[];return this.stroke&&this.stroke.toLive&&e.push(this.stroke.toSVG(this,!0)),e.push("'),e.join("")},complexity:function(){return 1}}),t.Line.ATTRIBUTE_NAMES=t.SHARED_ATTRIBUTES.concat("x1 y1 x2 y2".split(" ")),t.Line.fromElement=function(e,r){var i=t.parseAttributes(e,t.Line.ATTRIBUTE_NAMES),s=[i.x1||0,i.y1||0,i.x2||0,i.y2||0];return new t.Line(s,n(i,r))},t.Line.fromObject=function(e){var n=[e.x1,e.y1,e.x2,e.y2];return new t.Line(n,e)}}(typeof exports!="undefined"?exports:this),function(e){"use strict";function i(e){return"radius"in e&&e.radius>0}var t=e.fabric||(e.fabric={}),n=Math.PI*2,r=t.util.object.extend;if(t.Circle){t.warn("fabric.Circle is already defined.");return}t.Circle=t.util.createClass(t.Object,{type:"circle",initialize:function(e){e=e||{},this.set("radius",e.radius||0),this.callSuper("initialize",e);var t=this.get("radius")*2;this.set("width",t).set("height",t)},toObject:function(e){return r(this.callSuper("toObject",e),{radius:this.get("radius")})},toSVG:function(){var e=[];return this.fill&&this.fill.toLive&&e.push(this.fill.toSVG(this,!1)),this.stroke&&this.stroke.toLive&&e.push(this.stroke.toSVG(this,!1)),e.push("'),e.join("")},_render:function(e,t){e.beginPath(),e.globalAlpha=this.group?e.globalAlpha*this.opacity:this.opacity,e.arc(t?this.left:0,t?this.top:0,this.radius,0,n,!1),e.closePath(),this._renderFill(e),this._renderStroke(e)},getRadiusX:function(){return this.get("radius")*this.get("scaleX")},getRadiusY:function(){return this.get("radius")*this.get("scaleY")},setRadius:function(e){this.radius=e,this.set("width",e*2).set("height",e*2)},complexity:function(){return 1}}),t.Circle.ATTRIBUTE_NAMES=t.SHARED_ATTRIBUTES.concat("cx cy r".split(" ")),t.Circle.fromElement=function(e,n){n||(n={});var s=t.parseAttributes(e,t.Circle.ATTRIBUTE_NAMES);if(!i(s))throw new Error("value of `r` attribute is required and can not be negative");"left"in s&&(s.left-=n.width/2||0),"top"in s&&(s.top-=n.height/2||0);var o=new t.Circle(r(s,n));return o.cx=parseFloat(e.getAttribute("cx"))||0,o.cy=parseFloat(e.getAttribute("cy"))||0,o},t.Circle.fromObject=function(e){return new t.Circle(e)}}(typeof exports!="undefined"?exports:this),function(e){"use strict";var t=e.fabric||(e.fabric={});if(t.Triangle){t.warn("fabric.Triangle is already defined");return}t.Triangle=t.util.createClass(t.Object,{type:"triangle",initialize:function(e){e=e||{},this.callSuper("initialize",e),this.set("width",e.width||100).set("height",e.height||100)},_render:function(e){var t=this.width/2,n=this.height/2;e.beginPath(),e.moveTo(-t,n),e.lineTo(0,-n),e.lineTo(t,n),e.closePath(),this._renderFill(e),this._renderStroke(e)},_renderDashedStroke:function(e){var n=this.width/2,r=this.height/2;e.beginPath(),t.util.drawDashedLine(e,-n,r,0,-r,this.strokeDashArray),t.util.drawDashedLine(e,0,-r,n,r,this.strokeDashArray),t.util.drawDashedLine(e,n,r,-n,r,this.strokeDashArray),e.closePath()},toSVG:function(){var e=[],t=this.width/2,n=this.height/2,r=[-t+" "+n,"0 "+ -n,t+" "+n].join(",");return this.fill&&this.fill.toLive&&e.push(this.fill.toSVG(this,!0)),this.stroke&&this.stroke.toLive&&e.push(this.stroke.toSVG(this,!0)),e.push("'),e.join("")},complexity:function(){return 1}}),t.Triangle.fromObject=function(e){return new t.Triangle(e)}}(typeof exports!="undefined"?exports:this),function(e){"use strict";var t=e.fabric||(e.fabric={}),n=Math.PI*2,r=t.util.object.extend;if(t.Ellipse){t.warn("fabric.Ellipse is already defined.");return}t.Ellipse=t.util.createClass(t.Object,{type:"ellipse",rx:0,ry:0,initialize:function(e){e=e||{},this.callSuper("initialize",e),this.set("rx",e.rx||0),this.set("ry",e.ry||0),this.set("width",this.get("rx")*2),this.set("height",this.get("ry")*2)},toObject:function(e){return r(this.callSuper("toObject",e),{rx:this.get("rx"),ry:this.get("ry")})},toSVG:function(){var e=[];return this.fill&&this.fill.toLive&&e.push(this.fill.toSVG(this,!1)),this.stroke&&this.stroke.toLive&&e.push(this.stroke.toSVG(this,!1)),e.push("'),e.join("")},render:function(e,t){if(this.rx===0||this.ry===0)return;return this.callSuper("render",e,t)},_render:function(e,t){e.beginPath(),e.save(),e.globalAlpha=this.group?e.globalAlpha*this.opacity:this.opacity,this.transformMatrix&&this.group&&e.translate(this.cx,this.cy),e.transform(1,0,0,this.ry/this.rx,0,0),e.arc(t?this.left:0,t?this.top:0,this.rx,0,n,!1),this._renderFill(e),this._renderStroke(e),e.restore()},complexity:function(){return 1}}),t.Ellipse.ATTRIBUTE_NAMES=t.SHARED_ATTRIBUTES.concat("cx cy rx ry".split(" ")),t.Ellipse.fromElement=function(e,n){n||(n={});var i=t.parseAttributes(e,t.Ellipse.ATTRIBUTE_NAMES),s=i.left,o=i.top;"left"in i&&(i.left-=n.width/2||0),"top"in i&&(i.top-=n.height/2||0);var u=new t.Ellipse(r(i,n));return u.cx=s||0,u.cy=o||0,u},t.Ellipse.fromObject=function(e){return new t.Ellipse(e)}}(typeof exports!="undefined"?exports:this),function(e){"use strict";function r(e){return e.left=e.left||0,e.top=e.top||0,e}var t=e.fabric||(e.fabric={}),n=t.util.object.extend;if(t.Rect){console.warn("fabric.Rect is already defined");return}t.Rect=t.util.createClass(t.Object,{type:"rect",rx:0,ry:0,strokeDashArray:null,initialize:function(e){e=e||{},this._initStateProperties(),this.callSuper("initialize" -,e),this._initRxRy(),this.x=0,this.y=0},_initStateProperties:function(){this.stateProperties=this.stateProperties.concat(["rx","ry"])},_initRxRy:function(){this.rx&&!this.ry?this.ry=this.rx:this.ry&&!this.rx&&(this.rx=this.ry)},_render:function(e){var t=this.rx||0,n=this.ry||0,r=-this.width/2,i=-this.height/2,s=this.width,o=this.height,u=this.group&&this.group.type!=="group";e.beginPath(),e.globalAlpha=u?e.globalAlpha*this.opacity:this.opacity,this.transformMatrix&&u&&e.translate(this.width/2+this.x,this.height/2+this.y),!this.transformMatrix&&u&&e.translate(-this.group.width/2+this.width/2+this.x,-this.group.height/2+this.height/2+this.y),e.moveTo(r+t,i),e.lineTo(r+s-t,i),e.quadraticCurveTo(r+s,i,r+s,i+n,r+s,i+n),e.lineTo(r+s,i+o-n),e.quadraticCurveTo(r+s,i+o,r+s-t,i+o,r+s-t,i+o),e.lineTo(r+t,i+o),e.quadraticCurveTo(r,i+o,r,i+o-n,r,i+o-n),e.lineTo(r,i+n),e.quadraticCurveTo(r,i,r+t,i,r+t,i),e.closePath(),this._renderFill(e),this._renderStroke(e)},_renderDashedStroke:function(e){var n=-this.width/2,r=-this.height/2,i=this.width,s=this.height;e.beginPath(),t.util.drawDashedLine(e,n,r,n+i,r,this.strokeDashArray),t.util.drawDashedLine(e,n+i,r,n+i,r+s,this.strokeDashArray),t.util.drawDashedLine(e,n+i,r+s,n,r+s,this.strokeDashArray),t.util.drawDashedLine(e,n,r+s,n,r,this.strokeDashArray),e.closePath()},_normalizeLeftTopProperties:function(e){return"left"in e&&this.set("left",e.left+this.getWidth()/2),this.set("x",e.left||0),"top"in e&&this.set("top",e.top+this.getHeight()/2),this.set("y",e.top||0),this},toObject:function(e){return n(this.callSuper("toObject",e),{rx:this.get("rx")||0,ry:this.get("ry")||0})},toSVG:function(){var e=[];return this.fill&&this.fill.toLive&&e.push(this.fill.toSVG(this,!1)),this.stroke&&this.stroke.toLive&&e.push(this.stroke.toSVG(this,!1)),e.push("'),e.join("")},complexity:function(){return 1}}),t.Rect.ATTRIBUTE_NAMES=t.SHARED_ATTRIBUTES.concat("x y rx ry width height".split(" ")),t.Rect.fromElement=function(e,i){if(!e)return null;var s=t.parseAttributes(e,t.Rect.ATTRIBUTE_NAMES);s=r(s);var o=new t.Rect(n(i?t.util.object.clone(i):{},s));return o._normalizeLeftTopProperties(s),o},t.Rect.fromObject=function(e){return new t.Rect(e)}}(typeof exports!="undefined"?exports:this),function(e){"use strict";var t=e.fabric||(e.fabric={}),n=t.util.toFixed,r=t.util.array.min;if(t.Polyline){t.warn("fabric.Polyline is already defined");return}t.Polyline=t.util.createClass(t.Object,{type:"polyline",initialize:function(e,t,n){t=t||{},this.set("points",e),this.callSuper("initialize",t),this._calcDimensions(n)},_calcDimensions:function(e){return t.Polygon.prototype._calcDimensions.call(this,e)},toObject:function(e){return t.Polygon.prototype.toObject.call(this,e)},toSVG:function(){var e=[],t=[];for(var r=0,i=this.points.length;r'),t.join("")},_render:function(e){var t;e.beginPath(),e.moveTo(this.points[0].x,this.points[0].y);for(var n=0,r=this.points.length;n'),t.join("")},_render:function(e){var t;e.beginPath(),e.moveTo(this.points[0].x,this.points[0].y);for(var n=0,r=this.points.length;n1&&(g=Math.sqrt(g),n*=g,i*=g);var y=d/n,b=p/n,w=-p/i,E=d/i,S=y*l+b*c,x=w*l+E*c,T=y*e+b*t,N=w*e+E*t,C=(T-S)*(T-S)+(N-x)*(N-x),k=1/C-.25;k<0&&(k=0);var L=Math.sqrt(k);a===u&&(L=-L);var A=.5*(S+T)-L*(N-x),O=.5*(x+N)+L*(T-S),M=Math.atan2(x-O,S-A),_=Math.atan2(N-O,T-A),D=_-M;D<0&&a===1?D+=2*Math.PI:D>0&&a===0&&(D-=2*Math.PI);var P=Math.ceil(Math.abs(D/(Math.PI*.5+.001))),H=[];for(var B=0;B"},toObject:function(e){var t=h(this.callSuper("toObject",e),{path:this.path});return this.sourcePath&&(t.sourcePath=this.sourcePath),this.transformMatrix&&(t.transformMatrix=this.transformMatrix),t},toDatalessObject:function(e){var t=this.toObject(e);return this.sourcePath&&(t.path=this.sourcePath),delete t.sourcePath,t},toSVG:function(){var e=[],t=[];for(var n=0,r=this.path.length;n',"",""),t.join("")},complexity:function(){return this.path.length},_parsePath:function(){var e=[],n=[],r,i,s=/(-?\.\d+)|(-?\d+(\.\d+)?)/g,o,u;for(var a=0,f,l=this.path.length;ad)for(var v=1,m=f.length;v"];for(var n=0,r=e.length;n"),t.join("")},toString:function(){return"#"},isSameColor:function(){var e=this.getObjects()[0].get("fill");return this.getObjects().every(function(t){return t.get("fill")===e})},complexity:function(){return this.paths.reduce(function(e,t){return e+(t&&t.complexity?t.complexity():0)},0)},toGrayscale:function(){var e=this.paths.length;while(e--)this.paths[e].toGrayscale();return this},getObjects:function(){return this.paths}}),t.PathGroup.fromObject=function(e){var n=u(e.paths);return new t.PathGroup(n,e)}}(typeof exports!="undefined"?exports:this),function(e){"use strict";var t=e.fabric||(e.fabric={}),n=t.util.object.extend,r=t.util.array.min,i=t.util.array.max,s=t.util.array.invoke;if(t.Group)return;var o={lockMovementX:!0,lockMovementY:!0,lockRotation:!0,lockScalingX:!0,lockScalingY:!0,lockUniScaling:!0};t.Group=t.util.createClass(t.Object,t.Collection,{type:"group",initialize:function(e,t){t=t||{},this._objects=e||[];for(var r=this._objects.length;r--;)this._objects[r].group=this;this.originalState={},this.callSuper("initialize"),this._calcBounds(),this._updateObjectsCoords(),t&&n(this,t),this._setOpacityIfSame(),this.setCoords(!0),this.saveCoords()},_updateObjectsCoords:function(){var e=this.left,t=this.top;this.forEachObject(function(n){var r=n.get("left"),i=n.get("top");n.set("originalLeft",r),n.set("originalTop",i),n.set("left",r-e),n.set("top",i-t),n.setCoords(),n.__origHasControls=n.hasControls,n.hasControls=!1},this)},toString:function(){return"#"},getObjects:function(){return this._objects},addWithUpdate:function(e){return this._restoreObjectsState(),this._objects.push(e),e.group=this,this.forEachObject(function(e){e.set("active",!0),e.group=this},this),this._calcBounds(),this._updateObjectsCoords(),this},removeWithUpdate:function(e){return this._restoreObjectsState(),this.forEachObject(function(e){e.set("active",!0),e.group=this},this),this.remove(e),this._calcBounds(),this._updateObjectsCoords(),this},_onObjectAdded:function(e){e.group=this},_onObjectRemoved:function(e){delete e.group,e.set("active",!1)},delegatedProperties:{fill:!0,opacity:!0,fontFamily:!0,fontWeight:!0,fontSize:!0,fontStyle:!0,lineHeight:!0,textDecoration:!0,textShadow:!0,textAlign:!0,backgroundColor:!0},_set:function(e,t){if(e in this.delegatedProperties){var n=this._objects.length;this[e]=t;while(n--)this._objects[n].set(e,t)}else this[e]=t},toObject:function(e){return n(this.callSuper("toObject",e),{objects:s(this._objects,"toObject",e)})},render:function(e,n){if(!this.visible)return;e.save(),this.transform(e);var r=Math.max(this.scaleX,this.scaleY);this.clipTo&&t.util.clipContext(this,e);for(var i=0,s=this._objects.length;i'+e.join("")+""},get:function(e){if(e in o){if(this[e])return this[e];for(var t=0,n=this._objects.length;t','');if(this.stroke||this.strokeDashArray){var t=this.fill;this.fill=null,e.push("'),this.fill=t}return e.push(""),e.join("")},getSrc:function(){return this.getElement().src||this.getElement()._src},toString:function(){return'#'},clone:function(e,t){this.constructor.fromObject(this.toObject(t),e)},applyFilters:function(e){if(this.filters.length===0){this.setElement(this._originalImage),e&&e();return}var t=this._originalImage,n=fabric.util.createCanvasElement(),r=fabric.util.createImage(),i=this;n.width=t.width,n.height=t.height,n.getContext("2d").drawImage(t,0,0,t.width,t.height),this.filters.forEach(function(e){e&&e.applyTo(n)}),r.width=t.width,r.height=t.height;if(fabric.isLikelyNode){var s=n.toDataURL("image/png").substring(22);r.src=new Buffer(s,"base64"),i._element=r,e&&e()}else r.onload=function(){i._element=r,e&&e(),r.onload=n=t=null},r.src=n.toDataURL("image/png");return this},_render:function(e){e.drawImage(this._element,-this.width/2,-this.height/2,this.width,this.height)},_resetWidthHeight:function(){var e=this.getElement();this.set("width",e.width),this.set("height",e.height)},_initElement:function(e){this.setElement(fabric.util.getById(e)),fabric.util.addClass(this.getElement(),fabric.Image.CSS_CANVAS)},_initConfig:function(e){e||(e={}),this.setOptions(e),this._setWidthHeight(e)},_initFilters:function(e){e.filters&&e.filters.length&&(this.filters=e.filters.map(function(e){return e&&fabric.Image.filters[e.type].fromObject(e)}))},_setWidthHeight:function(e){this.width="width"in e?e.width:this.getElement().width||0,this.height="height"in e?e.height:this.getElement().height||0},complexity:function(){return 1}}),fabric.Image.CSS_CANVAS="canvas-img",fabric.Image.prototype.getSvgSrc=fabric.Image.prototype.getSrc,fabric.Image.fromObject=function(e,t){var n=fabric.document.createElement("img"),r=e.src;e.width&&(n.width=e.width),e.height&&(n.height=e.height),n.onload=function(){fabric.Image.prototype._initFilters.call(e,e);var r=new fabric.Image(n,e);t&&t(r),n=n.onload=n.onerror=null},n.onerror=function(){fabric.log("Error loading "+n.src),t&&t(null,!0),n=n.onload=n.onerror=null},n.src=r},fabric.Image.fromURL=function(e,t,n){fabric.util.loadImage(e,function(e){t(new fabric.Image(e,n))})},fabric.Image.ATTRIBUTE_NAMES=fabric.SHARED_ATTRIBUTES.concat("x y width height xlink:href".split(" ")),fabric.Image.fromElement=function(e,n,r){var i=fabric.parseAttributes(e,fabric.Image.ATTRIBUTE_NAMES);fabric.Image.fromURL(i["xlink:href"],n,t(r?fabric.util.object.clone(r):{},i))},fabric.Image.async=!0}(typeof exports!="undefined"?exports:this),fabric.util.object.extend(fabric.Object.prototype,{_getAngleValueForStraighten:function(){var e=this.getAngle()%360;return e>0?Math.round((e-1)/90)*90:Math.round(e/90)*90},straighten:function(){return this.setAngle(this._getAngleValueForStraighten()),this},fxStraighten:function(e){e=e||{};var t=function(){},n=e.onComplete||t,r=e.onChange||t,i=this;return fabric.util.animate({startValue:this.get("angle"),endValue:this._getAngleValueForStraighten(),duration:this.FX_DURATION,onChange:function(e){i.setAngle(e),r()},onComplete:function(){i.setCoords(),n()},onStart:function(){i.set("active",!1)}}),this}}),fabric.util.object.extend(fabric.StaticCanvas.prototype,{straightenObject:function(e){return e.straighten(),this.renderAll(),this},fxStraightenObject:function(e){return e.fxStraighten({onChange:this.renderAll.bind(this)}),this}}),fabric.Image.filters={},fabric.Image.filters.Grayscale=fabric.util.createClass({type:"Grayscale",applyTo:function(e){var t=e.getContext("2d"),n=t.getImageData(0,0,e.width,e.height),r=n.data,i=n.width*n.height*4,s=0,o;while(so&&f>o&&l>o&&u(a-f)0&&(r[s]=a,r[s+1]=f,r[s+2]=l);t.putImageData(n,0,0)},toJSON:function(){return{type:this.type,color:this.color}}}),fabric.Image.filters.Tint.fromObject=function(e){return new fabric.Image.filters.Tint(e)},fabric.Image.filters.Convolute=fabric.util.createClass({type:"Convolute",initialize:function(e){e||(e={}),this.opaque=e.opaque,this.matrix=e.matrix||[0,0,0,0,1,0,0,0,0];var t=fabric.util.createCanvasElement();this.tmpCtx=t.getContext("2d")},_createImageData:function(e,t){return this.tmpCtx.createImageData(e,t)},applyTo:function(e){var t=this.matrix,n=e.getContext("2d"),r=n.getImageData(0,0,e.width,e.height),i=Math.round(Math.sqrt(t.length)),s=Math.floor(i/2),o=r.data,u=r.width,a=r.height,f=u,l=a,c=this._createImageData(f,l),h=c.data,p=this.opaque?1:0;for(var d=0;d=0&&N=0&&C'},_render:function(e){var t=this.group&&this.group.type!=="group";t&&!this.transformMatrix?e.translate(-this.group.width/2+this.left,-this.group.height/2+this.top):t&&this.transformMatrix&&e.translate(-this.group.width/2,-this.group.height/2),typeof Cufon=="undefined"||this.useNative===!0?this._renderViaNative(e):this._renderViaCufon(e)},_renderViaCufon:function(e){var t=Cufon.textOptions||(Cufon.textOptions={});t.left=this.left,t.top=this.top,t.context=e,t.color=this.fill;var n=this._initDummyElementForCufon();this.transform(e),Cufon.replaceElement(n,{engine:"canvas",separate:"none",fontFamily:this.fontFamily,fontWeight:this.fontWeight,textDecoration:this.textDecoration,textShadow:this.textShadow,textAlign:this.textAlign,fontStyle:this.fontStyle,lineHeight:this.lineHeight,stroke:this.stroke,strokeWidth:this.strokeWidth,backgroundColor:this.backgroundColor,textBackgroundColor:this.textBackgroundColor}),this.width=t.width,this.height=t.height,this._totalLineHeight=t.totalLineHeight,this._fontAscent=t.fontAscent,this._boundaries=t.boundaries,this._shadowOffsets=t.shadowOffsets,this._shadows=t.shadows||[],n=null,this.setCoords()},_renderViaNative:function(e){this.transform(e,t.isLikelyNode),this._setTextStyles(e);var n=this.text.split(/\r?\n/);this.width=this._getTextWidth(e,n),this.height=this._getTextHeight(e,n),this._renderTextBackground(e,n),this.textAlign!=="left"&&this.textAlign!=="justify"&&(e.save(),e.translate(this.textAlign==="center"?this.width/2:this.width,0)),e.save(),this._setTextShadow(e),this.clipTo&&t.util.clipContext(this,e),this._renderTextFill(e,n),this._renderTextStroke(e,n),this.clipTo&&e.restore(),this.textShadow&&e.restore(),e.restore(),this.textAlign!=="left"&&this.textAlign!=="justify"&&e.restore(),this._renderTextDecoration(e,n),this._setBoundaries(e,n),this._totalLineHeight=0,this.setCoords()},_setBoundaries:function(e,t){this._boundaries=[];for(var n=0,r=t.length;nn&&(n=s)}return n},_setTextShadow:function(e){if(this.textShadow){var t=/\s+(-?\d+)(?:px)?\s+(-?\d+)(?:px)?\s+(\d+)(?:px)?\s*/,n=this.textShadow,r=t.exec(this.textShadow),i=n.replace(t,"");e.save(),e.shadowColor=i,e.shadowOffsetX=parseInt(r[1],10),e.shadowOffsetY=parseInt(r[2],10),e.shadowBlur=parseInt(r[3],10),this._shadows=[{blur:e.shadowBlur,color:e.shadowColor,offX:e.shadowOffsetX,offY:e.shadowOffsetY}],this._shadowOffsets=[[parseInt(e.shadowOffsetX,10),parseInt(e.shadowOffsetY,10)]]}},_drawTextLine:function(e,t,n,r,i){if(this.textAlign!=="justify"){t[e](n,r,i);return}var s=t.measureText(n).width,o=this.width;if(o>s){var u=n.split(/\s+/),a=t.measureText(n.replace(/\s+/g,"")).width,f=o-a,l=u.length-1,c=f/l,h=0;for(var p=0,d=u.length;p-1&&i(this.fontSize*this.lineHeight),this.textDecoration.indexOf("line-through")>-1&&i(this.fontSize*this.lineHeight-this.fontSize/2),this.textDecoration.indexOf("overline")>-1&&i(0)},_getFontDeclaration:function(){return[t.isLikelyNode?this.fontWeight:this.fontStyle,t.isLikelyNode?this.fontStyle:this.fontWeight,this.fontSize+"px",t.isLikelyNode?'"'+this.fontFamily+'"':this.fontFamily].join(" ")},_initDummyElementForCufon:function(){var e=t.document.createElement("pre"),n=t.document.createElement("div");return n.appendChild(e),typeof G_vmlCanvasManager=="undefined"?e.innerHTML=this.text:e.innerText=this.text.replace(/\r?\n/gi,"\r"),e.style.fontSize=this.fontSize+"px",e.style.letterSpacing="normal",e},render:function(e,t){if(!this.visible)return;e.save(),this._render(e),!t&&this.active&&(this.drawBorders(e),this.drawControls(e)),e.restore()},toObject:function(e){return n(this.callSuper("toObject",e),{text:this.text,fontSize:this.fontSize,fontWeight:this.fontWeight,fontFamily:this.fontFamily,fontStyle:this.fontStyle,lineHeight:this.lineHeight,textDecoration:this.textDecoration,textShadow:this.textShadow,textAlign:this.textAlign,path:this.path,stroke:this.stroke,strokeWidth:this.strokeWidth,backgroundColor:this.backgroundColor,textBackgroundColor:this.textBackgroundColor,useNative:this.useNative})},toSVG:function(){var e=this.text.split(/\r?\n/),t=this.useNative?this.fontSize*this.lineHeight:-this._fontAscent-this._fontAscent/5*this.lineHeight,n=-(this.width/2),r=this.useNative?this.fontSize-1:this.height/2-e.length*this.fontSize-this._totalLineHeight,s=this._getSVGTextAndBg(t,n,e),o=this._getSVGShadows(t,e);return r+=this._fontAscent?this._fontAscent/5*this.lineHeight:0,['',s.textBgRects.join(""),"',o.join(""),s.textSpans.join(""),"",""].join("")},_getSVGShadows:function(e,n){var r=[],s,o,u,a,f=1;if(!this._shadows||!this._boundaries)return r;for(s=0,u=this._shadows.length;s",t.util.string.escapeXml(n[o]),""),f=1}else f++;return r},_getSVGTextAndBg:function(e,n,r){var s=[],o=[],u,a,f,l=1;this.backgroundColor&&this._boundaries&&o.push("');for(u=0,f=r.length;u",t.util.string.escapeXml(r[u]),""),l=1):l++;if(!this.textBackgroundColor||!this._boundaries)continue;o.push("')}return{textSpans:s,textBgRects:o}},_getFillAttributes:function(e){var n=e&&typeof e=="string"?new t.Color(e):"";return!n||!n.getSource()||n.getAlpha()===1?'fill="'+e+'"':'opacity="'+n.getAlpha()+'" fill="'+n.setAlpha(1).toRgb()+'"'},setColor:function(e){return this.set("fill",e),this},getText:function(){return this.text},_set:function(e,t){e==="fontFamily"&&this.path&&(this.path=this.path.replace(/(.*?)([^\/]*)(\.font\.js)/,"$1"+t+"$3")),this.callSuper("_set",e,t),e in o&&(this._initDimensions(),this.setCoords())},complexity:function(){return 1}}),t.Text.ATTRIBUTE_NAMES=t.SHARED_ATTRIBUTES.concat("x y font-family font-style font-weight font-size text-decoration".split(" ")),t.Text.fromObject=function(e){return new t.Text(e.text,r(e))},t.Text.fromElement=function(e,n){if(!e)return null;var r=t.parseAttributes(e,t.Text.ATTRIBUTE_NAMES);n=t.util.object.extend(n?t.util.object.clone(n):{},r);var i=new t.Text(e.textContent,n);return i.set({left:i.getLeft()+i.getWidth()/2,top:i.getTop()-i.getHeight()/2}),i},t.util.createAccessors(t.Text)}(typeof exports!="undefined"?exports:this),function(){function request(e,t,n){var r=URL.parse(e);r.port||(r.port=r.protocol.indexOf("https:")===0?443:80);var i=r.port===443?HTTPS:HTTP,s=i.request({hostname:r.hostname,port:r.port,path:r.path,method:"GET"},function(e){var r="";t&&e.setEncoding(t),e.on("end",function(){n(r)}),e.on("data",function(t){e.statusCode===200&&(r+=t)})});s.on("error",function(e){e.errno===process.ECONNREFUSED?fabric.log("ECONNREFUSED: connection refused to "+r.hostname+":"+r.port):fabric.log(e.message)}),s.end()}function request_fs(e,t){var n=require("fs"),r=n.createReadStream(e),i="";r.on("data",function(e){i+=e}),r.on("end",function(){t(i)})}if(typeof document!="undefined"&&typeof window!="undefined")return;var DOMParser=(new require("xmldom")).DOMParser,URL=require("url"),HTTP=require("http"),HTTPS=require("https"),Canvas=require("canvas"),Image=require("canvas").Image;fabric.util.loadImage=function(e,t,n){var r=function(r){i.src=new Buffer(r,"binary"),i._src=e,t&&t.call(n,i)},i=new Image;e&&e.indexOf("data")===0?(i.src=i._src=e,t&&t.call(n,i)):e&&e.indexOf("http")!==0?request_fs(e,r):e&&request(e,"binary",r)},fabric.loadSVGFromURL=function(e,t){e=e.replace(/^\n\s*/,"").replace(/\?.*$/,"").trim(),e.indexOf("http")!==0?request_fs(e,function(e){fabric.loadSVGFromString(e,t)}):request(e,"",function(e){fabric.loadSVGFromString(e,t)})},fabric.loadSVGFromString=function(e,t){var n=(new DOMParser).parseFromString(e);fabric.parseSVGDocument(n.documentElement,function(e,n){t(e,n)})},fabric.util.getScript=function(url,callback){request(url,"",function(body){eval(body),callback&&callback()})},fabric.Image.fromObject=function(e,t){fabric.util.loadImage(e.src,function(n){var r=new fabric.Image(n);r._initConfig(e),r._initFilters(e),t(r)})},fabric.createCanvasForNode=function(e,t){var n=fabric.document.createElement("canvas"),r=new Canvas(e||600,t||600);n.style={},n.width=r.width,n.height=r.height;var i=fabric.Canvas||fabric.StaticCanvas,s=new i(n);return s.contextContainer=r.getContext("2d"),s.nodeCanvas=r,s.Font=Canvas.Font,s},fabric.StaticCanvas.prototype.createPNGStream=function(){return this.nodeCanvas.createPNGStream()},fabric.StaticCanvas.prototype.createJPEGStream=function(e){return this.nodeCanvas.createJPEGStream(e)};var origSetWidth=fabric.StaticCanvas.prototype.setWidth;fabric.StaticCanvas.prototype.setWidth=function(e){return origSetWidth.call(this,e),this.nodeCanvas.width=e,this},fabric.Canvas&&(fabric.Canvas.prototype.setWidth=fabric.StaticCanvas.prototype.setWidth);var origSetHeight=fabric.StaticCanvas.prototype.setHeight;fabric.StaticCanvas.prototype.setHeight=function(e){return origSetHeight.call(this,e),this.nodeCanvas.height=e,this},fabric.Canvas&&(fabric.Canvas.prototype.setHeight=fabric.StaticCanvas.prototype.setHeight)}(); \ No newline at end of file +/* build: `node build.js modules=ALL exclude=gestures` *//*! Fabric.js Copyright 2008-2013, Printio (Juriy Zaytsev, Maxim Chernyak) */var fabric=fabric||{version:"1.1.16"};typeof exports!="undefined"&&(exports.fabric=fabric),typeof document!="undefined"&&typeof window!="undefined"?(fabric.document=document,fabric.window=window):(fabric.document=require("jsdom").jsdom(""),fabric.window=fabric.document.createWindow()),fabric.isTouchSupported="ontouchstart"in fabric.document.documentElement,fabric.isLikelyNode=typeof Buffer!="undefined"&&typeof window=="undefined";var Cufon=function(){function r(e){var t=this.face=e.face;this.glyphs=e.glyphs,this.w=e.w,this.baseSize=parseInt(t["units-per-em"],10),this.family=t["font-family"].toLowerCase(),this.weight=t["font-weight"],this.style=t["font-style"]||"normal",this.viewBox=function(){var e=t.bbox.split(/\s+/),n={minX:parseInt(e[0],10),minY:parseInt(e[1],10),maxX:parseInt(e[2],10),maxY:parseInt(e[3],10)};return n.width=n.maxX-n.minX,n.height=n.maxY-n.minY,n.toString=function(){return[this.minX,this.minY,this.width,this.height].join(" ")},n}(),this.ascent=-parseInt(t.ascent,10),this.descent=-parseInt(t.descent,10),this.height=-this.ascent+this.descent}function i(){var e={},t={oblique:"italic",italic:"oblique"};this.add=function(t){(e[t.style]||(e[t.style]={}))[t.weight]=t},this.get=function(n,r){var i=e[n]||e[t[n]]||e.normal||e.italic||e.oblique;if(!i)return null;r={normal:400,bold:700}[r]||parseInt(r,10);if(i[r])return i[r];var s={1:1,99:0}[r%100],o=[],u,a;s===undefined&&(s=r>400),r==500&&(r=400);for(var f in i){f=parseInt(f,10);if(!u||fa)a=f;o.push(f)}return ra&&(r=a),o.sort(function(e,t){return(s?e>r&&t>r?et:et:e=i.length+e?r():setTimeout(arguments.callee,10)}),function(t){e?t():n.push(t)}}(),supports:function(e,t){var n=fabric.document.createElement("span").style;return n[e]===undefined?!1:(n[e]=t,n[e]===t)},textAlign:function(e,t,n,r){return t.get("textAlign")=="right"?n>0&&(e=" "+e):nk&&(k=N),A.push(N),N=0;continue}var O=t.glyphs[T[b]]||t.missingGlyph;if(!O)continue;N+=C=Number(O.w||t.w)+h}A.push(N),N=Math.max(k,N);var M=[];for(var b=A.length;b--;)M[b]=N-A[b];if(C===null)return null;d+=l.width-C,m+=l.minX;var _,D;if(f)_=u,D=u.firstChild;else{_=fabric.document.createElement("span"),_.className="cufon cufon-canvas",_.alt=n,D=fabric.document.createElement("canvas"),_.appendChild(D);if(i.printable){var P=fabric.document.createElement("span");P.className="cufon-alt",P.appendChild(fabric.document.createTextNode(n)),_.appendChild(P)}}var H=_.style,B=D.style||{},j=c.convert(l.height-p+v),F=Math.ceil(j),I=F/j;D.width=Math.ceil(c.convert(N+d-m)*I),D.height=F,p+=l.minY,B.top=Math.round(c.convert(p-t.ascent))+"px",B.left=Math.round(c.convert(m))+"px";var q=Math.ceil(c.convert(N*I)),R=q+"px",U=c.convert(t.height),z=(i.lineHeight-1)*c.convert(-t.ascent/5)*(L-1);Cufon.textOptions.width=q,Cufon.textOptions.height=U*L+z,Cufon.textOptions.lines=L,Cufon.textOptions.totalLineHeight=z,e?(H.width=R,H.height=U+"px"):(H.paddingLeft=R,H.paddingBottom=U-1+"px");var W=Cufon.textOptions.context||D.getContext("2d"),X=F/l.height;Cufon.textOptions.fontAscent=t.ascent*X,Cufon.textOptions.boundaries=null;for(var V=Cufon.textOptions.shadowOffsets,b=y.length;b--;)V[b]=[y[b][0]*X,y[b][1]*X];W.save(),W.scale(X,X),W.translate(-m-1/X*D.width/2+(Cufon.fonts[t.family].offsetLeft||0),-p-Cufon.textOptions.height/X/2+(Cufon.fonts[t.family].offsetTop||0)),W.lineWidth=t.face["underline-thickness"],W.save();var J=Cufon.getTextDecoration(i),K=i.fontStyle==="italic";W.save(),Q();if(g)for(var b=0,w=g.length;b.cufon-vml-canvas{text-indent:0}@media screen{cvml\\:shape,cvml\\:shadow{behavior:url(#default#VML);display:block;antialias:true;position:absolute}.cufon-vml-canvas{position:absolute;text-align:left}.cufon-vml{display:inline-block;position:relative;vertical-align:middle}.cufon-vml .cufon-alt{position:absolute;left:-10000in;font-size:1px}a .cufon-vml{cursor:pointer}}@media print{.cufon-vml *{display:none}.cufon-vml .cufon-alt{display:inline}}'),function(e,t,i,s,o,u,a){var f=t===null;f&&(t=o.alt);var l=e.viewBox,c=i.computedFontSize||(i.computedFontSize=new Cufon.CSS.Size(n(u,i.get("fontSize"))+"px",e.baseSize)),h=i.computedLSpacing;h==undefined&&(h=i.get("letterSpacing"),i.computedLSpacing=h=h=="normal"?0:~~c.convertFrom(r(u,h)));var p,d;if(f)p=o,d=o.firstChild;else{p=fabric.document.createElement("span"),p.className="cufon cufon-vml",p.alt=t,d=fabric.document.createElement("span"),d.className="cufon-vml-canvas",p.appendChild(d);if(s.printable){var v=fabric.document.createElement("span");v.className="cufon-alt",v.appendChild(fabric.document.createTextNode(t)),p.appendChild(v)}a||p.appendChild(fabric.document.createElement("cvml:shape"))}var m=p.style,g=d.style,y=c.convert(l.height),b=Math.ceil(y),w=b/y,E=l.minX,S=l.minY;g.height=b,g.top=Math.round(c.convert(S-e.ascent)),g.left=Math.round(c.convert(E)),m.height=c.convert(e.height)+"px";var x=Cufon.getTextDecoration(s),T=i.get("color"),N=Cufon.CSS.textTransform(t,i).split(""),C=0,k=0,L=null,A,O,M=s.textShadow;for(var _=0,D=0,P=N.length;_-1},complexity:function(){return this.getObjects().reduce(function(e,t){return e+=t.complexity?t.complexity():0,e},0)},toGrayscale:function(){return this.forEachObject(function(e){e.toGrayscale()})}},function(){function n(e,t){var n=e.indexOf(t);return n!==-1&&e.splice(n,1),e}function r(e,t){return Math.floor(Math.random()*(t-e+1))+e}function s(e){return e*i}function o(e){return e/i}function u(e,t,n){var r=Math.sin(n),i=Math.cos(n);e.subtractEquals(t);var s=e.x*i-e.y*r,o=e.x*r+e.y*i;return(new fabric.Point(s,o)).addEquals(t)}function a(e,t){return parseFloat(Number(e).toFixed(t))}function f(){return!1}function l(e){e||(e={});var t=+(new Date),n=e.duration||500,r=t+n,i,s=e.onChange||function(){},o=e.abort||function(){return!1},u=e.easing||function(e,t,n,r){return-n*Math.cos(e/r*(Math.PI/2))+n+t},a="startValue"in e?e.startValue:0,f="endValue"in e?e.endValue:100,l=e.byValue||f-a;e.onStart&&e.onStart(),function c(){i=+(new Date);var f=i>r?n:i-t;s(u(f,a,l,n));if(i>r||o()){e.onComplete&&e.onComplete();return}h(c)}()}function p(e,t,n){if(e){var r=fabric.util.createImage();r.onload=function(){t&&t.call(n,r),r=r.onload=null},r.src=e}else t&&t.call(n,e)}function d(e,t){function n(e){return fabric[fabric.util.string.camelize(fabric.util.string.capitalize(e))]}function r(){++s===o&&t&&t(i)}var i=[],s=0,o=e.length;e.forEach(function(e,t){if(!e.type)return;var s=n(e.type);s.async?s.fromObject(e,function(e,n){n||(i[t]=e),r()}):(i[t]=s.fromObject(e),r())})}function v(e,t,n){var r;return e.length>1?r=new fabric.PathGroup(e,t):r=e[0],typeof n!="undefined"&&r.setSourcePath(n),r}function m(e,t,n){if(n&&Object.prototype.toString.call(n)==="[object Array]")for(var r=0,i=n.length;rr)r+=u[p++%h],r>l&&(r=l),n[d?"lineTo":"moveTo"](r,0),d=!d;n.restore()}function y(e){return e||(e=fabric.document.createElement("canvas")),!e.getContext&&typeof G_vmlCanvasManager!="undefined"&&G_vmlCanvasManager.initElement(e),e}function b(){return fabric.isLikelyNode?new(require("canvas").Image):fabric.document.createElement("img")}function w(e){var t=e.prototype;for(var n=t.stateProperties.length;n--;){var r=t.stateProperties[n],i=r.charAt(0).toUpperCase()+r.slice(1),s="set"+i,o="get"+i;t[o]||(t[o]=function(e){return new Function('return this.get("'+e+'")')}(r)),t[s]||(t[s]=function(e){return new Function("value",'return this.set("'+e+'", value)')}(r))}}function E(e,t){t.save(),t.beginPath(),e.clipTo(t),t.clip()}function S(e,t){var n=[[e[0],e[2],e[4]],[e[1],e[3],e[5]],[0,0,1]],r=[[t[0],t[2],t[4]],[t[1],t[3],t[5]],[0,0,1]],i=[];for(var s=0;s<3;s++){i[s]=[];for(var o=0;o<3;o++){var u=0;for(var a=0;a<3;a++)u+=n[s][a]*r[a][o];i[s][o]=u}}return[i[0][0],i[1][0],i[0][1],i[1][1],i[0][2],i[1][2]]}var e=Math.sqrt,t=Math.atan2;fabric.util={};var i=Math.PI/180,c=fabric.window.requestAnimationFrame||fabric.window.webkitRequestAnimationFrame||fabric.window.mozRequestAnimationFrame||fabric.window.oRequestAnimationFrame||fabric.window.msRequestAnimationFrame||function(e){fabric.window.setTimeout(e,1e3/60)},h=function(){return c.apply(fabric.window,arguments)};fabric.util.removeFromArray=n,fabric.util.degreesToRadians=s,fabric.util.radiansToDegrees=o,fabric.util.rotatePoint=u,fabric.util.toFixed=a,fabric.util.getRandomInt=r,fabric.util.falseFunction=f,fabric.util.animate=l,fabric.util.requestAnimFrame=h,fabric.util.loadImage=p,fabric.util.enlivenObjects=d,fabric.util.groupSVGElements=v,fabric.util.populateWithProperties=m,fabric.util.drawDashedLine=g,fabric.util.createCanvasElement=y,fabric.util.createImage=b,fabric.util.createAccessors=w,fabric.util.clipContext=E,fabric.util.multiplyTransformMatrices=S}(),function(){function t(t,n){var r=e.call(arguments,2),i=[];for(var s=0,o=t.length;s=r&&(r=e[n][t]);else while(n--)e[n]>=r&&(r=e[n]);return r}function r(e,t){if(!e||e.length===0)return undefined;var n=e.length-1,r=t?e[n][t]:e[n];if(t)while(n--)e[n][t]>>0;if(n===0)return-1;var r=0;arguments.length>0&&(r=Number(arguments[1]),r!==r?r=0:r!==0&&r!==Number.POSITIVE_INFINITY&&r!==Number.NEGATIVE_INFINITY&&(r=(r>0||-1)*Math.floor(Math.abs(r))));if(r>=n)return-1;var i=r>=0?r:Math.max(n-Math.abs(r),0);for(;i>>0;n>>0;r>>0;n>>0;n>>0;i>>0,n=0,r;if(arguments.length>1)r=arguments[1];else do{if(n in this){r=this[n++];break}if(++n>=t)throw new TypeError}while(!0);for(;n/g,">")}String.prototype.trim||(String.prototype.trim=function(){return this.replace(/^[\s\xA0]+/,"").replace(/[\s\xA0]+$/,"")}),fabric.util.string={camelize:e,capitalize:t,escapeXml:n}}(),function(){var e=Array.prototype.slice,t=Function.prototype.apply,n=function(){};Function.prototype.bind||(Function.prototype.bind=function(r){var i=this,s=e.call(arguments,1),o;return s.length?o=function(){return t.call(i,this instanceof n?this:r,s.concat(e.call(arguments)))}:o=function(){return t.call(i,this instanceof n?this:r,arguments)},n.prototype=this.prototype,o.prototype=new n,o})}(),function(){function i(){}function s(t){var n=this.constructor.superclass.prototype[t];return arguments.length>1?n.apply(this,e.call(arguments,1)):n.call(this)}function o(){function u(){this.initialize.apply(this,arguments)}var n=null,o=e.call(arguments,0);typeof o[0]=="function"&&(n=o.shift()),u.superclass=n,u.subclasses=[],n&&(i.prototype=n.prototype,u.prototype=new i,n.subclasses.push(u));for(var a=0,f=o.length;a-1?e.prototype[i]=function(e){return function(){var n=this.constructor.superclass;this.constructor.superclass=r;var i=t[e].apply(this,arguments);this.constructor.superclass=n;if(e!=="initialize")return i}}(i):e.prototype[i]=t[i],n&&(t.toString!==Object.prototype.toString&&(e.prototype.toString=t.toString),t.valueOf!==Object.prototype.valueOf&&(e.prototype.valueOf=t.valueOf))};fabric.util.createClass=o}(),function(){function e(e){var t=Array.prototype.slice.call(arguments,1),n,r,i=t.length;for(r=0;r-1?s(e,t.match(/opacity:\s*(\d?\.?\d*)/)[1]):e;for(var r in t)if(r==="opacity")s(e,t[r]);else{var i=r==="float"||r==="cssFloat"?typeof n.styleFloat=="undefined"?"cssFloat":"styleFloat":r;n[i]=t[r]}return e}var t=fabric.document.createElement("div"),n=typeof t.style.opacity=="string",r=typeof t.style.filter=="string",i=/alpha\s*\(\s*opacity\s*=\s*([^\)]+)\)/,s=function(e){return e};n?s=function(e,t){return e.style.opacity=t,e}:r&&(s=function(e,t){var n=e.style;return e.currentStyle&&!e.currentStyle.hasLayout&&(n.zoom=1),i.test(n.filter)?(t=t>=.9999?"":"alpha(opacity="+t*100+")",n.filter=n.filter.replace(i,t)):n.filter+=" alpha(opacity="+t*100+")",e}),fabric.util.setStyle=e}(),function(){function t(e){return typeof e=="string"?fabric.document.getElementById(e):e}function s(e,t){var n=fabric.document.createElement(e);for(var r in t)r==="class"?n.className=t[r]:r==="for"?n.htmlFor=t[r]:n.setAttribute(r,t[r]);return n}function o(e,t){(" "+e.className+" ").indexOf(" "+t+" ")===-1&&(e.className+=(e.className?" ":"")+t)}function u(e,t,n){return typeof t=="string"&&(t=s(t,n)),e.parentNode&&e.parentNode.replaceChild(t,e),t.appendChild(e),t}function a(e){var t,n,r={left:0,top:0},i=e&&e.ownerDocument,s={left:0,top:0},o={borderLeftWidth:"left",borderTopWidth:"top",paddingLeft:"left",paddingTop:"top"};if(!i)return{left:0,top:0};for(var u in o)s[o[u]]+=parseInt(f(e,u),10)||0;return t=i.documentElement,typeof e.getBoundingClientRect!="undefined"&&(r=e.getBoundingClientRect()),i!=null&&i===i.window?n=i:n=i.nodeType===9&&i.defaultView,{left:r.left+n.pageXOffset-(t.clientLeft||0)+s.left,top:r.top+n.pageYOffset-(t.clientTop||0)+s.top}}function f(e,t){e.style||(e.style={});if(fabric.document.defaultView&&fabric.document.defaultView.getComputedStyle)return fabric.document.defaultView.getComputedStyle(e,null)[t];var n=e.style[t];return!n&&e.currentStyle&&(n=e.currentStyle[t]),n}var e=Array.prototype.slice,n=function(t){return e.call(t,0)},r;try{r=n(fabric.document.childNodes)instanceof Array}catch(i){}r||(n=function(e){var t=new Array(e.length),n=e.length;while(n--)t[n]=e[n];return t}),function(){function n(e){return typeof e.onselectstart!="undefined"&&(e.onselectstart=fabric.util.falseFunction),t?e.style[t]="none":typeof e.unselectable=="string"&&(e.unselectable="on"),e}function r(e){return typeof e.onselectstart!="undefined"&&(e.onselectstart=null),t?e.style[t]="":typeof e.unselectable=="string"&&(e.unselectable=""),e}var e=fabric.document.documentElement.style,t="userSelect"in e?"userSelect":"MozUserSelect"in e?"MozUserSelect":"WebkitUserSelect"in e?"WebkitUserSelect":"KhtmlUserSelect"in e?"KhtmlUserSelect":"";fabric.util.makeElementUnselectable=n,fabric.util.makeElementSelectable=r}(),function(){function e(e,t){var n=fabric.document.getElementsByTagName("head")[0],r=fabric.document.createElement("script"),i=!0;r.onload=r.onreadystatechange=function(e){if(i){if(typeof this.readyState=="string"&&this.readyState!=="loaded"&&this.readyState!=="complete")return;i=!1,t(e||fabric.window.event),r=r.onload=r.onreadystatechange=null}},r.src=e,n.appendChild(r)}fabric.util.getScript=e}(),fabric.util.getById=t,fabric.util.toArray=n,fabric.util.makeElement=s,fabric.util.addClass=o,fabric.util.wrapElement=u,fabric.util.getElementOffset=a,fabric.util.getElementStyle=f}(),function(){function e(e,t){return e+(/\?/.test(e)?"&":"?")+t}function n(){}function r(r,i){i||(i={});var s=i.method?i.method.toUpperCase():"GET",o=i.onComplete||function(){},u=t(),a;return u.onreadystatechange=function(){u.readyState===4&&(o(u),u.onreadystatechange=n)},s==="GET"&&(a=null,typeof i.parameters=="string"&&(r=e(r,i.parameters))),u.open(s,r,!0),(s==="POST"||s==="PUT")&&u.setRequestHeader("Content-Type","application/x-www-form-urlencoded"),u.send(a),u}var t=function(){var e=[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 t=e.length;t--;)try{var n=e[t]();if(n)return e[t]}catch(r){}}();fabric.util.request=r}(),function(){function e(e,t,n,r){return n*(e/=r)*e+t}function t(e,t,n,r){return-n*(e/=r)*(e-2)+t}function n(e,t,n,r){return e/=r/2,e<1?n/2*e*e+t:-n/2*(--e*(e-2)-1)+t}function r(e,t,n,r){return n*(e/=r)*e*e+t}function i(e,t,n,r){return n*((e=e/r-1)*e*e+1)+t}function s(e,t,n,r){return e/=r/2,e<1?n/2*e*e*e+t:n/2*((e-=2)*e*e+2)+t}function o(e,t,n,r){return n*(e/=r)*e*e*e+t}function u(e,t,n,r){return-n*((e=e/r-1)*e*e*e-1)+t}function a(e,t,n,r){return e/=r/2,e<1?n/2*e*e*e*e+t:-n/2*((e-=2)*e*e*e-2)+t}function f(e,t,n,r){return n*(e/=r)*e*e*e*e+t}function l(e,t,n,r){return n*((e=e/r-1)*e*e*e*e+1)+t}function c(e,t,n,r){return e/=r/2,e<1?n/2*e*e*e*e*e+t:n/2*((e-=2)*e*e*e*e+2)+t}function h(e,t,n,r){return-n*Math.cos(e/r*(Math.PI/2))+n+t}function p(e,t,n,r){return n*Math.sin(e/r*(Math.PI/2))+t}function d(e,t,n,r){return-n/2*(Math.cos(Math.PI*e/r)-1)+t}function v(e,t,n,r){return e===0?t:n*Math.pow(2,10*(e/r-1))+t}function m(e,t,n,r){return e===r?t+n:n*(-Math.pow(2,-10*e/r)+1)+t}function g(e,t,n,r){return e===0?t:e===r?t+n:(e/=r/2,e<1?n/2*Math.pow(2,10*(e-1))+t:n/2*(-Math.pow(2,-10*--e)+2)+t)}function y(e,t,n,r){return-n*(Math.sqrt(1-(e/=r)*e)-1)+t}function b(e,t,n,r){return n*Math.sqrt(1-(e=e/r-1)*e)+t}function w(e,t,n,r){return e/=r/2,e<1?-n/2*(Math.sqrt(1-e*e)-1)+t:n/2*(Math.sqrt(1-(e-=2)*e)+1)+t}function E(e,t,n,r){var i=1.70158,s=0,o=n;return e===0?t:(e/=r,e===1?t+n:(s||(s=r*.3),o-1;e=e.split(/\s+/);var n=[],r,i;if(t){r=0,i=e.length;for(;r/i,"")));if(!s.documentElement)return;t.parseSVGDocument(s.documentElement,function(r,i){w.set(e,{objects:t.util.array.invoke(r,"toObject"),options:i}),n(r,i)},r)}e=e.replace(/^\n\s*/,"").trim(),w.has(e,function(r){r?w.get(e,function(e){var t=S(e);n(t.objects,t.options)}):new t.util.request(e,{method:"get",onComplete:i})})}function S(e){var n=e.objects,i=e.options;return n=n.map(function(e){return t[r(e.type)].fromObject(e)}),{objects:n,options:i}}function x(e,n,r){e=e.trim();var i;if(typeof DOMParser!="undefined"){var s=new DOMParser;s&&s.parseFromString&&(i=s.parseFromString(e,"text/xml"))}else t.window.ActiveXObject&&(i=new ActiveXObject("Microsoft.XMLDOM"),i.async="false",i.loadXML(e.replace(//i,"")));t.parseSVGDocument(i.documentElement,function(e,t){n(e,t)},r)}function T(e){var t="";for(var n=0,r=e.length;n',"",""].join("")),t}function N(e){var t="";return e.backgroundColor&&e.backgroundColor.source&&(t=['',''].join("")),t}function C(e){var t=e.getElementsByTagName("linearGradient"),n=e.getElementsByTagName("radialGradient"),r,i,s={};i=t.length;for(;i--;)r=t[i],s[r.getAttribute("id")]=r;i=n.length;for(;i--;)r=n[i],s[r.getAttribute("id")]=r;return s}var t=e.fabric||(e.fabric={}),n=t.util.object.extend,r=t.util.string.capitalize,i=t.util.object.clone,s=t.util.toFixed,o=t.util.multiplyTransformMatrices;t.SHARED_ATTRIBUTES=["transform","fill","fill-opacity","fill-rule","opacity","stroke","stroke-dasharray","stroke-linecap","stroke-linejoin","stroke-miterlimit","stroke-opacity","stroke-width"];var u={"fill-opacity":"fillOpacity","fill-rule":"fillRule","font-family":"fontFamily","font-size":"fontSize","font-style":"fontStyle","font-weight":"fontWeight",cx:"left",x:"left",r:"radius","stroke-dasharray":"strokeDashArray","stroke-linecap":"strokeLineCap","stroke-linejoin":"strokeLineJoin","stroke-miterlimit":"strokeMiterLimit","stroke-opacity":"strokeOpacity","stroke-width":"strokeWidth","text-decoration":"textDecoration",cy:"top",y:"top",transform:"transformMatrix"},a={stroke:"strokeOpacity",fill:"fillOpacity"};t.parseTransformAttribute=function(){function e(e,t){var n=t[0];e[0]=Math.cos(n),e[1]=Math.sin(n),e[2]=-Math.sin(n),e[3]=Math.cos(n)}function n(e,t){var n=t[0],r=t.length===2?t[1]:t[0];e[0]=n,e[3]=r}function r(e,t){e[2]=t[0]}function i(e,t){e[1]=t[0]}function s(e,t){e[4]=t[0],t.length===2&&(e[5]=t[1])}var o=[1,0,0,1,0,0],u="(?:[-+]?\\d+(?:\\.\\d+)?(?:e[-+]?\\d+)?)",a="(?:\\s+,?\\s*|,\\s*)",f="(?:(skewX)\\s*\\(\\s*("+u+")\\s*\\))",l="(?:(skewY)\\s*\\(\\s*("+u+")\\s*\\))",c="(?:(rotate)\\s*\\(\\s*("+u+")(?:"+a+"("+u+")"+a+"("+u+"))?\\s*\\))",h="(?:(scale)\\s*\\(\\s*("+u+")(?:"+a+"("+u+"))?\\s*\\))",p="(?:(translate)\\s*\\(\\s*("+u+")(?:"+a+"("+u+"))?\\s*\\))",d="(?:(matrix)\\s*\\(\\s*("+u+")"+a+"("+u+")"+a+"("+u+")"+a+"("+u+")"+a+"("+u+")"+a+"("+u+")"+"\\s*\\))",v="(?:"+d+"|"+p+"|"+h+"|"+c+"|"+f+"|"+l+")",m="(?:"+v+"(?:"+a+v+")*"+")",g="^\\s*(?:"+m+"?)\\s*$",y=new RegExp(g),b=new RegExp(v,"g");return function(u){var a=o.concat(),f=[];if(!u||u&&!y.test(u))return a;u.replace(b,function(t){var u=(new RegExp(v)).exec(t).filter(function(e){return e!==""&&e!=null}),l=u[1],c=u.slice(2).map(parseFloat);switch(l){case"translate":s(a,c);break;case"rotate":e(a,c);break;case"scale":n(a,c);break;case"skewX":r(a,c);break;case"skewY":i(a,c);break;case"matrix":a=c}f.push(a.concat()),a=o.concat()});var l=f[0];while(f.length>1)f.shift(),l=t.util.multiplyTransformMatrices(l,f[0]);return l}}(),t.parseSVGDocument=function(){function s(e,t){while(e&&(e=e.parentNode))if(t.test(e.nodeName))return!0;return!1}var e=/^(path|circle|polygon|polyline|ellipse|rect|line|image|text)$/,n="(?:[-+]?\\d+(?:\\.\\d+)?(?:e[-+]?\\d+)?)",r=new RegExp("^\\s*("+n+"+)\\s*,?"+"\\s*("+n+"+)\\s*,?"+"\\s*("+n+"+)\\s*,?"+"\\s*("+n+"+)\\s*"+"$");return function(n,o,u){if(!n)return;var a=new Date,f=t.util.toArray(n.getElementsByTagName("*"));if(f.length===0){f=n.selectNodes("//*[name(.)!='svg']");var l=[];for(var c=0,h=f.length;c0&&this.init(e,t)}var t=e.fabric||(e.fabric={});if(t.Point){t.warn("fabric.Point is already defined");return}t.Point=n,n.prototype={constructor:n,init:function(e,t){this.x=e,this.y=t},add:function(e){return new n(this.x+e.x,this.y+e.y)},addEquals:function(e){return this.x+=e.x,this.y+=e.y,this},scalarAdd:function(e){return new n(this.x+e,this.y+e)},scalarAddEquals:function(e){return this.x+=e,this.y+=e,this},subtract:function(e){return new n(this.x-e.x,this.y-e.y)},subtractEquals:function(e){return this.x-=e.x,this.y-=e.y,this},scalarSubtract:function(e){return new n(this.x-e,this.y-e)},scalarSubtractEquals:function(e){return this.x-=e,this.y-=e,this},multiply:function(e){return new n(this.x*e,this.y*e)},multiplyEquals:function(e){return this.x*=e,this.y*=e,this},divide:function(e){return new n(this.x/e,this.y/e)},divideEquals:function(e){return this.x/=e,this.y/=e,this},eq:function(e){return this.x===e.x&&this.y===e.y},lt:function(e){return this.xe.x&&this.y>e.y},gte:function(e){return this.x>=e.x&&this.y>=e.y},lerp:function(e,t){return new n(this.x+(e.x-this.x)*t,this.y+(e.y-this.y)*t)},distanceFrom:function(e){var t=this.x-e.x,n=this.y-e.y;return Math.sqrt(t*t+n*n)},midPointFrom:function(e){return new n(this.x+(e.x-this.x)/2,this.y+(e.y-this.y)/2)},min:function(e){return new n(Math.min(this.x,e.x),Math.min(this.y,e.y))},max:function(e){return new n(Math.max(this.x,e.x),Math.max(this.y,e.y))},toString:function(){return this.x+","+this.y},setXY:function(e,t){this.x=e,this.y=t},setFromPoint:function(e){this.x=e.x,this.y=e.y},swap:function(e){var t=this.x,n=this.y;this.x=e.x,this.y=e.y,e.x=t,e.y=n}}}(typeof exports!="undefined"?exports:this),function(){function e(e){var t=e.getAttribute("style"),n=e.getAttribute("offset"),r,i;n=parseFloat(n)/(/%$/.test(n)?100:1);if(t){var s=t.split(/\s*;\s*/);s[s.length-1]===""&&s.pop();for(var o=s.length;o--;){var u=s[o].split(/\s*:\s*/),a=u[0].trim(),f=u[1].trim();a==="stop-color"?r=f:a==="stop-opacity"&&(i=f)}}return r||(r=e.getAttribute("stop-color")),i||(i=e.getAttribute("stop-opacity")),r=(new fabric.Color(r)).toRgb(),{offset:n,color:r,opacity:i}}function t(e,t){for(var n in t){if(typeof t[n]=="string"&&/^\d+%$/.test(t[n])){var r=parseFloat(t[n],10);if(n==="x1"||n==="x2"||n==="r2")t[n]=fabric.util.toFixed(e.width*r/100,2);else if(n==="y1"||n==="y2")t[n]=fabric.util.toFixed(e.height*r/100,2)}if(n==="x1"||n==="x2")t[n]-=fabric.util.toFixed(e.width/2,2);else if(n==="y1"||n==="y2")t[n]-=fabric.util.toFixed(e.height/2,2)}}function n(e,t){for(var n in t){if(n==="x1"||n==="x2")t[n]+=fabric.util.toFixed(e.width/2,2);else if(n==="y1"||n==="y2")t[n]+=fabric.util.toFixed(e.height/2,2);if(n==="x1"||n==="x2"||n==="r2")t[n]=fabric.util.toFixed(t[n]/e.width*100,2)+"%";else if(n==="y1"||n==="y2")t[n]=fabric.util.toFixed(t[n]/e.height*100,2)+"%"}}fabric.Gradient=fabric.util.createClass({initialize:function(e){e||(e={});var t={};this.id=fabric.Object.__uid++,this.type=e.type||"linear",t={x1:e.coords.x1||0,y1:e.coords.y1||0,x2:e.coords.x2||0,y2:e.coords.y2||0},this.type==="radial"&&(t.r1=e.coords.r1||0,t.r2=e.coords.r2||0),this.coords=t,this.gradientUnits=e.gradientUnits||"objectBoundingBox",this.colorStops=e.colorStops.slice()},addColorStop:function(e){for(var t in e){var n=new fabric.Color(e[t]);this.colorStops.push({offset:t,color:n.toRgb(),opacity:n.getAlpha()})}return this},toObject:function(){return{type:this.type,coords:this.coords,gradientUnits:this.gradientUnits,colorStops:this.colorStops}},toSVG:function(e,t){var r=fabric.util.object.clone(this.coords),i;this.colorStops.sort(function(e,t){return e.offset-t.offset}),t&&this.gradientUnits==="userSpaceOnUse"?(r.x1+=e.width/2,r.y1+=e.height/2,r.x2+=e.width/2,r.y2+=e.height/2):this.gradientUnits==="objectBoundingBox"&&n(e,r),this.type==="linear"?i=["']:this.type==="radial"&&(i=["']);for(var s=0;s');return i.push(this.type==="linear"?"":""),i.join("")},toLive:function(e){var t;if(!this.type)return;this.type==="linear"?t=e.createLinearGradient(this.coords.x1,this.coords.y1,this.coords.x2||e.canvas.width,this.coords.y2):this.type==="radial"&&(t=e.createRadialGradient(this.coords.x1,this.coords.y1,this.coords.r1,this.coords.x2,this.coords.y2,this.coords.r2));for(var n=0;n0&&this.init(e)}var t=e.fabric||(e.fabric={});if(t.Intersection){t.warn("fabric.Intersection is already defined");return}t.Intersection=n,t.Intersection.prototype={init:function(e){this.status=e,this.points=[]},appendPoint:function(e){this.points.push(e)},appendPoints:function(e){this.points=this.points.concat(e)}},t.Intersection.intersectLineLine=function(e,r,i,s){var o,u=(s.x-i.x)*(e.y-i.y)-(s.y-i.y)*(e.x-i.x),a=(r.x-e.x)*(e.y-i.y)-(r.y-e.y)*(e.x-i.x),f=(s.y-i.y)*(r.x-e.x)-(s.x-i.x)*(r.y-e.y);if(f!==0){var l=u/f,c=a/f;0<=l&&l<=1&&0<=c&&c<=1?(o=new n("Intersection"),o.points.push(new t.Point(e.x+l*(r.x-e.x),e.y+l*(r.y-e.y)))):o=new n("No Intersection")}else u===0||a===0?o=new n("Coincident"):o=new n("Parallel");return o},t.Intersection.intersectLinePolygon=function(e,t,r){var i=new n("No Intersection"),s=r.length;for(var o=0;o0&&(i.status="Intersection"),i},t.Intersection.intersectPolygonPolygon=function(e,t){var r=new n("No Intersection"),i=e.length;for(var s=0;s0&&(r.status="Intersection"),r},t.Intersection.intersectPolygonRectangle=function(e,r,i){var s=r.min(i),o=r.max(i),u=new t.Point(o.x,s.y),a=new t.Point(s.x,o.y),f=n.intersectLinePolygon(s,u,e),l=n.intersectLinePolygon(u,o,e),c=n.intersectLinePolygon(o,a,e),h=n.intersectLinePolygon(a,s,e),p=new n("No Intersection");return p.appendPoints(f.points),p.appendPoints(l.points),p.appendPoints(c.points),p.appendPoints(h.points),p.points.length>0&&(p.status="Intersection"),p}}(typeof exports!="undefined"?exports:this),function(e){"use strict";function n(e){e?this._tryParsingColor(e):this.setSource([0,0,0,1])}function r(e,t,n){return n<0&&(n+=1),n>1&&(n-=1),n<1/6?e+(t-e)*6*n:n<.5?t:n<2/3?e+(t-e)*(2/3-n)*6:e}var t=e.fabric||(e.fabric={});if(t.Color){t.warn("fabric.Color is already defined.");return}t.Color=n,t.Color.prototype={_tryParsingColor:function(e){var t;e in n.colorNameMap&&(e=n.colorNameMap[e]),t=n.sourceFromHex(e),t||(t=n.sourceFromRgb(e)),t||(t=n.sourceFromHsl(e)),t&&this.setSource(t)},_rgbToHsl:function(e,n,r){e/=255,n/=255,r/=255;var i,s,o,u=t.util.array.max([e,n,r]),a=t.util.array.min([e,n,r]);o=(u+a)/2;if(u===a)i=s=0;else{var f=u-a;s=o>.5?f/(2-u-a):f/(u+a);switch(u){case e:i=(n-r)/f+(n',''),t.push("',"Created with Fabric.js ",fabric.version,"","",fabric.createSVGFontFacesMarkup(this.getObjects()),fabric.createSVGRefElementsMarkup(this),""),this.backgroundColor&&this.backgroundColor.source&&t.push('"),this.backgroundImage&&t.push(''),this.overlayImage&&t.push('');for(var n=0,r=this.getObjects(),i=r.length;n"),t.join("")},remove:function(e){return this.getActiveObject()===e&&(this.fire("before:selection:cleared",{target:e}),this.discardActiveObject(),this.fire("selection:cleared")),fabric.Collection.remove.call(this,e)},sendToBack:function(e){return n(this._objects,e),this._objects.unshift(e),this.renderAll&&this.renderAll()},bringToFront:function(e){return n(this._objects,e),this._objects.push(e),this.renderAll&&this.renderAll()},sendBackwards:function(e){var t=this._objects.indexOf(e),r=t;if(t!==0){for(var i=t-1;i>=0;--i){var s=e.intersectsWithObject(this._objects[i])||e.isContainedWithinObject(this._objects[i])||this._objects[i].isContainedWithinObject(e);if(s){r=i;break}}n(this._objects,e),this._objects.splice(r,0,e)}return this.renderAll&&this.renderAll()},bringForward:function(e){var t=this.getObjects(),r=t.indexOf(e),i=r;if(r!==t.length-1){for(var s=r+1,o=this._objects.length;s"},e(fabric.StaticCanvas,{EMPTY_JSON:'{"objects": [], "background": "white"}',toGrayscale:function(e){var t=e.getContext("2d"),n=t.getImageData(0,0,e.width,e.height),r=n.data,i=n.width,s=n.height,o,u,a,f;for(a=0;a0&&(t>this.targetFindTolerance?t-=this.targetFindTolerance:t=0,n>this.targetFindTolerance?n-=this.targetFindTolerance:n=0);var o=!0,u=r.getImageData(t,n,this.targetFindTolerance*2||1,this.targetFindTolerance*2||1);for(var a=3,f=u.data.length;a0?0:-n),t.ey-(r>0?0:-r),i,o),e.lineWidth=this.selectionLineWidth,e.strokeStyle=this.selectionBorderColor;if(this.selectionDashArray.length>1){var u=t.ex+a-(n>0?0:i),f=t.ey+a-(r>0?0:o);e.beginPath(),fabric.util.drawDashedLine(e,u,f,u+i,f,this.selectionDashArray),fabric.util.drawDashedLine(e,u,f+o-1,u+i,f+o-1,this.selectionDashArray),fabric.util.drawDashedLine(e,u,f,u,f+o,this.selectionDashArray),fabric.util.drawDashedLine(e,u+i-1,f,u+i-1,f+o,this.selectionDashArray),e.closePath(),e.stroke()}else e.strokeRect(t.ex+a-(n>0?0:i),t.ey+a-(r>0?0:o),i,o)},_findSelectedObjects:function(e){var t=[],n=this._groupSelector.ex,r=this._groupSelector.ey,i=n+this._groupSelector.left,s=r+this._groupSelector.top,a,f=new fabric.Point(o(n,i),o(r,s)),l=new fabric.Point(u(n,i),u(r,s));for(var c=0,h=this._objects.length;c1&&(t=new fabric.Group(t),this.setActiveGroup(t),t.saveCoords(),this.fire("selection:created",{target:t}),this.renderAll())},findTarget:function(e,t){var n,r=this.getPointer(e);if(this.controlsAboveOverlay&&this.lastRenderedObjectWithControlsAboveOverlay&&this.lastRenderedObjectWithControlsAboveOverlay.visible&&this.containsPoint(e,this.lastRenderedObjectWithControlsAboveOverlay)&&this.lastRenderedObjectWithControlsAboveOverlay._findTargetCorner(e,this._offset))return n=this.lastRenderedObjectWithControlsAboveOverlay,n;var i=this.getActiveGroup();if(i&&!t&&this.containsPoint(e,i))return n=i,n;var s=[];for(var o=this._objects.length;o--;)if(this._objects[o]&&this._objects[o].visible&&this.containsPoint(e,this._objects[o])){if(!this.perPixelTargetFind&&!this._objects[o].perPixelTargetFind){n=this._objects[o],this.relatedTarget=n;break}s[s.length]=this._objects[o]}for(var u=0,a=s.length;u"},get:function(e){return this[e]},set:function(e,t){if(typeof e=="object")for(var n in e)this._set(n,e[n]);else typeof t=="function"?this._set(e,t(this.get(e))):this._set(e,t);return this},_set:function(e,t){var n=e==="scaleX"||e==="scaleY";n&&(t=this._constrainScale(t));if(e==="scaleX"&&t<0)this.flipX=!this.flipX,t*=-1;else if(e==="scaleY"&&t<0)this.flipY=!this.flipY,t*=-1;else if(e==="width"||e==="height")this.minScaleLimit=r(Math.min(.1,1/Math.max(this.width,this.height)),2);return this[e]=t,this},toggle:function(e){var t=this.get(e);return typeof t=="boolean"&&this.set(e,!t),this},setSourcePath:function(e){return this.sourcePath=e,this},render:function(e,n){if(this.width===0||this.height===0||!this.visible)return;e.save();var r=this.transformMatrix;r&&!this.group&&e.setTransform(r[0],r[1],r[2],r[3],r[4],r[5]),n||this.transform(e),this.stroke&&(e.lineWidth=this.strokeWidth,e.lineCap=this.strokeLineCap,e.lineJoin=this.strokeLineJoin,e.miterLimit=this.strokeMiterLimit,e.strokeStyle=this.stroke.toLive?this.stroke.toLive(e):this.stroke),this.overlayFill?e.fillStyle=this.overlayFill:this.fill&&(e.fillStyle=this.fill.toLive?this.fill.toLive(e):this.fill),r&&this.group&&(e.translate(-this.group.width/2,-this.group.height/2),e.transform(r[0],r[1],r[2],r[3],r[4],r[5])),this._setShadow(e),this.clipTo&&t.util.clipContext(this,e),this._render(e,n),this.clipTo&&e.restore(),this._removeShadow(e),this.active&&!n&&(this.drawBorders(e),this.drawControls(e)),e.restore()},_setShadow:function(e){if(!this.shadow)return;e.shadowColor=this.shadow.color,e.shadowBlur=this.shadow.blur,e.shadowOffsetX=this.shadow.offsetX,e.shadowOffsetY=this.shadow.offsetY},_removeShadow:function(e){e.shadowColor="",e.shadowBlur=e.shadowOffsetX=e.shadowOffsetY=0},_renderFill:function(e){if(!this.fill)return;this.fill.toLive&&(e.save(),e.translate(-this.width/2+this.fill.offsetX||0,-this.height/2+this.fill.offsetY||0)),e.fill(),this.fill.toLive&&e.restore(),this.shadow&&!this.shadow.affectStroke&&this._removeShadow(e)},_renderStroke:function(e){if(!this.stroke)return;e.save(),this.strokeDashArray?(1&this.strokeDashArray.length&&this.strokeDashArray.push.apply(this.strokeDashArray,this.strokeDashArray),o?(e.setLineDash(this.strokeDashArray),this._stroke&&this._stroke(e)):this._renderDashedStroke&&this._renderDashedStroke(e),e.stroke()):this._stroke?this._stroke(e):e.stroke(),this._removeShadow(e),e.restore()},clone:function(e,n){return this.constructor.fromObject?this.constructor.fromObject(this.toObject(n),e):new t.Object(this.toObject(n))},cloneAsImage:function(e){var n=this.toDataURL();return t.util.loadImage(n,function(n){e&&e(new t.Image(n))}),this},toDataURL:function(e){e||(e={});var n=t.util.createCanvasElement();n.width=this.getBoundingRectWidth(),n.height=this.getBoundingRectHeight(),t.util.wrapElement(n,"div");var r=new t.Canvas(n);e.format==="jpeg"&&(r.backgroundColor="#fff");var i={active:this.get("active"),left:this.getLeft(),top:this.getTop()};this.set({active:!1,left:n.width/2,top:n.height/2}),r.add(this);var s=r.toDataURL(e);return this.set(i).setCoords(),r.dispose(),r=null,s},isType:function(e){return this.type===e},toGrayscale:function(){var e=this.get("fill");return e&&this.set("overlayFill",(new t.Color(e)).toGrayscale().toRgb()),this},complexity:function(){return 0},toJSON:function(e){return this.toObject(e)},setGradient:function(e,n){n||(n={});var r={colorStops:[]};r.type=n.type||(n.r1||n.r2?"radial":"linear"),r.coords={x1:n.x1,y1:n.y1,x2:n.x2,y2:n.y2};if(n.r1||n.r2)r.coords.r1=n.r1,r.coords.r2=n.r2;for(var i in n.colorStops){var s=new t.Color(n.colorStops[i]);r.colorStops.push({offset:i,color:s.toRgb(),opacity:s.getAlpha()})}this.set(e,t.Gradient.forObject(this,r))},setPatternFill:function(e){return this.set("fill",new t.Pattern(e))},setShadow:function(e){return this.set("shadow",new t.Shadow(e))},animate:function(){if(arguments[0]&&typeof arguments[0]=="object"){var e=[],t,n;for(t in arguments[0])e.push(t);for(var r=0,i=e.length;re.x&&n.left+n.widthe.y&&n.top+n.height=e.y&&f.d.y>=e.y)continue;f.o.x===f.d.x&&f.o.x>=e.x?(o=f.o.x,u=e.y):(n=0,r=(f.d.y-f.o.y)/(f.d.x-f.o.x),i=e.y-n*e.x,s=f.o.y-r*f.o.x,o=-(i-s)/(n-r),u=i+n*o),o>=e.x&&(a+=1);if(a===2)break}return a},getBoundingRectWidth:function(){return this.getBoundingRect().width},getBoundingRectHeight:function(){return this.getBoundingRect().height},getBoundingRect:function(){this.oCoords||this.setCoords();var e=[this.oCoords.tl.x,this.oCoords.tr.x,this.oCoords.br.x,this.oCoords.bl.x],t=fabric.util.array.min(e),n=fabric.util.array.max(e),r=Math.abs(t-n),i=[this.oCoords.tl.y,this.oCoords.tr.y,this.oCoords.br.y,this.oCoords.bl.y],s=fabric.util.array.min(i),o=fabric.util.array.max(i),u=Math.abs(s-o);return{left:t,top:s,width:r,height:u}},getWidth:function(){return this.width*this.scaleX},getHeight:function(){return this.height*this.scaleY},_constrainScale:function(e){return Math.abs(e)1?this.strokeWidth:0,n=this.padding,r=e(this.angle);this.currentWidth=(this.width+t)*this.scaleX+n*2,this.currentHeight=(this.height+t)*this.scaleY+n*2,this.currentWidth<0&&(this.currentWidth=Math.abs(this.currentWidth));var i=Math.sqrt(Math.pow(this.currentWidth/2,2)+Math.pow(this.currentHeight/2,2)),s=Math.atan(isFinite(this.currentHeight/this.currentWidth)?this.currentHeight/this.currentWidth:0),o=Math.cos(s+r)*i,u=Math.sin(s+r)*i,a=Math.sin(r),f=Math.cos(r),l=this.getCenterPoint(),c={x:l.x-o,y:l.y-u},h={x:c.x+this.currentWidth*f,y:c.y+this.currentWidth*a},p={x:h.x-this.currentHeight*a,y:h.y+this.currentHeight*f},d={x:c.x-this.currentHeight*a,y:c.y+this.currentHeight*f},v={x:c.x-this.currentHeight/2*a,y:c.y+this.currentHeight/2*f},m={x:c.x+this.currentWidth/2*f,y:c.y+this.currentWidth/2*a},g={x:h.x-this.currentHeight/2*a,y:h.y+this.currentHeight/2*f},y={x:d.x+this.currentWidth/2*f,y:d.y+this.currentWidth/2*a},b={x:m.x,y:m.y};return this.oCoords={tl:c,tr:h,br:p,bl:d,ml:v,mt:m,mr:g,mb:y,mtr:b},this._setCornerCoords&&this._setCornerCoords(),this}})}(),fabric.util.object.extend(fabric.Object.prototype,{hasStateChanged:function(){return this.stateProperties.some(function(e){return this[e]!==this.originalState[e]},this)},saveState:function(e){return this.stateProperties.forEach(function(e){this.originalState[e]=this.get(e)},this),e&&e.stateProperties&&e.stateProperties.forEach(function(e){this.originalState[e]=this.get(e)},this),this},setupState:function(){return this.originalState={},this.saveState(),this}}),function(){var e=fabric.util.getPointer,t=fabric.util.degreesToRadians;fabric.util.object.extend(fabric.Object.prototype,{_findTargetCorner:function(t,n){if(!this.hasControls||!this.active)return!1;var r=e(t,this.canvas.upperCanvasEl),i=r.x-n.left,s=r.y-n.top,o,u;for(var a in this.oCoords){if(a==="mtr"&&!this.hasRotatingPoint)continue;if(!(!this.get("lockUniScaling")||a!=="mt"&&a!=="mr"&&a!=="mb"&&a!=="ml"))continue;u=this._getImageLines(this.oCoords[a].corner),o=this._findCrossPoints({x:i,y:s},u);if(o!==0&&o%2===1)return this.__corner=a,a}return!1},_setCornerCoords:function(){var e=this.oCoords,n=t(this.angle),r=t(45-this.angle),i=Math.sqrt(2*Math.pow(this.cornerSize,2))/2,s=i*Math.cos(r),o=i*Math.sin(r),u=Math.sin(n),a=Math.cos(n);e.tl.corner={tl:{x:e.tl.x-o,y:e.tl.y-s},tr:{x:e.tl.x+s,y:e.tl.y-o},bl:{x:e.tl.x-s,y:e.tl.y+o},br:{x:e.tl.x+o,y:e.tl.y+s}},e.tr.corner={tl:{x:e.tr.x-o,y:e.tr.y-s},tr:{x:e.tr.x+s,y:e.tr.y-o},br:{x:e.tr.x+o,y:e.tr.y+s},bl:{x:e.tr.x-s,y:e.tr.y+o}},e.bl.corner={tl:{x:e.bl.x-o,y:e.bl.y-s},bl:{x:e.bl.x-s,y:e.bl.y+o},br:{x:e.bl.x+o,y:e.bl.y+s},tr:{x:e.bl.x+s,y:e.bl.y-o}},e.br.corner={tr:{x:e.br.x+s,y:e.br.y-o},bl:{x:e.br.x-s,y:e.br.y+o},br:{x:e.br.x+o,y:e.br.y+s},tl:{x:e.br.x-o,y:e.br.y-s}},e.ml.corner={tl:{x:e.ml.x-o,y:e.ml.y-s},tr:{x:e.ml.x+s,y:e.ml.y-o},bl:{x:e.ml.x-s,y:e.ml.y+o},br:{x:e.ml.x+o,y:e.ml.y+s}},e.mt.corner={tl:{x:e.mt.x-o,y:e.mt.y-s},tr:{x:e.mt.x+s,y:e.mt.y-o},bl:{x:e.mt.x-s,y:e.mt.y+o},br:{x:e.mt.x+o,y:e.mt.y+s}},e.mr.corner={tl:{x:e.mr.x-o,y:e.mr.y-s},tr:{x:e.mr.x+s,y:e.mr.y-o},bl:{x:e.mr.x-s,y:e.mr.y+o},br:{x:e.mr.x+o,y:e.mr.y+s}},e.mb.corner={tl:{x:e.mb.x-o,y:e.mb.y-s},tr:{x:e.mb.x+s,y:e.mb.y-o},bl:{x:e.mb.x-s,y:e.mb.y+o},br:{x:e.mb.x+o,y:e.mb.y+s}},e.mtr.corner={tl:{x:e.mtr.x-o+u*this.rotatingPointOffset,y:e.mtr.y-s-a*this.rotatingPointOffset},tr:{x:e.mtr.x+s+u*this.rotatingPointOffset,y:e.mtr.y-o-a*this.rotatingPointOffset},bl:{x:e.mtr.x-s+u*this.rotatingPointOffset,y:e.mtr.y+o-a*this.rotatingPointOffset},br:{x:e.mtr.x+o+u*this.rotatingPointOffset,y:e.mtr.y+s-a*this.rotatingPointOffset}}},drawBorders:function(e){if(!this.hasBorders)return this;var t=this.padding,n=t*2,r=this.strokeWidth>1?this.strokeWidth:0;e.save(),e.globalAlpha=this.isMoving?this.borderOpacityWhenMoving:1,e.strokeStyle=this.borderColor;var i=1/this._constrainScale(this.scaleX),s=1/this._constrainScale(this.scaleY);e.lineWidth=1/this.borderScaleFactor,e.scale(i,s);var o=this.getWidth(),u=this.getHeight();e.strokeRect(~~(-(o/2)-t-r/2*this.scaleX)+.5,~~(-(u/2)-t-r/2*this.scaleY)+.5,~~(o+n+r*this.scaleX),~~(u+n+r*this.scaleY));if(this.hasRotatingPoint&&!this.get("lockRotation")&&this.hasControls){var a=(this.flipY?u+r*this.scaleY+t*2:-u-r*this.scaleY-t*2)/2;e.beginPath(),e.moveTo(0,a),e.lineTo(0,a+(this.flipY?this.rotatingPointOffset:-this.rotatingPointOffset)),e.closePath(),e.stroke()}return e.restore(),this},drawControls:function(e){if(!this.hasControls)return this;var t=this.cornerSize,n=t/2,r=this.strokeWidth/2,i=-(this.width/2),s=-(this.height/2),o,u,a=t/this.scaleX,f=t/this.scaleY,l=this.padding/this.scaleX,c=this.padding/this.scaleY,h=n/this.scaleY,p=n/this.scaleX,d=(n-t)/this.scaleX,v=(n-t)/this.scaleY,m=this.height,g=this.width,y=this.transparentCorners?"strokeRect":"fillRect",b=typeof G_vmlCanvasManager!="undefined";return e.save(),e.lineWidth=1/Math.max(this.scaleX,this.scaleY),e.globalAlpha=this.isMoving?this.borderOpacityWhenMoving:1,e.strokeStyle=e.fillStyle=this.cornerColor,o=i-p-r-l,u=s-h-r-c,b||e.clearRect(o,u,a,f),e[y](o,u,a,f),o=i+g-p+r+l,u=s-h-r-c,b||e.clearRect(o,u,a,f),e[y](o,u,a,f),o=i-p-r-l,u=s+m+v+r+c,b||e.clearRect(o,u,a,f),e[y](o,u,a,f),o=i+g+d+r+l,u=s+m+v+r+c,b||e.clearRect(o,u,a,f),e[y](o,u,a,f),this.get("lockUniScaling")||(o=i+g/2-p,u=s-h-r-c,b||e.clearRect(o,u,a,f),e[y](o,u,a,f),o=i+g/2-p,u=s+m+v+r+c,b||e.clearRect(o,u,a,f),e[y](o,u,a,f),o=i+g+d+r+l,u=s+m/2-h,b||e.clearRect(o,u,a,f),e[y](o,u,a,f),o=i-p-r-l,u=s+m/2-h,b||e.clearRect(o,u,a,f),e[y](o,u,a,f)),this.hasRotatingPoint&&(o=i+g/2-p,u=this.flipY?s+m+this.rotatingPointOffset/this.scaleY-f/2+r+c:s-this.rotatingPointOffset/this.scaleY-f/2-r-c,b||e.clearRect(o,u,a,f),e[y](o,u,a,f)),e.restore(),this}})}(),function(e){"use strict";var t=e.fabric||(e.fabric={}),n=t.util.object.extend,r={x1:1,x2:1,y1:1,y2:1},i=t.StaticCanvas.supports("setLineDash");if(t.Line){t.warn("fabric.Line is already defined");return}t.Line=t.util.createClass(t.Object,{type:"line",initialize:function(e,t){t=t||{},e||(e=[0,0,0,0]),this.callSuper("initialize",t),this.set("x1",e[0]),this.set("y1",e[1]),this.set("x2",e[2]),this.set("y2",e[3]),this._setWidthHeight(t)},_setWidthHeight:function(e){e||(e={}),this.set("width",Math.abs(this.x2-this.x1)||1),this.set("height",Math.abs(this.y2-this.y1)||1),this.set("left","left"in e?e.left:Math.min(this.x1,this.x2)+this.width/2),this.set("top","top"in e?e.top:Math.min(this.y1,this.y2)+this.height/2)},_set:function(e,t){return this[e]=t,e in r&&this._setWidthHeight(),this},_render:function(e){e.beginPath();var t=this.group&&this.group.type!=="group";t&&!this.transformMatrix&&e.translate(-this.group.width/2+this.left,-this.group.height/2+this.top);if(!this.strokeDashArray||this.strokeDashArray&&i){var n=this.x1<=this.x2?-1:1,r=this.y1<=this.y2?-1:1;e.moveTo(this.width===1?0:n*this.width/2,this.height===1?0:r*this.height/2),e.lineTo(this.width===1?0:n*-1*this.width/2,this.height===1?0:r*-1*this.height/2)}e.lineWidth=this.strokeWidth;var s=e.strokeStyle;e.strokeStyle=this.stroke||e.fillStyle,this._renderStroke(e),e.strokeStyle=s},_renderDashedStroke:function(e){var n=this.width===1?0:-this.width/2,r=this.height===1?0:-this.height/2;e.beginPath(),t.util.drawDashedLine(e,n,r,-n,-r,this.strokeDashArray),e.closePath()},toObject:function(e){return n(this.callSuper("toObject",e),{x1:this.get("x1"),y1:this.get("y1"),x2:this.get("x2"),y2:this.get("y2")})},toSVG:function(){var e=[];return this.stroke&&this.stroke.toLive&&e.push(this.stroke.toSVG(this,!0)),e.push("'),e.join("")},complexity:function(){return 1}}),t.Line.ATTRIBUTE_NAMES=t.SHARED_ATTRIBUTES.concat("x1 y1 x2 y2".split(" ")),t.Line.fromElement=function(e,r){var i=t.parseAttributes(e,t.Line.ATTRIBUTE_NAMES),s=[i.x1||0,i.y1||0,i.x2||0,i.y2||0];return new t.Line(s,n(i,r))},t.Line.fromObject=function(e){var n=[e.x1,e.y1,e.x2,e.y2];return new t.Line(n,e)}}(typeof exports!="undefined"?exports:this),function(e){"use strict";function i(e){return"radius"in e&&e.radius>0}var t=e.fabric||(e.fabric={}),n=Math.PI*2,r=t.util.object.extend;if(t.Circle){t.warn("fabric.Circle is already defined.");return}t.Circle=t.util.createClass(t.Object,{type:"circle",initialize:function(e){e=e||{},this.set("radius",e.radius||0),this.callSuper("initialize",e);var t=this.get("radius")*2;this.set("width",t).set("height",t)},toObject:function(e){return r(this.callSuper("toObject",e),{radius:this.get("radius")})},toSVG:function(){var e=[];return this.fill&&this.fill.toLive&&e.push(this.fill.toSVG(this,!1)),this.stroke&&this.stroke.toLive&&e.push(this.stroke.toSVG(this,!1)),e.push("'),e.join("")},_render:function(e,t){e.beginPath(),e.globalAlpha=this.group?e.globalAlpha*this.opacity:this.opacity,e.arc(t?this.left:0,t?this.top:0,this.radius,0,n,!1),e.closePath(),this._renderFill(e),this._renderStroke(e)},getRadiusX:function(){return this.get("radius")*this.get("scaleX")},getRadiusY:function(){return this.get("radius")*this.get("scaleY")},setRadius:function(e){this.radius=e,this.set("width",e*2).set("height",e*2)},complexity:function(){return 1}}),t.Circle.ATTRIBUTE_NAMES=t.SHARED_ATTRIBUTES.concat("cx cy r".split(" ")),t.Circle.fromElement=function(e,n){n||(n={});var s=t.parseAttributes(e,t.Circle.ATTRIBUTE_NAMES);if(!i(s))throw new Error("value of `r` attribute is required and can not be negative");"left"in s&&(s.left-=n.width/2||0),"top"in s&&(s.top-=n.height/2||0);var o=new t.Circle(r(s,n));return o.cx=parseFloat(e.getAttribute("cx"))||0,o.cy=parseFloat(e.getAttribute("cy"))||0,o},t.Circle.fromObject=function(e){return new t.Circle(e)}}(typeof exports!="undefined"?exports:this),function(e){"use strict";var t=e.fabric||(e.fabric={});if(t.Triangle){t.warn("fabric.Triangle is already defined");return}t.Triangle=t.util.createClass(t.Object,{type:"triangle",initialize:function(e){e=e||{},this.callSuper("initialize",e),this.set("width",e.width||100).set("height",e.height||100)},_render:function(e){var t=this.width/2,n=this.height/2;e.beginPath(),e.moveTo(-t,n),e.lineTo(0,-n),e.lineTo(t,n),e.closePath(),this._renderFill(e),this._renderStroke(e)},_renderDashedStroke:function(e){var n=this.width/2,r=this.height/2;e.beginPath(),t.util.drawDashedLine(e,-n,r,0,-r,this.strokeDashArray),t.util.drawDashedLine(e,0,-r,n,r,this.strokeDashArray),t.util.drawDashedLine(e,n,r,-n,r,this.strokeDashArray),e.closePath()},toSVG:function(){var e=[],t=this.width/2,n=this.height/2,r=[-t+" "+n,"0 "+ -n,t+" "+n].join(",");return this.fill&&this.fill.toLive&&e.push(this.fill.toSVG(this,!0)),this.stroke&&this.stroke.toLive&&e.push(this.stroke.toSVG(this,!0)),e.push("'),e.join("")},complexity:function(){return 1}}),t.Triangle.fromObject=function(e){return new t.Triangle(e)}}(typeof exports!="undefined"?exports:this),function(e){"use strict";var t=e.fabric||(e.fabric={}),n=Math.PI*2,r=t.util.object.extend;if(t.Ellipse){t.warn("fabric.Ellipse is already defined.");return}t.Ellipse=t.util.createClass(t.Object,{type:"ellipse",rx:0,ry:0,initialize:function(e){e=e||{},this.callSuper("initialize",e),this.set("rx",e.rx||0),this.set("ry",e.ry||0),this.set("width",this.get("rx")*2),this.set("height",this.get("ry")*2)},toObject:function(e){return r(this.callSuper("toObject",e),{rx:this.get("rx"),ry:this.get("ry")})},toSVG:function(){var e=[];return this.fill&&this.fill.toLive&&e.push(this.fill.toSVG(this,!1)),this.stroke&&this.stroke.toLive&&e.push(this.stroke.toSVG(this,!1)),e.push("'),e.join("")},render:function(e,t){if(this.rx===0||this.ry===0)return;return this.callSuper("render",e,t)},_render:function(e,t){e.beginPath(),e.save(),e.globalAlpha=this.group?e.globalAlpha*this.opacity:this.opacity,this.transformMatrix&&this.group&&e.translate(this.cx,this.cy),e.transform(1,0,0,this.ry/this.rx,0,0),e.arc(t?this.left:0,t?this.top:0,this.rx,0,n,!1),this._renderFill(e),this._renderStroke(e),e.restore()},complexity:function(){return 1}}),t.Ellipse.ATTRIBUTE_NAMES=t.SHARED_ATTRIBUTES.concat("cx cy rx ry".split(" ")),t.Ellipse.fromElement=function(e,n){n||(n={});var i=t.parseAttributes(e,t.Ellipse.ATTRIBUTE_NAMES),s=i.left,o=i.top;"left"in i&&(i.left-=n.width/2||0),"top"in i&&(i.top-=n.height/2||0);var u=new t.Ellipse(r(i,n));return u.cx=s||0,u.cy=o||0,u},t.Ellipse.fromObject=function(e){return new t.Ellipse(e)}}(typeof exports!="undefined"?exports:this),function(e){"use strict";function r(e){return e.left=e.left||0,e.top=e.top||0,e}var t=e.fabric||(e.fabric={}),n=t.util.object.extend;if(t.Rect){console.warn("fabric.Rect is already defined");return}t.Rect=t.util.createClass(t.Object,{type:"rect",rx:0,ry:0,strokeDashArray:null,initialize:function(e){e=e||{},this._initStateProperties(),this.callSuper("initialize",e),this._initRxRy(),this.x=0,this.y=0},_initStateProperties:function(){this.stateProperties=this.stateProperties.concat(["rx","ry"])},_initRxRy:function(){this.rx&&!this.ry?this.ry=this.rx:this.ry&&!this.rx&&(this.rx=this.ry)},_render:function(e){var t=this.rx||0,n=this.ry||0,r=-this.width/2,i=-this.height/2,s=this.width,o=this.height,u=this.group&&this.group.type!=="group";e.beginPath(),e.globalAlpha=u?e.globalAlpha*this.opacity:this.opacity,this.transformMatrix&&u&&e.translate(this.width/2+this.x,this.height/2+this.y),!this.transformMatrix&&u&&e.translate(-this.group.width/2+this.width/2+this.x,-this.group.height/2+this.height/2+this.y),e.moveTo(r+t,i),e.lineTo(r+s-t,i),e.quadraticCurveTo(r+s,i,r+s,i+n,r+s,i+n),e.lineTo(r+s,i+o-n),e.quadraticCurveTo(r+s,i+o,r+s-t,i+o,r+s-t,i+o),e.lineTo(r+t,i+o),e.quadraticCurveTo(r,i+o,r,i+o-n,r,i+o-n),e.lineTo(r,i+n),e.quadraticCurveTo(r,i,r+t,i,r+t,i),e.closePath(),this._renderFill(e),this._renderStroke(e)},_renderDashedStroke:function(e){var n=-this.width/2,r=-this.height/2,i=this.width,s=this.height;e.beginPath(),t.util.drawDashedLine(e,n,r,n+i,r,this.strokeDashArray),t.util.drawDashedLine(e,n+i,r,n+i,r+s,this.strokeDashArray),t.util.drawDashedLine(e,n+i,r+s,n,r+s,this.strokeDashArray),t.util.drawDashedLine(e,n,r+s,n,r,this.strokeDashArray),e.closePath()},_normalizeLeftTopProperties:function(e){return"left"in e&&this.set("left",e.left+this.getWidth()/2),this.set("x",e.left||0),"top"in e&&this.set("top",e.top+this.getHeight()/2),this.set("y",e.top||0),this},toObject:function(e){return n(this.callSuper("toObject",e),{rx:this.get("rx")||0,ry:this.get("ry")||0})},toSVG:function(){var e=[];return this.fill&&this.fill.toLive&&e.push(this.fill.toSVG(this,!1)),this.stroke&&this.stroke.toLive&&e.push(this.stroke.toSVG(this,!1)),e.push("'),e.join("")},complexity:function(){return 1}}),t.Rect.ATTRIBUTE_NAMES=t.SHARED_ATTRIBUTES.concat("x y rx ry width height".split(" ")),t.Rect.fromElement=function(e,i){if(!e)return null;var s=t.parseAttributes(e,t.Rect.ATTRIBUTE_NAMES);s=r(s);var o=new t.Rect(n(i?t.util.object.clone(i):{},s));return o._normalizeLeftTopProperties(s),o},t.Rect.fromObject=function(e){return new t.Rect(e)}}(typeof exports!="undefined"?exports:this),function(e){"use strict";var t=e.fabric||(e.fabric={}),n=t.util.toFixed,r=t.util.array.min;if(t.Polyline){t.warn("fabric.Polyline is already defined");return}t.Polyline=t.util.createClass(t.Object,{type:"polyline",initialize:function(e,t,n){t=t||{},this.set("points",e),this.callSuper("initialize",t),this._calcDimensions(n)},_calcDimensions:function(e){return t.Polygon.prototype._calcDimensions.call(this,e)},toObject:function(e){return t.Polygon.prototype.toObject.call(this,e)},toSVG:function(){var e=[],t=[];for(var r=0,i=this.points.length;r'),t.join("")},_render:function(e){var t;e.beginPath(),e.moveTo(this.points[0].x,this.points[0].y);for(var n=0,r=this.points.length;n'),t.join("")},_render:function(e){var t;e.beginPath(),e.moveTo(this.points[0].x,this.points[0].y);for(var n=0,r=this.points.length;n1&&(g=Math.sqrt(g),n*=g,i*=g);var y=d/n,b=p/n,w=-p/i,E=d/i,S=y*l+b*c,x=w*l+E*c,T=y*e+b*t,N=w*e+E*t,C=(T-S)*(T-S)+(N-x)*(N-x),k=1/C-.25;k<0&&(k=0);var L=Math.sqrt(k);a===u&&(L=-L);var A=.5*(S+T)-L*(N-x),O=.5*(x+N)+L*(T-S),M=Math.atan2(x-O,S-A),_=Math.atan2(N-O,T-A),D=_-M;D<0&&a===1?D+=2*Math.PI:D>0&&a===0&&(D-=2*Math.PI);var P=Math.ceil(Math.abs(D/(Math.PI*.5+.001))),H=[];for(var B=0;B"},toObject:function(e){var t=h(this.callSuper("toObject",e),{path:this.path});return this.sourcePath&&(t.sourcePath=this.sourcePath),this.transformMatrix&&(t.transformMatrix=this.transformMatrix),t},toDatalessObject:function(e){var t=this.toObject(e);return this.sourcePath&&(t.path=this.sourcePath),delete t.sourcePath,t},toSVG:function(){var e=[],t=[];for(var n=0,r=this.path.length;n',"",""),t.join("")},complexity:function(){return this.path.length},_parsePath:function(){var e=[],n=[],r,i,s=/(-?\.\d+)|(-?\d+(\.\d+)?)/g,o,u;for(var a=0,f,l=this.path.length;ad)for(var v=1,m=f.length;v"];for(var n=0,r=e.length;n"),t.join("")},toString:function(){return"#"},isSameColor:function(){var e=this.getObjects()[0].get("fill");return this.getObjects().every(function(t){return t.get("fill")===e})},complexity:function(){return this.paths.reduce(function(e,t){return e+(t&&t.complexity?t.complexity():0)},0)},toGrayscale:function(){var e=this.paths.length;while(e--)this.paths[e].toGrayscale();return this},getObjects:function(){return this.paths}}),t.PathGroup.fromObject=function(e){var n=u(e.paths);return new t.PathGroup(n,e)}}(typeof exports!="undefined"?exports:this),function(e){"use strict";var t=e.fabric||(e.fabric={}),n=t.util.object.extend,r=t.util.array.min,i=t.util.array.max,s=t.util.array.invoke;if(t.Group)return;var o={lockMovementX:!0,lockMovementY:!0,lockRotation:!0,lockScalingX:!0,lockScalingY:!0,lockUniScaling:!0};t.Group=t.util.createClass(t.Object,t.Collection,{type:"group",initialize:function(e,t){t=t||{},this._objects=e||[];for(var r=this._objects.length;r--;)this._objects[r].group=this;this.originalState={},this.callSuper("initialize"),this._calcBounds(),this._updateObjectsCoords(),t&&n(this,t),this._setOpacityIfSame(),this.setCoords(!0),this.saveCoords()},_updateObjectsCoords:function(){var e=this.left,t=this.top;this.forEachObject(function(n){var r=n.get("left"),i=n.get("top");n.set("originalLeft",r),n.set("originalTop",i),n.set("left",r-e),n.set("top",i-t),n.setCoords(),n.__origHasControls=n.hasControls,n.hasControls=!1},this)},toString:function(){return"#"},getObjects:function(){return this._objects},addWithUpdate:function(e){return this._restoreObjectsState(),this._objects.push(e),e.group=this,this.forEachObject(function(e){e.set("active",!0),e.group=this},this),this._calcBounds(),this._updateObjectsCoords(),this},removeWithUpdate:function(e){return this._restoreObjectsState(),this.forEachObject(function(e){e.set("active",!0),e.group=this},this),this.remove(e),this._calcBounds(),this._updateObjectsCoords(),this},_onObjectAdded:function(e){e.group=this},_onObjectRemoved:function(e){delete e.group,e.set("active",!1)},delegatedProperties:{fill:!0,opacity:!0,fontFamily:!0,fontWeight:!0,fontSize:!0,fontStyle:!0,lineHeight:!0,textDecoration:!0,textShadow:!0,textAlign:!0,backgroundColor:!0},_set:function(e,t){if(e in this.delegatedProperties){var n=this._objects.length;this[e]=t;while(n--)this._objects[n].set(e,t)}else this[e]=t},toObject:function(e){return n(this.callSuper("toObject",e),{objects:s(this._objects,"toObject",e)})},render:function(e,n){if(!this.visible)return;e.save(),this.transform(e);var r=Math.max(this.scaleX,this.scaleY);this.clipTo&&t.util.clipContext(this,e);for(var i=0,s=this._objects.length;i'+e.join("")+""},get:function(e){if(e in o){if(this[e])return this[e];for(var t=0,n=this._objects.length;t','');if(this.stroke||this.strokeDashArray){var t=this.fill;this.fill=null,e.push("'),this.fill=t}return e.push(""),e.join("")},getSrc:function(){return this.getElement().src||this.getElement()._src},toString:function(){return'#'},clone:function(e,t){this.constructor.fromObject(this.toObject(t),e)},applyFilters:function(e){if(this.filters.length===0){this.setElement(this._originalImage),e&&e();return}var t=this._originalImage,n=fabric.util.createCanvasElement(),r=fabric.util.createImage(),i=this;n.width=t.width,n.height=t.height,n.getContext("2d").drawImage(t,0,0,t.width,t.height),this.filters.forEach(function(e){e&&e.applyTo(n)}),r.width=t.width,r.height=t.height;if(fabric.isLikelyNode){var s=n.toDataURL("image/png").substring(22);r.src=new Buffer(s,"base64"),i._element=r,e&&e()}else r.onload=function(){i._element=r,e&&e(),r.onload=n=t=null},r.src=n.toDataURL("image/png");return this},_render:function(e){e.drawImage(this._element,-this.width/2,-this.height/2,this.width,this.height)},_resetWidthHeight:function(){var e=this.getElement();this.set("width",e.width),this.set("height",e.height)},_initElement:function(e){this.setElement(fabric.util.getById(e)),fabric.util.addClass(this.getElement(),fabric.Image.CSS_CANVAS)},_initConfig:function(e){e||(e={}),this.setOptions(e),this._setWidthHeight(e)},_initFilters:function(e){e.filters&&e.filters.length&&(this.filters=e.filters.map(function(e){return e&&fabric.Image.filters[e.type].fromObject(e)}))},_setWidthHeight:function(e){this.width="width"in e?e.width:this.getElement().width||0,this.height="height"in e?e.height:this.getElement().height||0},complexity:function(){return 1}}),fabric.Image.CSS_CANVAS="canvas-img",fabric.Image.prototype.getSvgSrc=fabric.Image.prototype.getSrc,fabric.Image.fromObject=function(e,t){var n=fabric.document.createElement("img"),r=e.src;e.width&&(n.width=e.width),e.height&&(n.height=e.height),n.onload=function(){fabric.Image.prototype._initFilters.call(e,e);var r=new fabric.Image(n,e);t&&t(r),n=n.onload=n.onerror=null},n.onerror=function(){fabric.log("Error loading "+n.src),t&&t(null,!0),n=n.onload=n.onerror=null},n.src=r},fabric.Image.fromURL=function(e,t,n){fabric.util.loadImage(e,function(e){t(new fabric.Image(e,n))})},fabric.Image.ATTRIBUTE_NAMES=fabric.SHARED_ATTRIBUTES.concat("x y width height xlink:href".split(" ")),fabric.Image.fromElement=function(e,n,r){var i=fabric.parseAttributes(e,fabric.Image.ATTRIBUTE_NAMES);fabric.Image.fromURL(i["xlink:href"],n,t(r?fabric.util.object.clone(r):{},i))},fabric.Image.async=!0}(typeof exports!="undefined"?exports:this),fabric.util.object.extend(fabric.Object.prototype,{_getAngleValueForStraighten:function(){var e=this.getAngle()%360;return e>0?Math.round((e-1)/90)*90:Math.round(e/90)*90},straighten:function(){return this.setAngle(this._getAngleValueForStraighten()),this},fxStraighten:function(e){e=e||{};var t=function(){},n=e.onComplete||t,r=e.onChange||t,i=this;return fabric.util.animate({startValue:this.get("angle"),endValue:this._getAngleValueForStraighten(),duration:this.FX_DURATION,onChange:function(e){i.setAngle(e),r()},onComplete:function(){i.setCoords(),n()},onStart:function(){i.set("active",!1)}}),this}}),fabric.util.object.extend(fabric.StaticCanvas.prototype,{straightenObject:function(e){return e.straighten(),this.renderAll(),this},fxStraightenObject:function(e){return e.fxStraighten({onChange:this.renderAll.bind(this)}),this}}),fabric.Image.filters=fabric.Image.filters||{},fabric.Image.filters.Brightness=fabric.util.createClass({type:"Brightness",initialize:function(e){e=e||{},this.brightness=e.brightness||100},applyTo:function(e){var t=e.getContext("2d"),n=t.getImageData(0,0,e.width,e.height),r=n.data,i=this.brightness;for(var s=0,o=r.length;s=0&&N=0&&Co&&f>o&&l>o&&u(a-f)0&&(r[s]=a,r[s+1]=f,r[s+2]=l);t.putImageData(n,0,0)},toJSON:function(){return{type:this.type,color:this.color}}}),fabric.Image.filters.Tint.fromObject=function(e){return new fabric.Image.filters.Tint(e)},function(e){"use strict";var t=e.fabric||(e.fabric={}),n=t.util.object.extend,r=t.util.object.clone,i=t.util.toFixed,s=t.StaticCanvas.supports("setLineDash");if(t.Text){t.warn("fabric.Text is already defined");return}var o={fontSize:!0,fontWeight:!0,fontFamily:!0,textDecoration:!0,fontStyle:!0,lineHeight:!0,stroke:!0,strokeWidth:!0,text:!0},u=t.Object.prototype.stateProperties.concat();u.push("fontFamily","fontWeight","fontSize","path","text","textDecoration","textShadow","textAlign","fontStyle","lineHeight","backgroundColor","textBackgroundColor","useNative"),t.Text=t.util.createClass(t.Object,{type:"text",fontSize:40,fontWeight:"normal",fontFamily:"Times New Roman",textDecoration:"",textShadow:"",textAlign:"left",fontStyle:"",lineHeight:1.3,backgroundColor:"",textBackgroundColor:"",path:null,useNative:!0,stateProperties:u,initialize:function(e,t){t=t||{},this.text=e,this.__skipDimension=!0,this.setOptions(t),this.__skipDimension=!1,this._initDimensions(),this.setCoords()},_initDimensions:function(){if(this.__skipDimension)return;var e=t.util.createCanvasElement();this._render(e.getContext("2d"))},toString:function(){return"#'},_render:function(e){var t=this.group&&this.group.type!=="group";t&&!this.transformMatrix?e.translate(-this.group.width/2+this.left,-this.group.height/2+this.top):t&&this.transformMatrix&&e.translate(-this.group.width/2,-this.group.height/2),typeof Cufon=="undefined"||this.useNative===!0?this._renderViaNative(e):this._renderViaCufon(e)},_renderViaCufon:function(e){var t=Cufon.textOptions||(Cufon.textOptions={});t.left=this.left,t.top=this.top,t.context=e,t.color=this.fill;var n=this._initDummyElementForCufon();this.transform(e),Cufon.replaceElement(n,{engine:"canvas",separate:"none",fontFamily:this.fontFamily,fontWeight:this.fontWeight,textDecoration:this.textDecoration,textShadow:this.textShadow,textAlign:this.textAlign,fontStyle:this.fontStyle,lineHeight:this.lineHeight,stroke:this.stroke,strokeWidth:this.strokeWidth,backgroundColor:this.backgroundColor,textBackgroundColor:this.textBackgroundColor}),this.width=t.width,this.height=t.height,this._totalLineHeight=t.totalLineHeight,this._fontAscent=t.fontAscent,this._boundaries=t.boundaries,this._shadowOffsets=t.shadowOffsets,this._shadows=t.shadows||[],n=null,this.setCoords()},_renderViaNative:function(e){this.transform(e,t.isLikelyNode),this._setTextStyles(e);var n=this.text.split(/\r?\n/);this.width=this._getTextWidth(e,n),this.height=this._getTextHeight(e,n),this._renderTextBackground(e,n),this.textAlign!=="left"&&this.textAlign!=="justify"&&(e.save(),e.translate(this.textAlign==="center"?this.width/2:this.width,0)),e.save(),this._setTextShadow(e),this.clipTo&&t.util.clipContext(this,e),this._renderTextFill(e,n),this._renderTextStroke(e,n),this.clipTo&&e.restore(),this.textShadow&&e.restore(),e.restore(),this.textAlign!=="left"&&this.textAlign!=="justify"&&e.restore(),this._renderTextDecoration(e,n),this._setBoundaries(e,n),this._totalLineHeight=0,this.setCoords()},_setBoundaries:function(e,t){this._boundaries=[];for(var n=0,r=t.length;nn&&(n=s)}return n},_setTextShadow:function(e){if(!this.textShadow)return;var t=/\s+(-?\d+)(?:px)?\s+(-?\d+)(?:px)?\s+(\d+)(?:px)?\s*/,n=this.textShadow,r=t.exec(this.textShadow),i=n.replace(t,"");e.save(),e.shadowColor=i,e.shadowOffsetX=parseInt(r[1],10),e.shadowOffsetY=parseInt(r[2],10),e.shadowBlur=parseInt(r[3],10),this._shadows=[{blur:e.shadowBlur,color:e.shadowColor,offX:e.shadowOffsetX,offY:e.shadowOffsetY}],this._shadowOffsets=[[parseInt(e.shadowOffsetX,10),parseInt(e.shadowOffsetY,10)]]},_drawTextLine:function(e,t,n,r,i){if(this.textAlign!=="justify"){t[e](n,r,i);return}var s=t.measureText(n).width,o=this.width;if(o>s){var u=n.split(/\s+/),a=t.measureText(n.replace(/\s+/g,"")).width,f=o-a,l=u.length-1,c=f/l,h=0;for(var p=0,d=u.length;p-1&&i(this.fontSize*this.lineHeight),this.textDecoration.indexOf("line-through")>-1&&i(this.fontSize*this.lineHeight-this.fontSize/2),this.textDecoration.indexOf("overline")>-1&&i(0)},_getFontDeclaration:function(){return[t.isLikelyNode?this.fontWeight:this.fontStyle,t.isLikelyNode?this.fontStyle:this.fontWeight,this.fontSize+"px",t.isLikelyNode?'"'+this.fontFamily+'"':this.fontFamily].join(" ")},_initDummyElementForCufon:function(){var e=t.document.createElement("pre"),n=t.document.createElement("div");return n.appendChild(e),typeof G_vmlCanvasManager=="undefined"?e.innerHTML=this.text:e.innerText=this.text.replace(/\r?\n/gi,"\r"),e.style.fontSize=this.fontSize+"px",e.style.letterSpacing="normal",e},render:function(e,t){if(!this.visible)return;e.save(),this._render(e),!t&&this.active&&(this.drawBorders(e),this.drawControls(e)),e.restore()},toObject:function(e){return n(this.callSuper("toObject",e),{text:this.text,fontSize:this.fontSize,fontWeight:this.fontWeight,fontFamily:this.fontFamily,fontStyle:this.fontStyle,lineHeight:this.lineHeight,textDecoration:this.textDecoration,textShadow:this.textShadow,textAlign:this.textAlign,path:this.path,backgroundColor:this.backgroundColor,textBackgroundColor:this.textBackgroundColor,useNative:this.useNative})},toSVG:function(){var e=this.text.split(/\r?\n/),t=this.useNative?this.fontSize*this.lineHeight:-this._fontAscent-this._fontAscent/5*this.lineHeight,n=-(this.width/2),r=this.useNative?this.fontSize-1:this.height/2-e.length*this.fontSize-this._totalLineHeight,s=this._getSVGTextAndBg(t,n,e),o=this._getSVGShadows(t,e);return r+=this._fontAscent?this._fontAscent/5*this.lineHeight:0,['',s.textBgRects.join(""),"',o.join(""),s.textSpans.join(""),"",""].join("")},_getSVGShadows:function(e,n){var r=[],s,o,u,a,f=1;if(!this._shadows||!this._boundaries)return r;for(s=0,u=this._shadows.length;s",t.util.string.escapeXml(n[o]),""),f=1}else f++;return r},_getSVGTextAndBg:function(e,n,r){var s=[],o=[],u,a,f,l=1;this.backgroundColor&&this._boundaries&&o.push("');for(u=0,f=r.length;u",t.util.string.escapeXml(r[u]),""),l=1):l++;if(!this.textBackgroundColor||!this._boundaries)continue;o.push("')}return{textSpans:s,textBgRects:o}},_getFillAttributes:function(e){var n=e&&typeof e=="string"?new t.Color(e):"";return!n||!n.getSource()||n.getAlpha()===1?'fill="'+e+'"':'opacity="'+n.getAlpha()+'" fill="'+n.setAlpha(1).toRgb()+'"'},setColor:function(e){return this.set("fill",e),this},getText:function(){return this.text},_set:function(e,t){e==="fontFamily"&&this.path&&(this.path=this.path.replace(/(.*?)([^\/]*)(\.font\.js)/,"$1"+t+"$3")),this.callSuper("_set",e,t),e in o&&(this._initDimensions(),this.setCoords())},complexity:function(){return 1}}),t.Text.ATTRIBUTE_NAMES=t.SHARED_ATTRIBUTES.concat("x y font-family font-style font-weight font-size text-decoration".split(" ")),t.Text.fromElement=function(e,n){if(!e)return null;var r=t.parseAttributes(e,t.Text.ATTRIBUTE_NAMES);n=t.util.object.extend(n?t.util.object.clone(n):{},r);var i=new t.Text(e.textContent,n);return i.set({left:i.getLeft()+i.getWidth()/2,top:i.getTop()-i.getHeight()/2}),i},t.Text.fromObject=function(e){return new t.Text(e.text,r(e))},t.util.createAccessors(t.Text)}(typeof exports!="undefined"?exports:this),function(){function request(e,t,n){var r=URL.parse(e);r.port||(r.port=r.protocol.indexOf("https:")===0?443:80);var i=r.port===443?HTTPS:HTTP,s=i.request({hostname:r.hostname,port:r.port,path:r.path,method:"GET"},function(e){var r="";t&&e.setEncoding(t),e.on("end",function(){n(r)}),e.on("data",function(t){e.statusCode===200&&(r+=t)})});s.on("error",function(e){e.errno===process.ECONNREFUSED?fabric.log("ECONNREFUSED: connection refused to "+r.hostname+":"+r.port):fabric.log(e.message)}),s.end()}function request_fs(e,t){var n=require("fs"),r=n.createReadStream(e),i="";r.on("data",function(e){i+=e}),r.on("end",function(){t(i)})}if(typeof document!="undefined"&&typeof window!="undefined")return;var DOMParser=(new require("xmldom")).DOMParser,URL=require("url"),HTTP=require("http"),HTTPS=require("https"),Canvas=require("canvas"),Image=require("canvas").Image;fabric.util.loadImage=function(e,t,n){var r=function(r){i.src=new Buffer(r,"binary"),i._src=e,t&&t.call(n,i)},i=new Image;e&&e.indexOf("data")===0?(i.src=i._src=e,t&&t.call(n,i)):e&&e.indexOf("http")!==0?request_fs(e,r):e&&request(e,"binary",r)},fabric.loadSVGFromURL=function(e,t){e=e.replace(/^\n\s*/,"").replace(/\?.*$/,"").trim(),e.indexOf("http")!==0?request_fs(e,function(e){fabric.loadSVGFromString(e,t)}):request(e,"",function(e){fabric.loadSVGFromString(e,t)})},fabric.loadSVGFromString=function(e,t){var n=(new DOMParser).parseFromString(e);fabric.parseSVGDocument(n.documentElement,function(e,n){t(e,n)})},fabric.util.getScript=function(url,callback){request(url,"",function(body){eval(body),callback&&callback()})},fabric.Image.fromObject=function(e,t){fabric.util.loadImage(e.src,function(n){var r=new fabric.Image(n);r._initConfig(e),r._initFilters(e),t(r)})},fabric.createCanvasForNode=function(e,t){var n=fabric.document.createElement("canvas"),r=new Canvas(e||600,t||600);n.style={},n.width=r.width,n.height=r.height;var i=fabric.Canvas||fabric.StaticCanvas,s=new i(n);return s.contextContainer=r.getContext("2d"),s.nodeCanvas=r,s.Font=Canvas.Font,s},fabric.StaticCanvas.prototype.createPNGStream=function(){return this.nodeCanvas.createPNGStream()},fabric.StaticCanvas.prototype.createJPEGStream=function(e){return this.nodeCanvas.createJPEGStream(e)};var origSetWidth=fabric.StaticCanvas.prototype.setWidth;fabric.StaticCanvas.prototype.setWidth=function(e){return origSetWidth.call(this,e),this.nodeCanvas.width=e,this},fabric.Canvas&&(fabric.Canvas.prototype.setWidth=fabric.StaticCanvas.prototype.setWidth);var origSetHeight=fabric.StaticCanvas.prototype.setHeight;fabric.StaticCanvas.prototype.setHeight=function(e){return origSetHeight.call(this,e),this.nodeCanvas.height=e,this},fabric.Canvas&&(fabric.Canvas.prototype.setHeight=fabric.StaticCanvas.prototype.setHeight)}(); \ No newline at end of file diff --git a/dist/all.min.js.gz b/dist/all.min.js.gz index 481680204edb33bdae1e4b88bbc8597aed35c5c5..d0b39671b85181424864d1c4e68157bb17d14241 100644 GIT binary patch delta 44086 zcmV(pK=8k!`~ua10|y_A2nd|7r?Cg)6o0!ibBq`sHNx!6tP zlT<%iqHH!2se+VaM^Zog%?y4JASqkz-d$g6kpKt`fWcs9Ff(vP^Q3C-7xJiLhy))R z#{pffU<+=|TbpM1;L}sJTx4^s#AX}ntXXlJj6MTW#5|K)mOH{E{2>{fX$96PBa{fP$LV{c$vB!R`^W|TVTjm_k2e7-^x z3MExlRq}VUX|q1QVjd1}2W~HjXRG*r^%w8YN{L!{J*N}ToS?9M1MpiIk%RfYQB-Y5 z#=c)DQB0cs5Je(|GGD-UITL&xrGIuC(n2)9=V%pBrZKasu;@xnv`m~Q_wf{wt~^FG zO5s8?h7eumx0ZTb7cuAZ4!>;DuA+u9({=*4+a8gR=xl+Tq?kW8r)iWEwt7VAP7)^C=Ut_{9IkVTnDLErb|Ey z?K>iw@y+sI(cv5Qm`dk*`+uakYjxW2Uy|Ai|8=xuKm!Xbhe4TV32F(}YfEQtw6Imf43zUf46~)zxzF0JlfIQP~Ca!XtkPeQAr~K6z*TMa4toFn{X_j9vawx516i! zsebT)UAR7YU?);61Alp1aP-|9#f)CFo6XGqc`Me;J-c~?uRnqOnX0l(juluX(|^B_ zC(1o`q0n0@R6%6jB&Wk-Hs$k|z#0j`oM`gw=4 zFj80Ev39=hzw2KKPgPUoX2-AuU;5$O@VDRGW0bLDlCcTz-hVbp$3lE-o%k<(SBc4Q zJ&@zdG5UV*iwB~dF|7YY0q%Prwo_ltD?4Ssh7Nc9*S?eH>BOP#Kvy*E%cp>+P4c+Z z7fgEY8Q{_g5fV{1@4p(dGh^L9dv<1dNtk))`FQqw_HkIr<^nhad^wX^wQ=Z79C*{) zH;A6{E#nC=lz-uAc+&bz<8cl-a~P=*hJV~cO(6XG&VB3z4xYY3!m0l&bz?de=7|?H z2_M2UX{`G}3S_^q4|)yY*!&=<#gE|+Xaw;UemcO;8~8`nxj!o2`4juN?EnD!0e$(n zpQXTIIP9Y|ocu}r!n+VR!XHVcMIEKbOZF8I?o$nhuYU@LkJ3P3oGpOd>6%}JpDIeI7lpUSrm45c}5AHDTwzk>bD_g^XLVP@(WP|?&R;lJEN z%OMcX=B5l$BM1%t0)}~VylU-2z~VN1M@!q*!%n;Bv>hKhRZ2zV&R~`T`FW0; z-#%<+#VJ}z1FO!N zERG1Ll-wZ7_#6>5O2Z7qMb@gE%tQv-Q>(dzQK*%JG~wV2k{|Gk+Qv)OFYUbK5Cn2? z#B4;Ku!TxV8>=&u{B@Ehl;4vB5_y4x8-*i2xX!X^49rL%KZgwUvHn1ml>H4T!hqaz zWPeRCN`5Hh6t+P1E|jTxiKr=&x`D_;RPT#gcaAxa9)=D&Ekj;nKsroBCnL zTcBq!PE-oRgAqZfan;pup>3l>z}o)M2>>p57^IGm5H4h_3?>tRc;i#%J5bc=J7oc+ z>qCb@8DLFGWQMuX6D{UW4hKSv6SoQG@_!oy-Y|beM*vD>3H6CXpIGwj*+MAK#k6wI zcc~M>4uBW{TnVse$Q|!sOPt(xz1mRQZq)**BE~&v_4hWmX?T}wIlRlKhZpUcmX+aM zm&3c3WAq9YM<%}DqS>`qNn@ENH!qF(rT^C11W12Rd1L%|@$xm`&t)8O7vO0*{(r=Tr0J%isP1g z`ai`w-fC>@Az6#vVssxK^al$hr}#G-!{2Y)?H2uf1Ao73PX>$5ch}$0-@gqOFWT)< zi+(2f_r>4oZSK#B0P zX0W=Iy){n6zF7Imb-k|J4cimQDdir^`QWs9x>wohl=>W$A2#3tg z7xI%l;T&Lg>_KqQm(CnJQnWUW8)X=l+`vo0z~3dnZW%h@FVXaKWp@uTzyTe>Y3LJ! zsuLX-A$PW-t_e&P(R6AG-+vh2H68O3B>y}Z$LNW@lbD_s5?&SD1I0{|z<(jtn(~yz zXOE5UEhYy+L}kKDL}SA{e41JQ#cS>8 z9`V%9kYK>JkONh(GJpJbE>>G9VdMyAt28#Rz#zw>_JJ!?%&-Gq1uTMlL(7;|ZMxdc zO55cpjg5PahdZ(1Z+>+Zn{fhi^g3-yM=^*ZJXBoWLyU$|4gZ4`P++l`R;(bQO|^=! zLz}XICzj6d4Vl_QxEd$xcXw-J6NoiEIS-2>nMy4SDrJfD-hT))}dFcZr?f;9uHL2pg`C$T^p6{i7K6DGTR{+37pUFiM8`YP%9)F-G#uIG$VJdc^qyTbX=JW@{9{ z3K$9Kc5z$;jqHYYSr)AVYpUJPdK?|3;(#ls!-A0sd=s21d26TyRt9y2Kn)%SxS}1h zjo4PO=aMmRp} z9Ie-nnST|iGk?|VqK1mGg^6*^xIh*st>t8z0XYzQ`6$KUw%(pwv|^A#J>U2=H??nj zwojW8=)}la*z22`$P*041{73iOtT!`x&ZFtxUAyllZ)!*9W6z!*|cV2qm$I7avg|$N0f<4^25# zN`HVh_YP1bD_^|_9q0-k9A7`sI{?y(y4a(0tO3zaKDs3bwKKxFPv-b^#o2Un#CvIw zw2E%-F5C%=*c3xfl9+VFSF6nRLg+0R9`8m$S%D<)Y=13; zwltCfaymU8nyVgA`wh<)G}&IjLyEJkG!7L}0lm$O^K8LK!ekyL=Ca|LfiJ)>Y*r?V zId0S?KfxvzecXmAx+ngYZQr8Bz4zpH*tIdt}B7d?s!9ar;hc`k~3Z)-q z!svas-A$EcTxwVqV*CL}(2fsiw12-3{UWa;jcT>a4PWS7<+#HBjZfW1;v0dA?YugBW^#c2-lvNGH)_!>H zRzq-@5z>2rXReL_uOQneg5d>EbR?PGIL1JHDH%&cnQVm2KnpPVUaEMKxPOe9i7dI| zk*kG-E}xS&MQKuWG#Jx}r8GjC0pMtSdjP)4f5U@Ua`gMjFETG>nh_GPkLX^m3^ zN$etulj!`t&D8x2Dl87J6rcddX)+_8=QRcpsK(Cu5?_B#Kpfhl=q&rXRk>`t+VV}s z3{bVDSE5{)+1W(ZiGLRk7gmmBZNtb)g@ycq*#1+z?ZV0;WvE)Q;l#>|Xb|IYYByev zFb!^aYh@$jM8q?kTj_B+P3~eTDd*wX1`s#*^N(+ow|#hLWzVzuVoG;r6t^W=3}^O` z^61N}D8I#kh-n<&usRngb_^9{=Aog4fc&~4=Xf-V^E~4i6@SLc1@a^JukggmnJuP8 z0tllGyb|gSVf0S!+4=FWlAWB^X zZ@}aRDplwWFiM?1kFDw4h*d-jnNrwSx^BHEYa4at(2QbGFBajQDaJY-EO~+hNl|AZ z@{U4I%!hoHntxEcm|3Pg+-S0<|G$It@M$m)8=(~BmuP^&X3~b;t)@z0ANJP`Io6h& zh{Im!=UtYJciO9!d?nMp@(=;zKhY6_6kjD*P8So9x=S+MM@Mb!d}<6_t0Tj-z$R7E zA|8pmB&1YbY7RR?aYDs`g>MJ=1O@R&9x%T@J3qZR{eO6Jb^7l0>ATa5ODp%?$(!R! zE;QouBj_D^Mpd;L(RGfjgAgV8QJC6*1J`sEwtGC#MqFvj_)httcay`ko8Zy`c@!1& z$cpw8bam9hyOcJfh1XG3r$@?I4HGAGDiN(JLDY~hGA02-1f{5NCQu*~rD3Vz!&iz> z%EZMIb$?i9(Yyf;NUgvi8KhxF>sb~(<0_g2u2wj=9Y0i zyCQ^V71HD|7l?1nuILY-KhqGS)Jm{EdnV(~@_)zYS*TkZz!e!59WylXC1fIoP1AAO zQO7eb9RPYGXz@5(n!}Bu_{2E-{!j$%NPi{NgyB-@5OG4a$`Fu@ETQ60vuPd49^pwq zJXF$vkwwfSvyBP54dt$ZPl0jRkW+rHZ_}bnl=3>O+woYYP+W(M&l+QyN;4U(3D!ss zV(p03f@F{f%ZxmWM;Io)(g<)3>)?;oXUi|!0!nKayJSZ#RGnSXf_ zV;=&d=|aI57(^2z0mhshe9HQbNS<|q*-MSnV%9L&7*1S}di%C2>w2e!I)_G8TS91N zR%?uj48KZIx9f8Y6jti_G7$vYG`>p1Oa+Gb*uv;42+;U?O)oJ;??}7ZzKtMgp+DIRkbZ6Bu(ML3X!tV3^La zzhTZ6kI4%TAnsCWv+)i!5$roGBSAN?M0CJxojCEbM!_QpR>4qjYOSr2 zM!d5%ugFgOjuGtK(cN|MK(|-4d$_FLVDAZC3w^)<-)}s8KJS~B))jl~8@H8_*yZGV)Gr!j}E@e4;spz-%IK}6QI?iMsT8gtiDXMc32RnL+u5-K-OcQLDZi1w8PO6Twn+j{qNI~}; zqK;oJ>zt3I&Ww&>Xa+F8bD2)IWU^;TP? z{Fw+u$0B)zm69A{+|RHZd1+`SF*K8?RIOeAl~PnTA?{B|nWF=f(XrnIHL1db2Ja?l zsxODc-&?KnFL!#b>=x|4;ik&55KtdIeydetyyc(exuFaiF+>}TWw%2P_~gy!B(1;ID2 z-gC6=r!3kEkn*BNsAwFQZ;fqlE{!oq*9?zy*ofVB7d>}Wvw!{He1oKQ^r1^P^h z1yQAml;vUuvrya*>1JrjHxcKM_#-?9;ejsGb>$Npv&xxE;1e`r6d8(LV-5FNB3o$F z^J*WA%X{f)IH%|UKtW;Q!e3O^8b@`oo@A;by4m4^&hB!R0YI@F*5|(5QDE_M+G>q? zP{8F?;8M7b^01rZ?vj+_m&5p} z%rGNgg0)rPsgdi_u9XaRz3K`8`P#LIF|Q3E_L;^iSGH>z-6B@emW;;=$-+_P=n2tK zXWmkm$4$JV-n&NA1ZLxty>ZDz+<)%2`1-Qx>r0I3yMN*8c0h(ksDx?FE-~RyK2FD2 zpLiw(p?n0fsAsWQ{hyC|k5sM8mZ-*_69Et10JE zU^a~WzcfOZt@;36HVx3F0n=q*J^c#DiODn5A5D7|{ zq5w7k+TuuhfBVLfHxd+OyZXJipPinvh`i6p$jFFqES483+8%}Qk0=9vCFG>)AMYaJ zq<^aR?l0h|Cbf0K8+*@gRugBpql$dU`(791I?=LR180n1Vocz%i?n{7uFF+}LY~2Y zm*r(LWGr~R#)*zb6LjeIEE)U_{*N3jP-jEgBv@3t!~K1@Fp9rK-Z6T9S3Y(YFr@13;kLhro;V_kYM-kFwT9lLvJ3BFZ9nEAYC;%X)yW(iGqi zF3=J0fU?41NB+;e^ktnsavQQ7vEV*1z|s;ILJVYbBuIbU$V(|JAb)=Z zE<)HeR3+$;zt? zRz_q)9*FnJgN!y_1W@i{kyb6!e^3xBViDM|aIhUwj1(6e1;_r|w0z}7#ecVo{Hy>` zZ3BBLbfw665}|su8}A-? zf?bV~nL`WE#*Vhk1S~x`AQclm2f{(-NL8{DrI6X5NvNDCylc6ZIiJ~Nmb2Nd`;?YZ zyZl(34z&;nZB2rxJ{7wwWPf83Ghh__Q2zHXZUQ@O6#Sj^LR-mN!K2{+#xtvx&<%y- z#FAfMroYSc@)xtaw(g~o>a9*wZN(hl(?gI)BI*M6O{;u~QX6t1t1M6O2l?Y8RdBvK zxXNEStAL3Ulb@8OcW}!eo*jjkD|X@TkCR^AC38Q{$?tpEQnqEev43eV<83t=(I_jL zxaGphx#hg20TJw%9fb@OaHY1st53Vum|;h;77kqTykP~Sj7DZyxz&mYK5N>VwWhQ; zncuOBl*M7V_inPM5UhfSu$Cvt8<`3Y=6i5O_8r$b+S@2ov>MLX%dEL5XA}9u)xG%k z)lmSPN^V$FImT$K1b>gMLdL1S2wMF`^@S4K88fpx;RJAQ^{L@XtTJJ%T$P|Ni9&g{3RxaD^WDchI7& z3Io#6Et>ujy9L8XzkEsx;(J&9j~_qwQ9rl8s^B<6*BppBj(^3#jXI6QW2{F8e$v(* zpmT1D=(E2GJKHovke{(_PeuUqNZ7j;kwl_ zyhb0+4cUtWTOha-ICU7#TZ;!!AkR!d1#1c&TzXW-@1U`kFXdu4%=VHh+Re;8(Ri#N zMY=HSA2|EREq@ae?j6M0;c!yy9qeXU_Nb3P!+t;G68b}{kZME2?55?ulp)+B_bOCe z#ng7u^%m`;7E%MDamfJ}V|TOM*h0IFE8p;0ZQRYA0Z6xMr7@Dap}X#k%6Xp)4XkHyFYax1Yd^R;%~#gZt*l1IS-Vbbr+=zeWZQ)@+|~M_-FpI6gRXMj z%kpD*05?P&b{s`3_oX*?HG%6Hvu-~yt95?Qs_*G+b(Vu&y8Cp?9zy4 z$TmJ~uW4oN6b}1xg}H-u);U2kpIT~GzK@%hm@!wPm`v6@YDLMV=MLj5T?30Vhl9WD z51;;3*njpaFnBq*)WaCRhCIZGh*Brj?%;70mxoH>y@>ENxjk*RUvydPG00%vN$1mDn)vYN+78 zuc>_)<~`h5P>H$nf4p~r=7As!?d9%{dU?NcJ!eJ;h3`U&rw30X-E!v$X(hsz*eA;G zZK~6M9ajA;-ltGA?Q1tJ58vT%?_ltkr;}p$FN3FF9Xu7MS$23J!$T24^E!A+!Ppx7 z!+$A7pp*7sa9||<+hb1druoWB^w%exOgH;^n?N4Ia897>y9c71xR{#JYYgdEMp!`+ z)}1hen@n-u`0NNjbW4w zpDU|q2uM}xyl6&qof-G6)`6VumHr={R7CcJ&c0Fwi-5OA*&^sl1fj>&(UHtRUq9;9^!-vMEn()f z(eElTf4?@8bI5aB4?WuoDH^5StI6slJ2f9p7M6Cxm;@JylMc5>`pt0ca4|%+Eq|8Z zO|nEJdb3)TSzyrQcu0#rERto9tX!sCYF{*(c!ezqy1h;8>aBp4Nh?Afhmx&h-t ziWepYT85pL@O^Q)%G31UBODZfiN%cqReWvhvYQ4kS z{!SSWq#2O^-cW$%5%eX!XVLp!9g=@Z{s8L4g~q^NLzmy2pFvIUCzvv*lrC>IZA(V5!zrok|}WQ1V!q zpk+joqIhiw4NnPdi+{8Ox+{VM+*>5p>l6t=JuXxZg(&aO2WagY7tUQyKbQ-R zhmalF+_0ClXo3&-BB+Lc&?n5Ywt~;f#f<*Rs+$G+d4Rve{r#H*`0p|N_XPfX3jcit z|NRC2`z!qSxBY!C1A$DJS1|bD0QD+t$V0KW2sr}&JVpSa;^fIGGJmxvPfy1cDXnYg zZWS*%5rp;)yzh7)3+iC z!AQx+l2%RzPqp;i&xtWWBB-T{K=-fv{Z&Gy=y1_0g=UB~#eec7;0Nv7D83Bgt_1{B zxGgHZPnav4m@wMee!PgMM#SNCJV#2lfYF=t8}9`wV}y%A!%s#LnLJ!Pe0X7Ym}IUP z&PZI56&Wu4_LruW0V=7|2@;o5;gaqdQ4B)@%-9^=k>`fy)G~4FfLJPJ5igBW=1|H~ zl)_@)8QMlH%71hC!9ZygXG&=_GLrw%Om5=>cX`Wh*|mU>`o**Zv#Ul3_{TWA8ZUb9 z-7XqYzCGQYyxV=Z$4JevB}z$(PyTUzy8G^0CA!@^=NB#Hdi?r{w3}glRGpNfF-W~E zIYNc4>+s|sx2L-iR0D&aAhwVozz8`ciYBP14gv*7=zs1Q{)6lV0|Vn9dJnQeL2?%q zL;w#VHi%Kyh{}r7WQC8FbNB--!Xi)7(`0^Y9C4Q1OcO-O=fqWuEVE`(6t}pRAjjtw z;--|sFljWQ`XKV=wQMaOKDg`NWan`A34?#Udp8Jr74maPY0Bv4CU=wkDM0TMI)NP< z^a>q`dw*`FbiY%(4JYMkRO2vMK@cE^q_zcibQ>{V19Hi^rNZ-?t+;Ib$vb2nLXy#IOVZ$GZa8Htij;uRfvrJ{Nd$>MRNhzgWC zUVl<_Q6fA)1XSax4YmlQq6V`t2FsRa(t36H_uOEZU?u&Gb7@2G$wf^7pE3oV5IpmU zccp9?^Q09D6|-Z~EA*i%j*71J4+U(u-g9TY=W4xYpR&X~tGKO1XCJ=&hnAr!9hFNd z2n-OweIk~Uw-QhxgkOqmkkWsLQ3`Hu=zpF}e&RIG*YuK;;Qu0rr0BnS=NfKA;tQGQ z(M~{&k-<;L!59LAx|)u5(0A)2kpjz&gGUj>-3F(^jZUDbenZNaCtZGJAH~7pgOitE zKRhXiyWXr)(579)FlP zSj|bWAMC8@-+Yz?POhIhS+Mgce#9Q#f=6*z+3fQzeiZBoe|nqJ3V()>STyCAB5!J; zD1{D%e=2@~NJ=AV%an4i1JS|Rzq1^+ui~d_B%j($>7<{L1-()%9==h1mLzAE)M9?+wY#gdG+=C z=SN3xzJKw{(W|#W0FZEQ9Gb zA;Rgmi1eJr$`u%wa{6Yf7MzWwPf0eGk(n#wAz8wXixL) zxKm_pfmnEzFY&TBMm$#&SUyHPR||I@!CsTT9rD=9(}FnE<UYNq>Nziu%3N$vfe{ z=-uEQ`746onTm)eaImM8_}#m@7eipZdlTco5HY8Su>L*!_*;Zw@7{&@Ck%S4ULZmu zNVw1mk2fZqazaKY^`wNzpqKUn@oD~!Cc2mlQ6D-=xVscH=aO?OOzivRo^kF=TGyVe zU2Wg)cc3f!KoteOS${9M33^NV_k#YN(!X>1cR}_^mm=+lULcwdzoOlMBF_`N5<>$q z=CT(|sMY@l`!+Fdz31pj+xY$v2j_u$6i~ZPA(EF8FbPe`+2`hi)y>W7;ll@OzB;dz zv#WHxQXKY~=7}45gEw#AAK>PlU1d{<-7J6uwve9jgdlD~Vt)x(T`M6^Jc!&!De2L4 zAzYcN6%dT-FpZ}XBfzo0QC^?HC~L*gk_$#fI|4UJFsi%}$H6FXMer&LMrks=o%6#& zs>T&1E_#%OGVdapBbi}Kh`9#4n@c<-7>K)A1r!S68;G3T1--bo?=xOnE2t7T0J&_u z9qMPQ2yHJL`G3}>9=JT{g{&OA_m2>-7dO+qnl7@NWw}_Nmj(UBBk(3$Eb?WY-BgI{ zLLtP4-jK_=f7=6&>mF3DN*p;6?b@Oj^k_@O6R`n5Ef9kK&9h?)#_?~xr=*GWe-Y0$ zyT_vAqJtUU4Oq4^*C)X~%njmnkc|Qv-h{#4-tI|(8Gi=RgXB^D;r!8QAeWB;)CTJdUS-6>H^BU$W z637J0o0}yhla6c6ahWBB!-RjxvyU&zE8zVd|;nI>=X|o*^$)HVPewnFd z*iZ3=4K;<|Mz?VuzKvkrl9o0$@ndp*k=Bm?sedLUFc4^%>FVeO&inT0 zBDPu!z4yE}k3MiH8MfCtc!|}%eEXJqKU&8q%mLzsQlwwrydJ$W0|dU=Rm^rZ7)ny>}BJ#)B8T!#nMCjY#7=0oFM~t6*w>FCyP#=D>LepdE(Z(An ziGSwU{}E0%dNm9K(<{ey@e^HawKm>iIUcsyZVh z+ZOfeT4kNWRn=Wp_H~o{+)>-fRd=m@qkp&kR&U>KUB9Y5a`SG{0$snTT{0GT)w?UR z?qa<%*IhO4sv37yjkEkiKFjW^Z%=02!}>VSUA670+V)g!*+09}BiQ%gN^HtCeXVcf zg?A1($Dxt_P^9*DMI<-NKjh-iHx&QONd8Qu-cbBAv-oGC^;xxacC>Hf0HL|+^MCJX zw~@O6Lf0I+hEN)JHv2`o+vQ7^8k(7j45X^BK{lR*84Da__*` z%Dn?Bv*<30ao}@VW(-9}u^qUMaVKLz>D65YrB|MUWS}ZYp>VcMute8_IOuU6I$?i1 zzMBj~G8{D;KC78Bts*bH6zY%ZvVU{Z)P#+_xv_T$2LfNk?d>NWkA48jE>)hkl21w2 zmqN>@F!hIuXfNFRvj&8m4EOg(!$_!>@pDzvem}2IYNeEds8o38tkKg*7#TQL8pBHI zz^oE{2=01BmyeD7mM$OHQdT1^m;EUU;Dbq(%tty<3i9a5YaU5oKRakl-+z8sH_Aa> zAF>GbrcoF7ry??+3 zP0dY1+B!m!$e2M4N6uP$p9rposJTnO4&<-uAYg0&kGq>tJe2HKd+4_CKqyqn;?}CT z_2xpDLszBTdfP(<^fxsFh=0@FP3S6t+dxI!w&awak?&|=@3R}&Rf5sLPoFT1*psuy zqumSs9DLHeiL%7x>B4TM8G+>QJ$@m{7(BezK)x1%|>Lds8=nf(pj;72S80)uyUSqhMgw?J(O#9e&| zNgZ?kFJ-VbxXRF&J)#R4e2YpEtjXA^OK9o}qSXkZRVZ>MiC1ChgKK3b<^`ofN&8g3 z#-SalL5_K(M#iYc)_?Gf+9Me2wvL>(-x5Rc>$e_<&$j1M^W88sDhHb18jl*z+z#i) z10JP*BYvPacflswlb*C*t|wsy3l%S8l5AA4Oz~S00Z4G*Bsee=M4rJR{I=G5diby) z)q8t&i|sSXlat`keq7!O;z#)24`ccL*Y6+2Vr$|9xLsZF$bYlO>79Itao9)vT8pnW zeO(=hxC4q4Uu*n&_ULrfu?4A__QUq)H*1&7E-UAC3_Q(f`2jAz4z>q_GQN1@Ghv}aL-;&&w>$z*>m@dl#7&F3~b!jxzCS0Nj_CI zN*m5sFEYJ+_Pn;LH+MKrp!vDBKk-~Z&?a^r9sJwF9;?!*? zJ}_J?6bX7p>R5G!)KRSxcZv(SP;y_Cn0@Kn$cdztIe*UCi0t44t$^&jZ=qTT(6?eT3;4UDY*+MKanQf^hyOKIgN@?;Wt6M~bDJz!+$_#U}f}q?``Kh6BZ>0so zHyc<@LffvJ)vmH7e8CE(zpz4Si~a`V%)gG|*MD8?c$^ukfVk`VOL>uy-x`(E@=Gk^ z(M^Z=6_cVUG)R`nUx^IH1fr!fh4@TVgidp8r#V(>jw3(cNiU{qiVZ|B)e)H(%~*vh zt&t#-_69Q9ySn%8<1T^34tC!~_<1dD5yNopQ5T7kpm0GLzs!iu}nAW$f3iV*vwThj44>k>9{Me_#hD!-IMjvwA6#B+r_Z)ib z0)p>&TRvso`H;2MGuHPAWL;-eYU?%2jDNi2QOiu46tNv(K6E)xTS7{TP-UxHidC2N z3<)P6Tv`dDu0yuU=>&O>ti*L!>cq?`{gFjD6Lynx`GL$K`7t&~bH#RTB$6lno0XAro*4OMp1x6!%tM+A4@gCUb$<_5 zd-Hgjqu-6nKfEk z{;~us*U>Q3osaDyzBWC?SLkFSg?~R`*&9ZGuF*QnvplHI6>tROd|bv8uTo zXTyDOE_Z-CDS3C#MX!CGmkfMo*B#SqeHG2Mjamtmutpun>?EwQ>p6~tf9ONl22ky| zviqL8eXl%yue$nP-Pv~pKTeDDg}XWBYePkkNja=-G9x!SfxaCp0d4&age%0;gN+9WJ|$J3f@$INSDM(+CeATDO@a2zl{bE-!i|;t_Ya| zT}D|EDAdg&U(9#)f@1^^q9+6&tltCYc2q(d>w-guZ+pqX)2DI4e}5|aBVj&Jt1q#v z5OEKmP|j1_vUVJ7bs0AVO0XW<-S%87vowcygQX zC0_|*ctVfVWDFGMyMK?r+858(98#kc&k89iI&tmBqluQp%Om5mZMg^_;GNG%Fv>~^j;;V8;YbKk5$>$D(Wga77yxb z;e}W_nJAE1f~xxhqJmx{t8S?3KhrO)`_HP*E&6kxO4E(Cx_@2HuC}T@qjzti0aS{SN1n8 zY?1(Wt!tyRFgUclo%FUgMSH33G-xy;t{EnYise((w?Ilr`+TbbS30RQ)4PMmw03s~ zPya@1cXu!(zkk{MJi1RVAyB0P8ZkCIW}IGdMaHA*RJZ8GBAx#J_lvyo-q77P6-n5L zrZloCjjt(a#iyGAgy808c<>j<|KsZNEUUsIIuyUMXtF;->g=|)hzmiAxvhxRwMf^0 z&zlQdTx7X!CfN~lHCZGdbWh0MM|4KK69Shycq+xoW`7?`*0NA@s~mCweP10u925egxIlE+v71Nss;IhF#jQGitL)9UFVbZ1A4st#NiySZ+p2)Zn6={b^6a$Itu=@zyA&V9|~v?n-0J6|43kyiBF84ucjAu zjv2oBhC|L_>%r$=_wj%DnPmlK_$%dKN!9zQSBsw@ji&*c~ChqWjlvzH5$X>oBF zyPAsjaC#TV9czWBK zBY(Wkil0^#9NqVtKEeF@rq3;^J$<;p*H|#9pMgp2A)|;t_TWD`#4-&G ze%CAk(X^62c9ZJKKru!<#}?IO{IW{YWS*3obzUUpA&}-txl4k9QQ52ez~fPgHQVd-2#&rhD2ZY%_M_|Y| zdU|7|D-4#$$tgbelrTsM59WKp+kYj@1ZKYB)`AOHTsue`qW~BX z74$vYH+q7Ear|iLM!=mXgUvj8urHZhRfPF1{HmKlEXk`UAO4jt5DD7P9&V5 zZcx-J1(teeArR-30U<0c#8G1suKMmw_GfqBSt?=#{F~qEfskUTmp>Q zo#zrWk;oK@0M!x-0Ago2s#;PebB9wmJ_+Ff>~uK!03ZIV^5af!No0u7S#=`~%mgv* zXjG=S3R8o@Da1f_%h&^Dfrj=rs;p>|s7?^vZIu^T-H{=!^bM>Aw1SW0DfUvkknqoI^RtrX+DYKyzA0$tur_yfMV zF^@lc-pupQj`0z3pQAfZ!Z@JMzFeh3BN?C5n6(ne)O+-jw&q;ysI=?kK#c|o!kWTT z5;8S=IQ60ngM(SXf>(Bs+i_&k^iZ zv+X)I=M@+PGP8=gbGtYNH8C4F*hI)oVp7-t(b$c$Mi`M`o6dzyvBp|ou?U=#$OFO( zG|IEW-SQMeGQG&$0BsiDsAVlkj^)mA*=u!bB4FtY@+DoEB3M#CFdPUZE`~4{?g62k~{2RtPhZkzOaK;3%^xZ|FMeX@87WBwt!P3YC#ed43WIsh#XH z#{+A<$kIwsE+2J37w3?IJYu5?fF@n$>1Hg?jkEjVz73_$V}$wgx>bsM+ETSqR`Hq%%bbLLye<8koMs7oT zy($VH6gM}8tV$$0sZL={6g1PYh6ER8#3C?}Zk*ImHWRRaRiROKB9@>)oEKZrT;@hy z2-Bq1Q{i$*EQh3#br9E*trT?^mSv<`T6iYZu#Pji*BznD0JDqXbfeoD@bcac)qCA{ z5K8g`^~iq%%h?<09Coq2HN@d-Pq_UsJgCzTd|sU|%CmGqFTd_SFmKrILN#y6lgu3m zS46boR2XfOnXMDVR7g5^R4zMo1vGh)w8bH4<2J>Sk~V{+byGAN-?uWQ^8MrAN*YSq z;z`=;sWlRxx1Khv4|6?jP;RjMK@Xj3mfZs?iT3r1pZw)dsnflsegY{BRu0hD5jJzgf*FsiYAm$%z$*a!h&4u zNS)#Aa>=(Au_ffX#uqnkKpKr!@{G%9hr&Gy2Fn*F_Y8}#Dob*fyMrwk)FNpu&5RW0 zg(O?Fd$?D`@Si#ZL^mt5o4M|p*u_q_ekxj>s_lvJhlZ=qxFMM9YhjRtJ64yuto47; zTr;H@WwE9Rqb3&AVpO2b6pMPiExHI$q9dkSvCFIhBGyN53_RW4jwxSbO zVrAWPG*8Pmu!wh8wV`C{`^JfPx_yz)GNaEl3PzAqTdQq%^kj2h>EzLkxaF(=%M9;+ zKHLxBsayiHcMu~W{Kz3idk1g=O{sq%Zs2!**#L3gj3_Tl;OfI@u%P#>j@ztR_OBbt zW_)(H=*GK4+9h|2JFTwaVQ#gD#6-Mt7Fk{Y``e#>>?}zq(;jL(c8;#NRi^lXJnDqn z|4(e!egAUooLruh%!AERB-%rf#gSS5dF06@aDqJV?*!>pc%x!}aPnX%-1C1V=$b2R z>|?p3l8&+}HtxE>_dI>o@LuEv6>i`Dd8E2z1M<-ImU(M6z4h!Kww@xrw=(iv()Aj; z@gCRp)alKnpF!KVmC$}xPFhJs8(UA>{)Vp$ouI$B_xHyy_x8R%`g#XivNIeE_x4`> zNZxOPi>6tQ_Vzx0{5bgd7-;qR-nUh{yvV2Z9;DsFw2*HP${P*`vu1x5JbOeq$O4)M zstMvp(7d8fJY^m1@9$$?s*6&M$S;mB?eK4Z``aGHQfi~SL)TG{fUKUVU(At>j0^rF z%42%$X=f5(&;}RB+58*vfp@R*`}gFLK-`CE1F97!9!Y<7B{=w_8d0T^09RR7eaP5()GVu~&tB5I=WORAEaRPTczyp@ z4O1)Dx|j^~D@Ex8$~do|sT5t%&!IdPg{&WeUEC}!NN85F;o7j0E)nX689`Bp*gXht z-|6+qTZ90fK+F^R)n5nVQqrBWDEk6V!%vh=XHw2W)vI*7)?9ymvDWx^0E&*20DYAG z$?wN2f~KO+DjZqQ>?q-+n1IcGw>F9O^fhp=6o*=M&r!<(4cB+u(5zI>rm zp1VqC7x$w8)@)VF+&k}z8S#PR?&{DnR05DU8_|ENQF_lRc16ALFDM%uGv zovmGCZzbyThvt7js;!QVJt8=hj*yR5C5p=ly-IYvA}4-$?1qM=k36*SK%!M^fQs?E zWG4sPl4c+@wR|t#%HK2epJG(yYR!L-&KE`cp%xLD(n_^>SKzyN*w}Y zRj$;p&q%eNnw%jv6jS%`Rucc&ahDr0H zJFy$onU__>Y8byHXG7xK+dIclxPz|ZeVl)D)!sdK-;@;&=mr72-fpP;V2o>y-u~tx zif9`J;;erM7;ZVeAv)IcNzTzBa<8Xc40jDX`cB_|sO$Dn*LMvydX7nIW2pJDKn!Vq z&mqO#cvN;^y>B^<4b{2Dh5#b6EbC4~a3UO%s+jNWQhPqHkIL2b;w{Uov)Lr9Jo-oI z^B1l4fP_iu$@{YSpv;H3D2SlOEJZ(j zNPh&W^VW5q)zEFDrf)eQibfq>y2Pf;p!xUc5#{OZQ6)!}o#@8U4f2Vo(!QZ@p*POg za+c*ms5o!GanOo|!UEayno1~(?xeMdf@kDeM}CuS8`s{_b|eR)5J&@#5-1X_N=_zIT0$rrnn5%g z+=xg-eH6S*DU9Th(xq^Iq`-TmzE-lcym3=Q#N(ij=(L=JC>^8Kqd zaAVWG7AF-T8JTeQW{zqwvO)9;Ys{?;FC4gKgnxsMJllDVNKaPvaNuTa^qaz_Z03L4 z+^DJ6iiWn|;{I!yod>80@L>OTDqLG#i^Ji;a6DrX-^duG+ii9rE_v@uqM3*{lL7Jg z0($YH0`6%`;Jh9D|0sz0E;Wp6Lfw18KzjV4jHUSVCxxzOej~=7?ZpnYkCq90Wq zoHf)=Qgf=iv?aL5`elif_OU!eJ8FL_o+J$PEQbGGj!<3)1Vwx{DuWWY<#9gifjLu5nkM{<^pmFMZKysECnwZiSYc+Jh40G6^qZ{(vr84;@ z#DRR|>e?N&@XDkru1$tQ{mOrCZWkJe_B?&UNEm&mhT?49V>6y*=Xt?XW9oH@t|72c zVTTOy0l^tfLxFOr6ez91A^pipg8rcfyXgxmEYNo9pR06M(W$hm%;Mu(!sj`St6GhN zi{R-k(_o`{u_W;{>WJy`>$litJaxM+HD~3O;(IZzftMYcRcd914_SZJFs9v6DJrm1 z#^~e&rE*;<_3&6b66&AE7b|zP@{h*wOXSfSf!Mt<8hjRabp9!+{^`euX#%o>W7b zYRIX^(nZ1#J3*`p3FHSP!4DH8Xc(s&{&IDg5?+wNgliAAEdD>BL|pCx{aw@Fx%i&* zcjWKaO15|<`nBo}4`l=3y5{XBq*2*=qN^r^D7EQzyG`_}tWac^?;=}#0BPYU3H|A< zs1X~}WV>Woi}7k~UdzXRH4ek&W5VJ_6XVc?S?=PQH1M*)b6N1qHUnjWFk9@4gBiV# zQd*!$?Q`-T1bn(E>&!#IZ88UUV<~|q5hXs{{IIhR|N9S zb_#ybC^6|8{cA}iEcS7Gci#S?`_UNptZTcHXS4Qw;SL^u-GSf%n*1g$X5}TCy({mb zrnN}_K>BNAT?_am^4WG~qetKLYSUTUevG)T=;=`Vz0oH!F9)&~rNg;0Nr3RGL{Ldu z$h3s(^e0oH8QMBG>(K%HEQJ;KQ2qQht#ZWrfuM>yAQ5xAy)1a>SB))vd9f;f-{KB# zB>v*0ES9u?>aD88d5GLZ?(UQMUqOS~BjqJTMluA8(2t?}CL(@*SdViJ1#c{JvL_S^ zrox9z<^hF9g%QFe48N~>L#AW+v4#&KW(Jk|--e)-aHjunK+*0kEO3lSl}M3Hi#9Ko zpYJ@n+_Z!-!V>mMy8UvV@Iu?7PbFg`aAA~+#~U7hZIxIs;%{_oS=m`TY!iL>S+YgU zZR3?wiadlOZE^Gr?Yw<& zNlpblf1;6?Mj0{YEqx6)`FIVix7f`pN(^>6wHE2r?gu@ zH;?&$aw#;I{}T`)rQDA;-zQ@D}*>MGv|ldRXo zm49be7MoiUo0|bUA^&qZ+{)r`E5YHSUa{4~7v*g25u2HAs;u;%WDXZbiC7 zsOa{{a0%Ii&&X_Cr-nl7Ch2&LqNPE4isBT1usQ%^ApMsy{7c6(lc)=3Vzq>GIj~a( zowDiH`;)Gnz}_~=S=>5xVzhKHFfUoovH@4?jzPd#M~E%K1?pZa{}*$_0lYV4CGEqk za){k5Lty6ms3gagMeU+ha_CX{HKzj#OiMX!(&7LZ4E{K)Z0WG_yW!BhEv z4D?Ajl{)l$t?#0qBjl5~!oo3b?;9{J=Z52r?Vu{1aGqUZ33$CKasq2Sl9s*5KC@Ym z6=Z1a5Ll#A2sA%lsu$igM3>t;^bf+d@9YmAM}ba>ujd3XIzkDo3^lB>L@AV4|KpVM zTE4u(9pD0$H(#!*8uPMV4E}3}h&OS687Mx3cn-@$Jg~^PX;s$1qUAtODg?5`?zN+) z(ioKJ{zy>gz6uUv*l$1QSJ~o-bS}Tiiy01QqrQ&H1q>|SWAEQU(a310(Qy%Eghr`t;N`Z{i$((aHgTZny$&IKRD( z^O~DY>jvM$o$+$4;-!f?9xCKm&Afw4 z@qqd`o+m5P*t1_zlPAi5H6q2Hq^ILDSsW&WURfd%)i7e+U$I111|7HV|M(<{n1C0E zy8RMk6!yyYD_1N;)WK_DjXLN=5d@(!H3XxAO+FXY3@y(DCJbU`Gcw_7xq*h`dn;<} zRkl-s02b7FfWEa7bS7L$rq|MRjm9Vmx^oA|xS7zc7Hqo9MR0R}!@tm{yEqisXY^&G z;?88;v5LdwblRiY48;Y!WLBCQrs}73OJG#ks9$G`AX-TZ&JZptd8Lx8UuP91r{hMI zt4q_(hAdI4$hlqc*}~|YQ81*(BWkRA31j8$kzxy6Hba_>RB_5{ERT6uN0m5X`TJOY zA1gUnIk@UqOyZ<}{Hw$#WTbVmI50*l@#}b$#@Q9-iL*7PlaCLSpWh!aUvrT)>8J?d zx{5v*BPlrGd+)Alls+ecMbrn~Xn5PvQ*~S=*Z!LC>~_0HvMw*H!>U8PkH1Tc*@8Fc z>+-w>k?z~c(ppEmIhH$BS_8S8o`A_{V@EDz9W>-(a}&gWtFX6V6j?E&sP-ykLevqV z=i8u;KOBsqI2NO*{aEaSSSlimEKNdbX@ttMzbt2nGpVjyG{`(EdW?%G7OWaG)`57d zLv44mof>WcLIh@~K!NN%YU?tdQm?jRI~8$8R#=78xP1nFx|V>T?^7Ew<$;(2E8O(7 zYC=(kC+)ORXu~7^&?VC$EroD+9+tV3`_iB})K?2#) z2A*TwLpbni-8j5|!<`DchDl>J=LKlnkssjr}M<+-!W2Uojzzp&!;-Grhm;~uknfGSLf z?1k67?wDVZZh&>EnGe=hWyfx1YgO5?s%&jmc5GF4%$1F$&YPh1Q~C3l$P!kPArR1F z4YfRffEjwQ;w1rhbro>UG0VP@mVz$ zI8xv_+^V7x6}jF}B+SAT2Mo&;KmkUfE4xsCYAulD?pACl%hy1E1>=QS9meV$ zlV<7qP|z}3{!#>@=Jbt_lc|GU+_rK^o2~nFyY1J+MM1z-pD(`sTF6vZkg%~*WloYU zv8t0jZCBx{U!pHhut`1Rz8?gTJ$^XJ;+^rP+Bs{Fcv?L`IB^LG=G1x zKk5?`1oIG9{EetTaT&EOSlaT{*kk_UliDf-^R}Q@`s*G_BU@}+FO{t$hiuq94B`fs zk*#@d;oRUrW7*kEc)VZ5^LW+E;opu1+?~Hy_J>>s{rco`xU5gj-^-!yx%|7S980a! zR9`1rF2B`6um;;5YFY}cWjf=9D1Xs6eWraUTBqJxx=@Rf(>W1q)HUn*qG+k3dA2VS zmw$@-=q_tgh6Q@@E5j;A_eYC%iWR3=aSA1#nI`-3h2IQ(dU!GJ^`_Bv>OhN5Pw5Vm zYN*sOb!^0GnCEbw+}xyXBX29#7E#VUVT-7BH+%RnHH0p36r?S7T*4rw5k@lWh8JX; z(O1^&=nopb?8%*pH^%nuq0t&k=6!&K;3n(8<&~$owe*rm$pjXjzBBqxB?E3lON2MN zOAy1iJ(%phGYmfDlk90MA>4r-APi-{KaSLmS8l!X)P+$mPq!I*BY9*XBDbI86i$;l zY8`(#iH`9e=h}aGS34VpP=x1IfLuz)LW_wdE^}-%1#f7l6f_IK22 zl6f^M2127>tUe~|YY1Q4;Xu)Em7^r%<*|cXvc1+!@tGC9JS)wQy?6Dl>ADC$_hK|) zXt!4KwqBn~-F}iB;05{=l_AEN>$_%ve~W+F%Zq$5^Aw;&tmX0!H%h+omZpqeCrrMi zn%VTgNPFBbwbc?lx+{kJo{eMLPEMyt(^UD{s>zhIB_2T1x4S!!bh1PVO+PBu>sR6_ z$J5*P(|D`9YGN(j5)AEjyA=ns`~#eM0j<|yq?)I71#aynhx)*JCRLqM8(Pu>0j__+ zE}Kl?Faw;HBbVYzI0|UvBah%zd71t$)yjS;G;86sfQ(?B<+cHyM>G)OK|VUbAhLZJ z$4wu5M<9!@b>q{sx?I4#OQe9t>UzOn3-)!2Li&C3?ISQp6of`nY}IoT#XB3*1!l~OVbgjJIuxS0qj;A=WlghLwF82cZ*Uh1 z%q_xbvljWGku)i+ncz|S$P<4=HL(gJi%EB~ubXNV6j@(FW}U%jZG0}^^P~D~;Iq)5 zm+)zPH4v%4pdek&+Ga3~GA9PX; zHG|TaLe#xl2JT|(oJDUbG#eShNwtc(e``8t_1-P&EUCLu#V3FZ-m|ccP1Cde%W}h9 z|FYaX)5RB=X-_GiG}C`wt@)G@{bDoy343wV3jBx{0iN|c<}Lc{%sa;98f=e1DUTC7E^T%PS1r7i1f%MbKQwr)o> z0V7&rjCB$uhgtg5c2luT`y{ zxCp2=CIz%r*A0r^?$r}>t;V|In~j_d^LD8?+fdvJ4BHho zh+Re>t-H8~Q8s_Alyqf5U;?F#A>t^%%*vJFZ7I6WJIlL`pYC@paJejm)*HEhG!p4e zU~JbG6Cey~6NFuzULb3eO|k)f;A7Va*uPcNl&EzwWSr2454)(M>v-GR{z{+GwnOON z`93ep@>1v#j&u+RVrv@D5HgpwEtN1dFsim%W)$b+4ZVN!sg;u&_ayW!yX)*~)Ue7f zfuo=tP6*|0Jy%-uu8mvZ;ls*$+O!1=Vg%9dKsr_QYs*>B2nBw^2ctPk3eVg6{fcS4TQAgj`lV=+K*m+FDU^*+`=3_4?-w(f{Bv(i^(1lTV|t zSz2eUHKl*`%^Q|x%1CCe$T&BY%l$-nGkI6GL-#oZ?owQ*SExHGUMQ!ro+R?!q%(Iz z_?GWGc^g5lI!R0iH9==mo%^$kbP!Xdw2wDvJh`PXA#X1O=H+aXW4sL8WPsjMXqjD)d<7$6zw|-Ws_Pu=3aEv_)>snjgv2)R` z1U9{2TQT%_-F{tWF{bBPyCvkTtqHR@09NwZc(hZJ>&^)ghAl83af*W;&yf{ebTgI< z%~)#YaX$_h12zgl0>DNyH#e=Y-+Y0`r2Hu@CE=$sAv7!*F<;xhF}k^VpffJKTE+{H zIaP52VJy88XuvyTE0&nJT1Q{VFVasmY(Kdg+ zf%G7-ZzD=}KO}U(Ph5ZV+xxG7dGq|}`=5RsJ>B1r=T|Q~T;tNidID$e^{sIEU_RlH z8ZhD~IKo;m z2J-eZNWh{@XGq06d_oJ0(g&F-t$=F}zh-54lG1~8Fu{z2Wm?tPypc`g$Ay1r6ni)p zzmte4W3IERd5-LQO?ou;dhYcqU?*}oE>Yqh-Kqjg(_$wZAO>(fA!Oh>7}4J##&e@M z9ZR?8_#5w_0xR!<8e3GkWx#(5WL?O$On@p{GDO(w@=Tvt8e3GrV45!ThM+Sl z8j)E$E@_(mu+kkXB%ZvXJ0WSTPAhXC+quR8ga)j5&wN+6j4cvdB#d_fER-zJ_ zm`32Hek5hTNP*CyT3V~GJp8KAr1ipRz|uwM+h1si|GK&L0Z5J=1&lP9ScPn`1_@0nRWwT2x$?B0C>aFGzGFoOG% z4vf(+R5pMs*Q<1T5we9)Bz!=vfX>L_IESy>+gMWJFGYQY7}Zk2k`(ZhiKsZWJqbF^ z6cJOC&_m3ZKN#bO59@~yD<+v}LS{RyRn{;s?C`La(rkLCWBGqpt~XXJIGadU-lJRK^wzr&`|_6hAN?K z9(`{j2}~dI`I?oj#=0Ub4k$YTE14ZB1|~6r8?wpeK75Gh<*lyQD5cxK;9Wqe<3_53 zi+hStQI8v`94;fIg1R7tCYU;7`Sbmp#%vU#&cLOzaao5{y4@T(!=^NCUyXFO-Xw67FAk?2XPx& z4IwuLq5-5nYhh*%_YdOX)5kF)X6_IE@-zxWk==%;hiP7MRh$2b(Hz~ePL3I(;tB@)!&pE1;8+V|L;QJ> z*3w>5deVwoLW<2$s%cX)m8@apD2$2+vL>EGiWTFEeE{w+caXO5Q-#$A6v-8KBn;L~qm=ztl05OSb-vuFmg6m9Db zEy83$jAxHdAaX~t`WBFNyLR5OT{VjWIxCi_&$3Dsk$xauE! zE^y&DC{WbLvuV}GnT+a$^Ddd1LAk|LT4gJj1T1$~%|(Z23Mb2&cS8?IPlp{SYe#=Y zavvljN$X6%1gty4dq!TxCgPbL&NSG5zIeg*~gh zb_y61q58roLPD(%_wuAa97$a?fhDA4k2w}QSGMfV6e}%G+QE;%{P6ypH_u<9eDnR+ z-+%l4(OWq8`LLxTNm?jRTOJ6Z4I+O}TqE#UU;+xeOBB+hsyQO`aS#E_C`dqI&&bAz zk@5|~!NP?$gljh-ypPmR?_wMU0jqXcrIx!_dzu@!!d;mm&zRT{;R z#3m6<7O_!!tqOKZFHgl*iR`81h9mQE7du^kTgN*u4;^40_A*XF>$XmQnZOG5v2wg# zTj4$ifs(evB|F4@5j4{Ha95Tcs8$vQD^`cX#K)~A=kf62 z)=4`^vevCaunJEpxS`!*EN0v)h{6`M=k22Ork{92N5K-P7_lOR~)*@+o53WivOXq?y!lOPxc z%tYo3D)l0t&9Y(~oGQECFFS}@n?j#WBN#;K{Hf)t(9aT%i~&DqlxWY>u-`u~~rc6|82KDqv>lNsS9ap5jucFcGk-#ho06 zn1ncHW|*DB{YWpX8ML-^h$woNUKNwqsv5#wHOh6`&)W-4YliRVbaugo9x` z+*59|48GIgHQ_Kku!amKG-<@^M^m1kZ-mz{JtXT{J1fgYmKK43an;J=2aSAFv7R40 zkJDNu5#He1uHQ10CQC(T7ODbS5o(D-m`VW;Orj|TZ^{Lnp}*za*zt{)^U~uS-8M5r z!LUNivI;$xS0@Mf&tv@O3I6l+6zHgEN@HpyS}b?i20Ju3XO8Uf8qJZN{-U$Nr8?rw z1O^Z615uQWKAmuX?I3(_GeSjgjElvjg$CKWhVXG3wi23Ws~e!|rTc#@O`pW9gyuc7 zuVbWdyVwllb+LC4NjDK&%%q`xsP55HnFD2Es6fcVTlh3xBF5?tF5F&bbT>3}8V>zb zQtd8LRV0{$;9N=l?z4X zWzvd9HD@t2yOO1i> z?(Sa}yw@FnvgyA=gu{ovaG^Kw&>x8?kplvC3Vre3nxeRzghYlJBijI$&a|6%3&!nFa2Kc!n(q0~!4_ zA-fU$*D^b2Z0s{z!ypO%G@s9vIqS7>s-}1;sZbfQKv9OHs5NAPq6{Kyqg&-LA(Tbo z^9g2uE!4?}xe7&UZpoph0NaQJ5@uyRDE+Q9j zwM5=7MLWU@HZ~4@a(y*KP|IPw#=q-fe06}|2k{#Jt`BY*1YMRD$&3(^U~sGh4lqD_ z{6z(`ox*q^l6Gq5;F|F#`6)VC&;g9|d(Fq!D394!buGtVNk3W2KtA75tHQV)=*K00 z+(`y$LIY76ZSktnI;`FG>VG&Ag?PA#R(?J`WeJK>qq}8Rsx}u7jCop}lfp+0EF>&c zz6P0r#syd`^pjK6grNzbM;SG``;B-u%Y$k%AEn@fc7_fqw{ ziOph9np5K&_}n5gP4+}4;}q7Z-5Yg(YZx;2CvBQH#^tym|8c^>E-d6p<)~n=3Q&cL zRM)rh|I7wC9JNbX!eg)f$ zPs3yt#s9O=H6%eaDUwx>voYW`S&r|Ma(u~xWVdP__POK~g&?;K~?$)n2^VSZD z*EvL4;)~SqZ-qbB?>t15IT7J2*tD)O;ICx{sR2f^2ib~%em~YAoV?JkKL=oE#j7V-Z1sBax*?Fkk(F)G( ztv}A}7I0Eaus~)pCRhA?I?d|3tZJ=j7JEd@EO_?`pQS>0T!igdDyq(Zst;s=9&dUM zNDg%L`}eDS1~+ac6TTwtIQz9j1de!UTg>4mN85L!3${9PZ8)nkUO6n&PV^HgEHVdI zr2e;7GI{NQhhls3{1G>ey#w|$q}=aNs(vdKGSSlQ4ppEElD82ksj{8!P`Z9Qoo&a# zGu+`wE01yY#+jvoAv8luS`NHEbxhj5^^Hk;8p24JY)CyV`9I8b&(qXYHC+P zi8aCp`7onj7Tkz-kYxHp>zW7AY5T1XIWRddz#gi7#^^5Ua}tyKfg67)6kr+bt~1eN zw)L#yDs52hD3AO0)DG&^S%aR<2@RlbXN4h@cMr#()h54t9V>woN*{b3p7N>4bLDyV0~n@y2ci8=by^cjfQ0rM|wh za+GmufD*Plrw)Wg-7VjTgn-iLPK;b4Ie{u0*OwdMVtK0w;D+CCp^JfrirAPpb0yT zPbv(pFtozZ3PaT(=Nksu_2|{1^@;{Dj+mPid_3nQb0xy9YFC0@BUK29ph=r0TWsui zH-;>Wr{SA-Ppj>UsiEdP%LZ2nc0x@PQt!it!=QZ-y%v8zdr}Gx(Q6b18$O!46daJ0 zvN0kww{}*8L_9^9m6ugnb5XUWf`XjaJ~ZIZ2dJ~ev{@JExiMZtOHuSYx-Lh!?Bf~! zscvJUmPSlPF=r6N^iW5giKxXby#*K%qO`^Bt#GVoG~4gxjO|%bwJF(;=Sm)l+WR{Q zAdoaC3o;OLpAX8x`jAF@KA7=O?VL`NpoA4nCSjS-7Z9$DSi%C@QY9gk(x-BxJ^H$$ zud9e;rR#pNo6!x0lJu)xE~QNRVcxGHOMxCIS4rM0c1s|fR2%xS>m@^ytfkPLgNWTy zlL3Vkf447%7jmnZ7UHm2tKtkbn1-%b&B)uZ4vrt>}XN0m{@F4-7l3pF@BGu$Fy4N z@k`D9)h$iL#)ZIcm3bCOX^gULo_67-S!X&Xe`i3ZHkwc5q}rcFhm_aS4x40$`;&e< zeB=qrZsWSE7U|-^(T>CSZ1O2gu^w$W`P0^R%TU|RH0}6JsC-F<&&<#EiUuB)&fvGy z)I3kYdk)iUzk70T_VncKAqa%1&7HT6)u}tJd&%vtP`uVQeD~~P;yItz7JD{qD}nFJ ze^W}>XCerT$@>cnX-3FnB{V~st_Q5XF(*BAQ*LJ9o+PH_ik;=Sm4)iiE5xc<(*idt zl27J*3HfK$u#V%h{Mb$mx0i#c=Z*hPJcC1mNZx2uU~|K~{swKNGGFR;YbM*I8to&Y zQMahNS4F$Iq%U}n5+TMl8G%@Ijw+Jaf0r%U&NP7=576Cy3AY}gcKy|De1Tz8DVi}` zvO9-VQz>S#V&FVmV!jJ0_OUv(n?lA5C!>g(-^MdhV^>bMN}cmVch0?o4S69Fa$k1# z6yv-4iUkAJ?e49p+23ETd5yVe8)}|)*L;R~FX8lD!@q0Wh((-S30{Jxc+I)Me_P5D zZ!+VPUyVT+(tg%~%sl_bni-kq0RiY>8^C}T% z7b0RiU9)>;m4$EQ++PC;TukX^e~E`iY>%-~lq7q&S89<*O5H{HnTlZhqVQ`8M5r5lQQU%M6@y?_K)ZL;Ai%`3|T(Qq%2 z?afWfz?V=K|EkolGxci`M7qe;otMg!^mM@1>5-JGwXT;yMRK4auzpr_e@iL(idpg% zGcuRY`}bT}lE$e-(HsguQ-d;e=wV5@m6C&KX>s`EY2OSo59Whi=jc_|_IT>T*;^<1 zu6f9n@>?8%D^qSPk4Kg&k4X|FI)%g%27_fpbP}?hsE^u&m5%DwI;y-ynyPc@s2)a{ zxpaX&*kLSSYSmonnk%Q~e@fR}iJHwQovT+HjjD8`Dr(d%%dOm+&vc*9M4!*hs9Hst z9Xrzhow{w)=dk z`+Vul^QCV6r8Cc$dN?kf;keYpajEC|vT4`c=$ad+=0?}tI5juAf9A%ixzRN@y5{x@ zyVQeo>8!9zJrS4AL|p2LxO67sQcuKXrE5NG*L0$tHJ|C4&zzdibj@eR zXnQ)%`>MC%tAq!$M2sAbNI&gNW=<20)^b5Er!mE^eDTLJzU&pf%F2kLD<|}r%@n;%jxuSJe2qlse+eX5iNUHdOOPfe)W*uL zst1c>)L-?jz&-@RX^(J+89r~PG(J+>Dcna$cpi2B>X{XEE$dOgD~8Nvri-%9R87+E zLdtGkn;G6A3SXgXi>QI<*dqpi1KVWJw@v6dy>AFsP%WjFA=(~|1?@tXAZ(fE*7va# z35cC(C7pIfe;vmcNnw32t?%F9Djyd8CbGglw8DTNU`F4MY8@!C*qu&^U0f!+YY zh_timC)|jIHrTiCKU^-D!T%vGfHSTv#V}xjW$y!&a<6)O zGgvqxyiR5XUp)+k_>%ecttc@AzKwPTp6OZ3fw{SdjTfmcXZthKBiR>20|2pfjfD< zlP;<(f1Ry&B)L$Ip*WupR#EDu#sXgv$w}bHT{9s1W41;+AvnT#U%|PjKoVBVtO^5N zLZCbul5W=3Fo5A#Stx8xVM8nI>HxzI>~s|NScc*4ok*YHFdAXkYlQht=!_y6N+7lc z?pFuA%&vy8frn;t0XE>IUyJnXR(e)X<3GY3e_kPb}(rWp!KoA*_a%GFiO|I$Les*7$-O^pw>f-d&tbqvwAUwt}#Iw9fZ&Cm;e+ zRCV-Q2K{Z5V9u-;jcGdEWlU@K*0LX$BX9N9HXnCbYza{dye-#^L{M00^^3S)by!nd z>~jZ8x2fBZURjUjL#7-KIQfM#qZCwFi1B;R9$}+2lF&xG)ghaJ;4}}OA055<{>3jxuipRo{D)U>fANt0 z?)jTnU%yuoZ_!SCno_5rKhSh&r3pW(%0hECVf~yKG}KW4C)>E^4Un$0Rg;nCleZao z**VF9sv!134pfByULA;U{HrFEtuATN)^P!sZLhJ2NaN2(@?-&2#j;_ z#kl8YU-#j}L*M1LSjarO(ULrL@Ojj6P6}FYsHopIDCQZ9RtE`OFtd!~Pb%X$U=<)P zW7K+U=6r^Bl-e%Y?t!yme=uablZ2_nz0Q*96)d}*$~{L!NgXFi3o4=RI8*!$VkS2a z>nLh2s`4X|_*YehF5^F-;q?ws_y4T^b0?LhA$hE_f3ET>o9(2_jXK!MsHR(POAe@gGG9KeP(%*#nn zTlE~r6b2DbNJzNem~br<-r8gCIVr8vP_*kyorW6^I6l3Os+^yU-SbOE+;O3o$+kJd z8j*IpL#*?Z^6V{M3UKM&-*-2eSOgsBzc(7Eo@DY1lgaNEn)k_q%#fP*%}){eiPY}C zmlgMFvh_Wrj~9{sf9`uoS3b&udGD7^Tzj^@^>iHk@#YzWu{h~BggRQp!9M)ifl5Vy z!~~6l==1r9{V%{jSa+T!+ovD{u_O%>Jou|G!z%obPrl8_jlLBflZpQ|lx%BO{ncWT zFY7j~6XAC;>mu1Uq%Py6L0nw{7gVj`pD#u8sw?8@uQWf;f5B@CUOT~(S=XG+6|(a_ zVWN>{O=&)ppT8Q}wc;??b^M>k*^61lompMkf&}UyY{6>ngs-;}FnlVP?`87kGjnxi zfUiQs;6p*vSWqi!2D!L^>om%r+QY*{R~Tv)zL*EV$Mklq7CxA(+Y zkjtWNZ!A~pf3~vqiS6J9Zb4E7J^2*A{t6bF%iGK1wq@?S1V$arLYYx6?Td3VE>?Vb zj?fVs`EpLt#h0%HUoNT!#ymF}^A$4YD8PtU$a$Ca>(=S=U1yRk`-_X3D$@#w1|i`; z*i3pLN$6ktyi@4ZeR|>BVRVg3GbJ3u)&Yi5cQER2e>xnRxhGde1Y93mUI$&If}S(GZ6j#!u2FS38yZin@$GYTY=`aU|#(sau6Z^G6TK==rM``JUthRjr z+9VcQe|;teUwH_(^?G&{Tm9icpy(Yha;q&L<(xXYpXXW?tLt6WYvSCv&{e&wQt}1SpSxGaq6YJqRfY;_m%zEW4*A#2E8FAC8B@uz z>hB+VWp$s^oaLOG%egj}^F7|xie7&Iiz(%ye}7>%J|QpUDn2Ez%(>l-_6BM8nRS|5g^@}?#^3{@C==~TCtQnU z>WcDtkD9Fu22o4*jsb!Hr(HAf2&P9*ybHJw?f8gkhO2#pmydg1O8AjmM)8h=VDYpq z!^K(h$A4X7w&9hLeYxLb>W*NOEtixo&rHR3FwD8_{Co#FpN&#+UmK%wom63Mi=P>M zBg`j0^wm5X0Si@|V(ATA9*Sluv+BuReDE8Am;5i0%Q&ulm2gH`|1)cgkSq(IN|}tf zgSnN-wqbCWB5kL789Brj3TB#ku_#XSsCOuty?=-J>DM`|sX9l;paoKHJIrf7IS}YH z2K=LwP2*C=*&QMpUuiOZtC(&%D-cN=_n3Of1L7he3nC_HH>WwNPJsb~qX2m9xD~Ue zn4K*}vCU^w;^uBj+?b+Rse+V;Tz`8e97sn;+KW92#3#jm=N(uASt);pxpy z(anCb7t|PWR1|WF%Y@x=Na>?hkcmh%k`FIQp6+viS^2s}I_(pxL&(F%s``=AeY2De zkK(T5t*aNPsf_}g0J)77{{#kOTqfn={xqZ0`8)4{wwwa9Nl%BiTmlOjn^e$;caY)cNm0+P zpUi(1V8iEJvbeI5S+OKg8?RM1+i>TBBiM#Iw9g&QHnd{?cV`<~FS!3d*Wl+GlvSiu z?DihO-7=~F%@_@P{63HC7(1e$yLk|+;hOotE5Il49+>Sum*brLJhzm`wr4%c4XlT! z56o`VOr}%*iDY_}teD?`K>U>&oW~qyd69ppxt$*_#&ek4`eaU=N3Q5Gau_iMuQ6Cr zM_Wf_v^_)OkHJx+-uRx62CoWc~%L*vq+G|AE2MA!7I_=oXz5(%4u|6CgR#_c))?>SDlonaslFRT6P!7 zd^Z&OAbZ2V?nlrEg>A!#G1kaPf z)7|iG?*Rg^hw<0g zj+CrtzV0Ogq2}lBM_)e^;n>Wt`#Of3^Rt+{EMJ6broP^j(~Wa9*x!e)vCH z$MXR?89ASO`ZIzRnDq>Vp8n;oiQcnLnx669yWBO>!s;{fRuQa2BQ<|~ze>(}mlihA z+vH>a(nJp$8+}Yprn~38i`{j+gugTRJKcQ+-*4gj6@0&i?=$%R2;XP${qZ!$YX)?Mj00fbIeD8f7Qa{Z{|L$nwFH<=1wW;i-6uzrGwD#0&WEVl<3Dz<<-xS8+Xh z68{taYal!w{pB_$e^`Hbv;pZ99x|0g4Y{wl9Jj7>^UmwsBAL7Qwy6^Y_qGceWMBH0 zNy|Zu^y$U0zQ`@W3E*7oAaLWIj`PVX%?sV!z0jqoQFfKRYwL#p zCzkl1%H^7=6dp)FlS|%HS%mX>!XvUnGjSS-YY{fTm}CgYk~V+S3w(2-AK~7~<$o_O zK1}O>HtFffKa7vvz4P2K&BP+)4GqO8x?E;BnVTVI%+yriVW4nw?W6r<>t{0UUOO}s zNOc2Ugy*&@l=$%74Q{JaUynYkL_hGs`c&_8;|DMa4~j|1H?h~7jzonds|U9m?oiUZCSMfxfqg>J*1lv@kdAxQ8+88= z2z%**jI-(*vMs=$iU9j6H)fXO+p&Sqxdr$A)Vk1NoL<6XL z$V63lR&4jv9Y7kSArI2QsafGa{k?XZ>QTJeX0m_&!|jfzoKJ0eBU?U{Er)jE;#KG7 zfBf^PIo-oE7YQE%|KlXq(Wnxf6*|`80bYm!p6bYd1_Zfc4L>qJC2%{d`wU2XIL&Sx z@emDphz@)+{z*fh1|yPm@Jf$Qs0ylp=7VN~wh?ZkUQRRcm(w1kJ%#dmytjz-{KabT z^Lu}lD@vs@MUkx%|2r7b-~T5V*%G5FX>Plf#F^>&kk>i74s@K!OaI<Sj<3g$6 zktDJ}kwQTpY_S&w_M*UE6wnJe^~JfaGsvex!*TSah2&&Jjttpu*h**!dM9o`DE&2J zm?Py4H=$98v*l&FG^1W~kcj+uVEo-!3`2kEYTjfOf%cmTeo&!4I6X_?JZT51zHq34 zKBIltvoL>=FON!e*}=R#d?IEV+#i&qN=K8<5U0BDxSMs}t@>R2B213wpKjiRMsUQ8 zGc0*b0~k>iYC^%GuV-7mUfy`xa?s#UhvtqJ%PODH-kPCKhp9LMyD9oW>-1UlrjJ@L3ZXHhp#&yBE93)P3)S+PunVc~1wuS82 z33M#K$m+VYGh#TDXZ1~uU3!~2%g{CPj@cKk``(X52G{F66=}{_ne*)g$}K^rgFgR# zXe$f9JKl%(_50AH!*k#B4jIb?fl_~8Y(4fodlUzU*kgQGnqkKLo-avSYx+@aUx{F# zVn+`*hypGi`_e~xHw9uCROm?q!3=`EX8|;5@BCR{zd>#BN};C}u3PF>?OhrL{zGn$ zlD)7$c{g}B>qR&CYt{?-YZC39+gRhMU7&#(^%_bK7o=x!ZLF`86xoVuP%nS-X%-G6 z*fu#1cp)++`{R!n`63HZu$NtB({L3<1y3cpJ0H)JlWH)%NUP^fxF6|-JcVXlB(j|G z^br0-B?rre`NZsuIDkUlSyIkIEua`Yo2uGdIfXK?;6g^wpG&3ZPA zWUU{PVSJg$sPTux%khU^GLwJ%<^)STl`lPW(d`fM2e?qe_8|xKBI#Tsb;@b-y{bF= zm_5%Y4~FFMR8K+cy?Pa=(e+B)mA*q>u}DbtJDI@{k7mXePy54D*g!Jzub8+Ji9cZC z5B|g`&u$GMxw(Z6iS|sBqDPgjw4|^YVF2N<9 z^CZqAgr*YX7aNI6Ocd)xjT&Trrx%7$bl9fwr@`D){JMZY4T=utz|3AI7yT5yW}vxR zim-^}RBQy?Ec|5GVBP^r8RQ@f_g{Ws4pG)D+WqeL93+Tw);<<_w;#(C` zc6@miS=~3rdG{ORNics4POUmUuZ+s`+}!gl=&v&xw;NgvW-OrdYZ11TLTD>ae6VWSN8e5Prix&rgl%pajOA{1Q4tdGP_rJE;wM z#L7bOt2BseV!D9Oxy(>rN$<6G#4>M4lqr;qVD!JmgRQM*Bx8T>QZ$n3{HjL8S{QQa zJ{vT}c!rOHZKc$hvqsxBiwn_FYDWA0aioKBy3V<65T+24w7^@*z_r7ddkTj=qR4;Y z#m#?f+i>G(I&U0a4PtX_QGvMEtIXl8P6zT%f(+F7o|la;a?$VrR>A~?8J-8Y$O54D z_}jRx5@@%W+`NB&3wwp&h{MRj?65k|3-K&mcln* zN$Qa>;s>sg^Wqw{?=E^djvPLp^}oLOb)xoMdphq9?bZVe5&(k@yz5^=+J3rdU5ivyjhII;fPhC``_wb|uuud+-nz4zIG?z4Z$5bOl{HXFn{#2Lsi^Db+w z%Pj^KSt!zOrWJ3`pqXxv!7f;94$nY$HS@!M$!@p4DAceWXRE2{vdVys&3Ym3HDf#` zjWswU)Wsovobp>Z@Ere%R+l|nGPAd2hBK>*u{{P7wwM@-jr|d7S#nA@>maWLmsLlO z&XLUi1;Kw4{}npOCfC6{0`mukUTm3MBYyc0KvIz({B87LKQ;r7Wq|aOAio9N`ESm* zO0N;oA>?)}s@|x>+zeokEZE1hOyz7llwMH_HCl22=M)J5-+hTlzY zx05`)_rjpT(hC7(sNd%BLAr;U|c{$kDdWO^3<5nUU30 zC6y7PnmXxwB8^;jah%I=LnIrM8SQ`SIqi%jE#x!4>D3;DV3mlD{i2t95P(%0ktxpX zGBy<}%CNE=dvS(E7Ij8s7B`W#xsO;;{&rOR6mUv+P7Pi&vkYHFx0yYA z2^(Bld(qixj--~Mu?V?+Fd#qJ=ii2Eq+esBBB^j_)MTZix(M&NlZCY&7dL-15o))q zE$K4W+sQXjt9g>CJGnTogJ?92(Pq`TgPYi7c6zvmH@DGPX?lu?q>*}-%(`rP=&9pU zn`zK%m-ke_gM*&GdcA3MojS+D^fXS*@lof@5)b)Q`3n}WDk|V)d5Rj9jVE{=-J)4% z#&(>Uusdn02wdr6hH4K_Q#)Wn^!f z4t@l$eCC_B8keReMsi<{6@{}!Ry}+x?rD3&9*dpm#^8#QiIFN5W+bpVrdvJuG}^C# z$y$9lEXEDLbhus61wN2gQ*aTID{>PTH?fP_Kb0PVbck@`JrYf2!ODLIp$eHAGk=p6 z3!sFB+*jE^a$_oWWw6pRvcStR3t(9IQUPDYhOnaEv|bm}1Q^#ZCy?oM0Y2V<>@B|s z4Y3RaOi$!eN|IxiO;Qq66xUv`?lSYnK=DAR?^lv;bMxe8 zkjc!fa1hS(bM+(xcb$I*xHY0=@k_ zQ;}HOy_?OJ2L>JlQubqwsC!(fArSL;O{8rkwEJVGZ6m4E{|BfDDlYLZt|x=c*^#x2jD#cIKY&DB4Lz$x^MWsVs>U$zOwXJ}1W9P%(e&ZEzr6b=VCcV0Vb6 z>S{Xj9H#>ackh2k9Pu7vVsSPq@M1BERtvl!0b5J^* z?24VcweFK*bm6ExOoN#(YL6k)kPdHp*7JzK1QEN9{b#V0w| zQTgS~>yR%cdrNeQJ*Zb_thE*%9KgWhLL+$27b{@I2ukEEt+TJ5;LD=s&MPq!{4!7t z%3@Kbv&2|`p2V?A2PY}*V&J&B!j9J2iUodWx5j^Pn-_@qQ#cit4|n)1?!H~frR#cP z^0^nujJk~5T-%45u@%g93KhRte?KFJ)C^B&Gx2EOy8oFJVDR$o+xIV@|M=_kx3UF% zySl?Sv()A@wckvK#F;G3x9u~1xy+os?_M``{AIfIitp5AgZm?rpJa5Uvh_q^eQ@n>1NPf7Ye_IAI@ZrG&jUM=R#{cd zK(ZkLvM<(1dSyjg_n6bp$|=DU2!bg)7hrQD(g%YLJr)Cq%IvO5y&NBkbIt03p0-Iz zM<2}PCSVa__1s5l&qhAd4?+jm4Z?L4iK>4Ge`E;2APAEFZnt1jo`(UUHSAzsAe!h# z3p-2-BTY!03BHYQtN z=946rT_Q%g_^Ze-hpMH#Gi);qgcw+@>hnG&>myyN(SV~fy@GZ8wmCDvikYLzAWtr*1Yc+Isse`k;U~{IZ-AjM#G*5hi zq)q6H7`z}0pCYU4PT{-|$Lo~adEY$KC1=J5xzQB&oTJhsu*zE30#Y1>Kx#Six*^^T zq$pY+fT+$lgJ>zo(v_+wCeF75$MCl|RKE`J*BGA%jk*hR z1BN%pe}DVak8O&;!^M|7TvC6!6(grrw_S5+%*r;lRGUj6{_+c~6qu3^cXdL zeSyU(cJA;dq32QtP6pQW+OVdLJ`oXbt#F}B_K z_s1U&=i?7jo$E50A-rL{PQuyly!Rp6eG;F+j{FG!y@LPVCc3~Y_T@W zcJtoR>G-UdlqbKR?!Jyc(l6Nm@cR}2KEU5^`S)Y^eS3RxvOZ1DV)z3IlaKV{;52zf zKOUbZZxQ41;OWyoToMbLa!l_@Ie3^y#*oLnhDOGE>Lwy;AAWx-4N(PrDH8H6IyZ+s zNy1s+V6$SnzKfdp@@z*~8sKW{i*hkT=Xvt?zwr1`b)xQwsmQ{bjr+7AMR0kz8kc+! zmAH!X9xS2Vu`>wp8 z1F<2dLnsT^hk1WgCL!?~g4tkBBieh6JjZEL3MNGSIKUssqkQHn*f`ldHr^TDYJxfc z7n#!Uiw{}lJ=M+meT z&K_s}B2)Kcnb&vjL`t+B0WYY$jQ{=%2{+Xj*LTwDIthOVPg(02Xxps3gxmct-W*D} zH`Mr-?h^b9?-HL)$*E-{-N^1WLBss1B%3mSDH{EAewE=9>0Jv$rrYv%iRO4UB*Dw2 z{C#utYdT=Z)sqPO@ zH{n#z#S%^yVg)Bt`tkUGoF*5ypL;Eq^^ff4bT4VSKt6R<%luzzVYBJf-!JmJ*S3-L zvv}9X;_+mbGY$yE%AYqk2mcHBTB|h(n+T^J0z7|8Xm#Ef4xUkE;~4=Zg$pSvapQ`g z;!8xW@ydgzf7=!O@?bdJWsXWP%st=?6w};$ zy03ruX1qlGVO$rD&nGfnl=sU`<-t~SdGIftOgs~P6H46jDiKU_nwT>gmb-(;e|y|p z?GFC()!*O{91Q>Zw`gxTc>HuICz#Sa`5UJB>aSl>ny>zfX%6-u%ZbM{2Y)%hG*2Ht zp)`+&(cZye_{ZI%c!)n|JsfhqHz|k%-CFVSmMmO^JBrs@yBo)3X|k0a65-Tz8zD92G8#$nw-!+I z9W{8%g>}GcIWJc*7>TKrBlM!xYEBYZcoTCTf6Y^lQdSi@g32@9Cdx3+$Wl1Xl~~Sj zezd~K^sq4;zc8kc_7Vd>Vg!HZD&*D?42o8DH*q^?t*oAj|sc8N- z$eW6xPlL><3hC1%c|5S{TOM6ZE7)SjJj0A|Hu!PLC5vzDKraDRZFPSlq^hi~rEMyS zDwT1bS2#S=#cS1r1Q&=EBGO^^pVw2=rE3QIL&Tn81JVizHpJ==siR9H%?@=if%R>r z(XllGbfNwto)8||>+GnuHm$KBVQE{s=vs9c>7%fn$ZP{jh!C2Ed+(~ryJF9BH>@>P-U ziIbL9!9;gv?_i`q;{C{HZh55k%RN9wTODQR1->DW){`o(6IWF4+&hdb?>m4#1XI~O zO-an=!??UqOWllc_td^`0b99!mM-R|YUA;{aF;@(RV}*L(#n4jOGKbzg%Kno5rji} z^OEd_u8~>h>kEhCB9po65STEuSG@}a$Gqq{HDjcxsW%lUdAi%YZ#BJdUl5daU1OmLQyV1rM_b<7@?l5>WV*VJT1Mc8289n>TX2V13G5aFKuHY>e-Qkgz#=FJosUEU!%Nzs-4K$7<_> z;4BHN1pfi(+$UQLq{W4~7f?>{M%h_!HJ%$#IQ)a=bhT@hdoI0q_sEm!t_6n23alWc zJHdbFa@ThaV6XNs$ztk(F8IyjhqOq~vnsI-RAG*atorWg zhu4|{k3=XxZYeRF=9)>+cAm$H?f!!V@3wo+FE1lE9vmr&`rH7Nq*tpg z6qZgBR2dU%GF_J;zB5M}Jq2>zX|Ve+^rCrN*{TRJ#u9rX-P zM_DhVdM4dT_9L2oTr7$zpa8}I)3Amcvhgc(gg(4t+g)K+Pt#@g+vS4BnU@QW3c{7a zgtJ_0-s>qkqgIU~Qr5bWI3ENoTjD>$v;Y>5?+|HE-ouBb1Mjx6m+nP7ek3Q<27%%s zTboe|5sKp!CR}b1ei47Cf#F1?c+aKSXNP;(QiQh?wiBobE|>D^a6Vp zZnKD2rxQ_`9m+}t2N4kO+Ov{VUK%U!Y7N#vYG>=9bEU2vIbXKB*lxA)1JR}hhW)n} z7%Yltw1CC6NzmYOz0G!IAR1(qTWATJuWm#AT`h%Cw7ja^tM-PT^p85``!Kc(-@D8-?$P zYj`*KuR7X`gMS+WuhR?u?QtMor+a-?#*98MYr0zn?k=Z+LxzCIp=e<~HFv;08O+*_ z=B0KF25CoeWjhY*V`D;z26Ul8@nuln0C!N|L|}I{9$2cCLWF5upsQG ziWN@sgjYLBwD_r)^e76%-I7Ng1N2-I(~u8@R0) zXqb%r)*Oz_n$1>|V%&%XtZ(QnKA%prx-P3)su6z@%)TL+tFnKt;HoS^$9NikdGnel zg1nUuu#A73n~;CN(MAfuz*A_U&_&ZM>k)a>*q=Ok@_6*ueL2)3SCT;R(d=EW@!2iZImx&N> zfz^_10D%RvaxhjnV}n;OfBNyqH?O|=H(82^+*wMh zg*kr?Y2_OseDdg_E7Q30jxI{#VW3d1&x=$Fz^qlO&ZCd8p309_oGF0)`lla$#zk2r zgnFkMe|5Q-m6!PNt5U=WsHYOFss(fpSDg;S6)OVY+MzfUEN0W;LVGfb+0jBPoQ)C2 zrrnBy>}vu0@iJAR6@h`-*sE0>oaIGYtr>rN6=SoQ-Mk{&VL?yKOvboof{j(%k*0|^ zW5{K96cUZ>j65n2Fr&3%DoUtng=`%}C_5hPFkB42@xU39RgOM5|M9LMy$-n48Is7! zVE5lR42b_FJt^JUE^{Ten;~p$=m9Sp8LbcQlhM~fPT&R0q_wFQV#IXREL4FRQVf3- z__f#+VW9-X;?#`oQJMN?fY31$N2h-Q0Mv`_K#@ zYRp5;c+^rs9C?xys9*)fwoKCyL1C6jIt8Ej{E`UkBm5oLYLxt7fnpGT{_$HT^&W#i z;y!gfZjLb8u8M#E`Bkfq?2bxw9@Nlhx5!m~{#Ni_$>w?`?(cZJWWHvZwb?+PFyo`SzhNTaDvUlAOU^vKMwcn4zRq@`2Piu Kq#Q}s!2$sPd@dva delta 43465 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

2hMnw|%-1ZlHrtW7 z+hBo&DzWvl_76uzeUL=<5^x$Kih60hTwK N{C^xPnSook0s#6Q2CV=9