Your IP : 3.15.193.167


Current Path : /var/www/admin_ftp_12/data/www/httpdocs/bitrix/js/main/amcharts/4.8.5/plugins/
Upload File :
Current File : /var/www/admin_ftp_12/data/www/httpdocs/bitrix/js/main/amcharts/4.8.5/plugins/annotation.js.map

{"version":3,"sources":["webpack:///../es2015/.internal/fabric/fabric.js","webpack:///c:/Users/Antanas/Dropbox/am/Projects/typescript/amcharts4dev/node_modules/ieee754/index.js","webpack:///c:/Users/Antanas/Dropbox/am/Projects/typescript/amcharts4dev/node_modules/isarray/index.js","webpack:///../../../../../src/.internal/plugins/annotation/AnnotationIcons.ts","webpack:///../../../../../src/.internal/plugins/annotation/Annotation.ts","webpack:///./plugins/annotation.js","webpack:///external \"jsdom\"","webpack:///c:/Users/Antanas/Dropbox/am/Projects/typescript/amcharts4dev/node_modules/buffer/index.js","webpack:///c:/Users/Antanas/Dropbox/am/Projects/typescript/amcharts4dev/node_modules/base64-js/index.js"],"names":["Buffer","fabric","version","exports","document","window","HTMLDocument","Document","implementation","createHTMLDocument","virtualWindow","__webpack_require__","JSDOM","decodeURIComponent","features","FetchExternalResources","resources","jsdomImplForWrapper","implForWrapper","nodeCanvas","Canvas","DOMParser","copyGLTo2DDrawImage","gl","pipelineState","glCanvas","canvas","targetCanvas","ctx","getContext","translate","height","scale","sourceY","drawImage","width","copyGLTo2DPutImageData","dWidth","destinationWidth","dHeight","destinationHeight","numBytes","u8","Uint8Array","this","imageBuffer","u8Clamped","Uint8ClampedArray","readPixels","RGBA","UNSIGNED_BYTE","imgData","ImageData","putImageData","isTouchSupported","navigator","maxTouchPoints","isLikelyNode","SHARED_ATTRIBUTES","DPI","reNum","fontPaths","iMatrix","perfLimitSizeTotal","maxCacheSideLimit","minCacheSideLimit","charWidthsCache","textureSize","disableStyleCopyPaste","enableGLFiltering","devicePixelRatio","webkitDevicePixelRatio","mozDevicePixelRatio","browserShadowBlurConstant","arcToSegmentsCache","boundsOfCurveCache","cachesBoundsOfCurve","forceGLPutImageData","initFilterBackend","isWebglSupported","console","log","maxTextureSize","WebglFilterBackend","tileSize","Canvas2dFilterBackend","_removeEventListener","eventName","handler","__eventListeners","eventListener","indexOf","util","array","fill","observe","arguments","length","prop","on","push","stopObserving","call","fire","options","listenersForEvent","i","len","filter","value","Observable","off","trigger","Collection","_objects","add","apply","_onObjectAdded","renderOnAddRemove","requestRenderAll","insertAt","object","index","nonSplicing","objects","splice","remove","somethingRemoved","_onObjectRemoved","forEachObject","callback","context","getObjects","type","concat","o","item","isEmpty","size","contains","complexity","reduce","memo","current","CommonMethods","_setOptions","set","_initGradient","filler","property","colorStops","Gradient","_initPattern","source","Pattern","_initClipping","clipTo","functionBody","getFunctionBody","Function","_setObject","obj","_set","key","get","toggle","global","sqrt","Math","atan2","pow","abs","PiBy180","PI","PiBy2","cos","angle","sin","sign","removeFromArray","idx","getRandomInt","min","max","floor","random","degreesToRadians","degrees","radiansToDegrees","radians","rotatePoint","point","origin","subtractEquals","v","rotateVector","Point","x","y","addEquals","vector","transformPoint","p","t","ignoreOffset","makeBoundingBoxFromPoints","points","xPoints","minX","yPoints","minY","left","top","invertTransform","a","r","toFixed","number","fractionDigits","parseFloat","Number","parseUnit","fontSize","unit","exec","Text","DEFAULT_SVG_FONT_SIZE","falseFunction","getKlass","namespace","string","camelize","charAt","toUpperCase","slice","resolveNamespace","getSvgAttributes","attributes","parts","split","loadImage","url","crossOrigin","img","createImage","onLoadCallback","onload","onerror","src","substring","loadImageInDom","div","createElement","style","position","appendChild","querySelector","parentNode","removeChild","enlivenObjects","reviver","enlivenedObjects","numLoadedObjects","numTotalObjects","onLoaded","forEach","fromObject","error","enlivenPatterns","patterns","numLoadedPatterns","numPatterns","enlivenedPatterns","pattern","groupSVGElements","elements","path","centerPoint","Group","sourcePath","populateWithProperties","destination","properties","Object","prototype","toString","drawDashedLine","x2","y2","da","dx","dy","rot","dc","di","draw","save","moveTo","rotate","restore","createCanvasElement","copyCanvasElement","newCanvas","toDataURL","canvasEl","format","quality","clipContext","receiver","beginPath","clip","multiplyTransformMatrices","b","is2x2","qrDecompose","denom","scaleX","scaleY","skewX","skewY","translateX","translateY","customTransformMatrix","skewMatrixX","tan","scaleMatrix","resetObjectTransform","target","flipX","flipY","saveObjectTransform","fn","String","match","isTransparent","tolerance","_isTransparent","imageData","getImageData","l","data","parsePreserveAspectRatioAttribute","attribute","align","meetOrSlice","aspectRatioAttrs","pop","alignX","alignY","clearFabricFontCache","fontFamily","toLowerCase","limitDimsByArea","ar","maximumArea","roughWidth","perfLimitSizeY","capValue","findScaleToFit","findScaleToCover","matrixToSVG","transform","map","NUM_FRACTION_DIGITS","join","_join","Array","arcToSegments","toX","toY","rx","ry","large","sweep","rotateX","argsString","th","sinTh","cosTh","fromX","fromY","px","py","rx2","ry2","py2","px2","pl","root","s","cx","cy","cx1","cy1","mTheta","calcVectorAngle","dtheta","segments","ceil","result","mDelta","mT","th3","segmentToBezier","th2","costh2","sinth2","costh3","sinth3","ux","uy","vx","vy","ta","tb","getBoundsOfCurve","x0","y0","x1","y1","x3","y3","c","t1","t2","b2ac","sqrtb2ac","tvalues","bounds","mt","j","jlen","drawArc","fx","fy","coords","segs","segsNorm","bezierCurveTo","getBoundsOfArc","tx","ty","bound","find","byProperty","condition","k","invoke","method","args","value1","value2","extend","deep","Element","hasOwnProperty","clone","getWholeChar","str","code","charCodeAt","isNaN","next","prev","replace","character","capitalize","firstLetterOnly","escapeXml","graphemeSplit","textstring","chr","graphemes","emptyFunction","IS_DONTENUM_BUGGY","addMethods","klass","parent","superclass","constructor","returnValue","valueOf","Subclass","callSuper","methodName","parentMethod","_this","superClassMethod","createClass","initialize","shift","subclasses","couldUseAttachEvent","attachEvent","addListener","element","addEventListener","removeListener","removeEventListener","getPointer","event","scroll","getScrollLeftTop","_evt","touchProp","changedTouches","getTouchInfo","clientX","clientY","parseEl","supportsOpacity","opacity","supportsFilters","reOpacity","setOpacity","es","currentStyle","hasLayout","zoom","test","setStyle","styles","elementStyle","cssText","styleFloat","_slice","sliceCanConvertNodelists","getElementStyle","toArray","arrayLike","childNodes","err","makeElement","tagName","el","className","htmlFor","setAttribute","docElement","documentElement","body","scrollLeft","scrollTop","host","nodeType","arr","defaultView","getComputedStyle","attr","undefined","selectProp","makeElementUnselectable","onselectstart","unselectable","makeElementSelectable","getScript","headEl","getElementsByTagName","scriptEl","loading","onreadystatechange","e","readyState","getById","id","getElementById","addClass","wrapElement","wrapper","replaceChild","getElementOffset","docElem","scrollLeftTop","doc","ownerDocument","box","offset","offsetAttributes","borderLeftWidth","borderTopWidth","paddingLeft","paddingTop","parseInt","getBoundingClientRect","clientLeft","clientTop","getNodeCanvas","impl","_canvas","_image","cleanUpJsdomNode","_currentSrc","_attributes","_classList","emptyFn","request","onComplete","xhr","XMLHttpRequest","parameters","param","addParamToUrl","open","setRequestHeader","send","warn","noop","_requestAnimFrame","requestAnimationFrame","webkitRequestAnimationFrame","mozRequestAnimationFrame","oRequestAnimationFrame","msRequestAnimationFrame","setTimeout","_cancelAnimFrame","cancelAnimationFrame","clearTimeout","requestAnimFrame","animate","timestamp","time","start","Date","duration","finish","onChange","abort","easing","d","startValue","endValue","byValue","onStart","tick","ticktime","currentTime","timePerc","valuePerc","cancelAnimFrame","animateColor","fromColor","toColor","startColor","Color","getSource","endColor","begin","end","pos","color","calculateColor","colorEasing","normalize","asin","elastic","opts","easeInBounce","easeOutBounce","ease","easeInQuad","easeOutQuad","easeInOutQuad","easeInCubic","easeOutCubic","easeInOutCubic","easeInQuart","easeOutQuart","easeInOutQuart","easeInQuint","easeOutQuint","easeInOutQuint","easeInSine","easeOutSine","easeInOutSine","easeInExpo","easeOutExpo","easeInOutExpo","easeInCirc","easeOutCirc","easeInOutCirc","easeInElastic","easeOutElastic","easeInOutElastic","easeInBack","easeOutBack","easeInOutBack","easeInOutBounce","attributesMap","display","visibility","fill-opacity","fill-rule","font-family","font-size","font-style","font-weight","letter-spacing","paint-order","stroke-dasharray","stroke-dashoffset","stroke-linecap","stroke-linejoin","stroke-miterlimit","stroke-opacity","stroke-width","text-decoration","text-anchor","clip-path","clip-rule","vector-effect","colorAttributes","stroke","normalizeAttr","normalizeValue","parentAttributes","parsed","isArray","transformMatrix","parseTransformAttribute","visible","fillIndex","strokeIndex","getSvgRegex","RegExp","_getMultipleNodes","nodeNames","nodeName","nodeList","nodeArray","elementMatchesRule","selectors","firstMatching","parentMatching","selectorMatches","selector","doesSomeParentMatch","matcher","classNames","getAttribute","elementById","node","nodelist","svgValidTagNamesRegEx","svgViewBoxElementsRegEx","svgInvalidAncestorsRegEx","svgValidParentsRegEx","cssRules","gradientDefs","clipPaths","skewMatrix","matrix","commaWsp","reTransformList","reTransform","attributeValue","matrices","m","operation","translateMatrix","rotateMatrix","multiplierX","multiplierY","combinedMatrix","reViewBoxAttrValue","applyViewboxTransform","viewBoxWidth","viewBoxHeight","viewBoxAttr","widthAttr","heightAttr","preserveAspectRatio","missingViewBox","missingDimAttr","toBeParsed","parsedDim","widthDiff","heightDiff","viewboxTransform","firstChild","recursivelyParseGradientsXlink","gradient","referencedGradient","substr","hasAttribute","children","referenceClone","cloneNode","removeAttribute","parseSVGDocument","parsingOptions","attrs","xlink","el2","currentTrans","oldLength","el3","nodeValue","parseUseDirectives","svgUid","__uid","descendants","selectNodes","hasAncestorWithNodeName","getGradientDefs","getCSSRules","parseElements","instances","reFontDeclaration","parseFontDeclaration","oStyle","fontStyle","fontWeight","lineHeight","elList","parseAttributes","parentFontSize","ownAttributes","rule","getGlobalStylesForElement","parseStyleAttribute","normalizedAttr","normalizedValue","normalizedStyle","font","mergedAttrs","setAlpha","getAlpha","toRgba","_setStrokeFillOpacity","ElementsParser","parse","chunk","pair","trim","parseStyleString","parseStyleObject","parsePointsAttribute","parsedPoints","allRules","styleContents","textContent","text","ruleObj","propertyValuePairs","_rule","loadSVGFromURL","xml","responseXML","ActiveXObject","responseText","async","loadXML","results","_options","allElements","loadSVGFromString","parser","parseFromString","regexUrl","proto","numElements","createObjects","createObject","findTag","fromElement","createCallback","checkIfDone","resolveGradient","Image","_originalElement","_removeTransformMatrix","resolveClipPath","extractPropertyDefinition","storage","lastIndex","gradientDef","createClipPathCallback","container","_newObj","fillRule","clipRule","objTransformInv","gTransform","clipPath","calcTransformMatrix","setPositionByOrigin","that","scalarAdd","scalar","scalarAddEquals","subtract","scalarSubtract","scalarSubtractEquals","multiply","multiplyEquals","divide","divideEquals","eq","lt","lte","gt","gte","lerp","distanceFrom","midPointFrom","setXY","setX","setY","setFromPoint","swap","Intersection","status","appendPoint","appendPoints","intersectLineLine","a1","a2","b1","b2","uaT","ubT","uB","ua","ub","intersectLinePolygon","inter","intersectPolygonPolygon","points1","points2","intersectPolygonRectangle","r1","r2","topRight","bottomLeft","inter1","inter2","inter3","inter4","_tryParsingColor","setSource","hue2rgb","q","colorNameMap","sourceFromHex","sourceFromRgb","sourceFromHsl","_rgbToHsl","g","h","round","_source","toRgb","toHsl","hsl","toHsla","toHex","toHexa","alpha","toGrayscale","average","currentAlpha","toBlackWhite","threshold","overlayWith","otherColor","otherSource","reRGBa","reHSLa","reHex","aliceblue","antiquewhite","aqua","aquamarine","azure","beige","bisque","black","blanchedalmond","blue","blueviolet","brown","burlywood","cadetblue","chartreuse","chocolate","coral","cornflowerblue","cornsilk","crimson","cyan","darkblue","darkcyan","darkgoldenrod","darkgray","darkgrey","darkgreen","darkkhaki","darkmagenta","darkolivegreen","darkorange","darkorchid","darkred","darksalmon","darkseagreen","darkslateblue","darkslategray","darkslategrey","darkturquoise","darkviolet","deeppink","deepskyblue","dimgray","dimgrey","dodgerblue","firebrick","floralwhite","forestgreen","fuchsia","gainsboro","ghostwhite","gold","goldenrod","gray","grey","green","greenyellow","honeydew","hotpink","indianred","indigo","ivory","khaki","lavender","lavenderblush","lawngreen","lemonchiffon","lightblue","lightcoral","lightcyan","lightgoldenrodyellow","lightgray","lightgrey","lightgreen","lightpink","lightsalmon","lightseagreen","lightskyblue","lightslategray","lightslategrey","lightsteelblue","lightyellow","lime","limegreen","linen","magenta","maroon","mediumaquamarine","mediumblue","mediumorchid","mediumpurple","mediumseagreen","mediumslateblue","mediumspringgreen","mediumturquoise","mediumvioletred","midnightblue","mintcream","mistyrose","moccasin","navajowhite","navy","oldlace","olive","olivedrab","orange","orangered","orchid","palegoldenrod","palegreen","paleturquoise","palevioletred","papayawhip","peachpuff","peru","pink","plum","powderblue","purple","rebeccapurple","red","rosybrown","royalblue","saddlebrown","salmon","sandybrown","seagreen","seashell","sienna","silver","skyblue","slateblue","slategray","slategrey","snow","springgreen","steelblue","teal","thistle","tomato","turquoise","violet","wheat","white","whitesmoke","yellow","yellowgreen","fromRgb","fromSource","fromRgba","fromHsl","fromHsla","fromHex","isShortNotation","isRGBa","oColor","getColorStop","colorAlpha","keyValuePairs","_convertPercentUnitsToValues","gradientUnits","propValue","addFactor","multFactor","ellipseMatrix","scaleFactor","offsetX","offsetY","gradientTransform","addColorStop","toObject","propertiesToInclude","toSVG","markup","commonAttributes","needsSwap","withViewport","additionalTransform","sort","pathOffset","reverse","minRadius","percentageShift","colorStop","toLive","createLinearGradient","createRadialGradient","instance","colorStopEls","getLinearCoords","getRadialCoords","forObject","repeat","patternTransform","setOptions","patternSource","patternWidth","patternHeight","patternOffsetX","patternOffsetY","patternImgSrc","complete","naturalWidth","naturalHeight","createPattern","Shadow","blur","affectStroke","includeDefaultValues","nonScaling","_parseShadow","shadow","shadowStr","offsetsAndBlur","reOffsetsAndBlur","fBoxX","fBoxY","StaticCanvas","CANVAS_INIT_ERROR","Error","renderAndResetBound","renderAndReset","bind","requestRenderAllBound","_initStatic","backgroundColor","backgroundImage","overlayColor","overlayImage","stateful","controlsAboveOverlay","allowTouchScrolling","imageSmoothingEnabled","viewportTransform","backgroundVpt","overlayVpt","onBeforeScaleRotate","enableRetinaScaling","vptCoords","skipOffscreen","cb","_createLowerCanvas","_initOptions","_setImageSmoothing","interactive","_initRetinaScaling","setOverlayImage","setBackgroundImage","setBackgroundColor","setOverlayColor","calcOffset","_isRetinaScaling","getRetinaScaling","lowerCanvasEl","contextContainer","_offset","image","__setBgOverlayImage","__setBgOverlayColor","webkitImageSmoothingEnabled","mozImageSmoothingEnabled","msImageSmoothingEnabled","oImageSmoothingEnabled","_createCanvasElement","_applyCanvasStyle","getWidth","getHeight","setWidth","setDimensions","setHeight","dimensions","cssValue","cssOnly","_setBackstoreDimension","hasLostContext","backstoreOnly","_setCssDimension","_isCurrentlyDrawing","freeDrawingBrush","_setBrushStyles","upperCanvasEl","cacheCanvasEl","wrapperEl","getZoom","setViewportTransform","vpt","activeObject","_activeObject","group","setCoords","calcViewportBoundaries","zoomToPoint","before","after","setZoom","absolutePan","relativePan","getElement","setupState","clearContext","clearRect","clear","_hasITextHandlers","_mouseUpITextHandler","_iTextInstances","renderAll","canvasToDrawOn","renderCanvas","isRendering","iVpt","tl","br","tr","bl","cancelRequestedRender","_renderBackground","_renderObjects","drawControls","shouldCache","_transformDone","renderCache","forClipping","drawClipPathOnCanvas","_renderOverlay","globalCompositeOperation","zoomX","zoomY","_cacheCanvas","cacheTranslationX","cacheTranslationY","render","_renderBackgroundOrOverlay","needsVpt","lineTo","closePath","fillStyle","getCenter","centerObjectH","_centerObject","getCenterPoint","centerObjectV","centerObject","center","viewportCenterObject","vpCenter","getVpCenter","viewportCenterObjectH","viewportCenterObjectV","toDatalessJSON","toDatalessObject","_toObjectMethod","_toObjects","_toObject","__serializeBgOverlay","excludeFromExport","originalValue","bgImage","overlay","background","svgViewportTransformation","_setSVGPreamble","_setSVGHeader","clipPathId","_setSVGBgOverlayColor","_setSVGBgOverlayImage","_setSVGObjects","suppressPreamble","encoding","viewBox","createSVGFontFacesMarkup","createSVGRefElementsMarkup","createSVGClipPathMarkup","toClipPathSVG","shouldTransform","row","rowIndex","charIndex","fontList","_setSVGObject","finalWidth","finalHeight","sendToBack","objs","activeSelection","unshift","bringToFront","sendBackwards","intersecting","newIdx","objsMoved","_findNewLowerIndex","intersectsWithObject","isContainedWithinObject","bringForward","_findNewUpperIndex","dispose","DataURLExporter","EMPTY_JSON","supports","setLineDash","toJSON","createPNGStream","createJPEGStream","BaseBrush","strokeLineCap","strokeLineJoin","strokeMiterLimit","strokeDashArray","setShadow","contextTop","strokeStyle","lineWidth","lineCap","miterLimit","lineJoin","_saveAndTransform","_setShadow","shadowColor","shadowBlur","shadowOffsetX","shadowOffsetY","needsFullRender","_resetShadow","PencilBrush","decimate","_points","_drawSegment","p1","p2","midPoint","quadraticCurveTo","onMouseDown","pointer","_isMainEvent","_prepareForDrawing","_captureDrawingPath","_render","onMouseMove","oldEnd","onMouseUp","_finalizeAndAddPath","_reset","_addPoint","pointerPoint","convertPointsToSVGPath","multSignX","multSignY","manyPoints","createPath","pathData","Path","strokeWidth","decimatePoints","distance","adjustedDistance","lastPoint","newPoints","CircleBrush","drawDot","addPoint","dot","arc","radius","originalRenderOnAddRemove","circles","circle","Circle","originX","originY","circleRadius","circleColor","SprayBrush","density","dotWidth","dotWidthVariance","randomOpacity","optimizeOverlapping","sprayChunks","addSprayChunk","sprayChunkPoints","rects","ilen","sprayChunk","rect","Rect","_getOptimizedRects","uniqueRects","uniqueRectsArray","globalAlpha","fillRect","PatternBrush","getPatternSrc","patternCanvas","patternCtx","getPatternSrcFunction","getPattern","topLeft","_getLeftTopCoords","supportLineDash","_initInteractive","_createCacheCanvas","uniScaleTransform","uniScaleKey","centeredScaling","centeredRotation","centeredKey","altActionKey","selection","selectionKey","altSelectionKey","selectionColor","selectionDashArray","selectionBorderColor","selectionLineWidth","selectionFullyContained","hoverCursor","moveCursor","defaultCursor","freeDrawingCursor","rotationCursor","notAllowedCursor","containerClass","perPixelTargetFind","targetFindTolerance","skipTargetFind","isDrawingMode","preserveObjectStacking","snapAngle","snapThreshold","stopContextMenu","fireRightClick","fireMiddleClick","_currentTransform","_groupSelector","_initWrapperElement","_createUpperCanvas","_initEventListeners","_chooseObjectsToRender","objsToRender","activeGroupObjects","activeObjects","getActiveObjects","contextTopDirty","renderTopLayer","_drawSelection","renderTop","_resetCurrentTransform","original","_shouldCenterTransform","mouseXSign","mouseYSign","containsPoint","xy","_normalizePointer","_findTargetCorner","invertedM","vptPointer","restorePointerVpt","isTargetTransparent","normalizedPointer","targetRelativeX","targetRelativeY","_cacheContext","contextCache","originalColor","selectionBackgroundColor","_renderControls","hasBorders","transparentCorners","_isSelectionKeyPressed","_shouldClearSelection","evented","selectable","centerTransform","action","altKey","_getOriginFromCorner","corner","_getActionFromCorner","alreadySelected","_setupCurrentTransform","ex","ey","lastX","lastY","theta","shiftKey","_beforeTransform","_translateObject","newLeft","newTop","moveX","moveY","_changeSkewTransformOrigin","mouseMove","by","origins","0","skew","originA","originB","flipSign","skewSign","_skewObject","skewed","lockSkewingX","lockSkewingY","actualMouseByOrigin","constraintPosition","actualMouseByCenter","toLocalPoint","lastMouseByCenter","dim","_getTransformedDimensions","translateToOriginPoint","_setObjectSkew","localMouse","_dim","newValue","newDim","dimNoSkew","otherBy","_otherBy","_by","newDimMouse","atan","_scaleObject","lockScalingX","lockScalingY","lockScalingFlip","scaled","_setLocalMouse","_setObjectScale","forbidScalingX","forbidScalingY","changeX","changeY","newScaleX","newScaleY","Textbox","w","getMinWidth","_scaleObjectEqually","_flipObject","dist","lastDist","signX","signY","padding","_rotateObject","lockRotation","lastAngle","curAngle","hasRotated","rightAngleLocked","leftAngleLocked","setCursor","cursor","groupSelector","aleft","atop","_setLineDash","strokeRect","findTarget","skipGroup","activeTarget","activeTargetSubs","aObjects","targets","_searchPossibleTargets","_checkTarget","globalPointer","isEditing","subTarget","objToCheck","pointerToUse","subTargetCheck","ignoreZoom","_absolutePointer","_pointer","cssScale","boundsWidth","boundsHeight","bottom","right","lowerCanvasClass","_copyCanvasStyle","class","touch-action","-ms-touch-action","fromEl","toEl","getSelectionContext","getSelectionElement","getActiveObject","active","_discardActiveObject","_hoveredTarget","_fireSelectionEvents","oldObjects","somethingChanged","added","removed","opt","oldObject","selected","deselected","updated","setActiveObject","currentActives","_setActiveObject","onSelect","onDeselect","discardActiveObject","removeListeners","originalProperties","_realizeGroupTransformOnObject","_unwindGroupTransformOnObject","originalValues","realizeTransform","clearContextTop","cursorOffset","mr","mb","ml","addEventOptions","passive","checkClick","button","cursorMap","mainTouchId","_bindEvents","addOrRemove","_getEventPrefix","enablePointerEvents","functor","eventjsFunctor","canvasElement","eventTypePrefix","_onResize","_onMouseDown","_onMouseMove","_onMouseOut","_onMouseEnter","_onMouseWheel","_onContextMenu","_onDoubleClick","_onDragOver","_onDragEnter","_onDragLeave","_onDrop","_onTouchStart","eventjs","_onGesture","_onDrag","_onOrientationChange","_onShake","_onLongPress","_onMouseUp","_onTouchEnd","eventsBound","_simpleEventHandler","self","__onTransformGesture","__onDrag","__onMouseWheel","hiddenTextarea","focus","currentTransform","__onOrientationChange","__onShake","__onLongPress","preventDefault","_fireEnterLeaveEvents","stopPropagation","_cacheTransformEventData","_handleEvent","_resetTransformEventData","getPointerId","evt","identifier","pointerId","isPrimary","touches","__onMouseDown","__onMouseUp","_willAddMouseDown","__onMouseMove","_shouldRender","shouldRender","isClick","_target","_onMouseUpInDrawingMode","_finalizeCurrentTransform","actionPerformed","_maybeGroupObjects","isMoving","_setCursorFromEvent","__corner","eventType","subTargets","absolutePointer","_scaling","hasStateChanged","_addEventOptions","_fire","_onMouseDownInDrawingMode","_onMouseMoveInDrawingMode","_previousPointer","shouldGroup","_shouldGroup","_handleGrouping","saveState","_transformObject","_fireOverOutEvents","fireSyntheticInOutEvents","targetName","canvasEvtOut","evtOut","canvasEvtIn","evtIn","config","inOpt","outOpt","inFires","oldTarget","targetChanged","previousTarget","nextTarget","reset","_beforeScaleTransform","_performTransformAction","_onScale","_isUniscalePossible","currentAction","getCornerCursor","actionIsDisabled","_getRotatedCornerCursor","hasRotatingPoint","n","_updateActiveSelection","_createActiveSelection","currentActiveObjects","removeWithUpdate","addWithUpdate","_createGroup","groupObjects","exitEditing","ActiveSelection","_groupSelectedObjects","aGroup","_collectObjects","currentObject","selectionX1Y1","selectionX2Y2","allowIntersect","intersectsWithRect","isContainedWithinRect","multiplier","toCanvasElement","cropping","scaledWidth","scaledHeight","originalWidth","originalHeight","newZoom","vp","originalInteractive","newVp","originalRetina","originalContextTop","loadFromDatalessJSON","json","loadFromJSON","serialized","JSON","_enlivenObjects","_setBgOverlay","enlivenedCanvasClip","__setupCanvas","loaded","cbIfLoaded","__setBgOverlay","enlivedObject","_toDataURL","_toDataURLWithMultiplier","toDataURLWithMultiplier","stringify","cloneWithoutData","backgroundImageOpacity","backgroundImageStretch","supportsLineDash","objectCaching","cornerSize","borderColor","borderDashArray","cornerColor","cornerStrokeColor","cornerStyle","cornerDashArray","strokeDashOffset","borderOpacityWhenMoving","borderScaleFactor","minScaleLimit","hasControls","rotatingPointOffset","lockMovementX","lockMovementY","lockUniScaling","statefullCache","noScaleCache","strokeUniform","dirty","paintFirst","stateProperties","cacheProperties","inverted","absolutePositioned","_cacheProperties","_updateCacheCanvas","_limitCacheSize","dims","limitedDims","capped","_getCacheCanvasDimensions","objectScale","getTotalObjectScaling","neededX","neededY","drawingWidth","drawingHeight","minCacheSize","dimensionsChanged","cacheWidth","cacheHeight","zoomChanged","shouldRedraw","additionalWidth","additionalHeight","shouldResizeCanvas","canvasWidth","canvasHeight","sizeGrowing","setTransform","calcOwnMatrix","_removeDefaultValues","getObjectScaling","scaling","retina","getObjectOpacity","shouldConstrainValue","isChanged","groupNeedsUpdate","_constrainScale","isOnACache","setOnGroup","getViewportTransform","isNotVisible","isOnScreen","_setupCompositeOperation","drawSelectionBackground","_setOpacity","drawCacheOnCanvas","_removeCacheCanvas","drawObject","propertySet","isCacheDirty","hasStroke","hasFill","needsItsOwnCache","ownCaching","willDrawShadow","drawClipPathOnCache","originalFill","originalStroke","_setClippingProperties","_setStrokeStyles","_setFillStyles","_drawClipPath","skipCanvas","_getNonTransformedDimensions","_removeShadow","decl","lineDashOffset","dashArray","alternative","getLineDash","styleOverride","drawBorders","forActiveSelection","drawBordersInGroup","multX","multY","_applyPatternGradientTransform","_renderPaintInOrder","_renderStroke","_renderFill","_renderDashedStroke","_findCenterFromElement","_assignTransformMatrixProps","preserveAspectRatioOptions","cropX","cropY","offsetLeft","offsetTop","objectForm","_fromObject","cloneAsImage","utils","origParams","originalShadow","withoutTransform","withoutShadow","boundingRect","getBoundingRect","shadowOffset","originalCanvas","isType","setGradient","setPatternFill","setColor","shouldCenterOrigin","_setOriginToCenter","_resetOrigin","centerH","viewportCenterH","centerV","viewportCenterV","viewportCenter","getLocalPointer","pClicked","objectLeftTop","createAccessors","extraParam","enlivedProps","originXOffset","originYOffset","translateToGivenOrigin","fromOriginX","fromOriginY","toOriginX","toOriginY","translateToCenterPoint","leftTop","getPointByOrigin","adjustPosition","to","offsetFrom","offsetTo","hypotFull","getScaledWidth","xFull","yFull","_originalOriginX","_originalOriginY","originPoint","multiplyMatrices","oCoords","aCoords","ownMatrixCache","matrixCache","getCoords","absolute","calculate","calcCoords","pointTL","pointBR","other","lines","_getImageLines","_findCrossPoints","_containsCenterOfCanvas","isPartiallyOnScreen","topline","rightline","bottomline","leftline","xi","iLine","xcount","lineKey","getScaledHeight","scaleToWidth","boundingRectFactor","scaleToHeight","_calcRotateMatrix","_calcTranslateMatrix","startMatrix","finalMatrix","cosP","sinP","cosPSinP","cosPMinusSinP","mtr","skipAbsolute","_setCornerCoords","transformMatrixKey","prefix","cache","dimensionMatrix","_calcDimensionsTransformMatrix","flipping","dimX","dimY","noSkew","_finalizeDimensions","bbox","_calculateCurrentDimensions","getSvgColorString","getSvgStyles","skipShadow","getSvgFilter","getSvgSpanStyles","useWhiteSpace","textDecoration","getSvgTextDecoration","deltaY","overline","underline","linethrough","getSvgCommons","getSvgTransform","full","getSvgTransformMatrix","_setSVGBg","textBgRects","_getFillAttributes","_createBaseSVGMarkup","_toSVG","_createBaseClipPathSVGMarkup","objectMarkup","commonPieces","clipPathMarkup","noStyle","styleInfo","shadowInfo","withShadow","vectorEffect","absoluteClipPath","addPaintOrder","saveProps","props","tmpObj","dashedPropertySet","keys","_isEqual","origValue","currentValue","firstPass","_controlsVisibility","isControlVisible","newTheta","cornerHypotenuse","cosHalfOffset","sinHalfOffset","wh","drawRotatingPoint","rotateHeight","scaleOffset","_drawControl","control","controlName","_getControlsVisibility","setControlVisible","setControlsVisibility","FX_DURATION","fxCenterObjectH","callbacks","empty","fxCenterObjectV","fxRemove","skipCallbacks","propsToAnimate","_animate","propPair","from","valueProgress","timeProgress","coordProps","makeEdgeToOriginGetter","propertyNames","originValues","axis1","axis2","dimension","nearest","farthest","Line","_setWidthHeight","_getLeftToOriginX","_getTopToOriginY","calcLinePoints","origStrokeStyle","xMult","yMult","ATTRIBUTE_NAMES","parsedAttributes","pi","startAngle","endAngle","setRadius","svgString","startX","startY","endX","endY","largeFlag","getRadiusX","getRadiusY","isValidRadius","Triangle","widthBy2","heightBy2","piBy2","Ellipse","getRx","getRy","_initRxRy","isRounded","Polyline","_setPositionDimensions","correctLeftTop","calcDim","_calcDimensions","fromSVG","diffX","diffY","commonRender","fromElementGenerator","_class","Polygon","_toString","commandLengths","repeatedCommands","M","fromArray","_parsePath","_renderPathCommands","tempX","tempY","previous","subpathStartX","subpathStartY","controlX","controlY","_getOffsetTransform","digits","currentPath","coordsStr","coordsParsed","re","command","commandLength","repeatedCommand","klen","aX","aY","pathUrl","useSetOnGroup","isAlreadyGrouped","_updateObjectsACoords","_calcBounds","_updateObjectsCoords","_updateObjectCoords","objectLeft","objectTop","_restoreObjectsState","_includeDefaultValues","objsToObject","originalDefaults","_obj","ownCache","_restoreObjectState","destroy","toActiveSelection","ungroupOnCanvas","setObjectsCoords","onlyWidthHeight","iLen","jLen","_getBounds","minXY","maxXY","enlivedClipPath","toGroup","newGroup","childrenOverride","srcFromAttribute","_lastScaleX","_lastScaleY","_filterScalingX","_filterScalingY","minimumScaleTrigger","cacheKey","filters","_initElement","_element","setElement","removeTexture","_initConfig","applyFilters","resizeFilter","applyResizeFilters","backend","filterBackend","evictCachesForKey","setCrossOrigin","getOriginalSize","_stroke","filterObj","getSrc","hasCrop","strokeSvg","imageMarkup","getSvgSrc","origFill","filtered","setSrc","minimumScale","elementToFilter","_filteredEl","sourceWidth","sourceHeight","isNeutralState","imgElement","_needsResize","elementToDraw","sW","sH","sX","sY","_resetWidthHeight","CSS_CANVAS","_initFilters","pAR","rWidth","rHeight","pWidth","pHeight","_object","resizeFilters","fromURL","imgOptions","_getAngleValueForStraighten","straighten","fxStraighten","straightenObject","fxStraightenObject","testPrecision","precision","fragmentSource","fragmentShader","createShader","FRAGMENT_SHADER","shaderSource","compileShader","getShaderParameter","COMPILE_STATUS","setupGLContext","captureGPUInfo","isSupported","getParameter","MAX_TEXTURE_SIZE","precisions","webGlPrecision","createWebGLCanvas","aPosition","Float32Array","chooseFastestCopyGLTo2DMethod","canUseImageData","canMeasurePerf","performance","canUseArrayBuffer","ArrayBuffer","canUseUint8Clamped","copyGLTo2D","startTime","drawImageTime","testContext","now","glOptions","premultipliedAlpha","depth","stencil","antialias","clearColor","cachedTexture","getCachedTexture","sourceTexture","createTexture","targetTexture","originalTexture","passes","webgl","programCache","pass","tempFbo","createFramebuffer","bindFramebuffer","FRAMEBUFFER","applyTo","resizeCanvasIfNeeded","bindTexture","TEXTURE_2D","deleteTexture","deleteFramebuffer","clearWebGLCaches","textureCache","textureImageSource","texture","texParameteri","TEXTURE_MAG_FILTER","NEAREST","TEXTURE_MIN_FILTER","TEXTURE_WRAP_S","CLAMP_TO_EDGE","TEXTURE_WRAP_T","texImage2D","uniqueId","gpuInfo","renderer","vendor","ext","getExtension","UNMASKED_RENDERER_WEBGL","UNMASKED_VENDOR_WEBGL","sourceElement","originalEl","originalImageData","BaseFilter","vertexSource","createProgram","vertexShader","VERTEX_SHADER","getShaderInfoLog","program","attachShader","linkProgram","getProgramParameter","LINK_STATUS","getProgramInfoLog","attributeLocations","getAttributeLocations","uniformLocations","getUniformLocations","uStepW","getUniformLocation","uStepH","getAttribLocation","sendAttributeData","aPositionData","attributeLocation","buffer","createBuffer","bindBuffer","ARRAY_BUFFER","enableVertexAttribArray","vertexAttribPointer","FLOAT","bufferData","STATIC_DRAW","_setupFrameBuffer","framebufferTexture2D","COLOR_ATTACHMENT0","_swapTextures","temp","main","mainParameter","applyToWebGL","applyTo2d","retrieveShader","shader","useProgram","uniform1f","sendUniformData","viewport","drawArrays","TRIANGLE_STRIP","bindAdditionalTexture","textureUnit","activeTexture","TEXTURE0","unbindAdditionalTexture","getMainParameter","setMainParameter","createHelpLayer","helpLayer","mainP","ColorMatrix","colorsOnly","uColorMatrix","uConstants","constants","uniformMatrix4fv","uniform4fv","Brightness","brightness","uBrightness","Convolute","opaque","Convolute_3_1","Convolute_3_0","Convolute_5_1","Convolute_5_0","Convolute_7_1","Convolute_7_0","Convolute_9_1","Convolute_9_0","dstOff","scx","scy","srcOff","wt","weights","side","halfSide","sw","sh","output","createImageData","dst","alphaFac","uMatrix","uOpaque","uHalfSize","uSize","uniform1fv","Grayscale","lightness","luminosity","mode","uMode","uniform1i","Invert","invert","uInvert","Noise","noise","rand","uNoise","uSeed","Pixelate","blocksize","_i","_j","_iLen","_jLen","uBlocksize","RemoveColor","useAlpha","lowC","highC","uLow","uHigh","Brownie","Vintage","Kodachrome","Technicolor","Polaroid","Sepia","BlackWhite","BlendColor","screen","diff","lighten","darken","exclusion","tint","buildSource","tg","alpha1","uColor","BlendImage","mask","TEXTURE1","calculateMatrix","canvas1","blendData","blendImage","uTransformMatrix","uImage","uniformMatrix3fv","Resize","resizeType","lanczosLobes","uDelta","uTaps","uniform2fv","horizontal","taps","filterWindow","getFilterWindow","generateShader","tempScale","getTaps","lobeFunction","lanczosCreate","offsets","fragmentSourceTOP","dW","dH","lobes","xx","rcpScaleX","rcpScaleY","newData","oW","oH","sliceByTwo","hermiteFastResize","bilinearFiltering","lanczosResize","tmpCanvas","doneW","doneH","stepW","stepH","dX","dY","srcData","destImg","destData","lanczos","ratioX","ratioY","rcpRatioX","rcpRatioY","range2X","range2Y","cacheLanc","icenter","process","u","weight","fX","fY","xDiff","yDiff","chnl","origPix","w4","pixels","destImage","destPixels","ratioW","ratioH","ratioWHalf","ratioHHalf","img2","data2","weightsAlpha","gxR","gxG","gxB","gxA","centerY","yy","centerX","w0","Contrast","contrast","contrastF","uContrast","Saturation","saturation","adjust","uSaturation","Blur","aspectRatio","simpleBlur","canvas2","blurLayer1","blurLayer2","percent","ctx1","ctx2","newImageData","delta","chooseRightDelta","blurScale","Gamma","gamma","rInv","gInv","bInv","rVals","gVals","bVals","uGamma","uniform3fv","Composed","subFilters","some","HueRotation","rotation","rad","aThirdSqtSin","OneMinusCos","_dimensionAffectingProps","_reNewline","_reSpacesAndTabs","_reSpaceAndTab","_reWords","textAlign","superscript","baseline","subscript","textBackgroundColor","_fontSizeFraction","_fontSizeMult","charSpacing","_measuringContext","_styleProperties","__charBounds","CACHE_FONT_SIZE","MIN_TEXT_WIDTH","__skipDimension","initDimensions","getMeasuringContext","_splitText","newLines","_splitTextIntoLines","textLines","_textLines","graphemeLines","_unwrappedTextLines","_unwrappedLines","_text","graphemeText","_clearCache","calcTextWidth","cursorWidth","enlargeSpaces","calcTextHeight","diffSpace","currentLineWidth","numberOfSpaces","accumulatedSpace","line","charBound","spaces","isEndOfWrapping","getLineWidth","kernedWidth","lineIndex","missingNewlineOffset","_setTextStyles","_renderTextLinesBackground","_renderTextDecoration","_renderText","_renderTextStroke","_renderTextFill","charStyle","forMeasuring","textBaseline","_getFontDeclaration","maxWidth","_renderTextLine","_renderChars","styleHas","heightOfLine","lineLeftOffset","lastColor","charBox","currentColor","lineTopOffset","leftOffset","_getLeftOffset","topOffset","_getTopOffset","boxStart","boxWidth","getHeightOfLine","_getLineLeftOffset","getValueOfPropertyAt","getFontCache","cacheProp","_applyCharStyles","styleDeclaration","_measureChar","_char","previousChar","prevCharStyle","coupleWidth","previousWidth","fontCache","couple","stylesAreEqual","fontMultiplier","measureText","getHeightOfChar","measureLine","lineInfo","_measureLine","_getWidthOfCharSpacing","grapheme","prevGrapheme","graphemeInfo","lineBounds","_getGraphemeBox","numOfSpaces","skipLeft","getCompleteStyleDeclaration","prevStyle","info","previousBox","__lineHeights","maxHeight","_renderTextCommon","lineHeights","isEmptyStyles","actualStyle","nextStyle","timeToRender","isJustify","charsToRender","shortCut","_renderChar","_hasStyleChanged","_getStyleDeclaration","fullDecl","shouldFill","shouldStroke","fillText","strokeText","setSuperscript","_setScript","setSubscript","schema","loc","get2DCursorLocation","setSelectionStyles","thisStyle","_hasStyleChangedForSvg","__lineWidths","_shouldClearDimensionCache","shouldClear","_forceClearCache","_size","_dy","lastDecoration","currentDecoration","currentFill","lastFill","styleObject","family","fontIsGeneric","genericFonts","newLine","newText","additionalProperties","needsDims","_key","parsedAnchor","textAnchor","originalStrokeWidth","textHeightScaleFactor","scaledDiff","textHeight","offX","p3","cleanStyle","letterCount","stylePropertyValue","stylesCount","allStyleObjectPropertiesMatch","graphemeCount","removeStyle","lineNum","charNum","_extendStyles","_getLineStyle","_setLineStyle","_setStyleDeclaration","selectionStart","skipWrapping","getSelectionStyles","startIndex","endIndex","selectionEnd","getStyleAtPosition","lineStyle","_deleteStyleDeclaration","_deleteLineStyle","parseDecoration","IText","editable","editingBorderColor","cursorColor","cursorDelay","cursorDuration","caching","_reSpace","_currentCursorOpacity","_selectionDirection","_abortCursorAnimation","__widthOfSpace","inCompositionMode","initBehavior","setSelectionStart","_updateAndFire","setSelectionEnd","_fireSelectionChanged","_updateTextarea","initDelayedCursor","cursorOffsetCache","renderCursorOrSelection","skipRestore","_clearTextArea","boundaries","_getCursorBoundaries","renderCursor","renderSelection","_getCursorBoundariesOffsets","cursorPosition","cursorLocation","charHeight","__isMousedown","startLine","endLine","startChar","endChar","realLineHeight","lineOffset","boxEnd","compositionColor","getCurrentCharFontSize","cp","_getCurrentCharIndex","getCurrentCharColor","initAddedHandler","initRemovedHandler","initCursorSelectionHandlers","initDoubleClickSimulation","mouseMoveHandler","_initCanvasHandlers","_removeCanvasHandlers","_tick","_currentTickState","_animateCursor","targetOpacity","completeMethod","tickState","isAborted","_onTickComplete","_cursorTimeout1","_currentTickCompleteState","restart","delay","abortCursorAnimation","_cursorTimeout2","selectAll","getSelectedText","findWordBoundaryLeft","startFrom","findWordBoundaryRight","findLineBoundaryLeft","findLineBoundaryRight","searchWordBoundary","direction","reNonWord","selectWord","newSelectionStart","newSelectionEnd","selectLine","enterEditing","exitEditingOnOthers","initHiddenTextarea","_saveEditingProps","_setEditingProps","_textBeforeEdit","initMouseMoveHandler","getSelectionStartFromPointer","currentStart","currentEnd","__selectionStartOnMouseDown","restartCursorIfNeeded","fromStringToGraphemeSelection","smallerTextStart","graphemeStart","smallerTextEnd","fromGraphemeToStringSelection","newSelection","updateTextareaPosition","updateFromTextArea","_calcTextareaPosition","desiredPosition","compositionStart","upperCanvas","upperCanvasWidth","upperCanvasHeight","clientWidth","clientHeight","_savedProps","_restoreEditingProps","isTextChanged","_removeExtraneousStyles","removeStyleFromTo","styleObj","cursorStart","cursorEnd","lineStart","charStart","lineEnd","charEnd","shiftLineStyles","numericChar","clonedStyles","numericLine","insertNewlineStyleObject","qty","copiedStyle","currentCharStyle","newLineStyles","somethingAdded","numIndex","insertCharStyleObject","quantity","currentLineStyles","currentLineStylesCloned","numericIndex","newStyle","insertNewStyleBlock","insertedText","cursorLoc","addedLines","linesLength","setSelectionStartEndWithShift","setSelectionInBoundaries","__lastClickTime","__lastLastClickTime","__lastPointer","__newClickTime","newPointer","isTripleClick","_stopEvent","__lastIsEditing","__lastSelected","initMousedownHandler","initMouseupHandler","initClicks","_mouseDownHandler","setCursorByClick","_mouseDownHandlerBefore","mouseUpHandler","currentActive","mouseOffset","prevWidth","_getNewSelectionStartFromOffset","distanceBtwLastCharAndCursor","distanceBtwNextCharAndCursor","onKeyDown","onKeyUp","onInput","copy","paste","onCompositionStart","onCompositionUpdate","onCompositionEnd","_clickHandlerInitialized","onClick","keysMap","9","27","33","34","35","36","37","38","39","40","ctrlKeysMapUp","67","88","ctrlKeysMapDown","65","keyCode","ctrlKey","metaKey","stopImmediatePropagation","_copyDone","fromPaste","removedText","nextText","charCount","nextCharCount","charDiff","textareaSelection","backDelete","copiedText","copiedTextStyle","compositionEnd","_getClipboardData","clipboardData","_getWidthBeforeCursor","widthBeforeCursor","getDownCursorOffset","isRight","selectionProp","_getSelectionForOffset","indexOnOtherLine","_getIndexOnLine","getUpCursorOffset","textBeforeCursor","charWidth","foundMatch","widthOfCharsOnLine","indexOnLine","leftEdge","rightEdge","offsetFromLeftEdge","moveCursorDown","_moveCursorUpOrDown","moveCursorUp","moveCursorWithShift","moveCursorWithoutShift","moveCursorLeft","_moveCursorLeftOrRight","_move","_moveLeft","_moveRight","moveCursorLeftWithoutShift","change","moveCursorLeftWithShift","moveCursorRight","actionName","moveCursorRightWithShift","moveCursorRightWithoutShift","changed","removeChars","insertChars","multipleSpacesRegex","_getSVGLeftTopOffsets","textAndBg","_getSVGTextAndBg","textTop","textLeft","_wrapSVGTextAndBg","lineTop","textSpans","textTopOffset","textLeftOffset","_setSVGTextLineBg","_setSVGTextLineText","_createTextCharSpan","styleDecl","shouldUseWhitespace","styleProps","fillStyles","dySpan","_pushTextBgRect","fillColor","_getSVGLineTopOffset","lastHeight","minWidth","dynamicMinWidth","__cachedLines","_wordJoiners","splitByGrapheme","_styleMap","_generateStyleMap","textInfo","realLineCount","realLineCharCount","isWrapping","nextOffset","shouldLimit","mapNextLine","_wrapText","desiredWidth","wrapped","_wrapLine","_measureWord","word","charOffset","_line","reservedSpace","words","infix","wordWidth","infixWidth","largestWordWidth","lineJustStarted","additionalSpace","linesToKeep","read","isLE","mLen","nBytes","eLen","eMax","eBias","nBits","NaN","Infinity","write","rt","LN2","module","AnnotationIcons","arrow","blank","colors","delete","discard","done","icon","more","pencil","ok","redo","select","textAdd","textWeight","textSize","tools","undo","heart","check","pin","like","dislike","tag","attention","smiley","Annotation_Annotation","_super","Annotation","_active","_currentTool","_currentColor","_currentWidth","_currentOpacity","_currentFontSize","_currentFontWeight","_colors","_widths","_opacities","_fontSizes","_fontWeights","_useMenu","_ownMenu","_pointerDown","_exportInited","icons","autoSize","tslib_es6","init","initExporting","_data","loadData","useMenu","exporting","menu","invalidate","ExportMenu","items","events","once","updateIndicator","sizeAnnotations","Interaction","ev","Keyboard","isKey","deleteSelected","updateSVG","_group","_indicatorId","Registry","getUniqueId","label","language","translateAny","handleClick","callbackTarget","svg","this_1","widths","this_2","opacities","this_3","fontSizes","this_4","setFontSize","fontWeights","this_5","setFontWeight","this_6","addIcon","mainitem","hex","_menu","hidden","addText","deactivate","defineProperty","_fabric","pixelWidth","pixelHeight","svgContainer","SVGContainer","currentTool","_currentLine","currentWidth","currentOpacity","_currentArrowhead","utils_Math","paper","pointerEvents","dom","activate","updateTool","matches","innerHTML","showBranch","hideBranch","indicator","newicon","createSvgElement","oldicon","insertBefore","getElementsByClassName","brushColor","rgba","setIconFill","currentFontSize","currentFontWeight","underConstruction","alert","res","atob","btoa","_originalBbox","getBBox","Plugin","registeredClasses","am4plugins_annotation","annotation_namespaceObject","jsdom","base64","ieee754","kMaxLength","TYPED_ARRAY_SUPPORT","RangeError","__proto__","arg","encodingOrOffset","allocUnsafe","TypeError","byteOffset","byteLength","fromArrayLike","fromArrayBuffer","isEncoding","actual","fromString","isBuffer","checked","val","isnan","assertSize","isView","loweredCase","utf8ToBytes","base64ToBytes","bidirectionalIndexOf","dir","arrayIndexOf","lastIndexOf","indexSize","arrLength","valLength","buf","readUInt16BE","foundIndex","found","hexWrite","remaining","strLen","utf8Write","blitBuffer","asciiWrite","byteArray","asciiToBytes","latin1Write","base64Write","ucs2Write","units","hi","lo","utf16leToBytes","base64Slice","fromByteArray","utf8Slice","secondByte","thirdByte","fourthByte","tempCodePoint","firstByte","codePoint","bytesPerSequence","codePoints","MAX_ARGUMENTS_LENGTH","fromCharCode","decodeCodePointsArray","SlowBuffer","alloc","INSPECT_MAX_BYTES","foo","subarray","typedArraySupport","poolSize","_augment","Symbol","species","configurable","allocUnsafeSlow","_isBuffer","compare","list","swap16","swap32","swap64","hexSlice","asciiSlice","latin1Slice","utf16leSlice","equals","inspect","thisStart","thisEnd","thisCopy","targetCopy","includes","isFinite","_arr","ret","out","bytes","checkOffset","checkInt","objectWriteUInt16","littleEndian","objectWriteUInt32","checkIEEE754","writeFloat","noAssert","writeDouble","newBuf","sliceLen","readUIntLE","mul","readUIntBE","readUInt8","readUInt16LE","readUInt32LE","readUInt32BE","readIntLE","readIntBE","readInt8","readInt16LE","readInt16BE","readInt32LE","readInt32BE","readFloatLE","readFloatBE","readDoubleLE","readDoubleBE","writeUIntLE","writeUIntBE","writeUInt8","writeUInt16LE","writeUInt16BE","writeUInt32LE","writeUInt32BE","writeIntLE","limit","sub","writeIntBE","writeInt8","writeInt16LE","writeInt16BE","writeInt32LE","writeInt32BE","writeFloatLE","writeFloatBE","writeDoubleLE","writeDoubleBE","targetStart","INVALID_BASE64_RE","leadSurrogate","toByteArray","stringtrim","base64clean","b64","lens","getLens","validLen","placeHoldersLen","tmp","Arr","_byteLength","curByte","revLookup","uint8","extraBytes","len2","encodeChunk","lookup","tripletToBase64","num"],"mappings":"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","file":"./plugins/annotation.js","sourcesContent":["/* build: `node build.js modules=ALL exclude=gestures,accessors requirejs minifier=uglifyjs` */\n/*! Fabric.js Copyright 2008-2015, Printio (Juriy Zaytsev, Maxim Chernyak) */\n\nvar fabric = fabric || { version: '3.3.0' };\nif (typeof exports !== 'undefined') {\n  exports.fabric = fabric;\n}\n/* _AMD_START_ */\nelse if (typeof define === 'function' && define.amd) {\n  define([], function() { return fabric; });\n}\n/* _AMD_END_ */\nif (typeof document !== 'undefined' && typeof window !== 'undefined') {\n  if (document instanceof (typeof HTMLDocument !== 'undefined' ? HTMLDocument : Document)) {\n    fabric.document = document;\n  }\n  else {\n    fabric.document = document.implementation.createHTMLDocument('');\n  }\n  fabric.window = window;\n}\nelse {\n  // assume we're running under node.js when document/window are not present\n  var jsdom = require('jsdom');\n  var virtualWindow = new jsdom.JSDOM(\n    decodeURIComponent('%3C!DOCTYPE%20html%3E%3Chtml%3E%3Chead%3E%3C%2Fhead%3E%3Cbody%3E%3C%2Fbody%3E%3C%2Fhtml%3E'),\n    {\n      features: {\n        FetchExternalResources: ['img']\n      },\n      resources: 'usable'\n    }).window;\n  fabric.document = virtualWindow.document;\n  fabric.jsdomImplForWrapper = require('jsdom/lib/jsdom/living/generated/utils').implForWrapper;\n  fabric.nodeCanvas = require('jsdom/lib/jsdom/utils').Canvas;\n  fabric.window = virtualWindow;\n  DOMParser = fabric.window.DOMParser;\n}\n\n/**\n * True when in environment that supports touch events\n * @type boolean\n */\nfabric.isTouchSupported = 'ontouchstart' in fabric.window || 'ontouchstart' in fabric.document ||\n  (fabric.window && fabric.window.navigator && fabric.window.navigator.maxTouchPoints > 0);\n\n/**\n * True when in environment that's probably Node.js\n * @type boolean\n */\nfabric.isLikelyNode = typeof Buffer !== 'undefined' &&\n                      typeof window === 'undefined';\n\n/* _FROM_SVG_START_ */\n/**\n * Attributes parsed from all SVG elements\n * @type array\n */\nfabric.SHARED_ATTRIBUTES = [\n  'display',\n  'transform',\n  'fill', 'fill-opacity', 'fill-rule',\n  'opacity',\n  'stroke', 'stroke-dasharray', 'stroke-linecap', 'stroke-dashoffset',\n  'stroke-linejoin', 'stroke-miterlimit',\n  'stroke-opacity', 'stroke-width',\n  'id', 'paint-order', 'vector-effect',\n  'instantiated_by_use', 'clip-path'\n];\n/* _FROM_SVG_END_ */\n\n/**\n * Pixel per Inch as a default value set to 96. Can be changed for more realistic conversion.\n */\nfabric.DPI = 96;\nfabric.reNum = '(?:[-+]?(?:\\\\d+|\\\\d*\\\\.\\\\d+)(?:[eE][-+]?\\\\d+)?)';\nfabric.fontPaths = { };\nfabric.iMatrix = [1, 0, 0, 1, 0, 0];\n\n/**\n * Pixel limit for cache canvases. 1Mpx , 4Mpx should be fine.\n * @since 1.7.14\n * @type Number\n * @default\n */\nfabric.perfLimitSizeTotal = 2097152;\n\n/**\n * Pixel limit for cache canvases width or height. IE fixes the maximum at 5000\n * @since 1.7.14\n * @type Number\n * @default\n */\nfabric.maxCacheSideLimit = 4096;\n\n/**\n * Lowest pixel limit for cache canvases, set at 256PX\n * @since 1.7.14\n * @type Number\n * @default\n */\nfabric.minCacheSideLimit = 256;\n\n/**\n * Cache Object for widths of chars in text rendering.\n */\nfabric.charWidthsCache = { };\n\n/**\n * if webgl is enabled and available, textureSize will determine the size\n * of the canvas backend\n * @since 2.0.0\n * @type Number\n * @default\n */\nfabric.textureSize = 2048;\n\n/**\n * When 'true', style information is not retained when copy/pasting text, making\n * pasted text use destination style.\n * Defaults to 'false'.\n * @type Boolean\n * @default\n */\nfabric.disableStyleCopyPaste = false;\n\n/**\n * Enable webgl for filtering picture is available\n * A filtering backend will be initialized, this will both take memory and\n * time since a default 2048x2048 canvas will be created for the gl context\n * @since 2.0.0\n * @type Boolean\n * @default\n */\nfabric.enableGLFiltering = true;\n\n/**\n * Device Pixel Ratio\n * @see https://developer.apple.com/library/safari/documentation/AudioVideo/Conceptual/HTML-canvas-guide/SettingUptheCanvas/SettingUptheCanvas.html\n */\nfabric.devicePixelRatio = fabric.window.devicePixelRatio ||\n                          fabric.window.webkitDevicePixelRatio ||\n                          fabric.window.mozDevicePixelRatio ||\n                          1;\n/**\n * Browser-specific constant to adjust CanvasRenderingContext2D.shadowBlur value,\n * which is unitless and not rendered equally across browsers.\n *\n * Values that work quite well (as of October 2017) are:\n * - Chrome: 1.5\n * - Edge: 1.75\n * - Firefox: 0.9\n * - Safari: 0.95\n *\n * @since 2.0.0\n * @type Number\n * @default 1\n */\nfabric.browserShadowBlurConstant = 1;\n\n/**\n * This object contains the result of arc to beizer conversion for faster retrieving if the same arc needs to be converted again.\n * It was an internal variable, is accessible since version 2.3.4\n */\nfabric.arcToSegmentsCache = { };\n\n/**\n * This object keeps the results of the boundsOfCurve calculation mapped by the joined arguments necessary to calculate it.\n * It does speed up calculation, if you parse and add always the same paths, but in case of heavy usage of freedrawing\n * you do not get any speed benefit and you get a big object in memory.\n * The object was a private variable before, while now is appended to the lib so that you have access to it and you\n * can eventually clear it.\n * It was an internal variable, is accessible since version 2.3.4\n */\nfabric.boundsOfCurveCache = { };\n\n/**\n * If disabled boundsOfCurveCache is not used. For apps that make heavy usage of pencil drawing probably disabling it is better\n * @default true\n */\nfabric.cachesBoundsOfCurve = true;\n\n/**\n * Skip performance testing of setupGLContext and force the use of putImageData that seems to be the one that works best on\n * Chrome + old hardware. if your users are experiencing empty images after filtering you may try to force this to true\n * this has to be set before instantiating the filtering backend ( before filtering the first image )\n * @type Boolean\n * @default false\n */\nfabric.forceGLPutImageData = false;\n\nfabric.initFilterBackend = function() {\n  if (fabric.enableGLFiltering && fabric.isWebglSupported && fabric.isWebglSupported(fabric.textureSize)) {\n    console.log('max texture size: ' + fabric.maxTextureSize);\n    return (new fabric.WebglFilterBackend({ tileSize: fabric.textureSize }));\n  }\n  else if (fabric.Canvas2dFilterBackend) {\n    return (new fabric.Canvas2dFilterBackend());\n  }\n};\n\n\n(function() {\n\n  /**\n   * @private\n   * @param {String} eventName\n   * @param {Function} handler\n   */\n  function _removeEventListener(eventName, handler) {\n    if (!this.__eventListeners[eventName]) {\n      return;\n    }\n    var eventListener = this.__eventListeners[eventName];\n    if (handler) {\n      eventListener[eventListener.indexOf(handler)] = false;\n    }\n    else {\n      fabric.util.array.fill(eventListener, false);\n    }\n  }\n\n  /**\n   * Observes specified event\n   * @deprecated `observe` deprecated since 0.8.34 (use `on` instead)\n   * @memberOf fabric.Observable\n   * @alias on\n   * @param {String|Object} eventName Event name (eg. 'after:render') or object with key/value pairs (eg. {'after:render': handler, 'selection:cleared': handler})\n   * @param {Function} handler Function that receives a notification when an event of the specified type occurs\n   * @return {Self} thisArg\n   * @chainable\n   */\n  function observe(eventName, handler) {\n    if (!this.__eventListeners) {\n      this.__eventListeners = { };\n    }\n    // one object with key/value pairs was passed\n    if (arguments.length === 1) {\n      for (var prop in eventName) {\n        this.on(prop, eventName[prop]);\n      }\n    }\n    else {\n      if (!this.__eventListeners[eventName]) {\n        this.__eventListeners[eventName] = [];\n      }\n      this.__eventListeners[eventName].push(handler);\n    }\n    return this;\n  }\n\n  /**\n   * Stops event observing for a particular event handler. Calling this method\n   * without arguments removes all handlers for all events\n   * @deprecated `stopObserving` deprecated since 0.8.34 (use `off` instead)\n   * @memberOf fabric.Observable\n   * @alias off\n   * @param {String|Object} eventName Event name (eg. 'after:render') or object with key/value pairs (eg. {'after:render': handler, 'selection:cleared': handler})\n   * @param {Function} handler Function to be deleted from EventListeners\n   * @return {Self} thisArg\n   * @chainable\n   */\n  function stopObserving(eventName, handler) {\n    if (!this.__eventListeners) {\n      return this;\n    }\n\n    // remove all key/value pairs (event name -> event handler)\n    if (arguments.length === 0) {\n      for (eventName in this.__eventListeners) {\n        _removeEventListener.call(this, eventName);\n      }\n    }\n    // one object with key/value pairs was passed\n    else if (arguments.length === 1 && typeof arguments[0] === 'object') {\n      for (var prop in eventName) {\n        _removeEventListener.call(this, prop, eventName[prop]);\n      }\n    }\n    else {\n      _removeEventListener.call(this, eventName, handler);\n    }\n    return this;\n  }\n\n  /**\n   * Fires event with an optional options object\n   * @deprecated `fire` deprecated since 1.0.7 (use `trigger` instead)\n   * @memberOf fabric.Observable\n   * @alias trigger\n   * @param {String} eventName Event name to fire\n   * @param {Object} [options] Options object\n   * @return {Self} thisArg\n   * @chainable\n   */\n  function fire(eventName, options) {\n    if (!this.__eventListeners) {\n      return this;\n    }\n\n    var listenersForEvent = this.__eventListeners[eventName];\n    if (!listenersForEvent) {\n      return this;\n    }\n\n    for (var i = 0, len = listenersForEvent.length; i < len; i++) {\n      listenersForEvent[i] && listenersForEvent[i].call(this, options || { });\n    }\n    this.__eventListeners[eventName] = listenersForEvent.filter(function(value) {\n      return value !== false;\n    });\n    return this;\n  }\n\n  /**\n   * @namespace fabric.Observable\n   * @tutorial {@link http://fabricjs.com/fabric-intro-part-2#events}\n   * @see {@link http://fabricjs.com/events|Events demo}\n   */\n  fabric.Observable = {\n    observe: observe,\n    stopObserving: stopObserving,\n    fire: fire,\n\n    on: observe,\n    off: stopObserving,\n    trigger: fire\n  };\n})();\n\n\n/**\n * @namespace fabric.Collection\n */\nfabric.Collection = {\n\n  _objects: [],\n\n  /**\n   * Adds objects to collection, Canvas or Group, then renders canvas\n   * (if `renderOnAddRemove` is not `false`).\n   * in case of Group no changes to bounding box are made.\n   * Objects should be instances of (or inherit from) fabric.Object\n   * Use of this function is highly discouraged for groups.\n   * you can add a bunch of objects with the add method but then you NEED\n   * to run a addWithUpdate call for the Group class or position/bbox will be wrong.\n   * @param {...fabric.Object} object Zero or more fabric instances\n   * @return {Self} thisArg\n   * @chainable\n   */\n  add: function () {\n    this._objects.push.apply(this._objects, arguments);\n    if (this._onObjectAdded) {\n      for (var i = 0, length = arguments.length; i < length; i++) {\n        this._onObjectAdded(arguments[i]);\n      }\n    }\n    this.renderOnAddRemove && this.requestRenderAll();\n    return this;\n  },\n\n  /**\n   * Inserts an object into collection at specified index, then renders canvas (if `renderOnAddRemove` is not `false`)\n   * An object should be an instance of (or inherit from) fabric.Object\n   * Use of this function is highly discouraged for groups.\n   * you can add a bunch of objects with the insertAt method but then you NEED\n   * to run a addWithUpdate call for the Group class or position/bbox will be wrong.\n   * @param {Object} object Object to insert\n   * @param {Number} index Index to insert object at\n   * @param {Boolean} nonSplicing When `true`, no splicing (shifting) of objects occurs\n   * @return {Self} thisArg\n   * @chainable\n   */\n  insertAt: function (object, index, nonSplicing) {\n    var objects = this._objects;\n    if (nonSplicing) {\n      objects[index] = object;\n    }\n    else {\n      objects.splice(index, 0, object);\n    }\n    this._onObjectAdded && this._onObjectAdded(object);\n    this.renderOnAddRemove && this.requestRenderAll();\n    return this;\n  },\n\n  /**\n   * Removes objects from a collection, then renders canvas (if `renderOnAddRemove` is not `false`)\n   * @param {...fabric.Object} object Zero or more fabric instances\n   * @return {Self} thisArg\n   * @chainable\n   */\n  remove: function() {\n    var objects = this._objects,\n        index, somethingRemoved = false;\n\n    for (var i = 0, length = arguments.length; i < length; i++) {\n      index = objects.indexOf(arguments[i]);\n\n      // only call onObjectRemoved if an object was actually removed\n      if (index !== -1) {\n        somethingRemoved = true;\n        objects.splice(index, 1);\n        this._onObjectRemoved && this._onObjectRemoved(arguments[i]);\n      }\n    }\n\n    this.renderOnAddRemove && somethingRemoved && this.requestRenderAll();\n    return this;\n  },\n\n  /**\n   * Executes given function for each object in this group\n   * @param {Function} callback\n   *                   Callback invoked with current object as first argument,\n   *                   index - as second and an array of all objects - as third.\n   *                   Callback is invoked in a context of Global Object (e.g. `window`)\n   *                   when no `context` argument is given\n   *\n   * @param {Object} context Context (aka thisObject)\n   * @return {Self} thisArg\n   * @chainable\n   */\n  forEachObject: function(callback, context) {\n    var objects = this.getObjects();\n    for (var i = 0, len = objects.length; i < len; i++) {\n      callback.call(context, objects[i], i, objects);\n    }\n    return this;\n  },\n\n  /**\n   * Returns an array of children objects of this instance\n   * Type parameter introduced in 1.3.10\n   * since 2.3.5 this method return always a COPY of the array;\n   * @param {String} [type] When specified, only objects of this type are returned\n   * @return {Array}\n   */\n  getObjects: function(type) {\n    if (typeof type === 'undefined') {\n      return this._objects.concat();\n    }\n    return this._objects.filter(function(o) {\n      return o.type === type;\n    });\n  },\n\n  /**\n   * Returns object at specified index\n   * @param {Number} index\n   * @return {Self} thisArg\n   */\n  item: function (index) {\n    return this._objects[index];\n  },\n\n  /**\n   * Returns true if collection contains no objects\n   * @return {Boolean} true if collection is empty\n   */\n  isEmpty: function () {\n    return this._objects.length === 0;\n  },\n\n  /**\n   * Returns a size of a collection (i.e: length of an array containing its objects)\n   * @return {Number} Collection size\n   */\n  size: function() {\n    return this._objects.length;\n  },\n\n  /**\n   * Returns true if collection contains an object\n   * @param {Object} object Object to check against\n   * @return {Boolean} `true` if collection contains an object\n   */\n  contains: function(object) {\n    return this._objects.indexOf(object) > -1;\n  },\n\n  /**\n   * Returns number representation of a collection complexity\n   * @return {Number} complexity\n   */\n  complexity: function () {\n    return this._objects.reduce(function (memo, current) {\n      memo += current.complexity ? current.complexity() : 0;\n      return memo;\n    }, 0);\n  }\n};\n\n\n/**\n * @namespace fabric.CommonMethods\n */\nfabric.CommonMethods = {\n\n  /**\n   * Sets object's properties from options\n   * @param {Object} [options] Options object\n   */\n  _setOptions: function(options) {\n    for (var prop in options) {\n      this.set(prop, options[prop]);\n    }\n  },\n\n  /**\n   * @private\n   * @param {Object} [filler] Options object\n   * @param {String} [property] property to set the Gradient to\n   */\n  _initGradient: function(filler, property) {\n    if (filler && filler.colorStops && !(filler instanceof fabric.Gradient)) {\n      this.set(property, new fabric.Gradient(filler));\n    }\n  },\n\n  /**\n   * @private\n   * @param {Object} [filler] Options object\n   * @param {String} [property] property to set the Pattern to\n   * @param {Function} [callback] callback to invoke after pattern load\n   */\n  _initPattern: function(filler, property, callback) {\n    if (filler && filler.source && !(filler instanceof fabric.Pattern)) {\n      this.set(property, new fabric.Pattern(filler, callback));\n    }\n    else {\n      callback && callback();\n    }\n  },\n\n  /**\n   * @private\n   * @param {Object} [options] Options object\n   */\n  _initClipping: function(options) {\n    if (!options.clipTo || typeof options.clipTo !== 'string') {\n      return;\n    }\n\n    var functionBody = fabric.util.getFunctionBody(options.clipTo);\n    if (typeof functionBody !== 'undefined') {\n      this.clipTo = new Function('ctx', functionBody);\n    }\n  },\n\n  /**\n   * @private\n   */\n  _setObject: function(obj) {\n    for (var prop in obj) {\n      this._set(prop, obj[prop]);\n    }\n  },\n\n  /**\n   * 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()`.\n   * @param {String|Object} key Property name or object (if object, iterate over the object properties)\n   * @param {Object|Function} value Property value (if function, the value is passed into it and its return value is used as a new one)\n   * @return {fabric.Object} thisArg\n   * @chainable\n   */\n  set: function(key, value) {\n    if (typeof key === 'object') {\n      this._setObject(key);\n    }\n    else {\n      if (typeof value === 'function' && key !== 'clipTo') {\n        this._set(key, value(this.get(key)));\n      }\n      else {\n        this._set(key, value);\n      }\n    }\n    return this;\n  },\n\n  _set: function(key, value) {\n    this[key] = value;\n  },\n\n  /**\n   * Toggles specified property from `true` to `false` or from `false` to `true`\n   * @param {String} property Property to toggle\n   * @return {fabric.Object} thisArg\n   * @chainable\n   */\n  toggle: function(property) {\n    var value = this.get(property);\n    if (typeof value === 'boolean') {\n      this.set(property, !value);\n    }\n    return this;\n  },\n\n  /**\n   * Basic getter\n   * @param {String} property Property name\n   * @return {*} value of a property\n   */\n  get: function(property) {\n    return this[property];\n  }\n};\n\n\n(function(global) {\n\n  var sqrt = Math.sqrt,\n      atan2 = Math.atan2,\n      pow = Math.pow,\n      abs = Math.abs,\n      PiBy180 = Math.PI / 180,\n      PiBy2 = Math.PI / 2;\n\n  /**\n   * @namespace fabric.util\n   */\n  fabric.util = {\n\n    /**\n     * Calculate the cos of an angle, avoiding returning floats for known results\n     * @static\n     * @memberOf fabric.util\n     * @param {Number} angle the angle in radians or in degree\n     * @return {Number}\n     */\n    cos: function(angle) {\n      if (angle === 0) { return 1; }\n      if (angle < 0) {\n        // cos(a) = cos(-a)\n        angle = -angle;\n      }\n      var angleSlice = angle / PiBy2;\n      switch (angleSlice) {\n        case 1: case 3: return 0;\n        case 2: return -1;\n      }\n      return Math.cos(angle);\n    },\n\n    /**\n     * Calculate the sin of an angle, avoiding returning floats for known results\n     * @static\n     * @memberOf fabric.util\n     * @param {Number} angle the angle in radians or in degree\n     * @return {Number}\n     */\n    sin: function(angle) {\n      if (angle === 0) { return 0; }\n      var angleSlice = angle / PiBy2, sign = 1;\n      if (angle < 0) {\n        // sin(-a) = -sin(a)\n        sign = -1;\n      }\n      switch (angleSlice) {\n        case 1: return sign;\n        case 2: return 0;\n        case 3: return -sign;\n      }\n      return Math.sin(angle);\n    },\n\n    /**\n     * Removes value from an array.\n     * Presence of value (and its position in an array) is determined via `Array.prototype.indexOf`\n     * @static\n     * @memberOf fabric.util\n     * @param {Array} array\n     * @param {*} value\n     * @return {Array} original array\n     */\n    removeFromArray: function(array, value) {\n      var idx = array.indexOf(value);\n      if (idx !== -1) {\n        array.splice(idx, 1);\n      }\n      return array;\n    },\n\n    /**\n     * Returns random number between 2 specified ones.\n     * @static\n     * @memberOf fabric.util\n     * @param {Number} min lower limit\n     * @param {Number} max upper limit\n     * @return {Number} random value (between min and max)\n     */\n    getRandomInt: function(min, max) {\n      return Math.floor(Math.random() * (max - min + 1)) + min;\n    },\n\n    /**\n     * Transforms degrees to radians.\n     * @static\n     * @memberOf fabric.util\n     * @param {Number} degrees value in degrees\n     * @return {Number} value in radians\n     */\n    degreesToRadians: function(degrees) {\n      return degrees * PiBy180;\n    },\n\n    /**\n     * Transforms radians to degrees.\n     * @static\n     * @memberOf fabric.util\n     * @param {Number} radians value in radians\n     * @return {Number} value in degrees\n     */\n    radiansToDegrees: function(radians) {\n      return radians / PiBy180;\n    },\n\n    /**\n     * Rotates `point` around `origin` with `radians`\n     * @static\n     * @memberOf fabric.util\n     * @param {fabric.Point} point The point to rotate\n     * @param {fabric.Point} origin The origin of the rotation\n     * @param {Number} radians The radians of the angle for the rotation\n     * @return {fabric.Point} The new rotated point\n     */\n    rotatePoint: function(point, origin, radians) {\n      point.subtractEquals(origin);\n      var v = fabric.util.rotateVector(point, radians);\n      return new fabric.Point(v.x, v.y).addEquals(origin);\n    },\n\n    /**\n     * Rotates `vector` with `radians`\n     * @static\n     * @memberOf fabric.util\n     * @param {Object} vector The vector to rotate (x and y)\n     * @param {Number} radians The radians of the angle for the rotation\n     * @return {Object} The new rotated point\n     */\n    rotateVector: function(vector, radians) {\n      var sin = fabric.util.sin(radians),\n          cos = fabric.util.cos(radians),\n          rx = vector.x * cos - vector.y * sin,\n          ry = vector.x * sin + vector.y * cos;\n      return {\n        x: rx,\n        y: ry\n      };\n    },\n\n    /**\n     * Apply transform t to point p\n     * @static\n     * @memberOf fabric.util\n     * @param  {fabric.Point} p The point to transform\n     * @param  {Array} t The transform\n     * @param  {Boolean} [ignoreOffset] Indicates that the offset should not be applied\n     * @return {fabric.Point} The transformed point\n     */\n    transformPoint: function(p, t, ignoreOffset) {\n      if (ignoreOffset) {\n        return new fabric.Point(\n          t[0] * p.x + t[2] * p.y,\n          t[1] * p.x + t[3] * p.y\n        );\n      }\n      return new fabric.Point(\n        t[0] * p.x + t[2] * p.y + t[4],\n        t[1] * p.x + t[3] * p.y + t[5]\n      );\n    },\n\n    /**\n     * Returns coordinates of points's bounding rectangle (left, top, width, height)\n     * @param {Array} points 4 points array\n     * @return {Object} Object with left, top, width, height properties\n     */\n    makeBoundingBoxFromPoints: function(points) {\n      var xPoints = [points[0].x, points[1].x, points[2].x, points[3].x],\n          minX = fabric.util.array.min(xPoints),\n          maxX = fabric.util.array.max(xPoints),\n          width = maxX - minX,\n          yPoints = [points[0].y, points[1].y, points[2].y, points[3].y],\n          minY = fabric.util.array.min(yPoints),\n          maxY = fabric.util.array.max(yPoints),\n          height = maxY - minY;\n\n      return {\n        left: minX,\n        top: minY,\n        width: width,\n        height: height\n      };\n    },\n\n    /**\n     * Invert transformation t\n     * @static\n     * @memberOf fabric.util\n     * @param {Array} t The transform\n     * @return {Array} The inverted transform\n     */\n    invertTransform: function(t) {\n      var a = 1 / (t[0] * t[3] - t[1] * t[2]),\n          r = [a * t[3], -a * t[1], -a * t[2], a * t[0]],\n          o = fabric.util.transformPoint({ x: t[4], y: t[5] }, r, true);\n      r[4] = -o.x;\n      r[5] = -o.y;\n      return r;\n    },\n\n    /**\n     * A wrapper around Number#toFixed, which contrary to native method returns number, not string.\n     * @static\n     * @memberOf fabric.util\n     * @param {Number|String} number number to operate on\n     * @param {Number} fractionDigits number of fraction digits to \"leave\"\n     * @return {Number}\n     */\n    toFixed: function(number, fractionDigits) {\n      return parseFloat(Number(number).toFixed(fractionDigits));\n    },\n\n    /**\n     * Converts from attribute value to pixel value if applicable.\n     * Returns converted pixels or original value not converted.\n     * @param {Number|String} value number to operate on\n     * @param {Number} fontSize\n     * @return {Number|String}\n     */\n    parseUnit: function(value, fontSize) {\n      var unit = /\\D{0,2}$/.exec(value),\n          number = parseFloat(value);\n      if (!fontSize) {\n        fontSize = fabric.Text.DEFAULT_SVG_FONT_SIZE;\n      }\n      switch (unit[0]) {\n        case 'mm':\n          return number * fabric.DPI / 25.4;\n\n        case 'cm':\n          return number * fabric.DPI / 2.54;\n\n        case 'in':\n          return number * fabric.DPI;\n\n        case 'pt':\n          return number * fabric.DPI / 72; // or * 4 / 3\n\n        case 'pc':\n          return number * fabric.DPI / 72 * 12; // or * 16\n\n        case 'em':\n          return number * fontSize;\n\n        default:\n          return number;\n      }\n    },\n\n    /**\n     * Function which always returns `false`.\n     * @static\n     * @memberOf fabric.util\n     * @return {Boolean}\n     */\n    falseFunction: function() {\n      return false;\n    },\n\n    /**\n     * Returns klass \"Class\" object of given namespace\n     * @memberOf fabric.util\n     * @param {String} type Type of object (eg. 'circle')\n     * @param {String} namespace Namespace to get klass \"Class\" object from\n     * @return {Object} klass \"Class\"\n     */\n    getKlass: function(type, namespace) {\n      // capitalize first letter only\n      type = fabric.util.string.camelize(type.charAt(0).toUpperCase() + type.slice(1));\n      return fabric.util.resolveNamespace(namespace)[type];\n    },\n\n    /**\n     * Returns array of attributes for given svg that fabric parses\n     * @memberOf fabric.util\n     * @param {String} type Type of svg element (eg. 'circle')\n     * @return {Array} string names of supported attributes\n     */\n    getSvgAttributes: function(type) {\n      var attributes = [\n        'instantiated_by_use',\n        'style',\n        'id',\n        'class'\n      ];\n      switch (type) {\n        case 'linearGradient':\n          attributes = attributes.concat(['x1', 'y1', 'x2', 'y2', 'gradientUnits', 'gradientTransform']);\n          break;\n        case 'radialGradient':\n          attributes = attributes.concat(['gradientUnits', 'gradientTransform', 'cx', 'cy', 'r', 'fx', 'fy', 'fr']);\n          break;\n        case 'stop':\n          attributes = attributes.concat(['offset', 'stop-color', 'stop-opacity']);\n          break;\n      }\n      return attributes;\n    },\n\n    /**\n     * Returns object of given namespace\n     * @memberOf fabric.util\n     * @param {String} namespace Namespace string e.g. 'fabric.Image.filter' or 'fabric'\n     * @return {Object} Object for given namespace (default fabric)\n     */\n    resolveNamespace: function(namespace) {\n      if (!namespace) {\n        return fabric;\n      }\n\n      var parts = namespace.split('.'),\n          len = parts.length, i,\n          obj = global || fabric.window;\n\n      for (i = 0; i < len; ++i) {\n        obj = obj[parts[i]];\n      }\n\n      return obj;\n    },\n\n    /**\n     * Loads image element from given url and passes it to a callback\n     * @memberOf fabric.util\n     * @param {String} url URL representing an image\n     * @param {Function} callback Callback; invoked with loaded image\n     * @param {*} [context] Context to invoke callback in\n     * @param {Object} [crossOrigin] crossOrigin value to set image element to\n     */\n    loadImage: function(url, callback, context, crossOrigin) {\n      if (!url) {\n        callback && callback.call(context, url);\n        return;\n      }\n\n      var img = fabric.util.createImage();\n\n      /** @ignore */\n      var onLoadCallback = function () {\n        callback && callback.call(context, img);\n        img = img.onload = img.onerror = null;\n      };\n\n      img.onload = onLoadCallback;\n      /** @ignore */\n      img.onerror = function() {\n        fabric.log('Error loading ' + img.src);\n        callback && callback.call(context, null, true);\n        img = img.onload = img.onerror = null;\n      };\n\n      // data-urls appear to be buggy with crossOrigin\n      // https://github.com/kangax/fabric.js/commit/d0abb90f1cd5c5ef9d2a94d3fb21a22330da3e0a#commitcomment-4513767\n      // see https://code.google.com/p/chromium/issues/detail?id=315152\n      //     https://bugzilla.mozilla.org/show_bug.cgi?id=935069\n      if (url.indexOf('data') !== 0 && crossOrigin) {\n        img.crossOrigin = crossOrigin;\n      }\n\n      // IE10 / IE11-Fix: SVG contents from data: URI\n      // will only be available if the IMG is present\n      // in the DOM (and visible)\n      if (url.substring(0,14) === 'data:image/svg') {\n        img.onload = null;\n        fabric.util.loadImageInDom(img, onLoadCallback);\n      }\n\n      img.src = url;\n    },\n\n    /**\n     * Attaches SVG image with data: URL to the dom\n     * @memberOf fabric.util\n     * @param {Object} img Image object with data:image/svg src\n     * @param {Function} callback Callback; invoked with loaded image\n     * @return {Object} DOM element (div containing the SVG image)\n     */\n    loadImageInDom: function(img, onLoadCallback) {\n      var div = fabric.document.createElement('div');\n      div.style.width = div.style.height = '1px';\n      div.style.left = div.style.top = '-100%';\n      div.style.position = 'absolute';\n      div.appendChild(img);\n      fabric.document.querySelector('body').appendChild(div);\n      /**\n       * Wrap in function to:\n       *   1. Call existing callback\n       *   2. Cleanup DOM\n       */\n      img.onload = function () {\n        onLoadCallback();\n        div.parentNode.removeChild(div);\n        div = null;\n      };\n    },\n\n    /**\n     * Creates corresponding fabric instances from their object representations\n     * @static\n     * @memberOf fabric.util\n     * @param {Array} objects Objects to enliven\n     * @param {Function} callback Callback to invoke when all objects are created\n     * @param {String} namespace Namespace to get klass \"Class\" object from\n     * @param {Function} reviver Method for further parsing of object elements,\n     * called after each fabric object created.\n     */\n    enlivenObjects: function(objects, callback, namespace, reviver) {\n      objects = objects || [];\n\n      var enlivenedObjects = [],\n          numLoadedObjects = 0,\n          numTotalObjects = objects.length;\n\n      function onLoaded() {\n        if (++numLoadedObjects === numTotalObjects) {\n          callback && callback(enlivenedObjects.filter(function(obj) {\n            // filter out undefined objects (objects that gave error)\n            return obj;\n          }));\n        }\n      }\n\n      if (!numTotalObjects) {\n        callback && callback(enlivenedObjects);\n        return;\n      }\n\n      objects.forEach(function (o, index) {\n        // if sparse array\n        if (!o || !o.type) {\n          onLoaded();\n          return;\n        }\n        var klass = fabric.util.getKlass(o.type, namespace);\n        klass.fromObject(o, function (obj, error) {\n          error || (enlivenedObjects[index] = obj);\n          reviver && reviver(o, obj, error);\n          onLoaded();\n        });\n      });\n    },\n\n    /**\n     * Create and wait for loading of patterns\n     * @static\n     * @memberOf fabric.util\n     * @param {Array} patterns Objects to enliven\n     * @param {Function} callback Callback to invoke when all objects are created\n     * called after each fabric object created.\n     */\n    enlivenPatterns: function(patterns, callback) {\n      patterns = patterns || [];\n\n      function onLoaded() {\n        if (++numLoadedPatterns === numPatterns) {\n          callback && callback(enlivenedPatterns);\n        }\n      }\n\n      var enlivenedPatterns = [],\n          numLoadedPatterns = 0,\n          numPatterns = patterns.length;\n\n      if (!numPatterns) {\n        callback && callback(enlivenedPatterns);\n        return;\n      }\n\n      patterns.forEach(function (p, index) {\n        if (p && p.source) {\n          new fabric.Pattern(p, function(pattern) {\n            enlivenedPatterns[index] = pattern;\n            onLoaded();\n          });\n        }\n        else {\n          enlivenedPatterns[index] = p;\n          onLoaded();\n        }\n      });\n    },\n\n    /**\n     * Groups SVG elements (usually those retrieved from SVG document)\n     * @static\n     * @memberOf fabric.util\n     * @param {Array} elements SVG elements to group\n     * @param {Object} [options] Options object\n     * @param {String} path Value to set sourcePath to\n     * @return {fabric.Object|fabric.Group}\n     */\n    groupSVGElements: function(elements, options, path) {\n      var object;\n      if (elements && elements.length === 1) {\n        return elements[0];\n      }\n      if (options) {\n        if (options.width && options.height) {\n          options.centerPoint = {\n            x: options.width / 2,\n            y: options.height / 2\n          };\n        }\n        else {\n          delete options.width;\n          delete options.height;\n        }\n      }\n      object = new fabric.Group(elements, options);\n      if (typeof path !== 'undefined') {\n        object.sourcePath = path;\n      }\n      return object;\n    },\n\n    /**\n     * Populates an object with properties of another object\n     * @static\n     * @memberOf fabric.util\n     * @param {Object} source Source object\n     * @param {Object} destination Destination object\n     * @return {Array} properties Properties names to include\n     */\n    populateWithProperties: function(source, destination, properties) {\n      if (properties && Object.prototype.toString.call(properties) === '[object Array]') {\n        for (var i = 0, len = properties.length; i < len; i++) {\n          if (properties[i] in source) {\n            destination[properties[i]] = source[properties[i]];\n          }\n        }\n      }\n    },\n\n    /**\n     * Draws a dashed line between two points\n     *\n     * This method is used to draw dashed line around selection area.\n     * See <a href=\"http://stackoverflow.com/questions/4576724/dotted-stroke-in-canvas\">dotted stroke in canvas</a>\n     *\n     * @param {CanvasRenderingContext2D} ctx context\n     * @param {Number} x  start x coordinate\n     * @param {Number} y start y coordinate\n     * @param {Number} x2 end x coordinate\n     * @param {Number} y2 end y coordinate\n     * @param {Array} da dash array pattern\n     */\n    drawDashedLine: function(ctx, x, y, x2, y2, da) {\n      var dx = x2 - x,\n          dy = y2 - y,\n          len = sqrt(dx * dx + dy * dy),\n          rot = atan2(dy, dx),\n          dc = da.length,\n          di = 0,\n          draw = true;\n\n      ctx.save();\n      ctx.translate(x, y);\n      ctx.moveTo(0, 0);\n      ctx.rotate(rot);\n\n      x = 0;\n      while (len > x) {\n        x += da[di++ % dc];\n        if (x > len) {\n          x = len;\n        }\n        ctx[draw ? 'lineTo' : 'moveTo'](x, 0);\n        draw = !draw;\n      }\n\n      ctx.restore();\n    },\n\n    /**\n     * Creates canvas element\n     * @static\n     * @memberOf fabric.util\n     * @return {CanvasElement} initialized canvas element\n     */\n    createCanvasElement: function() {\n      return fabric.document.createElement('canvas');\n    },\n\n    /**\n     * Creates a canvas element that is a copy of another and is also painted\n     * @param {CanvasElement} canvas to copy size and content of\n     * @static\n     * @memberOf fabric.util\n     * @return {CanvasElement} initialized canvas element\n     */\n    copyCanvasElement: function(canvas) {\n      var newCanvas = fabric.util.createCanvasElement();\n      newCanvas.width = canvas.width;\n      newCanvas.height = canvas.height;\n      newCanvas.getContext('2d').drawImage(canvas, 0, 0);\n      return newCanvas;\n    },\n\n    /**\n     * since 2.6.0 moved from canvas instance to utility.\n     * @param {CanvasElement} canvasEl to copy size and content of\n     * @param {String} format 'jpeg' or 'png', in some browsers 'webp' is ok too\n     * @param {Number} quality <= 1 and > 0\n     * @static\n     * @memberOf fabric.util\n     * @return {String} data url\n     */\n    toDataURL: function(canvasEl, format, quality) {\n      return canvasEl.toDataURL('image/' + format, quality);\n    },\n\n    /**\n     * Creates image element (works on client and node)\n     * @static\n     * @memberOf fabric.util\n     * @return {HTMLImageElement} HTML image element\n     */\n    createImage: function() {\n      return fabric.document.createElement('img');\n    },\n\n    /**\n     * @static\n     * @memberOf fabric.util\n     * @deprecated since 2.0.0\n     * @param {fabric.Object} receiver Object implementing `clipTo` method\n     * @param {CanvasRenderingContext2D} ctx Context to clip\n     */\n    clipContext: function(receiver, ctx) {\n      ctx.save();\n      ctx.beginPath();\n      receiver.clipTo(ctx);\n      ctx.clip();\n    },\n\n    /**\n     * Multiply matrix A by matrix B to nest transformations\n     * @static\n     * @memberOf fabric.util\n     * @param  {Array} a First transformMatrix\n     * @param  {Array} b Second transformMatrix\n     * @param  {Boolean} is2x2 flag to multiply matrices as 2x2 matrices\n     * @return {Array} The product of the two transform matrices\n     */\n    multiplyTransformMatrices: function(a, b, is2x2) {\n      // Matrix multiply a * b\n      return [\n        a[0] * b[0] + a[2] * b[1],\n        a[1] * b[0] + a[3] * b[1],\n        a[0] * b[2] + a[2] * b[3],\n        a[1] * b[2] + a[3] * b[3],\n        is2x2 ? 0 : a[0] * b[4] + a[2] * b[5] + a[4],\n        is2x2 ? 0 : a[1] * b[4] + a[3] * b[5] + a[5]\n      ];\n    },\n\n    /**\n     * Decomposes standard 2x2 matrix into transform componentes\n     * @static\n     * @memberOf fabric.util\n     * @param  {Array} a transformMatrix\n     * @return {Object} Components of transform\n     */\n    qrDecompose: function(a) {\n      var angle = atan2(a[1], a[0]),\n          denom = pow(a[0], 2) + pow(a[1], 2),\n          scaleX = sqrt(denom),\n          scaleY = (a[0] * a[3] - a[2] * a [1]) / scaleX,\n          skewX = atan2(a[0] * a[2] + a[1] * a [3], denom);\n      return {\n        angle: angle  / PiBy180,\n        scaleX: scaleX,\n        scaleY: scaleY,\n        skewX: skewX / PiBy180,\n        skewY: 0,\n        translateX: a[4],\n        translateY: a[5]\n      };\n    },\n\n    customTransformMatrix: function(scaleX, scaleY, skewX) {\n      var skewMatrixX = [1, 0, abs(Math.tan(skewX * PiBy180)), 1],\n          scaleMatrix = [abs(scaleX), 0, 0, abs(scaleY)];\n      return fabric.util.multiplyTransformMatrices(scaleMatrix, skewMatrixX, true);\n    },\n\n    /**\n     * reset an object transform state to neutral. Top and left are not accounted for\n     * @static\n     * @memberOf fabric.util\n     * @param  {fabric.Object} target object to transform\n     */\n    resetObjectTransform: function (target) {\n      target.scaleX = 1;\n      target.scaleY = 1;\n      target.skewX = 0;\n      target.skewY = 0;\n      target.flipX = false;\n      target.flipY = false;\n      target.rotate(0);\n    },\n\n    /**\n     * Extract Object transform values\n     * @static\n     * @memberOf fabric.util\n     * @param  {fabric.Object} target object to read from\n     * @return {Object} Components of transform\n     */\n    saveObjectTransform: function (target) {\n      return {\n        scaleX: target.scaleX,\n        scaleY: target.scaleY,\n        skewX: target.skewX,\n        skewY: target.skewY,\n        angle: target.angle,\n        left: target.left,\n        flipX: target.flipX,\n        flipY: target.flipY,\n        top: target.top\n      };\n    },\n\n    /**\n     * Returns string representation of function body\n     * @param {Function} fn Function to get body of\n     * @return {String} Function body\n     */\n    getFunctionBody: function(fn) {\n      return (String(fn).match(/function[^{]*\\{([\\s\\S]*)\\}/) || {})[1];\n    },\n\n    /**\n     * Returns true if context has transparent pixel\n     * at specified location (taking tolerance into account)\n     * @param {CanvasRenderingContext2D} ctx context\n     * @param {Number} x x coordinate\n     * @param {Number} y y coordinate\n     * @param {Number} tolerance Tolerance\n     */\n    isTransparent: function(ctx, x, y, tolerance) {\n\n      // If tolerance is > 0 adjust start coords to take into account.\n      // If moves off Canvas fix to 0\n      if (tolerance > 0) {\n        if (x > tolerance) {\n          x -= tolerance;\n        }\n        else {\n          x = 0;\n        }\n        if (y > tolerance) {\n          y -= tolerance;\n        }\n        else {\n          y = 0;\n        }\n      }\n\n      var _isTransparent = true, i, temp,\n          imageData = ctx.getImageData(x, y, (tolerance * 2) || 1, (tolerance * 2) || 1),\n          l = imageData.data.length;\n\n      // Split image data - for tolerance > 1, pixelDataSize = 4;\n      for (i = 3; i < l; i += 4) {\n        temp = imageData.data[i];\n        _isTransparent = temp <= 0;\n        if (_isTransparent === false) {\n          break; // Stop if colour found\n        }\n      }\n\n      imageData = null;\n\n      return _isTransparent;\n    },\n\n    /**\n     * Parse preserveAspectRatio attribute from element\n     * @param {string} attribute to be parsed\n     * @return {Object} an object containing align and meetOrSlice attribute\n     */\n    parsePreserveAspectRatioAttribute: function(attribute) {\n      var meetOrSlice = 'meet', alignX = 'Mid', alignY = 'Mid',\n          aspectRatioAttrs = attribute.split(' '), align;\n\n      if (aspectRatioAttrs && aspectRatioAttrs.length) {\n        meetOrSlice = aspectRatioAttrs.pop();\n        if (meetOrSlice !== 'meet' && meetOrSlice !== 'slice') {\n          align = meetOrSlice;\n          meetOrSlice = 'meet';\n        }\n        else if (aspectRatioAttrs.length) {\n          align = aspectRatioAttrs.pop();\n        }\n      }\n      //divide align in alignX and alignY\n      alignX = align !== 'none' ? align.slice(1, 4) : 'none';\n      alignY = align !== 'none' ? align.slice(5, 8) : 'none';\n      return {\n        meetOrSlice: meetOrSlice,\n        alignX: alignX,\n        alignY: alignY\n      };\n    },\n\n    /**\n     * Clear char widths cache for the given font family or all the cache if no\n     * fontFamily is specified.\n     * Use it if you know you are loading fonts in a lazy way and you are not waiting\n     * for custom fonts to load properly when adding text objects to the canvas.\n     * If a text object is added when its own font is not loaded yet, you will get wrong\n     * measurement and so wrong bounding boxes.\n     * After the font cache is cleared, either change the textObject text content or call\n     * initDimensions() to trigger a recalculation\n     * @memberOf fabric.util\n     * @param {String} [fontFamily] font family to clear\n     */\n    clearFabricFontCache: function(fontFamily) {\n      fontFamily = (fontFamily || '').toLowerCase();\n      if (!fontFamily) {\n        fabric.charWidthsCache = { };\n      }\n      else if (fabric.charWidthsCache[fontFamily]) {\n        delete fabric.charWidthsCache[fontFamily];\n      }\n    },\n\n    /**\n     * Given current aspect ratio, determines the max width and height that can\n     * respect the total allowed area for the cache.\n     * @memberOf fabric.util\n     * @param {Number} ar aspect ratio\n     * @param {Number} maximumArea Maximum area you want to achieve\n     * @return {Object.x} Limited dimensions by X\n     * @return {Object.y} Limited dimensions by Y\n     */\n    limitDimsByArea: function(ar, maximumArea) {\n      var roughWidth = Math.sqrt(maximumArea * ar),\n          perfLimitSizeY = Math.floor(maximumArea / roughWidth);\n      return { x: Math.floor(roughWidth), y: perfLimitSizeY };\n    },\n\n    capValue: function(min, value, max) {\n      return Math.max(min, Math.min(value, max));\n    },\n\n    findScaleToFit: function(source, destination) {\n      return Math.min(destination.width / source.width, destination.height / source.height);\n    },\n\n    findScaleToCover: function(source, destination) {\n      return Math.max(destination.width / source.width, destination.height / source.height);\n    },\n\n    /**\n     * given an array of 6 number returns something like `\"matrix(...numbers)\"`\n     * @memberOf fabric.util\n     * @param {Array} trasnform an array with 6 numbers\n     * @return {String} transform matrix for svg\n     * @return {Object.y} Limited dimensions by Y\n     */\n    matrixToSVG: function(transform) {\n      return 'matrix(' + transform.map(function(value) {\n        return fabric.util.toFixed(value, fabric.Object.NUM_FRACTION_DIGITS);\n      }).join(' ') + ')';\n    }\n  };\n})(typeof exports !== 'undefined' ? exports : this);\n\n\n(function() {\n\n  var _join = Array.prototype.join;\n\n  /* Adapted from http://dxr.mozilla.org/mozilla-central/source/content/svg/content/src/nsSVGPathDataParser.cpp\n   * by Andrea Bogazzi code is under MPL. if you don't have a copy of the license you can take it here\n   * http://mozilla.org/MPL/2.0/\n   */\n  function arcToSegments(toX, toY, rx, ry, large, sweep, rotateX) {\n    var argsString = _join.call(arguments);\n    if (fabric.arcToSegmentsCache[argsString]) {\n      return fabric.arcToSegmentsCache[argsString];\n    }\n\n    var PI = Math.PI, th = rotateX * PI / 180,\n        sinTh = fabric.util.sin(th),\n        cosTh = fabric.util.cos(th),\n        fromX = 0, fromY = 0;\n\n    rx = Math.abs(rx);\n    ry = Math.abs(ry);\n\n    var px = -cosTh * toX * 0.5 - sinTh * toY * 0.5,\n        py = -cosTh * toY * 0.5 + sinTh * toX * 0.5,\n        rx2 = rx * rx, ry2 = ry * ry, py2 = py * py, px2 = px * px,\n        pl = rx2 * ry2 - rx2 * py2 - ry2 * px2,\n        root = 0;\n\n    if (pl < 0) {\n      var s = Math.sqrt(1 - pl / (rx2 * ry2));\n      rx *= s;\n      ry *= s;\n    }\n    else {\n      root = (large === sweep ? -1.0 : 1.0) *\n              Math.sqrt( pl / (rx2 * py2 + ry2 * px2));\n    }\n\n    var cx = root * rx * py / ry,\n        cy = -root * ry * px / rx,\n        cx1 = cosTh * cx - sinTh * cy + toX * 0.5,\n        cy1 = sinTh * cx + cosTh * cy + toY * 0.5,\n        mTheta = calcVectorAngle(1, 0, (px - cx) / rx, (py - cy) / ry),\n        dtheta = calcVectorAngle((px - cx) / rx, (py - cy) / ry, (-px - cx) / rx, (-py - cy) / ry);\n\n    if (sweep === 0 && dtheta > 0) {\n      dtheta -= 2 * PI;\n    }\n    else if (sweep === 1 && dtheta < 0) {\n      dtheta += 2 * PI;\n    }\n\n    // Convert into cubic bezier segments <= 90deg\n    var segments = Math.ceil(Math.abs(dtheta / PI * 2)),\n        result = [], mDelta = dtheta / segments,\n        mT = 8 / 3 * Math.sin(mDelta / 4) * Math.sin(mDelta / 4) / Math.sin(mDelta / 2),\n        th3 = mTheta + mDelta;\n\n    for (var i = 0; i < segments; i++) {\n      result[i] = segmentToBezier(mTheta, th3, cosTh, sinTh, rx, ry, cx1, cy1, mT, fromX, fromY);\n      fromX = result[i][4];\n      fromY = result[i][5];\n      mTheta = th3;\n      th3 += mDelta;\n    }\n    fabric.arcToSegmentsCache[argsString] = result;\n    return result;\n  }\n\n  function segmentToBezier(th2, th3, cosTh, sinTh, rx, ry, cx1, cy1, mT, fromX, fromY) {\n    var costh2 = fabric.util.cos(th2),\n        sinth2 = fabric.util.sin(th2),\n        costh3 = fabric.util.cos(th3),\n        sinth3 = fabric.util.sin(th3),\n        toX = cosTh * rx * costh3 - sinTh * ry * sinth3 + cx1,\n        toY = sinTh * rx * costh3 + cosTh * ry * sinth3 + cy1,\n        cp1X = fromX + mT * ( -cosTh * rx * sinth2 - sinTh * ry * costh2),\n        cp1Y = fromY + mT * ( -sinTh * rx * sinth2 + cosTh * ry * costh2),\n        cp2X = toX + mT * ( cosTh * rx * sinth3 + sinTh * ry * costh3),\n        cp2Y = toY + mT * ( sinTh * rx * sinth3 - cosTh * ry * costh3);\n\n    return [\n      cp1X, cp1Y,\n      cp2X, cp2Y,\n      toX, toY\n    ];\n  }\n\n  /*\n   * Private\n   */\n  function calcVectorAngle(ux, uy, vx, vy) {\n    var ta = Math.atan2(uy, ux),\n        tb = Math.atan2(vy, vx);\n    if (tb >= ta) {\n      return tb - ta;\n    }\n    else {\n      return 2 * Math.PI - (ta - tb);\n    }\n  }\n\n  /**\n   * Draws arc\n   * @param {CanvasRenderingContext2D} ctx\n   * @param {Number} fx\n   * @param {Number} fy\n   * @param {Array} coords\n   */\n  fabric.util.drawArc = function(ctx, fx, fy, coords) {\n    var rx = coords[0],\n        ry = coords[1],\n        rot = coords[2],\n        large = coords[3],\n        sweep = coords[4],\n        tx = coords[5],\n        ty = coords[6],\n        segs = [[], [], [], []],\n        segsNorm = arcToSegments(tx - fx, ty - fy, rx, ry, large, sweep, rot);\n\n    for (var i = 0, len = segsNorm.length; i < len; i++) {\n      segs[i][0] = segsNorm[i][0] + fx;\n      segs[i][1] = segsNorm[i][1] + fy;\n      segs[i][2] = segsNorm[i][2] + fx;\n      segs[i][3] = segsNorm[i][3] + fy;\n      segs[i][4] = segsNorm[i][4] + fx;\n      segs[i][5] = segsNorm[i][5] + fy;\n      ctx.bezierCurveTo.apply(ctx, segs[i]);\n    }\n  };\n\n  /**\n   * Calculate bounding box of a elliptic-arc\n   * @param {Number} fx start point of arc\n   * @param {Number} fy\n   * @param {Number} rx horizontal radius\n   * @param {Number} ry vertical radius\n   * @param {Number} rot angle of horizontal axe\n   * @param {Number} large 1 or 0, whatever the arc is the big or the small on the 2 points\n   * @param {Number} sweep 1 or 0, 1 clockwise or counterclockwise direction\n   * @param {Number} tx end point of arc\n   * @param {Number} ty\n   */\n  fabric.util.getBoundsOfArc = function(fx, fy, rx, ry, rot, large, sweep, tx, ty) {\n\n    var fromX = 0, fromY = 0, bound, bounds = [],\n        segs = arcToSegments(tx - fx, ty - fy, rx, ry, large, sweep, rot);\n\n    for (var i = 0, len = segs.length; i < len; i++) {\n      bound = getBoundsOfCurve(fromX, fromY, segs[i][0], segs[i][1], segs[i][2], segs[i][3], segs[i][4], segs[i][5]);\n      bounds.push({ x: bound[0].x + fx, y: bound[0].y + fy });\n      bounds.push({ x: bound[1].x + fx, y: bound[1].y + fy });\n      fromX = segs[i][4];\n      fromY = segs[i][5];\n    }\n    return bounds;\n  };\n\n  /**\n   * Calculate bounding box of a beziercurve\n   * @param {Number} x0 starting point\n   * @param {Number} y0\n   * @param {Number} x1 first control point\n   * @param {Number} y1\n   * @param {Number} x2 secondo control point\n   * @param {Number} y2\n   * @param {Number} x3 end of beizer\n   * @param {Number} y3\n   */\n  // taken from http://jsbin.com/ivomiq/56/edit  no credits available for that.\n  function getBoundsOfCurve(x0, y0, x1, y1, x2, y2, x3, y3) {\n    var argsString;\n    if (fabric.cachesBoundsOfCurve) {\n      argsString = _join.call(arguments);\n      if (fabric.boundsOfCurveCache[argsString]) {\n        return fabric.boundsOfCurveCache[argsString];\n      }\n    }\n\n    var sqrt = Math.sqrt,\n        min = Math.min, max = Math.max,\n        abs = Math.abs, tvalues = [],\n        bounds = [[], []],\n        a, b, c, t, t1, t2, b2ac, sqrtb2ac;\n\n    b = 6 * x0 - 12 * x1 + 6 * x2;\n    a = -3 * x0 + 9 * x1 - 9 * x2 + 3 * x3;\n    c = 3 * x1 - 3 * x0;\n\n    for (var i = 0; i < 2; ++i) {\n      if (i > 0) {\n        b = 6 * y0 - 12 * y1 + 6 * y2;\n        a = -3 * y0 + 9 * y1 - 9 * y2 + 3 * y3;\n        c = 3 * y1 - 3 * y0;\n      }\n\n      if (abs(a) < 1e-12) {\n        if (abs(b) < 1e-12) {\n          continue;\n        }\n        t = -c / b;\n        if (0 < t && t < 1) {\n          tvalues.push(t);\n        }\n        continue;\n      }\n      b2ac = b * b - 4 * c * a;\n      if (b2ac < 0) {\n        continue;\n      }\n      sqrtb2ac = sqrt(b2ac);\n      t1 = (-b + sqrtb2ac) / (2 * a);\n      if (0 < t1 && t1 < 1) {\n        tvalues.push(t1);\n      }\n      t2 = (-b - sqrtb2ac) / (2 * a);\n      if (0 < t2 && t2 < 1) {\n        tvalues.push(t2);\n      }\n    }\n\n    var x, y, j = tvalues.length, jlen = j, mt;\n    while (j--) {\n      t = tvalues[j];\n      mt = 1 - t;\n      x = (mt * mt * mt * x0) + (3 * mt * mt * t * x1) + (3 * mt * t * t * x2) + (t * t * t * x3);\n      bounds[0][j] = x;\n\n      y = (mt * mt * mt * y0) + (3 * mt * mt * t * y1) + (3 * mt * t * t * y2) + (t * t * t * y3);\n      bounds[1][j] = y;\n    }\n\n    bounds[0][jlen] = x0;\n    bounds[1][jlen] = y0;\n    bounds[0][jlen + 1] = x3;\n    bounds[1][jlen + 1] = y3;\n    var result = [\n      {\n        x: min.apply(null, bounds[0]),\n        y: min.apply(null, bounds[1])\n      },\n      {\n        x: max.apply(null, bounds[0]),\n        y: max.apply(null, bounds[1])\n      }\n    ];\n    if (fabric.cachesBoundsOfCurve) {\n      fabric.boundsOfCurveCache[argsString] = result;\n    }\n    return result;\n  }\n\n  fabric.util.getBoundsOfCurve = getBoundsOfCurve;\n\n})();\n\n\n(function() {\n\n  var slice = Array.prototype.slice;\n\n  /**\n   * Invokes method on all items in a given array\n   * @memberOf fabric.util.array\n   * @param {Array} array Array to iterate over\n   * @param {String} method Name of a method to invoke\n   * @return {Array}\n   */\n  function invoke(array, method) {\n    var args = slice.call(arguments, 2), result = [];\n    for (var i = 0, len = array.length; i < len; i++) {\n      result[i] = args.length ? array[i][method].apply(array[i], args) : array[i][method].call(array[i]);\n    }\n    return result;\n  }\n\n  /**\n   * Finds maximum value in array (not necessarily \"first\" one)\n   * @memberOf fabric.util.array\n   * @param {Array} array Array to iterate over\n   * @param {String} byProperty\n   * @return {*}\n   */\n  function max(array, byProperty) {\n    return find(array, byProperty, function(value1, value2) {\n      return value1 >= value2;\n    });\n  }\n\n  /**\n   * Finds minimum value in array (not necessarily \"first\" one)\n   * @memberOf fabric.util.array\n   * @param {Array} array Array to iterate over\n   * @param {String} byProperty\n   * @return {*}\n   */\n  function min(array, byProperty) {\n    return find(array, byProperty, function(value1, value2) {\n      return value1 < value2;\n    });\n  }\n\n  /**\n   * @private\n   */\n  function fill(array, value) {\n    var k = array.length;\n    while (k--) {\n      array[k] = value;\n    }\n    return array;\n  }\n\n  /**\n   * @private\n   */\n  function find(array, byProperty, condition) {\n    if (!array || array.length === 0) {\n      return;\n    }\n\n    var i = array.length - 1,\n        result = byProperty ? array[i][byProperty] : array[i];\n    if (byProperty) {\n      while (i--) {\n        if (condition(array[i][byProperty], result)) {\n          result = array[i][byProperty];\n        }\n      }\n    }\n    else {\n      while (i--) {\n        if (condition(array[i], result)) {\n          result = array[i];\n        }\n      }\n    }\n    return result;\n  }\n\n  /**\n   * @namespace fabric.util.array\n   */\n  fabric.util.array = {\n    fill: fill,\n    invoke: invoke,\n    min: min,\n    max: max\n  };\n\n})();\n\n\n(function() {\n  /**\n   * Copies all enumerable properties of one js object to another\n   * this does not and cannot compete with generic utils.\n   * Does not clone or extend fabric.Object subclasses.\n   * This is mostly for internal use and has extra handling for fabricJS objects\n   * it skips the canvas property in deep cloning.\n   * @memberOf fabric.util.object\n   * @param {Object} destination Where to copy to\n   * @param {Object} source Where to copy from\n   * @return {Object}\n   */\n\n  function extend(destination, source, deep) {\n    // JScript DontEnum bug is not taken care of\n    // the deep clone is for internal use, is not meant to avoid\n    // javascript traps or cloning html element or self referenced objects.\n    if (deep) {\n      if (!fabric.isLikelyNode && source instanceof Element) {\n        // avoid cloning deep images, canvases,\n        destination = source;\n      }\n      else if (source instanceof Array) {\n        destination = [];\n        for (var i = 0, len = source.length; i < len; i++) {\n          destination[i] = extend({ }, source[i], deep);\n        }\n      }\n      else if (source && typeof source === 'object') {\n        for (var property in source) {\n          if (property === 'canvas') {\n            destination[property] = extend({ }, source[property]);\n          }\n          else if (source.hasOwnProperty(property)) {\n            destination[property] = extend({ }, source[property], deep);\n          }\n        }\n      }\n      else {\n        // this sounds odd for an extend but is ok for recursive use\n        destination = source;\n      }\n    }\n    else {\n      for (var property in source) {\n        destination[property] = source[property];\n      }\n    }\n    return destination;\n  }\n\n  /**\n   * Creates an empty object and copies all enumerable properties of another object to it\n   * @memberOf fabric.util.object\n   * TODO: this function return an empty object if you try to clone null\n   * @param {Object} object Object to clone\n   * @return {Object}\n   */\n  function clone(object, deep) {\n    return extend({ }, object, deep);\n  }\n\n  /** @namespace fabric.util.object */\n  fabric.util.object = {\n    extend: extend,\n    clone: clone\n  };\n  fabric.util.object.extend(fabric.util, fabric.Observable);\n})();\n\n\n(function() {\n\n  /**\n   * Camelizes a string\n   * @memberOf fabric.util.string\n   * @param {String} string String to camelize\n   * @return {String} Camelized version of a string\n   */\n  function camelize(string) {\n    return string.replace(/-+(.)?/g, function(match, character) {\n      return character ? character.toUpperCase() : '';\n    });\n  }\n\n  /**\n   * Capitalizes a string\n   * @memberOf fabric.util.string\n   * @param {String} string String to capitalize\n   * @param {Boolean} [firstLetterOnly] If true only first letter is capitalized\n   * and other letters stay untouched, if false first letter is capitalized\n   * and other letters are converted to lowercase.\n   * @return {String} Capitalized version of a string\n   */\n  function capitalize(string, firstLetterOnly) {\n    return string.charAt(0).toUpperCase() +\n      (firstLetterOnly ? string.slice(1) : string.slice(1).toLowerCase());\n  }\n\n  /**\n   * Escapes XML in a string\n   * @memberOf fabric.util.string\n   * @param {String} string String to escape\n   * @return {String} Escaped version of a string\n   */\n  function escapeXml(string) {\n    return string.replace(/&/g, '&amp;')\n      .replace(/\"/g, '&quot;')\n      .replace(/'/g, '&apos;')\n      .replace(/</g, '&lt;')\n      .replace(/>/g, '&gt;');\n  }\n\n  /**\n   * Divide a string in the user perceived single units\n   * @memberOf fabric.util.string\n   * @param {String} textstring String to escape\n   * @return {Array} array containing the graphemes\n   */\n  function graphemeSplit(textstring) {\n    var i = 0, chr, graphemes = [];\n    for (i = 0, chr; i < textstring.length; i++) {\n      if ((chr = getWholeChar(textstring, i)) === false) {\n        continue;\n      }\n      graphemes.push(chr);\n    }\n    return graphemes;\n  }\n\n  // taken from mdn in the charAt doc page.\n  function getWholeChar(str, i) {\n    var code = str.charCodeAt(i);\n\n    if (isNaN(code)) {\n      return ''; // Position not found\n    }\n    if (code < 0xD800 || code > 0xDFFF) {\n      return str.charAt(i);\n    }\n\n    // High surrogate (could change last hex to 0xDB7F to treat high private\n    // surrogates as single characters)\n    if (0xD800 <= code && code <= 0xDBFF) {\n      if (str.length <= (i + 1)) {\n        throw 'High surrogate without following low surrogate';\n      }\n      var next = str.charCodeAt(i + 1);\n      if (0xDC00 > next || next > 0xDFFF) {\n        throw 'High surrogate without following low surrogate';\n      }\n      return str.charAt(i) + str.charAt(i + 1);\n    }\n    // Low surrogate (0xDC00 <= code && code <= 0xDFFF)\n    if (i === 0) {\n      throw 'Low surrogate without preceding high surrogate';\n    }\n    var prev = str.charCodeAt(i - 1);\n\n    // (could change last hex to 0xDB7F to treat high private\n    // surrogates as single characters)\n    if (0xD800 > prev || prev > 0xDBFF) {\n      throw 'Low surrogate without preceding high surrogate';\n    }\n    // We can pass over low surrogates now as the second component\n    // in a pair which we have already processed\n    return false;\n  }\n\n\n  /**\n   * String utilities\n   * @namespace fabric.util.string\n   */\n  fabric.util.string = {\n    camelize: camelize,\n    capitalize: capitalize,\n    escapeXml: escapeXml,\n    graphemeSplit: graphemeSplit\n  };\n})();\n\n\n(function() {\n\n  var slice = Array.prototype.slice, emptyFunction = function() { },\n\n      IS_DONTENUM_BUGGY = (function() {\n        for (var p in { toString: 1 }) {\n          if (p === 'toString') {\n            return false;\n          }\n        }\n        return true;\n      })(),\n\n      /** @ignore */\n      addMethods = function(klass, source, parent) {\n        for (var property in source) {\n\n          if (property in klass.prototype &&\n              typeof klass.prototype[property] === 'function' &&\n              (source[property] + '').indexOf('callSuper') > -1) {\n\n            klass.prototype[property] = (function(property) {\n              return function() {\n\n                var superclass = this.constructor.superclass;\n                this.constructor.superclass = parent;\n                var returnValue = source[property].apply(this, arguments);\n                this.constructor.superclass = superclass;\n\n                if (property !== 'initialize') {\n                  return returnValue;\n                }\n              };\n            })(property);\n          }\n          else {\n            klass.prototype[property] = source[property];\n          }\n\n          if (IS_DONTENUM_BUGGY) {\n            if (source.toString !== Object.prototype.toString) {\n              klass.prototype.toString = source.toString;\n            }\n            if (source.valueOf !== Object.prototype.valueOf) {\n              klass.prototype.valueOf = source.valueOf;\n            }\n          }\n        }\n      };\n\n  function Subclass() { }\n\n  function callSuper(methodName) {\n    var parentMethod = null,\n        _this = this;\n\n    // climb prototype chain to find method not equal to callee's method\n    while (_this.constructor.superclass) {\n      var superClassMethod = _this.constructor.superclass.prototype[methodName];\n      if (_this[methodName] !== superClassMethod) {\n        parentMethod = superClassMethod;\n        break;\n      }\n      // eslint-disable-next-line\n      _this = _this.constructor.superclass.prototype;\n    }\n\n    if (!parentMethod) {\n      return console.log('tried to callSuper ' + methodName + ', method not found in prototype chain', this);\n    }\n\n    return (arguments.length > 1)\n      ? parentMethod.apply(this, slice.call(arguments, 1))\n      : parentMethod.call(this);\n  }\n\n  /**\n   * Helper for creation of \"classes\".\n   * @memberOf fabric.util\n   * @param {Function} [parent] optional \"Class\" to inherit from\n   * @param {Object} [properties] Properties shared by all instances of this class\n   *                  (be careful modifying objects defined here as this would affect all instances)\n   */\n  function createClass() {\n    var parent = null,\n        properties = slice.call(arguments, 0);\n\n    if (typeof properties[0] === 'function') {\n      parent = properties.shift();\n    }\n    function klass() {\n      this.initialize.apply(this, arguments);\n    }\n\n    klass.superclass = parent;\n    klass.subclasses = [];\n\n    if (parent) {\n      Subclass.prototype = parent.prototype;\n      klass.prototype = new Subclass();\n      parent.subclasses.push(klass);\n    }\n    for (var i = 0, length = properties.length; i < length; i++) {\n      addMethods(klass, properties[i], parent);\n    }\n    if (!klass.prototype.initialize) {\n      klass.prototype.initialize = emptyFunction;\n    }\n    klass.prototype.constructor = klass;\n    klass.prototype.callSuper = callSuper;\n    return klass;\n  }\n\n  fabric.util.createClass = createClass;\n})();\n\n\n(function () {\n  // since ie10 or ie9 can use addEventListener but they do not support options, i need to check\n  var couldUseAttachEvent = !!fabric.document.createElement('div').attachEvent;\n  /**\n   * Adds an event listener to an element\n   * @function\n   * @memberOf fabric.util\n   * @param {HTMLElement} element\n   * @param {String} eventName\n   * @param {Function} handler\n   */\n  fabric.util.addListener = function(element, eventName, handler, options) {\n    element && element.addEventListener(eventName, handler, couldUseAttachEvent ? false : options);\n  };\n\n  /**\n   * Removes an event listener from an element\n   * @function\n   * @memberOf fabric.util\n   * @param {HTMLElement} element\n   * @param {String} eventName\n   * @param {Function} handler\n   */\n  fabric.util.removeListener = function(element, eventName, handler, options) {\n    element && element.removeEventListener(eventName, handler, couldUseAttachEvent ? false : options);\n  };\n\n  function getTouchInfo(event) {\n    var touchProp = event.changedTouches;\n    if (touchProp && touchProp[0]) {\n      return touchProp[0];\n    }\n    return event;\n  }\n\n  fabric.util.getPointer = function(event) {\n    var element = event.target,\n        scroll = fabric.util.getScrollLeftTop(element),\n        _evt = getTouchInfo(event);\n    return {\n      x: _evt.clientX + scroll.left,\n      y: _evt.clientY + scroll.top\n    };\n  };\n})();\n\n\n(function () {\n\n  /**\n   * Cross-browser wrapper for setting element's style\n   * @memberOf fabric.util\n   * @param {HTMLElement} element\n   * @param {Object} styles\n   * @return {HTMLElement} Element that was passed as a first argument\n   */\n  function setStyle(element, styles) {\n    var elementStyle = element.style;\n    if (!elementStyle) {\n      return element;\n    }\n    if (typeof styles === 'string') {\n      element.style.cssText += ';' + styles;\n      return styles.indexOf('opacity') > -1\n        ? setOpacity(element, styles.match(/opacity:\\s*(\\d?\\.?\\d*)/)[1])\n        : element;\n    }\n    for (var property in styles) {\n      if (property === 'opacity') {\n        setOpacity(element, styles[property]);\n      }\n      else {\n        var normalizedProperty = (property === 'float' || property === 'cssFloat')\n          ? (typeof elementStyle.styleFloat === 'undefined' ? 'cssFloat' : 'styleFloat')\n          : property;\n        elementStyle[normalizedProperty] = styles[property];\n      }\n    }\n    return element;\n  }\n\n  var parseEl = fabric.document.createElement('div'),\n      supportsOpacity = typeof parseEl.style.opacity === 'string',\n      supportsFilters = typeof parseEl.style.filter === 'string',\n      reOpacity = /alpha\\s*\\(\\s*opacity\\s*=\\s*([^\\)]+)\\)/,\n\n      /** @ignore */\n      setOpacity = function (element) { return element; };\n\n  if (supportsOpacity) {\n    /** @ignore */\n    setOpacity = function(element, value) {\n      element.style.opacity = value;\n      return element;\n    };\n  }\n  else if (supportsFilters) {\n    /** @ignore */\n    setOpacity = function(element, value) {\n      var es = element.style;\n      if (element.currentStyle && !element.currentStyle.hasLayout) {\n        es.zoom = 1;\n      }\n      if (reOpacity.test(es.filter)) {\n        value = value >= 0.9999 ? '' : ('alpha(opacity=' + (value * 100) + ')');\n        es.filter = es.filter.replace(reOpacity, value);\n      }\n      else {\n        es.filter += ' alpha(opacity=' + (value * 100) + ')';\n      }\n      return element;\n    };\n  }\n\n  fabric.util.setStyle = setStyle;\n\n})();\n\n\n(function() {\n\n  var _slice = Array.prototype.slice;\n\n  /**\n   * Takes id and returns an element with that id (if one exists in a document)\n   * @memberOf fabric.util\n   * @param {String|HTMLElement} id\n   * @return {HTMLElement|null}\n   */\n  function getById(id) {\n    return typeof id === 'string' ? fabric.document.getElementById(id) : id;\n  }\n\n  var sliceCanConvertNodelists,\n      /**\n       * Converts an array-like object (e.g. arguments or NodeList) to an array\n       * @memberOf fabric.util\n       * @param {Object} arrayLike\n       * @return {Array}\n       */\n      toArray = function(arrayLike) {\n        return _slice.call(arrayLike, 0);\n      };\n\n  try {\n    sliceCanConvertNodelists = toArray(fabric.document.childNodes) instanceof Array;\n  }\n  catch (err) { }\n\n  if (!sliceCanConvertNodelists) {\n    toArray = function(arrayLike) {\n      var arr = new Array(arrayLike.length), i = arrayLike.length;\n      while (i--) {\n        arr[i] = arrayLike[i];\n      }\n      return arr;\n    };\n  }\n\n  /**\n   * Creates specified element with specified attributes\n   * @memberOf fabric.util\n   * @param {String} tagName Type of an element to create\n   * @param {Object} [attributes] Attributes to set on an element\n   * @return {HTMLElement} Newly created element\n   */\n  function makeElement(tagName, attributes) {\n    var el = fabric.document.createElement(tagName);\n    for (var prop in attributes) {\n      if (prop === 'class') {\n        el.className = attributes[prop];\n      }\n      else if (prop === 'for') {\n        el.htmlFor = attributes[prop];\n      }\n      else {\n        el.setAttribute(prop, attributes[prop]);\n      }\n    }\n    return el;\n  }\n\n  /**\n   * Adds class to an element\n   * @memberOf fabric.util\n   * @param {HTMLElement} element Element to add class to\n   * @param {String} className Class to add to an element\n   */\n  function addClass(element, className) {\n    if (element && (' ' + element.className + ' ').indexOf(' ' + className + ' ') === -1) {\n      element.className += (element.className ? ' ' : '') + className;\n    }\n  }\n\n  /**\n   * Wraps element with another element\n   * @memberOf fabric.util\n   * @param {HTMLElement} element Element to wrap\n   * @param {HTMLElement|String} wrapper Element to wrap with\n   * @param {Object} [attributes] Attributes to set on a wrapper\n   * @return {HTMLElement} wrapper\n   */\n  function wrapElement(element, wrapper, attributes) {\n    if (typeof wrapper === 'string') {\n      wrapper = makeElement(wrapper, attributes);\n    }\n    if (element.parentNode) {\n      element.parentNode.replaceChild(wrapper, element);\n    }\n    wrapper.appendChild(element);\n    return wrapper;\n  }\n\n  /**\n   * Returns element scroll offsets\n   * @memberOf fabric.util\n   * @param {HTMLElement} element Element to operate on\n   * @return {Object} Object with left/top values\n   */\n  function getScrollLeftTop(element) {\n\n    var left = 0,\n        top = 0,\n        docElement = fabric.document.documentElement,\n        body = fabric.document.body || {\n          scrollLeft: 0, scrollTop: 0\n        };\n\n    // While loop checks (and then sets element to) .parentNode OR .host\n    //  to account for ShadowDOM. We still want to traverse up out of ShadowDOM,\n    //  but the .parentNode of a root ShadowDOM node will always be null, instead\n    //  it should be accessed through .host. See http://stackoverflow.com/a/24765528/4383938\n    while (element && (element.parentNode || element.host)) {\n\n      // Set element to element parent, or 'host' in case of ShadowDOM\n      element = element.parentNode || element.host;\n\n      if (element === fabric.document) {\n        left = body.scrollLeft || docElement.scrollLeft || 0;\n        top = body.scrollTop ||  docElement.scrollTop || 0;\n      }\n      else {\n        left += element.scrollLeft || 0;\n        top += element.scrollTop || 0;\n      }\n\n      if (element.nodeType === 1 && element.style.position === 'fixed') {\n        break;\n      }\n    }\n\n    return { left: left, top: top };\n  }\n\n  /**\n   * Returns offset for a given element\n   * @function\n   * @memberOf fabric.util\n   * @param {HTMLElement} element Element to get offset for\n   * @return {Object} Object with \"left\" and \"top\" properties\n   */\n  function getElementOffset(element) {\n    var docElem,\n        doc = element && element.ownerDocument,\n        box = { left: 0, top: 0 },\n        offset = { left: 0, top: 0 },\n        scrollLeftTop,\n        offsetAttributes = {\n          borderLeftWidth: 'left',\n          borderTopWidth:  'top',\n          paddingLeft:     'left',\n          paddingTop:      'top'\n        };\n\n    if (!doc) {\n      return offset;\n    }\n\n    for (var attr in offsetAttributes) {\n      offset[offsetAttributes[attr]] += parseInt(getElementStyle(element, attr), 10) || 0;\n    }\n\n    docElem = doc.documentElement;\n    if ( typeof element.getBoundingClientRect !== 'undefined' ) {\n      box = element.getBoundingClientRect();\n    }\n\n    scrollLeftTop = getScrollLeftTop(element);\n\n    return {\n      left: box.left + scrollLeftTop.left - (docElem.clientLeft || 0) + offset.left,\n      top: box.top + scrollLeftTop.top - (docElem.clientTop || 0)  + offset.top\n    };\n  }\n\n  /**\n   * Returns style attribute value of a given element\n   * @memberOf fabric.util\n   * @param {HTMLElement} element Element to get style attribute for\n   * @param {String} attr Style attribute to get for element\n   * @return {String} Style attribute value of the given element.\n   */\n  var getElementStyle;\n  if (fabric.document.defaultView && fabric.document.defaultView.getComputedStyle) {\n    getElementStyle = function(element, attr) {\n      var style = fabric.document.defaultView.getComputedStyle(element, null);\n      return style ? style[attr] : undefined;\n    };\n  }\n  else {\n    getElementStyle = function(element, attr) {\n      var value = element.style[attr];\n      if (!value && element.currentStyle) {\n        value = element.currentStyle[attr];\n      }\n      return value;\n    };\n  }\n\n  (function () {\n    var style = fabric.document.documentElement.style,\n        selectProp = 'userSelect' in style\n          ? 'userSelect'\n          : 'MozUserSelect' in style\n            ? 'MozUserSelect'\n            : 'WebkitUserSelect' in style\n              ? 'WebkitUserSelect'\n              : 'KhtmlUserSelect' in style\n                ? 'KhtmlUserSelect'\n                : '';\n\n    /**\n     * Makes element unselectable\n     * @memberOf fabric.util\n     * @param {HTMLElement} element Element to make unselectable\n     * @return {HTMLElement} Element that was passed in\n     */\n    function makeElementUnselectable(element) {\n      if (typeof element.onselectstart !== 'undefined') {\n        element.onselectstart = fabric.util.falseFunction;\n      }\n      if (selectProp) {\n        element.style[selectProp] = 'none';\n      }\n      else if (typeof element.unselectable === 'string') {\n        element.unselectable = 'on';\n      }\n      return element;\n    }\n\n    /**\n     * Makes element selectable\n     * @memberOf fabric.util\n     * @param {HTMLElement} element Element to make selectable\n     * @return {HTMLElement} Element that was passed in\n     */\n    function makeElementSelectable(element) {\n      if (typeof element.onselectstart !== 'undefined') {\n        element.onselectstart = null;\n      }\n      if (selectProp) {\n        element.style[selectProp] = '';\n      }\n      else if (typeof element.unselectable === 'string') {\n        element.unselectable = '';\n      }\n      return element;\n    }\n\n    fabric.util.makeElementUnselectable = makeElementUnselectable;\n    fabric.util.makeElementSelectable = makeElementSelectable;\n  })();\n\n  (function() {\n\n    /**\n     * Inserts a script element with a given url into a document; invokes callback, when that script is finished loading\n     * @memberOf fabric.util\n     * @param {String} url URL of a script to load\n     * @param {Function} callback Callback to execute when script is finished loading\n     */\n    function getScript(url, callback) {\n      var headEl = fabric.document.getElementsByTagName('head')[0],\n          scriptEl = fabric.document.createElement('script'),\n          loading = true;\n\n      /** @ignore */\n      scriptEl.onload = /** @ignore */ scriptEl.onreadystatechange = function(e) {\n        if (loading) {\n          if (typeof this.readyState === 'string' &&\n              this.readyState !== 'loaded' &&\n              this.readyState !== 'complete') {\n            return;\n          }\n          loading = false;\n          callback(e || fabric.window.event);\n          scriptEl = scriptEl.onload = scriptEl.onreadystatechange = null;\n        }\n      };\n      scriptEl.src = url;\n      headEl.appendChild(scriptEl);\n      // causes issue in Opera\n      // headEl.removeChild(scriptEl);\n    }\n\n    fabric.util.getScript = getScript;\n  })();\n\n  function getNodeCanvas(element) {\n    var impl = fabric.jsdomImplForWrapper(element);\n    return impl._canvas || impl._image;\n  };\n\n  function cleanUpJsdomNode(element) {\n    if (!fabric.isLikelyNode) {\n      return;\n    }\n    var impl = fabric.jsdomImplForWrapper(element);\n    if (impl) {\n      impl._image = null;\n      impl._canvas = null;\n      // unsure if necessary\n      impl._currentSrc = null;\n      impl._attributes = null;\n      impl._classList = null;\n    }\n  }\n\n  fabric.util.getById = getById;\n  fabric.util.toArray = toArray;\n  fabric.util.makeElement = makeElement;\n  fabric.util.addClass = addClass;\n  fabric.util.wrapElement = wrapElement;\n  fabric.util.getScrollLeftTop = getScrollLeftTop;\n  fabric.util.getElementOffset = getElementOffset;\n  fabric.util.getElementStyle = getElementStyle;\n  fabric.util.getNodeCanvas = getNodeCanvas;\n  fabric.util.cleanUpJsdomNode = cleanUpJsdomNode;\n\n})();\n\n\n(function() {\n\n  function addParamToUrl(url, param) {\n    return url + (/\\?/.test(url) ? '&' : '?') + param;\n  }\n\n  function emptyFn() { }\n\n  /**\n   * Cross-browser abstraction for sending XMLHttpRequest\n   * @memberOf fabric.util\n   * @param {String} url URL to send XMLHttpRequest to\n   * @param {Object} [options] Options object\n   * @param {String} [options.method=\"GET\"]\n   * @param {String} [options.parameters] parameters to append to url in GET or in body\n   * @param {String} [options.body] body to send with POST or PUT request\n   * @param {Function} options.onComplete Callback to invoke when request is completed\n   * @return {XMLHttpRequest} request\n   */\n  function request(url, options) {\n    options || (options = { });\n\n    var method = options.method ? options.method.toUpperCase() : 'GET',\n        onComplete = options.onComplete || function() { },\n        xhr = new fabric.window.XMLHttpRequest(),\n        body = options.body || options.parameters;\n\n    /** @ignore */\n    xhr.onreadystatechange = function() {\n      if (xhr.readyState === 4) {\n        onComplete(xhr);\n        xhr.onreadystatechange = emptyFn;\n      }\n    };\n\n    if (method === 'GET') {\n      body = null;\n      if (typeof options.parameters === 'string') {\n        url = addParamToUrl(url, options.parameters);\n      }\n    }\n\n    xhr.open(method, url, true);\n\n    if (method === 'POST' || method === 'PUT') {\n      xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');\n    }\n\n    xhr.send(body);\n    return xhr;\n  }\n\n  fabric.util.request = request;\n})();\n\n\n/**\n * Wrapper around `console.log` (when available)\n * @param {*} [values] Values to log\n */\nfabric.log = function() { };\n\n/**\n * Wrapper around `console.warn` (when available)\n * @param {*} [values] Values to log as a warning\n */\nfabric.warn = function() { };\n\n/* eslint-disable */\nif (typeof console !== 'undefined') {\n\n  ['log', 'warn'].forEach(function(methodName) {\n\n    if (typeof console[methodName] !== 'undefined' &&\n        typeof console[methodName].apply === 'function') {\n\n      fabric[methodName] = function() {\n        return console[methodName].apply(console, arguments);\n      };\n    }\n  });\n}\n/* eslint-enable */\n\n\n(function() {\n\n  function noop() {\n    return false;\n  }\n\n  /**\n   * Changes value from one to another within certain period of time, invoking callbacks as value is being changed.\n   * @memberOf fabric.util\n   * @param {Object} [options] Animation options\n   * @param {Function} [options.onChange] Callback; invoked on every value change\n   * @param {Function} [options.onComplete] Callback; invoked when value change is completed\n   * @param {Number} [options.startValue=0] Starting value\n   * @param {Number} [options.endValue=100] Ending value\n   * @param {Number} [options.byValue=100] Value to modify the property by\n   * @param {Function} [options.easing] Easing function\n   * @param {Number} [options.duration=500] Duration of change (in ms)\n   * @param {Function} [options.abort] Additional function with logic. If returns true, onComplete is called.\n   */\n  function animate(options) {\n\n    requestAnimFrame(function(timestamp) {\n      options || (options = { });\n\n      var start = timestamp || +new Date(),\n          duration = options.duration || 500,\n          finish = start + duration, time,\n          onChange = options.onChange || noop,\n          abort = options.abort || noop,\n          onComplete = options.onComplete || noop,\n          easing = options.easing || function(t, b, c, d) {return -c * Math.cos(t / d * (Math.PI / 2)) + c + b;},\n          startValue = 'startValue' in options ? options.startValue : 0,\n          endValue = 'endValue' in options ? options.endValue : 100,\n          byValue = options.byValue || endValue - startValue;\n\n      options.onStart && options.onStart();\n\n      (function tick(ticktime) {\n        // TODO: move abort call after calculation\n        // and pass (current,valuePerc, timePerc) as arguments\n        if (abort()) {\n          onComplete(endValue, 1, 1);\n          return;\n        }\n        time = ticktime || +new Date();\n        var currentTime = time > finish ? duration : (time - start),\n            timePerc = currentTime / duration,\n            current = easing(currentTime, startValue, byValue, duration),\n            valuePerc = Math.abs((current - startValue) / byValue);\n        onChange(current, valuePerc, timePerc);\n        if (time > finish) {\n          options.onComplete && options.onComplete();\n          return;\n        }\n        requestAnimFrame(tick);\n      })(start);\n    });\n\n  }\n\n  var _requestAnimFrame = fabric.window.requestAnimationFrame       ||\n                          fabric.window.webkitRequestAnimationFrame ||\n                          fabric.window.mozRequestAnimationFrame    ||\n                          fabric.window.oRequestAnimationFrame      ||\n                          fabric.window.msRequestAnimationFrame     ||\n                          function(callback) {\n                            return fabric.window.setTimeout(callback, 1000 / 60);\n                          };\n\n  var _cancelAnimFrame = fabric.window.cancelAnimationFrame || fabric.window.clearTimeout;\n\n  /**\n   * requestAnimationFrame polyfill based on http://paulirish.com/2011/requestanimationframe-for-smart-animating/\n   * In order to get a precise start time, `requestAnimFrame` should be called as an entry into the method\n   * @memberOf fabric.util\n   * @param {Function} callback Callback to invoke\n   * @param {DOMElement} element optional Element to associate with animation\n   */\n  function requestAnimFrame() {\n    return _requestAnimFrame.apply(fabric.window, arguments);\n  }\n\n  function cancelAnimFrame() {\n    return _cancelAnimFrame.apply(fabric.window, arguments);\n  }\n\n  fabric.util.animate = animate;\n  fabric.util.requestAnimFrame = requestAnimFrame;\n  fabric.util.cancelAnimFrame = cancelAnimFrame;\n})();\n\n\n(function() {\n  // Calculate an in-between color. Returns a \"rgba()\" string.\n  // Credit: Edwin Martin <edwin@bitstorm.org>\n  //         http://www.bitstorm.org/jquery/color-animation/jquery.animate-colors.js\n  function calculateColor(begin, end, pos) {\n    var color = 'rgba('\n        + parseInt((begin[0] + pos * (end[0] - begin[0])), 10) + ','\n        + parseInt((begin[1] + pos * (end[1] - begin[1])), 10) + ','\n        + parseInt((begin[2] + pos * (end[2] - begin[2])), 10);\n\n    color += ',' + (begin && end ? parseFloat(begin[3] + pos * (end[3] - begin[3])) : 1);\n    color += ')';\n    return color;\n  }\n\n  /**\n   * Changes the color from one to another within certain period of time, invoking callbacks as value is being changed.\n   * @memberOf fabric.util\n   * @param {String} fromColor The starting color in hex or rgb(a) format.\n   * @param {String} toColor The starting color in hex or rgb(a) format.\n   * @param {Number} [duration] Duration of change (in ms).\n   * @param {Object} [options] Animation options\n   * @param {Function} [options.onChange] Callback; invoked on every value change\n   * @param {Function} [options.onComplete] Callback; invoked when value change is completed\n   * @param {Function} [options.colorEasing] Easing function. Note that this function only take two arguments (currentTime, duration). Thus the regular animation easing functions cannot be used.\n   * @param {Function} [options.abort] Additional function with logic. If returns true, onComplete is called.\n   */\n  function animateColor(fromColor, toColor, duration, options) {\n    var startColor = new fabric.Color(fromColor).getSource(),\n        endColor = new fabric.Color(toColor).getSource();\n\n    options = options || {};\n\n    fabric.util.animate(fabric.util.object.extend(options, {\n      duration: duration || 500,\n      startValue: startColor,\n      endValue: endColor,\n      byValue: endColor,\n      easing: function (currentTime, startValue, byValue, duration) {\n        var posValue = options.colorEasing\n          ? options.colorEasing(currentTime, duration)\n          : 1 - Math.cos(currentTime / duration * (Math.PI / 2));\n        return calculateColor(startValue, byValue, posValue);\n      }\n    }));\n  }\n\n  fabric.util.animateColor = animateColor;\n\n})();\n\n\n(function() {\n\n  function normalize(a, c, p, s) {\n    if (a < Math.abs(c)) {\n      a = c;\n      s = p / 4;\n    }\n    else {\n      //handle the 0/0 case:\n      if (c === 0 && a === 0) {\n        s = p / (2 * Math.PI) * Math.asin(1);\n      }\n      else {\n        s = p / (2 * Math.PI) * Math.asin(c / a);\n      }\n    }\n    return { a: a, c: c, p: p, s: s };\n  }\n\n  function elastic(opts, t, d) {\n    return opts.a *\n      Math.pow(2, 10 * (t -= 1)) *\n      Math.sin( (t * d - opts.s) * (2 * Math.PI) / opts.p );\n  }\n\n  /**\n   * Cubic easing out\n   * @memberOf fabric.util.ease\n   */\n  function easeOutCubic(t, b, c, d) {\n    return c * ((t = t / d - 1) * t * t + 1) + b;\n  }\n\n  /**\n   * Cubic easing in and out\n   * @memberOf fabric.util.ease\n   */\n  function easeInOutCubic(t, b, c, d) {\n    t /= d / 2;\n    if (t < 1) {\n      return c / 2 * t * t * t + b;\n    }\n    return c / 2 * ((t -= 2) * t * t + 2) + b;\n  }\n\n  /**\n   * Quartic easing in\n   * @memberOf fabric.util.ease\n   */\n  function easeInQuart(t, b, c, d) {\n    return c * (t /= d) * t * t * t + b;\n  }\n\n  /**\n   * Quartic easing out\n   * @memberOf fabric.util.ease\n   */\n  function easeOutQuart(t, b, c, d) {\n    return -c * ((t = t / d - 1) * t * t * t - 1) + b;\n  }\n\n  /**\n   * Quartic easing in and out\n   * @memberOf fabric.util.ease\n   */\n  function easeInOutQuart(t, b, c, d) {\n    t /= d / 2;\n    if (t < 1) {\n      return c / 2 * t * t * t * t + b;\n    }\n    return -c / 2 * ((t -= 2) * t * t * t - 2) + b;\n  }\n\n  /**\n   * Quintic easing in\n   * @memberOf fabric.util.ease\n   */\n  function easeInQuint(t, b, c, d) {\n    return c * (t /= d) * t * t * t * t + b;\n  }\n\n  /**\n   * Quintic easing out\n   * @memberOf fabric.util.ease\n   */\n  function easeOutQuint(t, b, c, d) {\n    return c * ((t = t / d - 1) * t * t * t * t + 1) + b;\n  }\n\n  /**\n   * Quintic easing in and out\n   * @memberOf fabric.util.ease\n   */\n  function easeInOutQuint(t, b, c, d) {\n    t /= d / 2;\n    if (t < 1) {\n      return c / 2 * t * t * t * t * t + b;\n    }\n    return c / 2 * ((t -= 2) * t * t * t * t + 2) + b;\n  }\n\n  /**\n   * Sinusoidal easing in\n   * @memberOf fabric.util.ease\n   */\n  function easeInSine(t, b, c, d) {\n    return -c * Math.cos(t / d * (Math.PI / 2)) + c + b;\n  }\n\n  /**\n   * Sinusoidal easing out\n   * @memberOf fabric.util.ease\n   */\n  function easeOutSine(t, b, c, d) {\n    return c * Math.sin(t / d * (Math.PI / 2)) + b;\n  }\n\n  /**\n   * Sinusoidal easing in and out\n   * @memberOf fabric.util.ease\n   */\n  function easeInOutSine(t, b, c, d) {\n    return -c / 2 * (Math.cos(Math.PI * t / d) - 1) + b;\n  }\n\n  /**\n   * Exponential easing in\n   * @memberOf fabric.util.ease\n   */\n  function easeInExpo(t, b, c, d) {\n    return (t === 0) ? b : c * Math.pow(2, 10 * (t / d - 1)) + b;\n  }\n\n  /**\n   * Exponential easing out\n   * @memberOf fabric.util.ease\n   */\n  function easeOutExpo(t, b, c, d) {\n    return (t === d) ? b + c : c * (-Math.pow(2, -10 * t / d) + 1) + b;\n  }\n\n  /**\n   * Exponential easing in and out\n   * @memberOf fabric.util.ease\n   */\n  function easeInOutExpo(t, b, c, d) {\n    if (t === 0) {\n      return b;\n    }\n    if (t === d) {\n      return b + c;\n    }\n    t /= d / 2;\n    if (t < 1) {\n      return c / 2 * Math.pow(2, 10 * (t - 1)) + b;\n    }\n    return c / 2 * (-Math.pow(2, -10 * --t) + 2) + b;\n  }\n\n  /**\n   * Circular easing in\n   * @memberOf fabric.util.ease\n   */\n  function easeInCirc(t, b, c, d) {\n    return -c * (Math.sqrt(1 - (t /= d) * t) - 1) + b;\n  }\n\n  /**\n   * Circular easing out\n   * @memberOf fabric.util.ease\n   */\n  function easeOutCirc(t, b, c, d) {\n    return c * Math.sqrt(1 - (t = t / d - 1) * t) + b;\n  }\n\n  /**\n   * Circular easing in and out\n   * @memberOf fabric.util.ease\n   */\n  function easeInOutCirc(t, b, c, d) {\n    t /= d / 2;\n    if (t < 1) {\n      return -c / 2 * (Math.sqrt(1 - t * t) - 1) + b;\n    }\n    return c / 2 * (Math.sqrt(1 - (t -= 2) * t) + 1) + b;\n  }\n\n  /**\n   * Elastic easing in\n   * @memberOf fabric.util.ease\n   */\n  function easeInElastic(t, b, c, d) {\n    var s = 1.70158, p = 0, a = c;\n    if (t === 0) {\n      return b;\n    }\n    t /= d;\n    if (t === 1) {\n      return b + c;\n    }\n    if (!p) {\n      p = d * 0.3;\n    }\n    var opts = normalize(a, c, p, s);\n    return -elastic(opts, t, d) + b;\n  }\n\n  /**\n   * Elastic easing out\n   * @memberOf fabric.util.ease\n   */\n  function easeOutElastic(t, b, c, d) {\n    var s = 1.70158, p = 0, a = c;\n    if (t === 0) {\n      return b;\n    }\n    t /= d;\n    if (t === 1) {\n      return b + c;\n    }\n    if (!p) {\n      p = d * 0.3;\n    }\n    var opts = normalize(a, c, p, s);\n    return opts.a * Math.pow(2, -10 * t) * Math.sin((t * d - opts.s) * (2 * Math.PI) / opts.p ) + opts.c + b;\n  }\n\n  /**\n   * Elastic easing in and out\n   * @memberOf fabric.util.ease\n   */\n  function easeInOutElastic(t, b, c, d) {\n    var s = 1.70158, p = 0, a = c;\n    if (t === 0) {\n      return b;\n    }\n    t /= d / 2;\n    if (t === 2) {\n      return b + c;\n    }\n    if (!p) {\n      p = d * (0.3 * 1.5);\n    }\n    var opts = normalize(a, c, p, s);\n    if (t < 1) {\n      return -0.5 * elastic(opts, t, d) + b;\n    }\n    return opts.a * Math.pow(2, -10 * (t -= 1)) *\n      Math.sin((t * d - opts.s) * (2 * Math.PI) / opts.p ) * 0.5 + opts.c + b;\n  }\n\n  /**\n   * Backwards easing in\n   * @memberOf fabric.util.ease\n   */\n  function easeInBack(t, b, c, d, s) {\n    if (s === undefined) {\n      s = 1.70158;\n    }\n    return c * (t /= d) * t * ((s + 1) * t - s) + b;\n  }\n\n  /**\n   * Backwards easing out\n   * @memberOf fabric.util.ease\n   */\n  function easeOutBack(t, b, c, d, s) {\n    if (s === undefined) {\n      s = 1.70158;\n    }\n    return c * ((t = t / d - 1) * t * ((s + 1) * t + s) + 1) + b;\n  }\n\n  /**\n   * Backwards easing in and out\n   * @memberOf fabric.util.ease\n   */\n  function easeInOutBack(t, b, c, d, s) {\n    if (s === undefined) {\n      s = 1.70158;\n    }\n    t /= d / 2;\n    if (t < 1) {\n      return c / 2 * (t * t * (((s *= (1.525)) + 1) * t - s)) + b;\n    }\n    return c / 2 * ((t -= 2) * t * (((s *= (1.525)) + 1) * t + s) + 2) + b;\n  }\n\n  /**\n   * Bouncing easing in\n   * @memberOf fabric.util.ease\n   */\n  function easeInBounce(t, b, c, d) {\n    return c - easeOutBounce (d - t, 0, c, d) + b;\n  }\n\n  /**\n   * Bouncing easing out\n   * @memberOf fabric.util.ease\n   */\n  function easeOutBounce(t, b, c, d) {\n    if ((t /= d) < (1 / 2.75)) {\n      return c * (7.5625 * t * t) + b;\n    }\n    else if (t < (2 / 2.75)) {\n      return c * (7.5625 * (t -= (1.5 / 2.75)) * t + 0.75) + b;\n    }\n    else if (t < (2.5 / 2.75)) {\n      return c * (7.5625 * (t -= (2.25 / 2.75)) * t + 0.9375) + b;\n    }\n    else {\n      return c * (7.5625 * (t -= (2.625 / 2.75)) * t + 0.984375) + b;\n    }\n  }\n\n  /**\n   * Bouncing easing in and out\n   * @memberOf fabric.util.ease\n   */\n  function easeInOutBounce(t, b, c, d) {\n    if (t < d / 2) {\n      return easeInBounce (t * 2, 0, c, d) * 0.5 + b;\n    }\n    return easeOutBounce(t * 2 - d, 0, c, d) * 0.5 + c * 0.5 + b;\n  }\n\n  /**\n   * Easing functions\n   * See <a href=\"http://gizma.com/easing/\">Easing Equations by Robert Penner</a>\n   * @namespace fabric.util.ease\n   */\n  fabric.util.ease = {\n\n    /**\n     * Quadratic easing in\n     * @memberOf fabric.util.ease\n     */\n    easeInQuad: function(t, b, c, d) {\n      return c * (t /= d) * t + b;\n    },\n\n    /**\n     * Quadratic easing out\n     * @memberOf fabric.util.ease\n     */\n    easeOutQuad: function(t, b, c, d) {\n      return -c * (t /= d) * (t - 2) + b;\n    },\n\n    /**\n     * Quadratic easing in and out\n     * @memberOf fabric.util.ease\n     */\n    easeInOutQuad: function(t, b, c, d) {\n      t /= (d / 2);\n      if (t < 1) {\n        return c / 2 * t * t + b;\n      }\n      return -c / 2 * ((--t) * (t - 2) - 1) + b;\n    },\n\n    /**\n     * Cubic easing in\n     * @memberOf fabric.util.ease\n     */\n    easeInCubic: function(t, b, c, d) {\n      return c * (t /= d) * t * t + b;\n    },\n\n    easeOutCubic: easeOutCubic,\n    easeInOutCubic: easeInOutCubic,\n    easeInQuart: easeInQuart,\n    easeOutQuart: easeOutQuart,\n    easeInOutQuart: easeInOutQuart,\n    easeInQuint: easeInQuint,\n    easeOutQuint: easeOutQuint,\n    easeInOutQuint: easeInOutQuint,\n    easeInSine: easeInSine,\n    easeOutSine: easeOutSine,\n    easeInOutSine: easeInOutSine,\n    easeInExpo: easeInExpo,\n    easeOutExpo: easeOutExpo,\n    easeInOutExpo: easeInOutExpo,\n    easeInCirc: easeInCirc,\n    easeOutCirc: easeOutCirc,\n    easeInOutCirc: easeInOutCirc,\n    easeInElastic: easeInElastic,\n    easeOutElastic: easeOutElastic,\n    easeInOutElastic: easeInOutElastic,\n    easeInBack: easeInBack,\n    easeOutBack: easeOutBack,\n    easeInOutBack: easeInOutBack,\n    easeInBounce: easeInBounce,\n    easeOutBounce: easeOutBounce,\n    easeInOutBounce: easeInOutBounce\n  };\n\n})();\n\n\n(function(global) {\n\n  'use strict';\n\n  /**\n   * @name fabric\n   * @namespace\n   */\n\n  var fabric = global.fabric || (global.fabric = { }),\n      extend = fabric.util.object.extend,\n      clone = fabric.util.object.clone,\n      toFixed = fabric.util.toFixed,\n      parseUnit = fabric.util.parseUnit,\n      multiplyTransformMatrices = fabric.util.multiplyTransformMatrices,\n\n      svgValidTagNames = ['path', 'circle', 'polygon', 'polyline', 'ellipse', 'rect', 'line',\n        'image', 'text'],\n      svgViewBoxElements = ['symbol', 'image', 'marker', 'pattern', 'view', 'svg'],\n      svgInvalidAncestors = ['pattern', 'defs', 'symbol', 'metadata', 'clipPath', 'mask', 'desc'],\n      svgValidParents = ['symbol', 'g', 'a', 'svg', 'clipPath', 'defs'],\n\n      attributesMap = {\n        cx:                   'left',\n        x:                    'left',\n        r:                    'radius',\n        cy:                   'top',\n        y:                    'top',\n        display:              'visible',\n        visibility:           'visible',\n        transform:            'transformMatrix',\n        'fill-opacity':       'fillOpacity',\n        'fill-rule':          'fillRule',\n        'font-family':        'fontFamily',\n        'font-size':          'fontSize',\n        'font-style':         'fontStyle',\n        'font-weight':        'fontWeight',\n        'letter-spacing':     'charSpacing',\n        'paint-order':        'paintFirst',\n        'stroke-dasharray':   'strokeDashArray',\n        'stroke-dashoffset':  'strokeDashOffset',\n        'stroke-linecap':     'strokeLineCap',\n        'stroke-linejoin':    'strokeLineJoin',\n        'stroke-miterlimit':  'strokeMiterLimit',\n        'stroke-opacity':     'strokeOpacity',\n        'stroke-width':       'strokeWidth',\n        'text-decoration':    'textDecoration',\n        'text-anchor':        'textAnchor',\n        opacity:              'opacity',\n        'clip-path':          'clipPath',\n        'clip-rule':          'clipRule',\n        'vector-effect':      'strokeUniform'\n      },\n\n      colorAttributes = {\n        stroke: 'strokeOpacity',\n        fill:   'fillOpacity'\n      };\n\n  fabric.svgValidTagNamesRegEx = getSvgRegex(svgValidTagNames);\n  fabric.svgViewBoxElementsRegEx = getSvgRegex(svgViewBoxElements);\n  fabric.svgInvalidAncestorsRegEx = getSvgRegex(svgInvalidAncestors);\n  fabric.svgValidParentsRegEx = getSvgRegex(svgValidParents);\n\n  fabric.cssRules = { };\n  fabric.gradientDefs = { };\n  fabric.clipPaths = { };\n\n  function normalizeAttr(attr) {\n    // transform attribute names\n    if (attr in attributesMap) {\n      return attributesMap[attr];\n    }\n    return attr;\n  }\n\n  function normalizeValue(attr, value, parentAttributes, fontSize) {\n    var isArray = Object.prototype.toString.call(value) === '[object Array]',\n        parsed;\n\n    if ((attr === 'fill' || attr === 'stroke') && value === 'none') {\n      value = '';\n    }\n    else if (attr === 'vector-effect') {\n      value = value === 'non-scaling-stroke';\n    }\n    else if (attr === 'strokeDashArray') {\n      if (value === 'none') {\n        value = null;\n      }\n      else {\n        value = value.replace(/,/g, ' ').split(/\\s+/).map(parseFloat);\n      }\n    }\n    else if (attr === 'transformMatrix') {\n      if (parentAttributes && parentAttributes.transformMatrix) {\n        value = multiplyTransformMatrices(\n          parentAttributes.transformMatrix, fabric.parseTransformAttribute(value));\n      }\n      else {\n        value = fabric.parseTransformAttribute(value);\n      }\n    }\n    else if (attr === 'visible') {\n      value = value !== 'none' && value !== 'hidden';\n      // display=none on parent element always takes precedence over child element\n      if (parentAttributes && parentAttributes.visible === false) {\n        value = false;\n      }\n    }\n    else if (attr === 'opacity') {\n      value = parseFloat(value);\n      if (parentAttributes && typeof parentAttributes.opacity !== 'undefined') {\n        value *= parentAttributes.opacity;\n      }\n    }\n    else if (attr === 'textAnchor' /* text-anchor */) {\n      value = value === 'start' ? 'left' : value === 'end' ? 'right' : 'center';\n    }\n    else if (attr === 'charSpacing') {\n      // parseUnit returns px and we convert it to em\n      parsed = parseUnit(value, fontSize) / fontSize * 1000;\n    }\n    else if (attr === 'paintFirst') {\n      var fillIndex = value.indexOf('fill');\n      var strokeIndex = value.indexOf('stroke');\n      var value = 'fill';\n      if (fillIndex > -1 && strokeIndex > -1 && strokeIndex < fillIndex) {\n        value = 'stroke';\n      }\n      else if (fillIndex === -1 && strokeIndex > -1) {\n        value = 'stroke';\n      }\n    }\n    else if (attr === 'href' || attr === 'xlink:href') {\n      return value;\n    }\n    else {\n      parsed = isArray ? value.map(parseUnit) : parseUnit(value, fontSize);\n    }\n\n    return (!isArray && isNaN(parsed) ? value : parsed);\n  }\n\n  /**\n    * @private\n    */\n  function getSvgRegex(arr) {\n    return new RegExp('^(' + arr.join('|') + ')\\\\b', 'i');\n  }\n\n  /**\n   * @private\n   * @param {Object} attributes Array of attributes to parse\n   */\n  function _setStrokeFillOpacity(attributes) {\n    for (var attr in colorAttributes) {\n\n      if (typeof attributes[colorAttributes[attr]] === 'undefined' || attributes[attr] === '') {\n        continue;\n      }\n\n      if (typeof attributes[attr] === 'undefined') {\n        if (!fabric.Object.prototype[attr]) {\n          continue;\n        }\n        attributes[attr] = fabric.Object.prototype[attr];\n      }\n\n      if (attributes[attr].indexOf('url(') === 0) {\n        continue;\n      }\n\n      var color = new fabric.Color(attributes[attr]);\n      attributes[attr] = color.setAlpha(toFixed(color.getAlpha() * attributes[colorAttributes[attr]], 2)).toRgba();\n    }\n    return attributes;\n  }\n\n  /**\n   * @private\n   */\n  function _getMultipleNodes(doc, nodeNames) {\n    var nodeName, nodeArray = [], nodeList, i, len;\n    for (i = 0, len = nodeNames.length; i < len; i++) {\n      nodeName = nodeNames[i];\n      nodeList = doc.getElementsByTagName(nodeName);\n      nodeArray = nodeArray.concat(Array.prototype.slice.call(nodeList));\n    }\n    return nodeArray;\n  }\n\n  /**\n   * Parses \"transform\" attribute, returning an array of values\n   * @static\n   * @function\n   * @memberOf fabric\n   * @param {String} attributeValue String containing attribute value\n   * @return {Array} Array of 6 elements representing transformation matrix\n   */\n  fabric.parseTransformAttribute = (function() {\n    function rotateMatrix(matrix, args) {\n      var cos = fabric.util.cos(args[0]), sin = fabric.util.sin(args[0]),\n          x = 0, y = 0;\n      if (args.length === 3) {\n        x = args[1];\n        y = args[2];\n      }\n\n      matrix[0] = cos;\n      matrix[1] = sin;\n      matrix[2] = -sin;\n      matrix[3] = cos;\n      matrix[4] = x - (cos * x - sin * y);\n      matrix[5] = y - (sin * x + cos * y);\n    }\n\n    function scaleMatrix(matrix, args) {\n      var multiplierX = args[0],\n          multiplierY = (args.length === 2) ? args[1] : args[0];\n\n      matrix[0] = multiplierX;\n      matrix[3] = multiplierY;\n    }\n\n    function skewMatrix(matrix, args, pos) {\n      matrix[pos] = Math.tan(fabric.util.degreesToRadians(args[0]));\n    }\n\n    function translateMatrix(matrix, args) {\n      matrix[4] = args[0];\n      if (args.length === 2) {\n        matrix[5] = args[1];\n      }\n    }\n\n    // identity matrix\n    var iMatrix = fabric.iMatrix,\n\n        // == begin transform regexp\n        number = fabric.reNum,\n\n        commaWsp = '(?:\\\\s+,?\\\\s*|,\\\\s*)',\n\n        skewX = '(?:(skewX)\\\\s*\\\\(\\\\s*(' + number + ')\\\\s*\\\\))',\n\n        skewY = '(?:(skewY)\\\\s*\\\\(\\\\s*(' + number + ')\\\\s*\\\\))',\n\n        rotate = '(?:(rotate)\\\\s*\\\\(\\\\s*(' + number + ')(?:' +\n                    commaWsp + '(' + number + ')' +\n                    commaWsp + '(' + number + '))?\\\\s*\\\\))',\n\n        scale = '(?:(scale)\\\\s*\\\\(\\\\s*(' + number + ')(?:' +\n                    commaWsp + '(' + number + '))?\\\\s*\\\\))',\n\n        translate = '(?:(translate)\\\\s*\\\\(\\\\s*(' + number + ')(?:' +\n                    commaWsp + '(' + number + '))?\\\\s*\\\\))',\n\n        matrix = '(?:(matrix)\\\\s*\\\\(\\\\s*' +\n                  '(' + number + ')' + commaWsp +\n                  '(' + number + ')' + commaWsp +\n                  '(' + number + ')' + commaWsp +\n                  '(' + number + ')' + commaWsp +\n                  '(' + number + ')' + commaWsp +\n                  '(' + number + ')' +\n                  '\\\\s*\\\\))',\n\n        transform = '(?:' +\n                    matrix + '|' +\n                    translate + '|' +\n                    scale + '|' +\n                    rotate + '|' +\n                    skewX + '|' +\n                    skewY +\n                    ')',\n\n        transforms = '(?:' + transform + '(?:' + commaWsp + '*' + transform + ')*' + ')',\n\n        transformList = '^\\\\s*(?:' + transforms + '?)\\\\s*$',\n\n        // http://www.w3.org/TR/SVG/coords.html#TransformAttribute\n        reTransformList = new RegExp(transformList),\n        // == end transform regexp\n\n        reTransform = new RegExp(transform, 'g');\n\n    return function(attributeValue) {\n\n      // start with identity matrix\n      var matrix = iMatrix.concat(),\n          matrices = [];\n\n      // return if no argument was given or\n      // an argument does not match transform attribute regexp\n      if (!attributeValue || (attributeValue && !reTransformList.test(attributeValue))) {\n        return matrix;\n      }\n\n      attributeValue.replace(reTransform, function(match) {\n\n        var m = new RegExp(transform).exec(match).filter(function (match) {\n              // match !== '' && match != null\n              return (!!match);\n            }),\n            operation = m[1],\n            args = m.slice(2).map(parseFloat);\n\n        switch (operation) {\n          case 'translate':\n            translateMatrix(matrix, args);\n            break;\n          case 'rotate':\n            args[0] = fabric.util.degreesToRadians(args[0]);\n            rotateMatrix(matrix, args);\n            break;\n          case 'scale':\n            scaleMatrix(matrix, args);\n            break;\n          case 'skewX':\n            skewMatrix(matrix, args, 2);\n            break;\n          case 'skewY':\n            skewMatrix(matrix, args, 1);\n            break;\n          case 'matrix':\n            matrix = args;\n            break;\n        }\n\n        // snapshot current matrix into matrices array\n        matrices.push(matrix.concat());\n        // reset\n        matrix = iMatrix.concat();\n      });\n\n      var combinedMatrix = matrices[0];\n      while (matrices.length > 1) {\n        matrices.shift();\n        combinedMatrix = fabric.util.multiplyTransformMatrices(combinedMatrix, matrices[0]);\n      }\n      return combinedMatrix;\n    };\n  })();\n\n  /**\n   * @private\n   */\n  function parseStyleString(style, oStyle) {\n    var attr, value;\n    style.replace(/;\\s*$/, '').split(';').forEach(function (chunk) {\n      var pair = chunk.split(':');\n\n      attr = pair[0].trim().toLowerCase();\n      value =  pair[1].trim();\n\n      oStyle[attr] = value;\n    });\n  }\n\n  /**\n   * @private\n   */\n  function parseStyleObject(style, oStyle) {\n    var attr, value;\n    for (var prop in style) {\n      if (typeof style[prop] === 'undefined') {\n        continue;\n      }\n\n      attr = prop.toLowerCase();\n      value = style[prop];\n\n      oStyle[attr] = value;\n    }\n  }\n\n  /**\n   * @private\n   */\n  function getGlobalStylesForElement(element, svgUid) {\n    var styles = { };\n    for (var rule in fabric.cssRules[svgUid]) {\n      if (elementMatchesRule(element, rule.split(' '))) {\n        for (var property in fabric.cssRules[svgUid][rule]) {\n          styles[property] = fabric.cssRules[svgUid][rule][property];\n        }\n      }\n    }\n    return styles;\n  }\n\n  /**\n   * @private\n   */\n  function elementMatchesRule(element, selectors) {\n    var firstMatching, parentMatching = true;\n    //start from rightmost selector.\n    firstMatching = selectorMatches(element, selectors.pop());\n    if (firstMatching && selectors.length) {\n      parentMatching = doesSomeParentMatch(element, selectors);\n    }\n    return firstMatching && parentMatching && (selectors.length === 0);\n  }\n\n  function doesSomeParentMatch(element, selectors) {\n    var selector, parentMatching = true;\n    while (element.parentNode && element.parentNode.nodeType === 1 && selectors.length) {\n      if (parentMatching) {\n        selector = selectors.pop();\n      }\n      element = element.parentNode;\n      parentMatching = selectorMatches(element, selector);\n    }\n    return selectors.length === 0;\n  }\n\n  /**\n   * @private\n   */\n  function selectorMatches(element, selector) {\n    var nodeName = element.nodeName,\n        classNames = element.getAttribute('class'),\n        id = element.getAttribute('id'), matcher, i;\n    // i check if a selector matches slicing away part from it.\n    // if i get empty string i should match\n    matcher = new RegExp('^' + nodeName, 'i');\n    selector = selector.replace(matcher, '');\n    if (id && selector.length) {\n      matcher = new RegExp('#' + id + '(?![a-zA-Z\\\\-]+)', 'i');\n      selector = selector.replace(matcher, '');\n    }\n    if (classNames && selector.length) {\n      classNames = classNames.split(' ');\n      for (i = classNames.length; i--;) {\n        matcher = new RegExp('\\\\.' + classNames[i] + '(?![a-zA-Z\\\\-]+)', 'i');\n        selector = selector.replace(matcher, '');\n      }\n    }\n    return selector.length === 0;\n  }\n\n  /**\n   * @private\n   * to support IE8 missing getElementById on SVGdocument and on node xmlDOM\n   */\n  function elementById(doc, id) {\n    var el;\n    doc.getElementById && (el = doc.getElementById(id));\n    if (el) {\n      return el;\n    }\n    var node, i, len, nodelist = doc.getElementsByTagName('*');\n    for (i = 0, len = nodelist.length; i < len; i++) {\n      node = nodelist[i];\n      if (id === node.getAttribute('id')) {\n        return node;\n      }\n    }\n  }\n\n  /**\n   * @private\n   */\n  function parseUseDirectives(doc) {\n    var nodelist = _getMultipleNodes(doc, ['use', 'svg:use']), i = 0;\n    while (nodelist.length && i < nodelist.length) {\n      var el = nodelist[i],\n          xlink = (el.getAttribute('xlink:href') || el.getAttribute('href')).substr(1),\n          x = el.getAttribute('x') || 0,\n          y = el.getAttribute('y') || 0,\n          el2 = elementById(doc, xlink).cloneNode(true),\n          currentTrans = (el2.getAttribute('transform') || '') + ' translate(' + x + ', ' + y + ')',\n          parentNode, oldLength = nodelist.length, attr, j, attrs, len;\n\n      applyViewboxTransform(el2);\n      if (/^svg$/i.test(el2.nodeName)) {\n        var el3 = el2.ownerDocument.createElement('g');\n        for (j = 0, attrs = el2.attributes, len = attrs.length; j < len; j++) {\n          attr = attrs.item(j);\n          el3.setAttribute(attr.nodeName, attr.nodeValue);\n        }\n        // el2.firstChild != null\n        while (el2.firstChild) {\n          el3.appendChild(el2.firstChild);\n        }\n        el2 = el3;\n      }\n\n      for (j = 0, attrs = el.attributes, len = attrs.length; j < len; j++) {\n        attr = attrs.item(j);\n        if (attr.nodeName === 'x' || attr.nodeName === 'y' ||\n          attr.nodeName === 'xlink:href' || attr.nodeName === 'href') {\n          continue;\n        }\n\n        if (attr.nodeName === 'transform') {\n          currentTrans = attr.nodeValue + ' ' + currentTrans;\n        }\n        else {\n          el2.setAttribute(attr.nodeName, attr.nodeValue);\n        }\n      }\n\n      el2.setAttribute('transform', currentTrans);\n      el2.setAttribute('instantiated_by_use', '1');\n      el2.removeAttribute('id');\n      parentNode = el.parentNode;\n      parentNode.replaceChild(el2, el);\n      // some browsers do not shorten nodelist after replaceChild (IE8)\n      if (nodelist.length === oldLength) {\n        i++;\n      }\n    }\n  }\n\n  // http://www.w3.org/TR/SVG/coords.html#ViewBoxAttribute\n  // matches, e.g.: +14.56e-12, etc.\n  var reViewBoxAttrValue = new RegExp(\n    '^' +\n    '\\\\s*(' + fabric.reNum + '+)\\\\s*,?' +\n    '\\\\s*(' + fabric.reNum + '+)\\\\s*,?' +\n    '\\\\s*(' + fabric.reNum + '+)\\\\s*,?' +\n    '\\\\s*(' + fabric.reNum + '+)\\\\s*' +\n    '$'\n  );\n\n  /**\n   * Add a <g> element that envelop all child elements and makes the viewbox transformMatrix descend on all elements\n   */\n  function applyViewboxTransform(element) {\n\n    var viewBoxAttr = element.getAttribute('viewBox'),\n        scaleX = 1,\n        scaleY = 1,\n        minX = 0,\n        minY = 0,\n        viewBoxWidth, viewBoxHeight, matrix, el,\n        widthAttr = element.getAttribute('width'),\n        heightAttr = element.getAttribute('height'),\n        x = element.getAttribute('x') || 0,\n        y = element.getAttribute('y') || 0,\n        preserveAspectRatio = element.getAttribute('preserveAspectRatio') || '',\n        missingViewBox = (!viewBoxAttr || !fabric.svgViewBoxElementsRegEx.test(element.nodeName)\n                           || !(viewBoxAttr = viewBoxAttr.match(reViewBoxAttrValue))),\n        missingDimAttr = (!widthAttr || !heightAttr || widthAttr === '100%' || heightAttr === '100%'),\n        toBeParsed = missingViewBox && missingDimAttr,\n        parsedDim = { }, translateMatrix = '', widthDiff = 0, heightDiff = 0;\n\n    parsedDim.width = 0;\n    parsedDim.height = 0;\n    parsedDim.toBeParsed = toBeParsed;\n\n    if (toBeParsed) {\n      return parsedDim;\n    }\n\n    if (missingViewBox) {\n      parsedDim.width = parseUnit(widthAttr);\n      parsedDim.height = parseUnit(heightAttr);\n      return parsedDim;\n    }\n\n    minX = -parseFloat(viewBoxAttr[1]);\n    minY = -parseFloat(viewBoxAttr[2]);\n    viewBoxWidth = parseFloat(viewBoxAttr[3]);\n    viewBoxHeight = parseFloat(viewBoxAttr[4]);\n\n    if (!missingDimAttr) {\n      parsedDim.width = parseUnit(widthAttr);\n      parsedDim.height = parseUnit(heightAttr);\n      scaleX = parsedDim.width / viewBoxWidth;\n      scaleY = parsedDim.height / viewBoxHeight;\n    }\n    else {\n      parsedDim.width = viewBoxWidth;\n      parsedDim.height = viewBoxHeight;\n    }\n\n    // default is to preserve aspect ratio\n    preserveAspectRatio = fabric.util.parsePreserveAspectRatioAttribute(preserveAspectRatio);\n    if (preserveAspectRatio.alignX !== 'none') {\n      //translate all container for the effect of Mid, Min, Max\n      if (preserveAspectRatio.meetOrSlice === 'meet') {\n        scaleY = scaleX = (scaleX > scaleY ? scaleY : scaleX);\n        // calculate additional translation to move the viewbox\n      }\n      if (preserveAspectRatio.meetOrSlice === 'slice') {\n        scaleY = scaleX = (scaleX > scaleY ? scaleX : scaleY);\n        // calculate additional translation to move the viewbox\n      }\n      widthDiff = parsedDim.width - viewBoxWidth * scaleX;\n      heightDiff = parsedDim.height - viewBoxHeight * scaleX;\n      if (preserveAspectRatio.alignX === 'Mid') {\n        widthDiff /= 2;\n      }\n      if (preserveAspectRatio.alignY === 'Mid') {\n        heightDiff /= 2;\n      }\n      if (preserveAspectRatio.alignX === 'Min') {\n        widthDiff = 0;\n      }\n      if (preserveAspectRatio.alignY === 'Min') {\n        heightDiff = 0;\n      }\n    }\n\n    if (scaleX === 1 && scaleY === 1 && minX === 0 && minY === 0 && x === 0 && y === 0) {\n      return parsedDim;\n    }\n\n    if (x || y) {\n      translateMatrix = ' translate(' + parseUnit(x) + ' ' + parseUnit(y) + ') ';\n    }\n\n    matrix = translateMatrix + ' matrix(' + scaleX +\n                  ' 0' +\n                  ' 0 ' +\n                  scaleY + ' ' +\n                  (minX * scaleX + widthDiff) + ' ' +\n                  (minY * scaleY + heightDiff) + ') ';\n    parsedDim.viewboxTransform = fabric.parseTransformAttribute(matrix);\n    if (element.nodeName === 'svg') {\n      el = element.ownerDocument.createElement('g');\n      // element.firstChild != null\n      while (element.firstChild) {\n        el.appendChild(element.firstChild);\n      }\n      element.appendChild(el);\n    }\n    else {\n      el = element;\n      matrix = el.getAttribute('transform') + matrix;\n    }\n    el.setAttribute('transform', matrix);\n    return parsedDim;\n  }\n\n  function hasAncestorWithNodeName(element, nodeName) {\n    while (element && (element = element.parentNode)) {\n      if (element.nodeName && nodeName.test(element.nodeName.replace('svg:', ''))\n        && !element.getAttribute('instantiated_by_use')) {\n        return true;\n      }\n    }\n    return false;\n  }\n\n  /**\n   * Parses an SVG document, converts it to an array of corresponding fabric.* instances and passes them to a callback\n   * @static\n   * @function\n   * @memberOf fabric\n   * @param {SVGDocument} doc SVG document to parse\n   * @param {Function} callback Callback to call when parsing is finished;\n   * It's being passed an array of elements (parsed from a document).\n   * @param {Function} [reviver] Method for further parsing of SVG elements, called after each fabric object created.\n   * @param {Object} [parsingOptions] options for parsing document\n   * @param {String} [parsingOptions.crossOrigin] crossOrigin settings\n   */\n  fabric.parseSVGDocument = function(doc, callback, reviver, parsingOptions) {\n    if (!doc) {\n      return;\n    }\n\n    parseUseDirectives(doc);\n\n    var svgUid =  fabric.Object.__uid++, i, len,\n        options = applyViewboxTransform(doc),\n        descendants = fabric.util.toArray(doc.getElementsByTagName('*'));\n    options.crossOrigin = parsingOptions && parsingOptions.crossOrigin;\n    options.svgUid = svgUid;\n\n    if (descendants.length === 0 && fabric.isLikelyNode) {\n      // we're likely in node, where \"o3-xml\" library fails to gEBTN(\"*\")\n      // https://github.com/ajaxorg/node-o3-xml/issues/21\n      descendants = doc.selectNodes('//*[name(.)!=\"svg\"]');\n      var arr = [];\n      for (i = 0, len = descendants.length; i < len; i++) {\n        arr[i] = descendants[i];\n      }\n      descendants = arr;\n    }\n\n    var elements = descendants.filter(function(el) {\n      applyViewboxTransform(el);\n      return fabric.svgValidTagNamesRegEx.test(el.nodeName.replace('svg:', '')) &&\n            !hasAncestorWithNodeName(el, fabric.svgInvalidAncestorsRegEx); // http://www.w3.org/TR/SVG/struct.html#DefsElement\n    });\n\n    if (!elements || (elements && !elements.length)) {\n      callback && callback([], {});\n      return;\n    }\n    var clipPaths = { };\n    descendants.filter(function(el) {\n      return el.nodeName.replace('svg:', '') === 'clipPath';\n    }).forEach(function(el) {\n      var id = el.getAttribute('id');\n      clipPaths[id] = fabric.util.toArray(el.getElementsByTagName('*')).filter(function(el) {\n        return fabric.svgValidTagNamesRegEx.test(el.nodeName.replace('svg:', ''));\n      });\n    });\n    fabric.gradientDefs[svgUid] = fabric.getGradientDefs(doc);\n    fabric.cssRules[svgUid] = fabric.getCSSRules(doc);\n    fabric.clipPaths[svgUid] = clipPaths;\n    // Precedence of rules:   style > class > attribute\n    fabric.parseElements(elements, function(instances, elements) {\n      if (callback) {\n        callback(instances, options, elements, descendants);\n        delete fabric.gradientDefs[svgUid];\n        delete fabric.cssRules[svgUid];\n        delete fabric.clipPaths[svgUid];\n      }\n    }, clone(options), reviver, parsingOptions);\n  };\n\n  function recursivelyParseGradientsXlink(doc, gradient) {\n    var gradientsAttrs = ['gradientTransform', 'x1', 'x2', 'y1', 'y2', 'gradientUnits', 'cx', 'cy', 'r', 'fx', 'fy'],\n        xlinkAttr = 'xlink:href',\n        xLink = gradient.getAttribute(xlinkAttr).substr(1),\n        referencedGradient = elementById(doc, xLink);\n    if (referencedGradient && referencedGradient.getAttribute(xlinkAttr)) {\n      recursivelyParseGradientsXlink(doc, referencedGradient);\n    }\n    gradientsAttrs.forEach(function(attr) {\n      if (!gradient.hasAttribute(attr)) {\n        gradient.setAttribute(attr, referencedGradient.getAttribute(attr));\n      }\n    });\n    if (!gradient.children.length) {\n      var referenceClone = referencedGradient.cloneNode(true);\n      while (referenceClone.firstChild) {\n        gradient.appendChild(referenceClone.firstChild);\n      }\n    }\n    gradient.removeAttribute(xlinkAttr);\n  }\n\n  var reFontDeclaration = new RegExp(\n    '(normal|italic)?\\\\s*(normal|small-caps)?\\\\s*' +\n    '(normal|bold|bolder|lighter|100|200|300|400|500|600|700|800|900)?\\\\s*(' +\n      fabric.reNum +\n    '(?:px|cm|mm|em|pt|pc|in)*)(?:\\\\/(normal|' + fabric.reNum + '))?\\\\s+(.*)');\n\n  extend(fabric, {\n    /**\n     * Parses a short font declaration, building adding its properties to a style object\n     * @static\n     * @function\n     * @memberOf fabric\n     * @param {String} value font declaration\n     * @param {Object} oStyle definition\n     */\n    parseFontDeclaration: function(value, oStyle) {\n      var match = value.match(reFontDeclaration);\n\n      if (!match) {\n        return;\n      }\n      var fontStyle = match[1],\n          // font variant is not used\n          // fontVariant = match[2],\n          fontWeight = match[3],\n          fontSize = match[4],\n          lineHeight = match[5],\n          fontFamily = match[6];\n\n      if (fontStyle) {\n        oStyle.fontStyle = fontStyle;\n      }\n      if (fontWeight) {\n        oStyle.fontWeight = isNaN(parseFloat(fontWeight)) ? fontWeight : parseFloat(fontWeight);\n      }\n      if (fontSize) {\n        oStyle.fontSize = parseUnit(fontSize);\n      }\n      if (fontFamily) {\n        oStyle.fontFamily = fontFamily;\n      }\n      if (lineHeight) {\n        oStyle.lineHeight = lineHeight === 'normal' ? 1 : lineHeight;\n      }\n    },\n\n    /**\n     * Parses an SVG document, returning all of the gradient declarations found in it\n     * @static\n     * @function\n     * @memberOf fabric\n     * @param {SVGDocument} doc SVG document to parse\n     * @return {Object} Gradient definitions; key corresponds to element id, value -- to gradient definition element\n     */\n    getGradientDefs: function(doc) {\n      var tagArray = [\n            'linearGradient',\n            'radialGradient',\n            'svg:linearGradient',\n            'svg:radialGradient'],\n          elList = _getMultipleNodes(doc, tagArray),\n          el, j = 0, gradientDefs = { };\n      j = elList.length;\n      while (j--) {\n        el = elList[j];\n        if (el.getAttribute('xlink:href')) {\n          recursivelyParseGradientsXlink(doc, el);\n        }\n        gradientDefs[el.getAttribute('id')] = el;\n      }\n      return gradientDefs;\n    },\n\n    /**\n     * Returns an object of attributes' name/value, given element and an array of attribute names;\n     * Parses parent \"g\" nodes recursively upwards.\n     * @static\n     * @memberOf fabric\n     * @param {DOMElement} element Element to parse\n     * @param {Array} attributes Array of attributes to parse\n     * @return {Object} object containing parsed attributes' names/values\n     */\n    parseAttributes: function(element, attributes, svgUid) {\n\n      if (!element) {\n        return;\n      }\n\n      var value,\n          parentAttributes = { },\n          fontSize, parentFontSize;\n\n      if (typeof svgUid === 'undefined') {\n        svgUid = element.getAttribute('svgUid');\n      }\n      // if there's a parent container (`g` or `a` or `symbol` node), parse its attributes recursively upwards\n      if (element.parentNode && fabric.svgValidParentsRegEx.test(element.parentNode.nodeName)) {\n        parentAttributes = fabric.parseAttributes(element.parentNode, attributes, svgUid);\n      }\n\n      var ownAttributes = attributes.reduce(function(memo, attr) {\n        value = element.getAttribute(attr);\n        if (value) { // eslint-disable-line\n          memo[attr] = value;\n        }\n        return memo;\n      }, { });\n      // add values parsed from style, which take precedence over attributes\n      // (see: http://www.w3.org/TR/SVG/styling.html#UsingPresentationAttributes)\n      ownAttributes = extend(ownAttributes,\n        extend(getGlobalStylesForElement(element, svgUid), fabric.parseStyleAttribute(element)));\n\n      fontSize = parentFontSize = parentAttributes.fontSize || fabric.Text.DEFAULT_SVG_FONT_SIZE;\n      if (ownAttributes['font-size']) {\n        // looks like the minimum should be 9px when dealing with ems. this is what looks like in browsers.\n        ownAttributes['font-size'] = fontSize = parseUnit(ownAttributes['font-size'], parentFontSize);\n      }\n\n      var normalizedAttr, normalizedValue, normalizedStyle = {};\n      for (var attr in ownAttributes) {\n        normalizedAttr = normalizeAttr(attr);\n        normalizedValue = normalizeValue(normalizedAttr, ownAttributes[attr], parentAttributes, fontSize);\n        normalizedStyle[normalizedAttr] = normalizedValue;\n      }\n      if (normalizedStyle && normalizedStyle.font) {\n        fabric.parseFontDeclaration(normalizedStyle.font, normalizedStyle);\n      }\n      var mergedAttrs = extend(parentAttributes, normalizedStyle);\n      return fabric.svgValidParentsRegEx.test(element.nodeName) ? mergedAttrs : _setStrokeFillOpacity(mergedAttrs);\n    },\n\n    /**\n     * Transforms an array of svg elements to corresponding fabric.* instances\n     * @static\n     * @memberOf fabric\n     * @param {Array} elements Array of elements to parse\n     * @param {Function} callback Being passed an array of fabric instances (transformed from SVG elements)\n     * @param {Object} [options] Options object\n     * @param {Function} [reviver] Method for further parsing of SVG elements, called after each fabric object created.\n     */\n    parseElements: function(elements, callback, options, reviver, parsingOptions) {\n      new fabric.ElementsParser(elements, callback, options, reviver, parsingOptions).parse();\n    },\n\n    /**\n     * Parses \"style\" attribute, retuning an object with values\n     * @static\n     * @memberOf fabric\n     * @param {SVGElement} element Element to parse\n     * @return {Object} Objects with values parsed from style attribute of an element\n     */\n    parseStyleAttribute: function(element) {\n      var oStyle = { },\n          style = element.getAttribute('style');\n\n      if (!style) {\n        return oStyle;\n      }\n\n      if (typeof style === 'string') {\n        parseStyleString(style, oStyle);\n      }\n      else {\n        parseStyleObject(style, oStyle);\n      }\n\n      return oStyle;\n    },\n\n    /**\n     * Parses \"points\" attribute, returning an array of values\n     * @static\n     * @memberOf fabric\n     * @param {String} points points attribute string\n     * @return {Array} array of points\n     */\n    parsePointsAttribute: function(points) {\n\n      // points attribute is required and must not be empty\n      if (!points) {\n        return null;\n      }\n\n      // replace commas with whitespace and remove bookending whitespace\n      points = points.replace(/,/g, ' ').trim();\n\n      points = points.split(/\\s+/);\n      var parsedPoints = [], i, len;\n\n      for (i = 0, len = points.length; i < len; i += 2) {\n        parsedPoints.push({\n          x: parseFloat(points[i]),\n          y: parseFloat(points[i + 1])\n        });\n      }\n\n      // odd number of points is an error\n      // if (parsedPoints.length % 2 !== 0) {\n      //   return null;\n      // }\n\n      return parsedPoints;\n    },\n\n    /**\n     * Returns CSS rules for a given SVG document\n     * @static\n     * @function\n     * @memberOf fabric\n     * @param {SVGDocument} doc SVG document to parse\n     * @return {Object} CSS rules of this document\n     */\n    getCSSRules: function(doc) {\n      var styles = doc.getElementsByTagName('style'), i, len,\n          allRules = { }, rules;\n\n      // very crude parsing of style contents\n      for (i = 0, len = styles.length; i < len; i++) {\n        // IE9 doesn't support textContent, but provides text instead.\n        var styleContents = styles[i].textContent || styles[i].text;\n\n        // remove comments\n        styleContents = styleContents.replace(/\\/\\*[\\s\\S]*?\\*\\//g, '');\n        if (styleContents.trim() === '') {\n          continue;\n        }\n        rules = styleContents.match(/[^{]*\\{[\\s\\S]*?\\}/g);\n        rules = rules.map(function(rule) { return rule.trim(); });\n        // eslint-disable-next-line no-loop-func\n        rules.forEach(function(rule) {\n\n          var match = rule.match(/([\\s\\S]*?)\\s*\\{([^}]*)\\}/),\n              ruleObj = { }, declaration = match[2].trim(),\n              propertyValuePairs = declaration.replace(/;$/, '').split(/\\s*;\\s*/);\n\n          for (i = 0, len = propertyValuePairs.length; i < len; i++) {\n            var pair = propertyValuePairs[i].split(/\\s*:\\s*/),\n                property = pair[0],\n                value = pair[1];\n            ruleObj[property] = value;\n          }\n          rule = match[1];\n          rule.split(',').forEach(function(_rule) {\n            _rule = _rule.replace(/^svg/i, '').trim();\n            if (_rule === '') {\n              return;\n            }\n            if (allRules[_rule]) {\n              fabric.util.object.extend(allRules[_rule], ruleObj);\n            }\n            else {\n              allRules[_rule] = fabric.util.object.clone(ruleObj);\n            }\n          });\n        });\n      }\n      return allRules;\n    },\n\n    /**\n     * Takes url corresponding to an SVG document, and parses it into a set of fabric objects.\n     * Note that SVG is fetched via XMLHttpRequest, so it needs to conform to SOP (Same Origin Policy)\n     * @memberOf fabric\n     * @param {String} url\n     * @param {Function} callback\n     * @param {Function} [reviver] Method for further parsing of SVG elements, called after each fabric object created.\n     * @param {Object} [options] Object containing options for parsing\n     * @param {String} [options.crossOrigin] crossOrigin crossOrigin setting to use for external resources\n     */\n    loadSVGFromURL: function(url, callback, reviver, options) {\n\n      url = url.replace(/^\\n\\s*/, '').trim();\n      new fabric.util.request(url, {\n        method: 'get',\n        onComplete: onComplete\n      });\n\n      function onComplete(r) {\n\n        var xml = r.responseXML;\n        if (xml && !xml.documentElement && fabric.window.ActiveXObject && r.responseText) {\n          xml = new ActiveXObject('Microsoft.XMLDOM');\n          xml.async = 'false';\n          //IE chokes on DOCTYPE\n          xml.loadXML(r.responseText.replace(/<!DOCTYPE[\\s\\S]*?(\\[[\\s\\S]*\\])*?>/i, ''));\n        }\n        if (!xml || !xml.documentElement) {\n          callback && callback(null);\n          return false;\n        }\n\n        fabric.parseSVGDocument(xml.documentElement, function (results, _options, elements, allElements) {\n          callback && callback(results, _options, elements, allElements);\n        }, reviver, options);\n      }\n    },\n\n    /**\n     * Takes string corresponding to an SVG document, and parses it into a set of fabric objects\n     * @memberOf fabric\n     * @param {String} string\n     * @param {Function} callback\n     * @param {Function} [reviver] Method for further parsing of SVG elements, called after each fabric object created.\n     * @param {Object} [options] Object containing options for parsing\n     * @param {String} [options.crossOrigin] crossOrigin crossOrigin setting to use for external resources\n     */\n    loadSVGFromString: function(string, callback, reviver, options) {\n      string = string.trim();\n      var doc;\n      if (typeof fabric.window.DOMParser !== 'undefined') {\n        var parser = new fabric.window.DOMParser();\n        if (parser && parser.parseFromString) {\n          doc = parser.parseFromString(string, 'text/xml');\n        }\n      }\n      else if (fabric.window.ActiveXObject) {\n        doc = new ActiveXObject('Microsoft.XMLDOM');\n        doc.async = 'false';\n        // IE chokes on DOCTYPE\n        doc.loadXML(string.replace(/<!DOCTYPE[\\s\\S]*?(\\[[\\s\\S]*\\])*?>/i, ''));\n      }\n\n      fabric.parseSVGDocument(doc.documentElement, function (results, _options, elements, allElements) {\n        callback(results, _options, elements, allElements);\n      }, reviver, options);\n    }\n  });\n\n})(typeof exports !== 'undefined' ? exports : this);\n\n\nfabric.ElementsParser = function(elements, callback, options, reviver, parsingOptions) {\n  this.elements = elements;\n  this.callback = callback;\n  this.options = options;\n  this.reviver = reviver;\n  this.svgUid = (options && options.svgUid) || 0;\n  this.parsingOptions = parsingOptions;\n  this.regexUrl = /^url\\(['\"]?#([^'\"]+)['\"]?\\)/g;\n};\n\n(function(proto) {\n  proto.parse = function() {\n    this.instances = new Array(this.elements.length);\n    this.numElements = this.elements.length;\n    this.createObjects();\n  };\n\n  proto.createObjects = function() {\n    var _this = this;\n    this.elements.forEach(function(element, i) {\n      element.setAttribute('svgUid', _this.svgUid);\n      _this.createObject(element, i);\n    });\n  };\n\n  proto.findTag = function(el) {\n    return fabric[fabric.util.string.capitalize(el.tagName.replace('svg:', ''))];\n  };\n\n  proto.createObject = function(el, index) {\n    var klass = this.findTag(el);\n    if (klass && klass.fromElement) {\n      try {\n        klass.fromElement(el, this.createCallback(index, el), this.options);\n      }\n      catch (err) {\n        fabric.log(err);\n      }\n    }\n    else {\n      this.checkIfDone();\n    }\n  };\n\n  proto.createCallback = function(index, el) {\n    var _this = this;\n    return function(obj) {\n      var _options;\n      _this.resolveGradient(obj, 'fill');\n      _this.resolveGradient(obj, 'stroke');\n      if (obj instanceof fabric.Image && obj._originalElement) {\n        _options = obj.parsePreserveAspectRatioAttribute(el);\n      }\n      obj._removeTransformMatrix(_options);\n      _this.resolveClipPath(obj);\n      _this.reviver && _this.reviver(el, obj);\n      _this.instances[index] = obj;\n      _this.checkIfDone();\n    };\n  };\n\n  proto.extractPropertyDefinition = function(obj, property, storage) {\n    var value = obj[property];\n    if (!(/^url\\(/).test(value)) {\n      return;\n    }\n    var id = this.regexUrl.exec(value)[1];\n    this.regexUrl.lastIndex = 0;\n    return fabric[storage][this.svgUid][id];\n  };\n\n  proto.resolveGradient = function(obj, property) {\n    var gradientDef = this.extractPropertyDefinition(obj, property, 'gradientDefs');\n    if (gradientDef) {\n      obj.set(property, fabric.Gradient.fromElement(gradientDef, obj));\n    }\n  };\n\n  proto.createClipPathCallback = function(obj, container) {\n    return function(_newObj) {\n      _newObj._removeTransformMatrix();\n      _newObj.fillRule = _newObj.clipRule;\n      container.push(_newObj);\n    };\n  };\n\n  proto.resolveClipPath = function(obj) {\n    var clipPath = this.extractPropertyDefinition(obj, 'clipPath', 'clipPaths'),\n        element, klass, objTransformInv, container, gTransform, options;\n    if (clipPath) {\n      container = [];\n      objTransformInv = fabric.util.invertTransform(obj.calcTransformMatrix());\n      for (var i = 0; i < clipPath.length; i++) {\n        element = clipPath[i];\n        klass = this.findTag(element);\n        klass.fromElement(\n          element,\n          this.createClipPathCallback(obj, container),\n          this.options\n        );\n      }\n      if (container.length === 1) {\n        clipPath = container[0];\n      }\n      else {\n        clipPath = new fabric.Group(container);\n      }\n      gTransform = fabric.util.multiplyTransformMatrices(\n        objTransformInv,\n        clipPath.calcTransformMatrix()\n      );\n      var options = fabric.util.qrDecompose(gTransform);\n      clipPath.flipX = false;\n      clipPath.flipY = false;\n      clipPath.set('scaleX', options.scaleX);\n      clipPath.set('scaleY', options.scaleY);\n      clipPath.angle = options.angle;\n      clipPath.skewX = options.skewX;\n      clipPath.skewY = 0;\n      clipPath.setPositionByOrigin({ x: options.translateX, y: options.translateY }, 'center', 'center');\n      obj.clipPath = clipPath;\n    }\n  };\n\n  proto.checkIfDone = function() {\n    if (--this.numElements === 0) {\n      this.instances = this.instances.filter(function(el) {\n        // eslint-disable-next-line no-eq-null, eqeqeq\n        return el != null;\n      });\n      this.callback(this.instances, this.elements);\n    }\n  };\n})(fabric.ElementsParser.prototype);\n\n\n(function(global) {\n\n  'use strict';\n\n  /* Adaptation of work of Kevin Lindsey (kevin@kevlindev.com) */\n\n  var fabric = global.fabric || (global.fabric = { });\n\n  if (fabric.Point) {\n    fabric.warn('fabric.Point is already defined');\n    return;\n  }\n\n  fabric.Point = Point;\n\n  /**\n   * Point class\n   * @class fabric.Point\n   * @memberOf fabric\n   * @constructor\n   * @param {Number} x\n   * @param {Number} y\n   * @return {fabric.Point} thisArg\n   */\n  function Point(x, y) {\n    this.x = x;\n    this.y = y;\n  }\n\n  Point.prototype = /** @lends fabric.Point.prototype */ {\n\n    type: 'point',\n\n    constructor: Point,\n\n    /**\n     * Adds another point to this one and returns another one\n     * @param {fabric.Point} that\n     * @return {fabric.Point} new Point instance with added values\n     */\n    add: function (that) {\n      return new Point(this.x + that.x, this.y + that.y);\n    },\n\n    /**\n     * Adds another point to this one\n     * @param {fabric.Point} that\n     * @return {fabric.Point} thisArg\n     * @chainable\n     */\n    addEquals: function (that) {\n      this.x += that.x;\n      this.y += that.y;\n      return this;\n    },\n\n    /**\n     * Adds value to this point and returns a new one\n     * @param {Number} scalar\n     * @return {fabric.Point} new Point with added value\n     */\n    scalarAdd: function (scalar) {\n      return new Point(this.x + scalar, this.y + scalar);\n    },\n\n    /**\n     * Adds value to this point\n     * @param {Number} scalar\n     * @return {fabric.Point} thisArg\n     * @chainable\n     */\n    scalarAddEquals: function (scalar) {\n      this.x += scalar;\n      this.y += scalar;\n      return this;\n    },\n\n    /**\n     * Subtracts another point from this point and returns a new one\n     * @param {fabric.Point} that\n     * @return {fabric.Point} new Point object with subtracted values\n     */\n    subtract: function (that) {\n      return new Point(this.x - that.x, this.y - that.y);\n    },\n\n    /**\n     * Subtracts another point from this point\n     * @param {fabric.Point} that\n     * @return {fabric.Point} thisArg\n     * @chainable\n     */\n    subtractEquals: function (that) {\n      this.x -= that.x;\n      this.y -= that.y;\n      return this;\n    },\n\n    /**\n     * Subtracts value from this point and returns a new one\n     * @param {Number} scalar\n     * @return {fabric.Point}\n     */\n    scalarSubtract: function (scalar) {\n      return new Point(this.x - scalar, this.y - scalar);\n    },\n\n    /**\n     * Subtracts value from this point\n     * @param {Number} scalar\n     * @return {fabric.Point} thisArg\n     * @chainable\n     */\n    scalarSubtractEquals: function (scalar) {\n      this.x -= scalar;\n      this.y -= scalar;\n      return this;\n    },\n\n    /**\n     * Multiplies this point by a value and returns a new one\n     * TODO: rename in scalarMultiply in 2.0\n     * @param {Number} scalar\n     * @return {fabric.Point}\n     */\n    multiply: function (scalar) {\n      return new Point(this.x * scalar, this.y * scalar);\n    },\n\n    /**\n     * Multiplies this point by a value\n     * TODO: rename in scalarMultiplyEquals in 2.0\n     * @param {Number} scalar\n     * @return {fabric.Point} thisArg\n     * @chainable\n     */\n    multiplyEquals: function (scalar) {\n      this.x *= scalar;\n      this.y *= scalar;\n      return this;\n    },\n\n    /**\n     * Divides this point by a value and returns a new one\n     * TODO: rename in scalarDivide in 2.0\n     * @param {Number} scalar\n     * @return {fabric.Point}\n     */\n    divide: function (scalar) {\n      return new Point(this.x / scalar, this.y / scalar);\n    },\n\n    /**\n     * Divides this point by a value\n     * TODO: rename in scalarDivideEquals in 2.0\n     * @param {Number} scalar\n     * @return {fabric.Point} thisArg\n     * @chainable\n     */\n    divideEquals: function (scalar) {\n      this.x /= scalar;\n      this.y /= scalar;\n      return this;\n    },\n\n    /**\n     * Returns true if this point is equal to another one\n     * @param {fabric.Point} that\n     * @return {Boolean}\n     */\n    eq: function (that) {\n      return (this.x === that.x && this.y === that.y);\n    },\n\n    /**\n     * Returns true if this point is less than another one\n     * @param {fabric.Point} that\n     * @return {Boolean}\n     */\n    lt: function (that) {\n      return (this.x < that.x && this.y < that.y);\n    },\n\n    /**\n     * Returns true if this point is less than or equal to another one\n     * @param {fabric.Point} that\n     * @return {Boolean}\n     */\n    lte: function (that) {\n      return (this.x <= that.x && this.y <= that.y);\n    },\n\n    /**\n\n     * Returns true if this point is greater another one\n     * @param {fabric.Point} that\n     * @return {Boolean}\n     */\n    gt: function (that) {\n      return (this.x > that.x && this.y > that.y);\n    },\n\n    /**\n     * Returns true if this point is greater than or equal to another one\n     * @param {fabric.Point} that\n     * @return {Boolean}\n     */\n    gte: function (that) {\n      return (this.x >= that.x && this.y >= that.y);\n    },\n\n    /**\n     * Returns new point which is the result of linear interpolation with this one and another one\n     * @param {fabric.Point} that\n     * @param {Number} t , position of interpolation, between 0 and 1 default 0.5\n     * @return {fabric.Point}\n     */\n    lerp: function (that, t) {\n      if (typeof t === 'undefined') {\n        t = 0.5;\n      }\n      t = Math.max(Math.min(1, t), 0);\n      return new Point(this.x + (that.x - this.x) * t, this.y + (that.y - this.y) * t);\n    },\n\n    /**\n     * Returns distance from this point and another one\n     * @param {fabric.Point} that\n     * @return {Number}\n     */\n    distanceFrom: function (that) {\n      var dx = this.x - that.x,\n          dy = this.y - that.y;\n      return Math.sqrt(dx * dx + dy * dy);\n    },\n\n    /**\n     * Returns the point between this point and another one\n     * @param {fabric.Point} that\n     * @return {fabric.Point}\n     */\n    midPointFrom: function (that) {\n      return this.lerp(that);\n    },\n\n    /**\n     * Returns a new point which is the min of this and another one\n     * @param {fabric.Point} that\n     * @return {fabric.Point}\n     */\n    min: function (that) {\n      return new Point(Math.min(this.x, that.x), Math.min(this.y, that.y));\n    },\n\n    /**\n     * Returns a new point which is the max of this and another one\n     * @param {fabric.Point} that\n     * @return {fabric.Point}\n     */\n    max: function (that) {\n      return new Point(Math.max(this.x, that.x), Math.max(this.y, that.y));\n    },\n\n    /**\n     * Returns string representation of this point\n     * @return {String}\n     */\n    toString: function () {\n      return this.x + ',' + this.y;\n    },\n\n    /**\n     * Sets x/y of this point\n     * @param {Number} x\n     * @param {Number} y\n     * @chainable\n     */\n    setXY: function (x, y) {\n      this.x = x;\n      this.y = y;\n      return this;\n    },\n\n    /**\n     * Sets x of this point\n     * @param {Number} x\n     * @chainable\n     */\n    setX: function (x) {\n      this.x = x;\n      return this;\n    },\n\n    /**\n     * Sets y of this point\n     * @param {Number} y\n     * @chainable\n     */\n    setY: function (y) {\n      this.y = y;\n      return this;\n    },\n\n    /**\n     * Sets x/y of this point from another point\n     * @param {fabric.Point} that\n     * @chainable\n     */\n    setFromPoint: function (that) {\n      this.x = that.x;\n      this.y = that.y;\n      return this;\n    },\n\n    /**\n     * Swaps x/y of this point and another point\n     * @param {fabric.Point} that\n     */\n    swap: function (that) {\n      var x = this.x,\n          y = this.y;\n      this.x = that.x;\n      this.y = that.y;\n      that.x = x;\n      that.y = y;\n    },\n\n    /**\n     * return a cloned instance of the point\n     * @return {fabric.Point}\n     */\n    clone: function () {\n      return new Point(this.x, this.y);\n    }\n  };\n\n})(typeof exports !== 'undefined' ? exports : this);\n\n\n(function(global) {\n\n  'use strict';\n\n  /* Adaptation of work of Kevin Lindsey (kevin@kevlindev.com) */\n  var fabric = global.fabric || (global.fabric = { });\n\n  if (fabric.Intersection) {\n    fabric.warn('fabric.Intersection is already defined');\n    return;\n  }\n\n  /**\n   * Intersection class\n   * @class fabric.Intersection\n   * @memberOf fabric\n   * @constructor\n   */\n  function Intersection(status) {\n    this.status = status;\n    this.points = [];\n  }\n\n  fabric.Intersection = Intersection;\n\n  fabric.Intersection.prototype = /** @lends fabric.Intersection.prototype */ {\n\n    constructor: Intersection,\n\n    /**\n     * Appends a point to intersection\n     * @param {fabric.Point} point\n     * @return {fabric.Intersection} thisArg\n     * @chainable\n     */\n    appendPoint: function (point) {\n      this.points.push(point);\n      return this;\n    },\n\n    /**\n     * Appends points to intersection\n     * @param {Array} points\n     * @return {fabric.Intersection} thisArg\n     * @chainable\n     */\n    appendPoints: function (points) {\n      this.points = this.points.concat(points);\n      return this;\n    }\n  };\n\n  /**\n   * Checks if one line intersects another\n   * TODO: rename in intersectSegmentSegment\n   * @static\n   * @param {fabric.Point} a1\n   * @param {fabric.Point} a2\n   * @param {fabric.Point} b1\n   * @param {fabric.Point} b2\n   * @return {fabric.Intersection}\n   */\n  fabric.Intersection.intersectLineLine = function (a1, a2, b1, b2) {\n    var result,\n        uaT = (b2.x - b1.x) * (a1.y - b1.y) - (b2.y - b1.y) * (a1.x - b1.x),\n        ubT = (a2.x - a1.x) * (a1.y - b1.y) - (a2.y - a1.y) * (a1.x - b1.x),\n        uB = (b2.y - b1.y) * (a2.x - a1.x) - (b2.x - b1.x) * (a2.y - a1.y);\n    if (uB !== 0) {\n      var ua = uaT / uB,\n          ub = ubT / uB;\n      if (0 <= ua && ua <= 1 && 0 <= ub && ub <= 1) {\n        result = new Intersection('Intersection');\n        result.appendPoint(new fabric.Point(a1.x + ua * (a2.x - a1.x), a1.y + ua * (a2.y - a1.y)));\n      }\n      else {\n        result = new Intersection();\n      }\n    }\n    else {\n      if (uaT === 0 || ubT === 0) {\n        result = new Intersection('Coincident');\n      }\n      else {\n        result = new Intersection('Parallel');\n      }\n    }\n    return result;\n  };\n\n  /**\n   * Checks if line intersects polygon\n   * TODO: rename in intersectSegmentPolygon\n   * fix detection of coincident\n   * @static\n   * @param {fabric.Point} a1\n   * @param {fabric.Point} a2\n   * @param {Array} points\n   * @return {fabric.Intersection}\n   */\n  fabric.Intersection.intersectLinePolygon = function(a1, a2, points) {\n    var result = new Intersection(),\n        length = points.length,\n        b1, b2, inter, i;\n\n    for (i = 0; i < length; i++) {\n      b1 = points[i];\n      b2 = points[(i + 1) % length];\n      inter = Intersection.intersectLineLine(a1, a2, b1, b2);\n\n      result.appendPoints(inter.points);\n    }\n    if (result.points.length > 0) {\n      result.status = 'Intersection';\n    }\n    return result;\n  };\n\n  /**\n   * Checks if polygon intersects another polygon\n   * @static\n   * @param {Array} points1\n   * @param {Array} points2\n   * @return {fabric.Intersection}\n   */\n  fabric.Intersection.intersectPolygonPolygon = function (points1, points2) {\n    var result = new Intersection(),\n        length = points1.length, i;\n\n    for (i = 0; i < length; i++) {\n      var a1 = points1[i],\n          a2 = points1[(i + 1) % length],\n          inter = Intersection.intersectLinePolygon(a1, a2, points2);\n\n      result.appendPoints(inter.points);\n    }\n    if (result.points.length > 0) {\n      result.status = 'Intersection';\n    }\n    return result;\n  };\n\n  /**\n   * Checks if polygon intersects rectangle\n   * @static\n   * @param {Array} points\n   * @param {fabric.Point} r1\n   * @param {fabric.Point} r2\n   * @return {fabric.Intersection}\n   */\n  fabric.Intersection.intersectPolygonRectangle = function (points, r1, r2) {\n    var min = r1.min(r2),\n        max = r1.max(r2),\n        topRight = new fabric.Point(max.x, min.y),\n        bottomLeft = new fabric.Point(min.x, max.y),\n        inter1 = Intersection.intersectLinePolygon(min, topRight, points),\n        inter2 = Intersection.intersectLinePolygon(topRight, max, points),\n        inter3 = Intersection.intersectLinePolygon(max, bottomLeft, points),\n        inter4 = Intersection.intersectLinePolygon(bottomLeft, min, points),\n        result = new Intersection();\n\n    result.appendPoints(inter1.points);\n    result.appendPoints(inter2.points);\n    result.appendPoints(inter3.points);\n    result.appendPoints(inter4.points);\n\n    if (result.points.length > 0) {\n      result.status = 'Intersection';\n    }\n    return result;\n  };\n\n})(typeof exports !== 'undefined' ? exports : this);\n\n\n(function(global) {\n\n  'use strict';\n\n  var fabric = global.fabric || (global.fabric = { });\n\n  if (fabric.Color) {\n    fabric.warn('fabric.Color is already defined.');\n    return;\n  }\n\n  /**\n   * Color class\n   * The purpose of {@link fabric.Color} is to abstract and encapsulate common color operations;\n   * {@link fabric.Color} is a constructor and creates instances of {@link fabric.Color} objects.\n   *\n   * @class fabric.Color\n   * @param {String} color optional in hex or rgb(a) or hsl format or from known color list\n   * @return {fabric.Color} thisArg\n   * @tutorial {@link http://fabricjs.com/fabric-intro-part-2/#colors}\n   */\n  function Color(color) {\n    if (!color) {\n      this.setSource([0, 0, 0, 1]);\n    }\n    else {\n      this._tryParsingColor(color);\n    }\n  }\n\n  fabric.Color = Color;\n\n  fabric.Color.prototype = /** @lends fabric.Color.prototype */ {\n\n    /**\n     * @private\n     * @param {String|Array} color Color value to parse\n     */\n    _tryParsingColor: function(color) {\n      var source;\n\n      if (color in Color.colorNameMap) {\n        color = Color.colorNameMap[color];\n      }\n\n      if (color === 'transparent') {\n        source = [255, 255, 255, 0];\n      }\n\n      if (!source) {\n        source = Color.sourceFromHex(color);\n      }\n      if (!source) {\n        source = Color.sourceFromRgb(color);\n      }\n      if (!source) {\n        source = Color.sourceFromHsl(color);\n      }\n      if (!source) {\n        //if color is not recognize let's make black as canvas does\n        source = [0, 0, 0, 1];\n      }\n      if (source) {\n        this.setSource(source);\n      }\n    },\n\n    /**\n     * Adapted from <a href=\"https://rawgithub.com/mjijackson/mjijackson.github.com/master/2008/02/rgb-to-hsl-and-rgb-to-hsv-color-model-conversion-algorithms-in-javascript.html\">https://github.com/mjijackson</a>\n     * @private\n     * @param {Number} r Red color value\n     * @param {Number} g Green color value\n     * @param {Number} b Blue color value\n     * @return {Array} Hsl color\n     */\n    _rgbToHsl: function(r, g, b) {\n      r /= 255; g /= 255; b /= 255;\n\n      var h, s, l,\n          max = fabric.util.array.max([r, g, b]),\n          min = fabric.util.array.min([r, g, b]);\n\n      l = (max + min) / 2;\n\n      if (max === min) {\n        h = s = 0; // achromatic\n      }\n      else {\n        var d = max - min;\n        s = l > 0.5 ? d / (2 - max - min) : d / (max + min);\n        switch (max) {\n          case r:\n            h = (g - b) / d + (g < b ? 6 : 0);\n            break;\n          case g:\n            h = (b - r) / d + 2;\n            break;\n          case b:\n            h = (r - g) / d + 4;\n            break;\n        }\n        h /= 6;\n      }\n\n      return [\n        Math.round(h * 360),\n        Math.round(s * 100),\n        Math.round(l * 100)\n      ];\n    },\n\n    /**\n     * Returns source of this color (where source is an array representation; ex: [200, 200, 100, 1])\n     * @return {Array}\n     */\n    getSource: function() {\n      return this._source;\n    },\n\n    /**\n     * Sets source of this color (where source is an array representation; ex: [200, 200, 100, 1])\n     * @param {Array} source\n     */\n    setSource: function(source) {\n      this._source = source;\n    },\n\n    /**\n     * Returns color representation in RGB format\n     * @return {String} ex: rgb(0-255,0-255,0-255)\n     */\n    toRgb: function() {\n      var source = this.getSource();\n      return 'rgb(' + source[0] + ',' + source[1] + ',' + source[2] + ')';\n    },\n\n    /**\n     * Returns color representation in RGBA format\n     * @return {String} ex: rgba(0-255,0-255,0-255,0-1)\n     */\n    toRgba: function() {\n      var source = this.getSource();\n      return 'rgba(' + source[0] + ',' + source[1] + ',' + source[2] + ',' + source[3] + ')';\n    },\n\n    /**\n     * Returns color representation in HSL format\n     * @return {String} ex: hsl(0-360,0%-100%,0%-100%)\n     */\n    toHsl: function() {\n      var source = this.getSource(),\n          hsl = this._rgbToHsl(source[0], source[1], source[2]);\n\n      return 'hsl(' + hsl[0] + ',' + hsl[1] + '%,' + hsl[2] + '%)';\n    },\n\n    /**\n     * Returns color representation in HSLA format\n     * @return {String} ex: hsla(0-360,0%-100%,0%-100%,0-1)\n     */\n    toHsla: function() {\n      var source = this.getSource(),\n          hsl = this._rgbToHsl(source[0], source[1], source[2]);\n\n      return 'hsla(' + hsl[0] + ',' + hsl[1] + '%,' + hsl[2] + '%,' + source[3] + ')';\n    },\n\n    /**\n     * Returns color representation in HEX format\n     * @return {String} ex: FF5555\n     */\n    toHex: function() {\n      var source = this.getSource(), r, g, b;\n\n      r = source[0].toString(16);\n      r = (r.length === 1) ? ('0' + r) : r;\n\n      g = source[1].toString(16);\n      g = (g.length === 1) ? ('0' + g) : g;\n\n      b = source[2].toString(16);\n      b = (b.length === 1) ? ('0' + b) : b;\n\n      return r.toUpperCase() + g.toUpperCase() + b.toUpperCase();\n    },\n\n    /**\n     * Returns color representation in HEXA format\n     * @return {String} ex: FF5555CC\n     */\n    toHexa: function() {\n      var source = this.getSource(), a;\n\n      a = Math.round(source[3] * 255);\n      a = a.toString(16);\n      a = (a.length === 1) ? ('0' + a) : a;\n\n      return this.toHex() + a.toUpperCase();\n    },\n\n    /**\n     * Gets value of alpha channel for this color\n     * @return {Number} 0-1\n     */\n    getAlpha: function() {\n      return this.getSource()[3];\n    },\n\n    /**\n     * Sets value of alpha channel for this color\n     * @param {Number} alpha Alpha value 0-1\n     * @return {fabric.Color} thisArg\n     */\n    setAlpha: function(alpha) {\n      var source = this.getSource();\n      source[3] = alpha;\n      this.setSource(source);\n      return this;\n    },\n\n    /**\n     * Transforms color to its grayscale representation\n     * @return {fabric.Color} thisArg\n     */\n    toGrayscale: function() {\n      var source = this.getSource(),\n          average = parseInt((source[0] * 0.3 + source[1] * 0.59 + source[2] * 0.11).toFixed(0), 10),\n          currentAlpha = source[3];\n      this.setSource([average, average, average, currentAlpha]);\n      return this;\n    },\n\n    /**\n     * Transforms color to its black and white representation\n     * @param {Number} threshold\n     * @return {fabric.Color} thisArg\n     */\n    toBlackWhite: function(threshold) {\n      var source = this.getSource(),\n          average = (source[0] * 0.3 + source[1] * 0.59 + source[2] * 0.11).toFixed(0),\n          currentAlpha = source[3];\n\n      threshold = threshold || 127;\n\n      average = (Number(average) < Number(threshold)) ? 0 : 255;\n      this.setSource([average, average, average, currentAlpha]);\n      return this;\n    },\n\n    /**\n     * Overlays color with another color\n     * @param {String|fabric.Color} otherColor\n     * @return {fabric.Color} thisArg\n     */\n    overlayWith: function(otherColor) {\n      if (!(otherColor instanceof Color)) {\n        otherColor = new Color(otherColor);\n      }\n\n      var result = [],\n          alpha = this.getAlpha(),\n          otherAlpha = 0.5,\n          source = this.getSource(),\n          otherSource = otherColor.getSource(), i;\n\n      for (i = 0; i < 3; i++) {\n        result.push(Math.round((source[i] * (1 - otherAlpha)) + (otherSource[i] * otherAlpha)));\n      }\n\n      result[3] = alpha;\n      this.setSource(result);\n      return this;\n    }\n  };\n\n  /**\n   * 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))\n   * @static\n   * @field\n   * @memberOf fabric.Color\n   */\n  // eslint-disable-next-line max-len\n  fabric.Color.reRGBa = /^rgba?\\(\\s*(\\d{1,3}(?:\\.\\d+)?\\%?)\\s*,\\s*(\\d{1,3}(?:\\.\\d+)?\\%?)\\s*,\\s*(\\d{1,3}(?:\\.\\d+)?\\%?)\\s*(?:\\s*,\\s*((?:\\d*\\.?\\d+)?)\\s*)?\\)$/i;\n\n  /**\n   * 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 ))\n   * @static\n   * @field\n   * @memberOf fabric.Color\n   */\n  fabric.Color.reHSLa = /^hsla?\\(\\s*(\\d{1,3})\\s*,\\s*(\\d{1,3}\\%)\\s*,\\s*(\\d{1,3}\\%)\\s*(?:\\s*,\\s*(\\d+(?:\\.\\d+)?)\\s*)?\\)$/i;\n\n  /**\n   * Regex matching color in HEX format (ex: #FF5544CC, #FF5555, 010155, aff)\n   * @static\n   * @field\n   * @memberOf fabric.Color\n   */\n  fabric.Color.reHex = /^#?([0-9a-f]{8}|[0-9a-f]{6}|[0-9a-f]{4}|[0-9a-f]{3})$/i;\n\n  /**\n   * Map of the 148 color names with HEX code\n   * @static\n   * @field\n   * @memberOf fabric.Color\n   * @see: https://www.w3.org/TR/css3-color/#svg-color\n   */\n  fabric.Color.colorNameMap = {\n    aliceblue:            '#F0F8FF',\n    antiquewhite:         '#FAEBD7',\n    aqua:                 '#00FFFF',\n    aquamarine:           '#7FFFD4',\n    azure:                '#F0FFFF',\n    beige:                '#F5F5DC',\n    bisque:               '#FFE4C4',\n    black:                '#000000',\n    blanchedalmond:       '#FFEBCD',\n    blue:                 '#0000FF',\n    blueviolet:           '#8A2BE2',\n    brown:                '#A52A2A',\n    burlywood:            '#DEB887',\n    cadetblue:            '#5F9EA0',\n    chartreuse:           '#7FFF00',\n    chocolate:            '#D2691E',\n    coral:                '#FF7F50',\n    cornflowerblue:       '#6495ED',\n    cornsilk:             '#FFF8DC',\n    crimson:              '#DC143C',\n    cyan:                 '#00FFFF',\n    darkblue:             '#00008B',\n    darkcyan:             '#008B8B',\n    darkgoldenrod:        '#B8860B',\n    darkgray:             '#A9A9A9',\n    darkgrey:             '#A9A9A9',\n    darkgreen:            '#006400',\n    darkkhaki:            '#BDB76B',\n    darkmagenta:          '#8B008B',\n    darkolivegreen:       '#556B2F',\n    darkorange:           '#FF8C00',\n    darkorchid:           '#9932CC',\n    darkred:              '#8B0000',\n    darksalmon:           '#E9967A',\n    darkseagreen:         '#8FBC8F',\n    darkslateblue:        '#483D8B',\n    darkslategray:        '#2F4F4F',\n    darkslategrey:        '#2F4F4F',\n    darkturquoise:        '#00CED1',\n    darkviolet:           '#9400D3',\n    deeppink:             '#FF1493',\n    deepskyblue:          '#00BFFF',\n    dimgray:              '#696969',\n    dimgrey:              '#696969',\n    dodgerblue:           '#1E90FF',\n    firebrick:            '#B22222',\n    floralwhite:          '#FFFAF0',\n    forestgreen:          '#228B22',\n    fuchsia:              '#FF00FF',\n    gainsboro:            '#DCDCDC',\n    ghostwhite:           '#F8F8FF',\n    gold:                 '#FFD700',\n    goldenrod:            '#DAA520',\n    gray:                 '#808080',\n    grey:                 '#808080',\n    green:                '#008000',\n    greenyellow:          '#ADFF2F',\n    honeydew:             '#F0FFF0',\n    hotpink:              '#FF69B4',\n    indianred:            '#CD5C5C',\n    indigo:               '#4B0082',\n    ivory:                '#FFFFF0',\n    khaki:                '#F0E68C',\n    lavender:             '#E6E6FA',\n    lavenderblush:        '#FFF0F5',\n    lawngreen:            '#7CFC00',\n    lemonchiffon:         '#FFFACD',\n    lightblue:            '#ADD8E6',\n    lightcoral:           '#F08080',\n    lightcyan:            '#E0FFFF',\n    lightgoldenrodyellow: '#FAFAD2',\n    lightgray:            '#D3D3D3',\n    lightgrey:            '#D3D3D3',\n    lightgreen:           '#90EE90',\n    lightpink:            '#FFB6C1',\n    lightsalmon:          '#FFA07A',\n    lightseagreen:        '#20B2AA',\n    lightskyblue:         '#87CEFA',\n    lightslategray:       '#778899',\n    lightslategrey:       '#778899',\n    lightsteelblue:       '#B0C4DE',\n    lightyellow:          '#FFFFE0',\n    lime:                 '#00FF00',\n    limegreen:            '#32CD32',\n    linen:                '#FAF0E6',\n    magenta:              '#FF00FF',\n    maroon:               '#800000',\n    mediumaquamarine:     '#66CDAA',\n    mediumblue:           '#0000CD',\n    mediumorchid:         '#BA55D3',\n    mediumpurple:         '#9370DB',\n    mediumseagreen:       '#3CB371',\n    mediumslateblue:      '#7B68EE',\n    mediumspringgreen:    '#00FA9A',\n    mediumturquoise:      '#48D1CC',\n    mediumvioletred:      '#C71585',\n    midnightblue:         '#191970',\n    mintcream:            '#F5FFFA',\n    mistyrose:            '#FFE4E1',\n    moccasin:             '#FFE4B5',\n    navajowhite:          '#FFDEAD',\n    navy:                 '#000080',\n    oldlace:              '#FDF5E6',\n    olive:                '#808000',\n    olivedrab:            '#6B8E23',\n    orange:               '#FFA500',\n    orangered:            '#FF4500',\n    orchid:               '#DA70D6',\n    palegoldenrod:        '#EEE8AA',\n    palegreen:            '#98FB98',\n    paleturquoise:        '#AFEEEE',\n    palevioletred:        '#DB7093',\n    papayawhip:           '#FFEFD5',\n    peachpuff:            '#FFDAB9',\n    peru:                 '#CD853F',\n    pink:                 '#FFC0CB',\n    plum:                 '#DDA0DD',\n    powderblue:           '#B0E0E6',\n    purple:               '#800080',\n    rebeccapurple:        '#663399',\n    red:                  '#FF0000',\n    rosybrown:            '#BC8F8F',\n    royalblue:            '#4169E1',\n    saddlebrown:          '#8B4513',\n    salmon:               '#FA8072',\n    sandybrown:           '#F4A460',\n    seagreen:             '#2E8B57',\n    seashell:             '#FFF5EE',\n    sienna:               '#A0522D',\n    silver:               '#C0C0C0',\n    skyblue:              '#87CEEB',\n    slateblue:            '#6A5ACD',\n    slategray:            '#708090',\n    slategrey:            '#708090',\n    snow:                 '#FFFAFA',\n    springgreen:          '#00FF7F',\n    steelblue:            '#4682B4',\n    tan:                  '#D2B48C',\n    teal:                 '#008080',\n    thistle:              '#D8BFD8',\n    tomato:               '#FF6347',\n    turquoise:            '#40E0D0',\n    violet:               '#EE82EE',\n    wheat:                '#F5DEB3',\n    white:                '#FFFFFF',\n    whitesmoke:           '#F5F5F5',\n    yellow:               '#FFFF00',\n    yellowgreen:          '#9ACD32'\n  };\n\n  /**\n   * @private\n   * @param {Number} p\n   * @param {Number} q\n   * @param {Number} t\n   * @return {Number}\n   */\n  function hue2rgb(p, q, t) {\n    if (t < 0) {\n      t += 1;\n    }\n    if (t > 1) {\n      t -= 1;\n    }\n    if (t < 1 / 6) {\n      return p + (q - p) * 6 * t;\n    }\n    if (t < 1 / 2) {\n      return q;\n    }\n    if (t < 2 / 3) {\n      return p + (q - p) * (2 / 3 - t) * 6;\n    }\n    return p;\n  }\n\n  /**\n   * Returns new color object, when given a color in RGB format\n   * @memberOf fabric.Color\n   * @param {String} color Color value ex: rgb(0-255,0-255,0-255)\n   * @return {fabric.Color}\n   */\n  fabric.Color.fromRgb = function(color) {\n    return Color.fromSource(Color.sourceFromRgb(color));\n  };\n\n  /**\n   * Returns array representation (ex: [100, 100, 200, 1]) of a color that's in RGB or RGBA format\n   * @memberOf fabric.Color\n   * @param {String} color Color value ex: rgb(0-255,0-255,0-255), rgb(0%-100%,0%-100%,0%-100%)\n   * @return {Array} source\n   */\n  fabric.Color.sourceFromRgb = function(color) {\n    var match = color.match(Color.reRGBa);\n    if (match) {\n      var r = parseInt(match[1], 10) / (/%$/.test(match[1]) ? 100 : 1) * (/%$/.test(match[1]) ? 255 : 1),\n          g = parseInt(match[2], 10) / (/%$/.test(match[2]) ? 100 : 1) * (/%$/.test(match[2]) ? 255 : 1),\n          b = parseInt(match[3], 10) / (/%$/.test(match[3]) ? 100 : 1) * (/%$/.test(match[3]) ? 255 : 1);\n\n      return [\n        parseInt(r, 10),\n        parseInt(g, 10),\n        parseInt(b, 10),\n        match[4] ? parseFloat(match[4]) : 1\n      ];\n    }\n  };\n\n  /**\n   * Returns new color object, when given a color in RGBA format\n   * @static\n   * @function\n   * @memberOf fabric.Color\n   * @param {String} color\n   * @return {fabric.Color}\n   */\n  fabric.Color.fromRgba = Color.fromRgb;\n\n  /**\n   * Returns new color object, when given a color in HSL format\n   * @param {String} color Color value ex: hsl(0-260,0%-100%,0%-100%)\n   * @memberOf fabric.Color\n   * @return {fabric.Color}\n   */\n  fabric.Color.fromHsl = function(color) {\n    return Color.fromSource(Color.sourceFromHsl(color));\n  };\n\n  /**\n   * Returns array representation (ex: [100, 100, 200, 1]) of a color that's in HSL or HSLA format.\n   * Adapted from <a href=\"https://rawgithub.com/mjijackson/mjijackson.github.com/master/2008/02/rgb-to-hsl-and-rgb-to-hsv-color-model-conversion-algorithms-in-javascript.html\">https://github.com/mjijackson</a>\n   * @memberOf fabric.Color\n   * @param {String} color Color value ex: hsl(0-360,0%-100%,0%-100%) or hsla(0-360,0%-100%,0%-100%, 0-1)\n   * @return {Array} source\n   * @see http://http://www.w3.org/TR/css3-color/#hsl-color\n   */\n  fabric.Color.sourceFromHsl = function(color) {\n    var match = color.match(Color.reHSLa);\n    if (!match) {\n      return;\n    }\n\n    var h = (((parseFloat(match[1]) % 360) + 360) % 360) / 360,\n        s = parseFloat(match[2]) / (/%$/.test(match[2]) ? 100 : 1),\n        l = parseFloat(match[3]) / (/%$/.test(match[3]) ? 100 : 1),\n        r, g, b;\n\n    if (s === 0) {\n      r = g = b = l;\n    }\n    else {\n      var q = l <= 0.5 ? l * (s + 1) : l + s - l * s,\n          p = l * 2 - q;\n\n      r = hue2rgb(p, q, h + 1 / 3);\n      g = hue2rgb(p, q, h);\n      b = hue2rgb(p, q, h - 1 / 3);\n    }\n\n    return [\n      Math.round(r * 255),\n      Math.round(g * 255),\n      Math.round(b * 255),\n      match[4] ? parseFloat(match[4]) : 1\n    ];\n  };\n\n  /**\n   * Returns new color object, when given a color in HSLA format\n   * @static\n   * @function\n   * @memberOf fabric.Color\n   * @param {String} color\n   * @return {fabric.Color}\n   */\n  fabric.Color.fromHsla = Color.fromHsl;\n\n  /**\n   * Returns new color object, when given a color in HEX format\n   * @static\n   * @memberOf fabric.Color\n   * @param {String} color Color value ex: FF5555\n   * @return {fabric.Color}\n   */\n  fabric.Color.fromHex = function(color) {\n    return Color.fromSource(Color.sourceFromHex(color));\n  };\n\n  /**\n   * Returns array representation (ex: [100, 100, 200, 1]) of a color that's in HEX format\n   * @static\n   * @memberOf fabric.Color\n   * @param {String} color ex: FF5555 or FF5544CC (RGBa)\n   * @return {Array} source\n   */\n  fabric.Color.sourceFromHex = function(color) {\n    if (color.match(Color.reHex)) {\n      var value = color.slice(color.indexOf('#') + 1),\n          isShortNotation = (value.length === 3 || value.length === 4),\n          isRGBa = (value.length === 8 || value.length === 4),\n          r = isShortNotation ? (value.charAt(0) + value.charAt(0)) : value.substring(0, 2),\n          g = isShortNotation ? (value.charAt(1) + value.charAt(1)) : value.substring(2, 4),\n          b = isShortNotation ? (value.charAt(2) + value.charAt(2)) : value.substring(4, 6),\n          a = isRGBa ? (isShortNotation ? (value.charAt(3) + value.charAt(3)) : value.substring(6, 8)) : 'FF';\n\n      return [\n        parseInt(r, 16),\n        parseInt(g, 16),\n        parseInt(b, 16),\n        parseFloat((parseInt(a, 16) / 255).toFixed(2))\n      ];\n    }\n  };\n\n  /**\n   * Returns new color object, when given color in array representation (ex: [200, 100, 100, 0.5])\n   * @static\n   * @memberOf fabric.Color\n   * @param {Array} source\n   * @return {fabric.Color}\n   */\n  fabric.Color.fromSource = function(source) {\n    var oColor = new Color();\n    oColor.setSource(source);\n    return oColor;\n  };\n\n})(typeof exports !== 'undefined' ? exports : this);\n\n\n(function() {\n\n  /* _FROM_SVG_START_ */\n  function getColorStop(el) {\n    var style = el.getAttribute('style'),\n        offset = el.getAttribute('offset') || 0,\n        color, colorAlpha, opacity, i;\n\n    // convert percents to absolute values\n    offset = parseFloat(offset) / (/%$/.test(offset) ? 100 : 1);\n    offset = offset < 0 ? 0 : offset > 1 ? 1 : offset;\n    if (style) {\n      var keyValuePairs = style.split(/\\s*;\\s*/);\n\n      if (keyValuePairs[keyValuePairs.length - 1] === '') {\n        keyValuePairs.pop();\n      }\n\n      for (i = keyValuePairs.length; i--; ) {\n\n        var split = keyValuePairs[i].split(/\\s*:\\s*/),\n            key = split[0].trim(),\n            value = split[1].trim();\n\n        if (key === 'stop-color') {\n          color = value;\n        }\n        else if (key === 'stop-opacity') {\n          opacity = value;\n        }\n      }\n    }\n\n    if (!color) {\n      color = el.getAttribute('stop-color') || 'rgb(0,0,0)';\n    }\n    if (!opacity) {\n      opacity = el.getAttribute('stop-opacity');\n    }\n\n    color = new fabric.Color(color);\n    colorAlpha = color.getAlpha();\n    opacity = isNaN(parseFloat(opacity)) ? 1 : parseFloat(opacity);\n    opacity *= colorAlpha;\n\n    return {\n      offset: offset,\n      color: color.toRgb(),\n      opacity: opacity\n    };\n  }\n\n  function getLinearCoords(el) {\n    return {\n      x1: el.getAttribute('x1') || 0,\n      y1: el.getAttribute('y1') || 0,\n      x2: el.getAttribute('x2') || '100%',\n      y2: el.getAttribute('y2') || 0\n    };\n  }\n\n  function getRadialCoords(el) {\n    return {\n      x1: el.getAttribute('fx') || el.getAttribute('cx') || '50%',\n      y1: el.getAttribute('fy') || el.getAttribute('cy') || '50%',\n      r1: 0,\n      x2: el.getAttribute('cx') || '50%',\n      y2: el.getAttribute('cy') || '50%',\n      r2: el.getAttribute('r') || '50%'\n    };\n  }\n  /* _FROM_SVG_END_ */\n\n  var clone = fabric.util.object.clone;\n\n  /**\n   * Gradient class\n   * @class fabric.Gradient\n   * @tutorial {@link http://fabricjs.com/fabric-intro-part-2#gradients}\n   * @see {@link fabric.Gradient#initialize} for constructor definition\n   */\n  fabric.Gradient = fabric.util.createClass(/** @lends fabric.Gradient.prototype */ {\n\n    /**\n     * Horizontal offset for aligning gradients coming from SVG when outside pathgroups\n     * @type Number\n     * @default 0\n     */\n    offsetX: 0,\n\n    /**\n     * Vertical offset for aligning gradients coming from SVG when outside pathgroups\n     * @type Number\n     * @default 0\n     */\n    offsetY: 0,\n\n    /**\n     * Constructor\n     * @param {Object} [options] Options object with type, coords, gradientUnits and colorStops\n     * @return {fabric.Gradient} thisArg\n     */\n    initialize: function(options) {\n      options || (options = { });\n\n      var coords = { };\n\n      this.id = fabric.Object.__uid++;\n      this.type = options.type || 'linear';\n\n      coords = {\n        x1: options.coords.x1 || 0,\n        y1: options.coords.y1 || 0,\n        x2: options.coords.x2 || 0,\n        y2: options.coords.y2 || 0\n      };\n\n      if (this.type === 'radial') {\n        coords.r1 = options.coords.r1 || 0;\n        coords.r2 = options.coords.r2 || 0;\n      }\n      this.coords = coords;\n      this.colorStops = options.colorStops.slice();\n      if (options.gradientTransform) {\n        this.gradientTransform = options.gradientTransform;\n      }\n      this.offsetX = options.offsetX || this.offsetX;\n      this.offsetY = options.offsetY || this.offsetY;\n    },\n\n    /**\n     * Adds another colorStop\n     * @param {Object} colorStop Object with offset and color\n     * @return {fabric.Gradient} thisArg\n     */\n    addColorStop: function(colorStops) {\n      for (var position in colorStops) {\n        var color = new fabric.Color(colorStops[position]);\n        this.colorStops.push({\n          offset: parseFloat(position),\n          color: color.toRgb(),\n          opacity: color.getAlpha()\n        });\n      }\n      return this;\n    },\n\n    /**\n     * Returns object representation of a gradient\n     * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output\n     * @return {Object}\n     */\n    toObject: function(propertiesToInclude) {\n      var object = {\n        type: this.type,\n        coords: this.coords,\n        colorStops: this.colorStops,\n        offsetX: this.offsetX,\n        offsetY: this.offsetY,\n        gradientTransform: this.gradientTransform ? this.gradientTransform.concat() : this.gradientTransform\n      };\n      fabric.util.populateWithProperties(this, object, propertiesToInclude);\n\n      return object;\n    },\n\n    /* _TO_SVG_START_ */\n    /**\n     * Returns SVG representation of an gradient\n     * @param {Object} object Object to create a gradient for\n     * @return {String} SVG representation of an gradient (linear/radial)\n     */\n    toSVG: function(object, options) {\n      var coords = clone(this.coords, true), i, len, options = options || {},\n          markup, commonAttributes, colorStops = clone(this.colorStops, true),\n          needsSwap = coords.r1 > coords.r2,\n          transform = this.gradientTransform ? this.gradientTransform.concat() : fabric.iMatrix.concat(),\n          offsetX = object.width / 2 - this.offsetX, offsetY = object.height / 2 - this.offsetY,\n          withViewport = !!options.additionalTransform;\n      // colorStops must be sorted ascending\n      colorStops.sort(function(a, b) {\n        return a.offset - b.offset;\n      });\n\n      if (object.type === 'path') {\n        offsetX -= object.pathOffset.x;\n        offsetY -= object.pathOffset.y;\n      }\n\n      transform[4] -= offsetX;\n      transform[5] -= offsetY;\n\n      commonAttributes = 'id=\"SVGID_' + this.id +\n                     '\" gradientUnits=\"userSpaceOnUse\"';\n      commonAttributes += ' gradientTransform=\"' + (withViewport ?\n        options.additionalTransform + ' ' : '') + fabric.util.matrixToSVG(transform) + '\" ';\n\n      if (this.type === 'linear') {\n        markup = [\n          '<linearGradient ',\n          commonAttributes,\n          ' x1=\"', coords.x1,\n          '\" y1=\"', coords.y1,\n          '\" x2=\"', coords.x2,\n          '\" y2=\"', coords.y2,\n          '\">\\n'\n        ];\n      }\n      else if (this.type === 'radial') {\n        // svg radial gradient has just 1 radius. the biggest.\n        markup = [\n          '<radialGradient ',\n          commonAttributes,\n          ' cx=\"', needsSwap ? coords.x1 : coords.x2,\n          '\" cy=\"', needsSwap ? coords.y1 : coords.y2,\n          '\" r=\"', needsSwap ? coords.r1 : coords.r2,\n          '\" fx=\"', needsSwap ? coords.x2 : coords.x1,\n          '\" fy=\"', needsSwap ? coords.y2 : coords.y1,\n          '\">\\n'\n        ];\n      }\n\n      if (this.type === 'radial') {\n        if (needsSwap) {\n          // svg goes from internal to external radius. if radius are inverted, swap color stops.\n          colorStops = colorStops.concat();\n          colorStops.reverse();\n          for (i = 0, len = colorStops.length; i < len; i++) {\n            colorStops[i].offset = 1 - colorStops[i].offset;\n          }\n        }\n        var minRadius = Math.min(coords.r1, coords.r2);\n        if (minRadius > 0) {\n          // i have to shift all colorStops and add new one in 0.\n          var maxRadius = Math.max(coords.r1, coords.r2),\n              percentageShift = minRadius / maxRadius;\n          for (i = 0, len = colorStops.length; i < len; i++) {\n            colorStops[i].offset += percentageShift * (1 - colorStops[i].offset);\n          }\n        }\n      }\n\n      for (i = 0, len = colorStops.length; i < len; i++) {\n        var colorStop = colorStops[i];\n        markup.push(\n          '<stop ',\n          'offset=\"', (colorStop.offset * 100) + '%',\n          '\" style=\"stop-color:', colorStop.color,\n          (typeof colorStop.opacity !== 'undefined' ? ';stop-opacity: ' + colorStop.opacity : ';'),\n          '\"/>\\n'\n        );\n      }\n\n      markup.push((this.type === 'linear' ? '</linearGradient>\\n' : '</radialGradient>\\n'));\n\n      return markup.join('');\n    },\n    /* _TO_SVG_END_ */\n\n    /**\n     * Returns an instance of CanvasGradient\n     * @param {CanvasRenderingContext2D} ctx Context to render on\n     * @return {CanvasGradient}\n     */\n    toLive: function(ctx) {\n      var gradient, coords = fabric.util.object.clone(this.coords), i, len;\n\n      if (!this.type) {\n        return;\n      }\n\n      if (this.type === 'linear') {\n        gradient = ctx.createLinearGradient(\n          coords.x1, coords.y1, coords.x2, coords.y2);\n      }\n      else if (this.type === 'radial') {\n        gradient = ctx.createRadialGradient(\n          coords.x1, coords.y1, coords.r1, coords.x2, coords.y2, coords.r2);\n      }\n\n      for (i = 0, len = this.colorStops.length; i < len; i++) {\n        var color = this.colorStops[i].color,\n            opacity = this.colorStops[i].opacity,\n            offset = this.colorStops[i].offset;\n\n        if (typeof opacity !== 'undefined') {\n          color = new fabric.Color(color).setAlpha(opacity).toRgba();\n        }\n        gradient.addColorStop(offset, color);\n      }\n\n      return gradient;\n    }\n  });\n\n  fabric.util.object.extend(fabric.Gradient, {\n\n    /* _FROM_SVG_START_ */\n    /**\n     * Returns {@link fabric.Gradient} instance from an SVG element\n     * @static\n     * @memberOf fabric.Gradient\n     * @param {SVGGradientElement} el SVG gradient element\n     * @param {fabric.Object} instance\n     * @return {fabric.Gradient} Gradient instance\n     * @see http://www.w3.org/TR/SVG/pservers.html#LinearGradientElement\n     * @see http://www.w3.org/TR/SVG/pservers.html#RadialGradientElement\n     */\n    fromElement: function(el, instance) {\n      /**\n       *  @example:\n       *\n       *  <linearGradient id=\"linearGrad1\">\n       *    <stop offset=\"0%\" stop-color=\"white\"/>\n       *    <stop offset=\"100%\" stop-color=\"black\"/>\n       *  </linearGradient>\n       *\n       *  OR\n       *\n       *  <linearGradient id=\"linearGrad2\">\n       *    <stop offset=\"0\" style=\"stop-color:rgb(255,255,255)\"/>\n       *    <stop offset=\"1\" style=\"stop-color:rgb(0,0,0)\"/>\n       *  </linearGradient>\n       *\n       *  OR\n       *\n       *  <radialGradient id=\"radialGrad1\">\n       *    <stop offset=\"0%\" stop-color=\"white\" stop-opacity=\"1\" />\n       *    <stop offset=\"50%\" stop-color=\"black\" stop-opacity=\"0.5\" />\n       *    <stop offset=\"100%\" stop-color=\"white\" stop-opacity=\"1\" />\n       *  </radialGradient>\n       *\n       *  OR\n       *\n       *  <radialGradient id=\"radialGrad2\">\n       *    <stop offset=\"0\" stop-color=\"rgb(255,255,255)\" />\n       *    <stop offset=\"0.5\" stop-color=\"rgb(0,0,0)\" />\n       *    <stop offset=\"1\" stop-color=\"rgb(255,255,255)\" />\n       *  </radialGradient>\n       *\n       */\n\n      var colorStopEls = el.getElementsByTagName('stop'),\n          type,\n          gradientUnits = el.getAttribute('gradientUnits') || 'objectBoundingBox',\n          gradientTransform = el.getAttribute('gradientTransform'),\n          colorStops = [],\n          coords, ellipseMatrix, i;\n\n      if (el.nodeName === 'linearGradient' || el.nodeName === 'LINEARGRADIENT') {\n        type = 'linear';\n      }\n      else {\n        type = 'radial';\n      }\n\n      if (type === 'linear') {\n        coords = getLinearCoords(el);\n      }\n      else if (type === 'radial') {\n        coords = getRadialCoords(el);\n      }\n\n      for (i = colorStopEls.length; i--; ) {\n        colorStops.push(getColorStop(colorStopEls[i]));\n      }\n\n      ellipseMatrix = _convertPercentUnitsToValues(instance, coords, gradientUnits);\n\n      var gradient = new fabric.Gradient({\n        type: type,\n        coords: coords,\n        colorStops: colorStops,\n        offsetX: -instance.left,\n        offsetY: -instance.top\n      });\n\n      if (gradientTransform || ellipseMatrix !== '') {\n        gradient.gradientTransform = fabric.parseTransformAttribute((gradientTransform || '') + ellipseMatrix);\n      }\n\n      return gradient;\n    },\n    /* _FROM_SVG_END_ */\n\n    /**\n     * Returns {@link fabric.Gradient} instance from its object representation\n     * @static\n     * @memberOf fabric.Gradient\n     * @param {Object} obj\n     * @param {Object} [options] Options object\n     */\n    forObject: function(obj, options) {\n      options || (options = { });\n      _convertPercentUnitsToValues(obj, options.coords, 'userSpaceOnUse');\n      return new fabric.Gradient(options);\n    }\n  });\n\n  /**\n   * @private\n   */\n  function _convertPercentUnitsToValues(object, options, gradientUnits) {\n    var propValue, addFactor = 0, multFactor = 1, ellipseMatrix = '';\n    for (var prop in options) {\n      if (options[prop] === 'Infinity') {\n        options[prop] = 1;\n      }\n      else if (options[prop] === '-Infinity') {\n        options[prop] = 0;\n      }\n      propValue = parseFloat(options[prop], 10);\n      if (typeof options[prop] === 'string' && /^(\\d+\\.\\d+)%|(\\d+)%$/.test(options[prop])) {\n        multFactor = 0.01;\n      }\n      else {\n        multFactor = 1;\n      }\n      if (prop === 'x1' || prop === 'x2' || prop === 'r2') {\n        multFactor *= gradientUnits === 'objectBoundingBox' ? object.width : 1;\n        addFactor = gradientUnits === 'objectBoundingBox' ? object.left || 0 : 0;\n      }\n      else if (prop === 'y1' || prop === 'y2') {\n        multFactor *= gradientUnits === 'objectBoundingBox' ? object.height : 1;\n        addFactor = gradientUnits === 'objectBoundingBox' ? object.top || 0 : 0;\n      }\n      options[prop] = propValue * multFactor + addFactor;\n    }\n    if (object.type === 'ellipse' &&\n        options.r2 !== null &&\n        gradientUnits === 'objectBoundingBox' &&\n        object.rx !== object.ry) {\n\n      var scaleFactor = object.ry / object.rx;\n      ellipseMatrix = ' scale(1, ' + scaleFactor + ')';\n      if (options.y1) {\n        options.y1 /= scaleFactor;\n      }\n      if (options.y2) {\n        options.y2 /= scaleFactor;\n      }\n    }\n    return ellipseMatrix;\n  }\n})();\n\n\n(function() {\n\n  'use strict';\n\n  var toFixed = fabric.util.toFixed;\n\n  /**\n   * Pattern class\n   * @class fabric.Pattern\n   * @see {@link http://fabricjs.com/patterns|Pattern demo}\n   * @see {@link http://fabricjs.com/dynamic-patterns|DynamicPattern demo}\n   * @see {@link fabric.Pattern#initialize} for constructor definition\n   */\n\n\n  fabric.Pattern = fabric.util.createClass(/** @lends fabric.Pattern.prototype */ {\n\n    /**\n     * Repeat property of a pattern (one of repeat, repeat-x, repeat-y or no-repeat)\n     * @type String\n     * @default\n     */\n    repeat: 'repeat',\n\n    /**\n     * Pattern horizontal offset from object's left/top corner\n     * @type Number\n     * @default\n     */\n    offsetX: 0,\n\n    /**\n     * Pattern vertical offset from object's left/top corner\n     * @type Number\n     * @default\n     */\n    offsetY: 0,\n\n    /**\n     * crossOrigin value (one of \"\", \"anonymous\", \"use-credentials\")\n     * @see https://developer.mozilla.org/en-US/docs/HTML/CORS_settings_attributes\n     * @type String\n     * @default\n     */\n    crossOrigin: '',\n\n    /**\n     * transform matrix to change the pattern, imported from svgs.\n     * @type Array\n     * @default\n     */\n    patternTransform: null,\n\n    /**\n     * Constructor\n     * @param {Object} [options] Options object\n     * @param {Function} [callback] function to invoke after callback init.\n     * @return {fabric.Pattern} thisArg\n     */\n    initialize: function(options, callback) {\n      options || (options = { });\n\n      this.id = fabric.Object.__uid++;\n      this.setOptions(options);\n      if (!options.source || (options.source && typeof options.source !== 'string')) {\n        callback && callback(this);\n        return;\n      }\n      // function string\n      if (typeof fabric.util.getFunctionBody(options.source) !== 'undefined') {\n        this.source = new Function(fabric.util.getFunctionBody(options.source));\n        callback && callback(this);\n      }\n      else {\n        // img src string\n        var _this = this;\n        this.source = fabric.util.createImage();\n        fabric.util.loadImage(options.source, function(img) {\n          _this.source = img;\n          callback && callback(_this);\n        }, null, this.crossOrigin);\n      }\n    },\n\n    /**\n     * Returns object representation of a pattern\n     * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output\n     * @return {Object} Object representation of a pattern instance\n     */\n    toObject: function(propertiesToInclude) {\n      var NUM_FRACTION_DIGITS = fabric.Object.NUM_FRACTION_DIGITS,\n          source, object;\n\n      // callback\n      if (typeof this.source === 'function') {\n        source = String(this.source);\n      }\n      // <img> element\n      else if (typeof this.source.src === 'string') {\n        source = this.source.src;\n      }\n      // <canvas> element\n      else if (typeof this.source === 'object' && this.source.toDataURL) {\n        source = this.source.toDataURL();\n      }\n\n      object = {\n        type: 'pattern',\n        source: source,\n        repeat: this.repeat,\n        crossOrigin: this.crossOrigin,\n        offsetX: toFixed(this.offsetX, NUM_FRACTION_DIGITS),\n        offsetY: toFixed(this.offsetY, NUM_FRACTION_DIGITS),\n        patternTransform: this.patternTransform ? this.patternTransform.concat() : null\n      };\n      fabric.util.populateWithProperties(this, object, propertiesToInclude);\n\n      return object;\n    },\n\n    /* _TO_SVG_START_ */\n    /**\n     * Returns SVG representation of a pattern\n     * @param {fabric.Object} object\n     * @return {String} SVG representation of a pattern\n     */\n    toSVG: function(object) {\n      var patternSource = typeof this.source === 'function' ? this.source() : this.source,\n          patternWidth = patternSource.width / object.width,\n          patternHeight = patternSource.height / object.height,\n          patternOffsetX = this.offsetX / object.width,\n          patternOffsetY = this.offsetY / object.height,\n          patternImgSrc = '';\n      if (this.repeat === 'repeat-x' || this.repeat === 'no-repeat') {\n        patternHeight = 1;\n        if (patternOffsetY) {\n          patternHeight += Math.abs(patternOffsetY);\n        }\n      }\n      if (this.repeat === 'repeat-y' || this.repeat === 'no-repeat') {\n        patternWidth = 1;\n        if (patternOffsetX) {\n          patternWidth += Math.abs(patternOffsetX);\n        }\n\n      }\n      if (patternSource.src) {\n        patternImgSrc = patternSource.src;\n      }\n      else if (patternSource.toDataURL) {\n        patternImgSrc = patternSource.toDataURL();\n      }\n\n      return '<pattern id=\"SVGID_' + this.id +\n                    '\" x=\"' + patternOffsetX +\n                    '\" y=\"' + patternOffsetY +\n                    '\" width=\"' + patternWidth +\n                    '\" height=\"' + patternHeight + '\">\\n' +\n               '<image x=\"0\" y=\"0\"' +\n                      ' width=\"' + patternSource.width +\n                      '\" height=\"' + patternSource.height +\n                      '\" xlink:href=\"' + patternImgSrc +\n               '\"></image>\\n' +\n             '</pattern>\\n';\n    },\n    /* _TO_SVG_END_ */\n\n    setOptions: function(options) {\n      for (var prop in options) {\n        this[prop] = options[prop];\n      }\n    },\n\n    /**\n     * Returns an instance of CanvasPattern\n     * @param {CanvasRenderingContext2D} ctx Context to create pattern\n     * @return {CanvasPattern}\n     */\n    toLive: function(ctx) {\n      var source = typeof this.source === 'function' ? this.source() : this.source;\n\n      // if the image failed to load, return, and allow rest to continue loading\n      if (!source) {\n        return '';\n      }\n\n      // if an image\n      if (typeof source.src !== 'undefined') {\n        if (!source.complete) {\n          return '';\n        }\n        if (source.naturalWidth === 0 || source.naturalHeight === 0) {\n          return '';\n        }\n      }\n      return ctx.createPattern(source, this.repeat);\n    }\n  });\n})();\n\n\n(function(global) {\n\n  'use strict';\n\n  var fabric = global.fabric || (global.fabric = { }),\n      toFixed = fabric.util.toFixed;\n\n  if (fabric.Shadow) {\n    fabric.warn('fabric.Shadow is already defined.');\n    return;\n  }\n\n  /**\n   * Shadow class\n   * @class fabric.Shadow\n   * @see {@link http://fabricjs.com/shadows|Shadow demo}\n   * @see {@link fabric.Shadow#initialize} for constructor definition\n   */\n  fabric.Shadow = fabric.util.createClass(/** @lends fabric.Shadow.prototype */ {\n\n    /**\n     * Shadow color\n     * @type String\n     * @default\n     */\n    color: 'rgb(0,0,0)',\n\n    /**\n     * Shadow blur\n     * @type Number\n     */\n    blur: 0,\n\n    /**\n     * Shadow horizontal offset\n     * @type Number\n     * @default\n     */\n    offsetX: 0,\n\n    /**\n     * Shadow vertical offset\n     * @type Number\n     * @default\n     */\n    offsetY: 0,\n\n    /**\n     * Whether the shadow should affect stroke operations\n     * @type Boolean\n     * @default\n     */\n    affectStroke: false,\n\n    /**\n     * Indicates whether toObject should include default values\n     * @type Boolean\n     * @default\n     */\n    includeDefaultValues: true,\n\n    /**\n     * When `false`, the shadow will scale with the object.\n     * When `true`, the shadow's offsetX, offsetY, and blur will not be affected by the object's scale.\n     * default to false\n     * @type Boolean\n     * @default\n     */\n    nonScaling: false,\n\n    /**\n     * Constructor\n     * @param {Object|String} [options] Options object with any of color, blur, offsetX, offsetY properties or string (e.g. \"rgba(0,0,0,0.2) 2px 2px 10px\")\n     * @return {fabric.Shadow} thisArg\n     */\n    initialize: function(options) {\n\n      if (typeof options === 'string') {\n        options = this._parseShadow(options);\n      }\n\n      for (var prop in options) {\n        this[prop] = options[prop];\n      }\n\n      this.id = fabric.Object.__uid++;\n    },\n\n    /**\n     * @private\n     * @param {String} shadow Shadow value to parse\n     * @return {Object} Shadow object with color, offsetX, offsetY and blur\n     */\n    _parseShadow: function(shadow) {\n      var shadowStr = shadow.trim(),\n          offsetsAndBlur = fabric.Shadow.reOffsetsAndBlur.exec(shadowStr) || [],\n          color = shadowStr.replace(fabric.Shadow.reOffsetsAndBlur, '') || 'rgb(0,0,0)';\n\n      return {\n        color: color.trim(),\n        offsetX: parseInt(offsetsAndBlur[1], 10) || 0,\n        offsetY: parseInt(offsetsAndBlur[2], 10) || 0,\n        blur: parseInt(offsetsAndBlur[3], 10) || 0\n      };\n    },\n\n    /**\n     * Returns a string representation of an instance\n     * @see http://www.w3.org/TR/css-text-decor-3/#text-shadow\n     * @return {String} Returns CSS3 text-shadow declaration\n     */\n    toString: function() {\n      return [this.offsetX, this.offsetY, this.blur, this.color].join('px ');\n    },\n\n    /* _TO_SVG_START_ */\n    /**\n     * Returns SVG representation of a shadow\n     * @param {fabric.Object} object\n     * @return {String} SVG representation of a shadow\n     */\n    toSVG: function(object) {\n      var fBoxX = 40, fBoxY = 40, NUM_FRACTION_DIGITS = fabric.Object.NUM_FRACTION_DIGITS,\n          offset = fabric.util.rotateVector(\n            { x: this.offsetX, y: this.offsetY },\n            fabric.util.degreesToRadians(-object.angle)),\n          BLUR_BOX = 20, color = new fabric.Color(this.color);\n\n      if (object.width && object.height) {\n        //http://www.w3.org/TR/SVG/filters.html#FilterEffectsRegion\n        // we add some extra space to filter box to contain the blur ( 20 )\n        fBoxX = toFixed((Math.abs(offset.x) + this.blur) / object.width, NUM_FRACTION_DIGITS) * 100 + BLUR_BOX;\n        fBoxY = toFixed((Math.abs(offset.y) + this.blur) / object.height, NUM_FRACTION_DIGITS) * 100 + BLUR_BOX;\n      }\n      if (object.flipX) {\n        offset.x *= -1;\n      }\n      if (object.flipY) {\n        offset.y *= -1;\n      }\n\n      return (\n        '<filter id=\"SVGID_' + this.id + '\" y=\"-' + fBoxY + '%\" height=\"' + (100 + 2 * fBoxY) + '%\" ' +\n          'x=\"-' + fBoxX + '%\" width=\"' + (100 + 2 * fBoxX) + '%\" ' + '>\\n' +\n          '\\t<feGaussianBlur in=\"SourceAlpha\" stdDeviation=\"' +\n            toFixed(this.blur ? this.blur / 2 : 0, NUM_FRACTION_DIGITS) + '\"></feGaussianBlur>\\n' +\n          '\\t<feOffset dx=\"' + toFixed(offset.x, NUM_FRACTION_DIGITS) +\n          '\" dy=\"' + toFixed(offset.y, NUM_FRACTION_DIGITS) + '\" result=\"oBlur\" ></feOffset>\\n' +\n          '\\t<feFlood flood-color=\"' + color.toRgb() + '\" flood-opacity=\"' + color.getAlpha() + '\"/>\\n' +\n          '\\t<feComposite in2=\"oBlur\" operator=\"in\" />\\n' +\n          '\\t<feMerge>\\n' +\n            '\\t\\t<feMergeNode></feMergeNode>\\n' +\n            '\\t\\t<feMergeNode in=\"SourceGraphic\"></feMergeNode>\\n' +\n          '\\t</feMerge>\\n' +\n        '</filter>\\n');\n    },\n    /* _TO_SVG_END_ */\n\n    /**\n     * Returns object representation of a shadow\n     * @return {Object} Object representation of a shadow instance\n     */\n    toObject: function() {\n      if (this.includeDefaultValues) {\n        return {\n          color: this.color,\n          blur: this.blur,\n          offsetX: this.offsetX,\n          offsetY: this.offsetY,\n          affectStroke: this.affectStroke,\n          nonScaling: this.nonScaling\n        };\n      }\n      var obj = { }, proto = fabric.Shadow.prototype;\n\n      ['color', 'blur', 'offsetX', 'offsetY', 'affectStroke', 'nonScaling'].forEach(function(prop) {\n        if (this[prop] !== proto[prop]) {\n          obj[prop] = this[prop];\n        }\n      }, this);\n\n      return obj;\n    }\n  });\n\n  /**\n   * Regex matching shadow offsetX, offsetY and blur (ex: \"2px 2px 10px rgba(0,0,0,0.2)\", \"rgb(0,255,0) 2px 2px\")\n   * @static\n   * @field\n   * @memberOf fabric.Shadow\n   */\n  // eslint-disable-next-line max-len\n  fabric.Shadow.reOffsetsAndBlur = /(?:\\s|^)(-?\\d+(?:px)?(?:\\s?|$))?(-?\\d+(?:px)?(?:\\s?|$))?(\\d+(?:px)?)?(?:\\s?|$)(?:$|\\s)/;\n\n})(typeof exports !== 'undefined' ? exports : this);\n\n\n(function () {\n\n  'use strict';\n\n  if (fabric.StaticCanvas) {\n    fabric.warn('fabric.StaticCanvas is already defined.');\n    return;\n  }\n\n  // aliases for faster resolution\n  var extend = fabric.util.object.extend,\n      getElementOffset = fabric.util.getElementOffset,\n      removeFromArray = fabric.util.removeFromArray,\n      toFixed = fabric.util.toFixed,\n      transformPoint = fabric.util.transformPoint,\n      invertTransform = fabric.util.invertTransform,\n      getNodeCanvas = fabric.util.getNodeCanvas,\n      createCanvasElement = fabric.util.createCanvasElement,\n\n      CANVAS_INIT_ERROR = new Error('Could not initialize `canvas` element');\n\n  /**\n   * Static canvas class\n   * @class fabric.StaticCanvas\n   * @mixes fabric.Collection\n   * @mixes fabric.Observable\n   * @see {@link http://fabricjs.com/static_canvas|StaticCanvas demo}\n   * @see {@link fabric.StaticCanvas#initialize} for constructor definition\n   * @fires before:render\n   * @fires after:render\n   * @fires canvas:cleared\n   * @fires object:added\n   * @fires object:removed\n   */\n  fabric.StaticCanvas = fabric.util.createClass(fabric.CommonMethods, /** @lends fabric.StaticCanvas.prototype */ {\n\n    /**\n     * Constructor\n     * @param {HTMLElement | String} el &lt;canvas> element to initialize instance on\n     * @param {Object} [options] Options object\n     * @return {Object} thisArg\n     */\n    initialize: function(el, options) {\n      options || (options = { });\n      this.renderAndResetBound = this.renderAndReset.bind(this);\n      this.requestRenderAllBound = this.requestRenderAll.bind(this);\n      this._initStatic(el, options);\n    },\n\n    /**\n     * Background color of canvas instance.\n     * Should be set via {@link fabric.StaticCanvas#setBackgroundColor}.\n     * @type {(String|fabric.Pattern)}\n     * @default\n     */\n    backgroundColor: '',\n\n    /**\n     * Background image of canvas instance.\n     * Should be set via {@link fabric.StaticCanvas#setBackgroundImage}.\n     * <b>Backwards incompatibility note:</b> The \"backgroundImageOpacity\"\n     * and \"backgroundImageStretch\" properties are deprecated since 1.3.9.\n     * Use {@link fabric.Image#opacity}, {@link fabric.Image#width} and {@link fabric.Image#height}.\n     * since 2.4.0 image caching is active, please when putting an image as background, add to the\n     * canvas property a reference to the canvas it is on. Otherwise the image cannot detect the zoom\n     * vale. As an alternative you can disable image objectCaching\n     * @type fabric.Image\n     * @default\n     */\n    backgroundImage: null,\n\n    /**\n     * Overlay color of canvas instance.\n     * Should be set via {@link fabric.StaticCanvas#setOverlayColor}\n     * @since 1.3.9\n     * @type {(String|fabric.Pattern)}\n     * @default\n     */\n    overlayColor: '',\n\n    /**\n     * Overlay image of canvas instance.\n     * Should be set via {@link fabric.StaticCanvas#setOverlayImage}.\n     * <b>Backwards incompatibility note:</b> The \"overlayImageLeft\"\n     * and \"overlayImageTop\" properties are deprecated since 1.3.9.\n     * Use {@link fabric.Image#left} and {@link fabric.Image#top}.\n     * since 2.4.0 image caching is active, please when putting an image as overlay, add to the\n     * canvas property a reference to the canvas it is on. Otherwise the image cannot detect the zoom\n     * vale. As an alternative you can disable image objectCaching\n     * @type fabric.Image\n     * @default\n     */\n    overlayImage: null,\n\n    /**\n     * Indicates whether toObject/toDatalessObject should include default values\n     * if set to false, takes precedence over the object value.\n     * @type Boolean\n     * @default\n     */\n    includeDefaultValues: true,\n\n    /**\n     * Indicates whether objects' state should be saved\n     * @type Boolean\n     * @default\n     */\n    stateful: false,\n\n    /**\n     * Indicates whether {@link fabric.Collection.add}, {@link fabric.Collection.insertAt} and {@link fabric.Collection.remove},\n     * {@link fabric.StaticCanvas.moveTo}, {@link fabric.StaticCanvas.clear} and many more, should also re-render canvas.\n     * Disabling this option will not give a performance boost when adding/removing a lot of objects to/from canvas at once\n     * since the renders are quequed and executed one per frame.\n     * Disabling is suggested anyway and managing the renders of the app manually is not a big effort ( canvas.requestRenderAll() )\n     * Left default to true to do not break documentation and old app, fiddles.\n     * @type Boolean\n     * @default\n     */\n    renderOnAddRemove: true,\n\n    /**\n     * Function that determines clipping of entire canvas area\n     * Being passed context as first argument.\n     * If you are using code minification, ctx argument can be minified/manglied you should use\n     * as a workaround `var ctx = arguments[0];` in the function;\n     * See clipping canvas area in {@link https://github.com/kangax/fabric.js/wiki/FAQ}\n     * @deprecated since 2.0.0\n     * @type Function\n     * @default\n     */\n    clipTo: null,\n\n    /**\n     * Indicates whether object controls (borders/controls) are rendered above overlay image\n     * @type Boolean\n     * @default\n     */\n    controlsAboveOverlay: false,\n\n    /**\n     * Indicates whether the browser can be scrolled when using a touchscreen and dragging on the canvas\n     * @type Boolean\n     * @default\n     */\n    allowTouchScrolling: false,\n\n    /**\n     * Indicates whether this canvas will use image smoothing, this is on by default in browsers\n     * @type Boolean\n     * @default\n     */\n    imageSmoothingEnabled: true,\n\n    /**\n     * The transformation (in the format of Canvas transform) which focuses the viewport\n     * @type Array\n     * @default\n     */\n    viewportTransform: fabric.iMatrix.concat(),\n\n    /**\n     * if set to false background image is not affected by viewport transform\n     * @since 1.6.3\n     * @type Boolean\n     * @default\n     */\n    backgroundVpt: true,\n\n    /**\n     * if set to false overlya image is not affected by viewport transform\n     * @since 1.6.3\n     * @type Boolean\n     * @default\n     */\n    overlayVpt: true,\n\n    /**\n     * Callback; invoked right before object is about to be scaled/rotated\n     * @deprecated since 2.3.0\n     * Use before:transform event\n     */\n    onBeforeScaleRotate: function () {\n      /* NOOP */\n    },\n\n    /**\n     * When true, canvas is scaled by devicePixelRatio for better rendering on retina screens\n     * @type Boolean\n     * @default\n     */\n    enableRetinaScaling: true,\n\n    /**\n     * Describe canvas element extension over design\n     * properties are tl,tr,bl,br.\n     * if canvas is not zoomed/panned those points are the four corner of canvas\n     * if canvas is viewportTransformed you those points indicate the extension\n     * of canvas element in plain untrasformed coordinates\n     * The coordinates get updated with @method calcViewportBoundaries.\n     * @memberOf fabric.StaticCanvas.prototype\n     */\n    vptCoords: { },\n\n    /**\n     * Based on vptCoords and object.aCoords, skip rendering of objects that\n     * are not included in current viewport.\n     * May greatly help in applications with crowded canvas and use of zoom/pan\n     * If One of the corner of the bounding box of the object is on the canvas\n     * the objects get rendered.\n     * @memberOf fabric.StaticCanvas.prototype\n     * @type Boolean\n     * @default\n     */\n    skipOffscreen: true,\n\n    /**\n     * a fabricObject that, without stroke define a clipping area with their shape. filled in black\n     * the clipPath object gets used when the canvas has rendered, and the context is placed in the\n     * top left corner of the canvas.\n     * clipPath will clip away controls, if you do not want this to happen use controlsAboveOverlay = true\n     * @type fabric.Object\n     */\n    clipPath: undefined,\n\n    /**\n     * @private\n     * @param {HTMLElement | String} el &lt;canvas> element to initialize instance on\n     * @param {Object} [options] Options object\n     */\n    _initStatic: function(el, options) {\n      var cb = this.requestRenderAllBound;\n      this._objects = [];\n      this._createLowerCanvas(el);\n      this._initOptions(options);\n      this._setImageSmoothing();\n      // only initialize retina scaling once\n      if (!this.interactive) {\n        this._initRetinaScaling();\n      }\n\n      if (options.overlayImage) {\n        this.setOverlayImage(options.overlayImage, cb);\n      }\n      if (options.backgroundImage) {\n        this.setBackgroundImage(options.backgroundImage, cb);\n      }\n      if (options.backgroundColor) {\n        this.setBackgroundColor(options.backgroundColor, cb);\n      }\n      if (options.overlayColor) {\n        this.setOverlayColor(options.overlayColor, cb);\n      }\n      this.calcOffset();\n    },\n\n    /**\n     * @private\n     */\n    _isRetinaScaling: function() {\n      return (fabric.devicePixelRatio !== 1 && this.enableRetinaScaling);\n    },\n\n    /**\n     * @private\n     * @return {Number} retinaScaling if applied, otherwise 1;\n     */\n    getRetinaScaling: function() {\n      return this._isRetinaScaling() ? fabric.devicePixelRatio : 1;\n    },\n\n    /**\n     * @private\n     */\n    _initRetinaScaling: function() {\n      if (!this._isRetinaScaling()) {\n        return;\n      }\n      this.lowerCanvasEl.setAttribute('width', this.width * fabric.devicePixelRatio);\n      this.lowerCanvasEl.setAttribute('height', this.height * fabric.devicePixelRatio);\n\n      this.contextContainer.scale(fabric.devicePixelRatio, fabric.devicePixelRatio);\n    },\n\n    /**\n     * Calculates canvas element offset relative to the document\n     * This method is also attached as \"resize\" event handler of window\n     * @return {fabric.Canvas} instance\n     * @chainable\n     */\n    calcOffset: function () {\n      this._offset = getElementOffset(this.lowerCanvasEl);\n      return this;\n    },\n\n    /**\n     * Sets {@link fabric.StaticCanvas#overlayImage|overlay image} for this canvas\n     * @param {(fabric.Image|String)} image fabric.Image instance or URL of an image to set overlay to\n     * @param {Function} callback callback to invoke when image is loaded and set as an overlay\n     * @param {Object} [options] Optional options to set for the {@link fabric.Image|overlay image}.\n     * @return {fabric.Canvas} thisArg\n     * @chainable\n     * @see {@link http://jsfiddle.net/fabricjs/MnzHT/|jsFiddle demo}\n     * @example <caption>Normal overlayImage with left/top = 0</caption>\n     * canvas.setOverlayImage('http://fabricjs.com/assets/jail_cell_bars.png', canvas.renderAll.bind(canvas), {\n     *   // Needed to position overlayImage at 0/0\n     *   originX: 'left',\n     *   originY: 'top'\n     * });\n     * @example <caption>overlayImage with different properties</caption>\n     * canvas.setOverlayImage('http://fabricjs.com/assets/jail_cell_bars.png', canvas.renderAll.bind(canvas), {\n     *   opacity: 0.5,\n     *   angle: 45,\n     *   left: 400,\n     *   top: 400,\n     *   originX: 'left',\n     *   originY: 'top'\n     * });\n     * @example <caption>Stretched overlayImage #1 - width/height correspond to canvas width/height</caption>\n     * fabric.Image.fromURL('http://fabricjs.com/assets/jail_cell_bars.png', function(img) {\n     *    img.set({width: canvas.width, height: canvas.height, originX: 'left', originY: 'top'});\n     *    canvas.setOverlayImage(img, canvas.renderAll.bind(canvas));\n     * });\n     * @example <caption>Stretched overlayImage #2 - width/height correspond to canvas width/height</caption>\n     * canvas.setOverlayImage('http://fabricjs.com/assets/jail_cell_bars.png', canvas.renderAll.bind(canvas), {\n     *   width: canvas.width,\n     *   height: canvas.height,\n     *   // Needed to position overlayImage at 0/0\n     *   originX: 'left',\n     *   originY: 'top'\n     * });\n     * @example <caption>overlayImage loaded from cross-origin</caption>\n     * canvas.setOverlayImage('http://fabricjs.com/assets/jail_cell_bars.png', canvas.renderAll.bind(canvas), {\n     *   opacity: 0.5,\n     *   angle: 45,\n     *   left: 400,\n     *   top: 400,\n     *   originX: 'left',\n     *   originY: 'top',\n     *   crossOrigin: 'anonymous'\n     * });\n     */\n    setOverlayImage: function (image, callback, options) {\n      return this.__setBgOverlayImage('overlayImage', image, callback, options);\n    },\n\n    /**\n     * Sets {@link fabric.StaticCanvas#backgroundImage|background image} for this canvas\n     * @param {(fabric.Image|String)} image fabric.Image instance or URL of an image to set background to\n     * @param {Function} callback Callback to invoke when image is loaded and set as background\n     * @param {Object} [options] Optional options to set for the {@link fabric.Image|background image}.\n     * @return {fabric.Canvas} thisArg\n     * @chainable\n     * @see {@link http://jsfiddle.net/djnr8o7a/28/|jsFiddle demo}\n     * @example <caption>Normal backgroundImage with left/top = 0</caption>\n     * canvas.setBackgroundImage('http://fabricjs.com/assets/honey_im_subtle.png', canvas.renderAll.bind(canvas), {\n     *   // Needed to position backgroundImage at 0/0\n     *   originX: 'left',\n     *   originY: 'top'\n     * });\n     * @example <caption>backgroundImage with different properties</caption>\n     * canvas.setBackgroundImage('http://fabricjs.com/assets/honey_im_subtle.png', canvas.renderAll.bind(canvas), {\n     *   opacity: 0.5,\n     *   angle: 45,\n     *   left: 400,\n     *   top: 400,\n     *   originX: 'left',\n     *   originY: 'top'\n     * });\n     * @example <caption>Stretched backgroundImage #1 - width/height correspond to canvas width/height</caption>\n     * fabric.Image.fromURL('http://fabricjs.com/assets/honey_im_subtle.png', function(img) {\n     *    img.set({width: canvas.width, height: canvas.height, originX: 'left', originY: 'top'});\n     *    canvas.setBackgroundImage(img, canvas.renderAll.bind(canvas));\n     * });\n     * @example <caption>Stretched backgroundImage #2 - width/height correspond to canvas width/height</caption>\n     * canvas.setBackgroundImage('http://fabricjs.com/assets/honey_im_subtle.png', canvas.renderAll.bind(canvas), {\n     *   width: canvas.width,\n     *   height: canvas.height,\n     *   // Needed to position backgroundImage at 0/0\n     *   originX: 'left',\n     *   originY: 'top'\n     * });\n     * @example <caption>backgroundImage loaded from cross-origin</caption>\n     * canvas.setBackgroundImage('http://fabricjs.com/assets/honey_im_subtle.png', canvas.renderAll.bind(canvas), {\n     *   opacity: 0.5,\n     *   angle: 45,\n     *   left: 400,\n     *   top: 400,\n     *   originX: 'left',\n     *   originY: 'top',\n     *   crossOrigin: 'anonymous'\n     * });\n     */\n    // TODO: fix stretched examples\n    setBackgroundImage: function (image, callback, options) {\n      return this.__setBgOverlayImage('backgroundImage', image, callback, options);\n    },\n\n    /**\n     * Sets {@link fabric.StaticCanvas#overlayColor|foreground color} for this canvas\n     * @param {(String|fabric.Pattern)} overlayColor Color or pattern to set foreground color to\n     * @param {Function} callback Callback to invoke when foreground color is set\n     * @return {fabric.Canvas} thisArg\n     * @chainable\n     * @see {@link http://jsfiddle.net/fabricjs/pB55h/|jsFiddle demo}\n     * @example <caption>Normal overlayColor - color value</caption>\n     * canvas.setOverlayColor('rgba(255, 73, 64, 0.6)', canvas.renderAll.bind(canvas));\n     * @example <caption>fabric.Pattern used as overlayColor</caption>\n     * canvas.setOverlayColor({\n     *   source: 'http://fabricjs.com/assets/escheresque_ste.png'\n     * }, canvas.renderAll.bind(canvas));\n     * @example <caption>fabric.Pattern used as overlayColor with repeat and offset</caption>\n     * canvas.setOverlayColor({\n     *   source: 'http://fabricjs.com/assets/escheresque_ste.png',\n     *   repeat: 'repeat',\n     *   offsetX: 200,\n     *   offsetY: 100\n     * }, canvas.renderAll.bind(canvas));\n     */\n    setOverlayColor: function(overlayColor, callback) {\n      return this.__setBgOverlayColor('overlayColor', overlayColor, callback);\n    },\n\n    /**\n     * Sets {@link fabric.StaticCanvas#backgroundColor|background color} for this canvas\n     * @param {(String|fabric.Pattern)} backgroundColor Color or pattern to set background color to\n     * @param {Function} callback Callback to invoke when background color is set\n     * @return {fabric.Canvas} thisArg\n     * @chainable\n     * @see {@link http://jsfiddle.net/fabricjs/hXzvk/|jsFiddle demo}\n     * @example <caption>Normal backgroundColor - color value</caption>\n     * canvas.setBackgroundColor('rgba(255, 73, 64, 0.6)', canvas.renderAll.bind(canvas));\n     * @example <caption>fabric.Pattern used as backgroundColor</caption>\n     * canvas.setBackgroundColor({\n     *   source: 'http://fabricjs.com/assets/escheresque_ste.png'\n     * }, canvas.renderAll.bind(canvas));\n     * @example <caption>fabric.Pattern used as backgroundColor with repeat and offset</caption>\n     * canvas.setBackgroundColor({\n     *   source: 'http://fabricjs.com/assets/escheresque_ste.png',\n     *   repeat: 'repeat',\n     *   offsetX: 200,\n     *   offsetY: 100\n     * }, canvas.renderAll.bind(canvas));\n     */\n    setBackgroundColor: function(backgroundColor, callback) {\n      return this.__setBgOverlayColor('backgroundColor', backgroundColor, callback);\n    },\n\n    /**\n     * @private\n     * @see {@link http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#dom-context-2d-imagesmoothingenabled|WhatWG Canvas Standard}\n     */\n    _setImageSmoothing: function() {\n      var ctx = this.getContext();\n\n      ctx.imageSmoothingEnabled = ctx.imageSmoothingEnabled || ctx.webkitImageSmoothingEnabled\n        || ctx.mozImageSmoothingEnabled || ctx.msImageSmoothingEnabled || ctx.oImageSmoothingEnabled;\n      ctx.imageSmoothingEnabled = this.imageSmoothingEnabled;\n    },\n\n    /**\n     * @private\n     * @param {String} property Property to set ({@link fabric.StaticCanvas#backgroundImage|backgroundImage}\n     * or {@link fabric.StaticCanvas#overlayImage|overlayImage})\n     * @param {(fabric.Image|String|null)} image fabric.Image instance, URL of an image or null to set background or overlay to\n     * @param {Function} callback Callback to invoke when image is loaded and set as background or overlay\n     * @param {Object} [options] Optional options to set for the {@link fabric.Image|image}.\n     */\n    __setBgOverlayImage: function(property, image, callback, options) {\n      if (typeof image === 'string') {\n        fabric.util.loadImage(image, function(img) {\n          if (img) {\n            var instance = new fabric.Image(img, options);\n            this[property] = instance;\n            instance.canvas = this;\n          }\n          callback && callback(img);\n        }, this, options && options.crossOrigin);\n      }\n      else {\n        options && image.setOptions(options);\n        this[property] = image;\n        image && (image.canvas = this);\n        callback && callback(image);\n      }\n\n      return this;\n    },\n\n    /**\n     * @private\n     * @param {String} property Property to set ({@link fabric.StaticCanvas#backgroundColor|backgroundColor}\n     * or {@link fabric.StaticCanvas#overlayColor|overlayColor})\n     * @param {(Object|String|null)} color Object with pattern information, color value or null\n     * @param {Function} [callback] Callback is invoked when color is set\n     */\n    __setBgOverlayColor: function(property, color, callback) {\n      this[property] = color;\n      this._initGradient(color, property);\n      this._initPattern(color, property, callback);\n      return this;\n    },\n\n    /**\n     * @private\n     */\n    _createCanvasElement: function() {\n      var element = createCanvasElement();\n      if (!element) {\n        throw CANVAS_INIT_ERROR;\n      }\n      if (!element.style) {\n        element.style = { };\n      }\n      if (typeof element.getContext === 'undefined') {\n        throw CANVAS_INIT_ERROR;\n      }\n      return element;\n    },\n\n    /**\n     * @private\n     * @param {Object} [options] Options object\n     */\n    _initOptions: function (options) {\n      var lowerCanvasEl = this.lowerCanvasEl;\n      this._setOptions(options);\n\n      this.width = this.width || parseInt(lowerCanvasEl.width, 10) || 0;\n      this.height = this.height || parseInt(lowerCanvasEl.height, 10) || 0;\n\n      if (!this.lowerCanvasEl.style) {\n        return;\n      }\n\n      lowerCanvasEl.width = this.width;\n      lowerCanvasEl.height = this.height;\n\n      lowerCanvasEl.style.width = this.width + 'px';\n      lowerCanvasEl.style.height = this.height + 'px';\n\n      this.viewportTransform = this.viewportTransform.slice();\n    },\n\n    /**\n     * Creates a bottom canvas\n     * @private\n     * @param {HTMLElement} [canvasEl]\n     */\n    _createLowerCanvas: function (canvasEl) {\n      // canvasEl === 'HTMLCanvasElement' does not work on jsdom/node\n      if (canvasEl && canvasEl.getContext) {\n        this.lowerCanvasEl = canvasEl;\n      }\n      else {\n        this.lowerCanvasEl = fabric.util.getById(canvasEl) || this._createCanvasElement();\n      }\n\n      fabric.util.addClass(this.lowerCanvasEl, 'lower-canvas');\n\n      if (this.interactive) {\n        this._applyCanvasStyle(this.lowerCanvasEl);\n      }\n\n      this.contextContainer = this.lowerCanvasEl.getContext('2d');\n    },\n\n    /**\n     * Returns canvas width (in px)\n     * @return {Number}\n     */\n    getWidth: function () {\n      return this.width;\n    },\n\n    /**\n     * Returns canvas height (in px)\n     * @return {Number}\n     */\n    getHeight: function () {\n      return this.height;\n    },\n\n    /**\n     * Sets width of this canvas instance\n     * @param {Number|String} value                         Value to set width to\n     * @param {Object}        [options]                     Options object\n     * @param {Boolean}       [options.backstoreOnly=false] Set the given dimensions only as canvas backstore dimensions\n     * @param {Boolean}       [options.cssOnly=false]       Set the given dimensions only as css dimensions\n     * @return {fabric.Canvas} instance\n     * @chainable true\n     */\n    setWidth: function (value, options) {\n      return this.setDimensions({ width: value }, options);\n    },\n\n    /**\n     * Sets height of this canvas instance\n     * @param {Number|String} value                         Value to set height to\n     * @param {Object}        [options]                     Options object\n     * @param {Boolean}       [options.backstoreOnly=false] Set the given dimensions only as canvas backstore dimensions\n     * @param {Boolean}       [options.cssOnly=false]       Set the given dimensions only as css dimensions\n     * @return {fabric.Canvas} instance\n     * @chainable true\n     */\n    setHeight: function (value, options) {\n      return this.setDimensions({ height: value }, options);\n    },\n\n    /**\n     * Sets dimensions (width, height) of this canvas instance. when options.cssOnly flag active you should also supply the unit of measure (px/%/em)\n     * @param {Object}        dimensions                    Object with width/height properties\n     * @param {Number|String} [dimensions.width]            Width of canvas element\n     * @param {Number|String} [dimensions.height]           Height of canvas element\n     * @param {Object}        [options]                     Options object\n     * @param {Boolean}       [options.backstoreOnly=false] Set the given dimensions only as canvas backstore dimensions\n     * @param {Boolean}       [options.cssOnly=false]       Set the given dimensions only as css dimensions\n     * @return {fabric.Canvas} thisArg\n     * @chainable\n     */\n    setDimensions: function (dimensions, options) {\n      var cssValue;\n\n      options = options || {};\n\n      for (var prop in dimensions) {\n        cssValue = dimensions[prop];\n\n        if (!options.cssOnly) {\n          this._setBackstoreDimension(prop, dimensions[prop]);\n          cssValue += 'px';\n          this.hasLostContext = true;\n        }\n\n        if (!options.backstoreOnly) {\n          this._setCssDimension(prop, cssValue);\n        }\n      }\n      if (this._isCurrentlyDrawing) {\n        this.freeDrawingBrush && this.freeDrawingBrush._setBrushStyles();\n      }\n      this._initRetinaScaling();\n      this._setImageSmoothing();\n      this.calcOffset();\n\n      if (!options.cssOnly) {\n        this.requestRenderAll();\n      }\n\n      return this;\n    },\n\n    /**\n     * Helper for setting width/height\n     * @private\n     * @param {String} prop property (width|height)\n     * @param {Number} value value to set property to\n     * @return {fabric.Canvas} instance\n     * @chainable true\n     */\n    _setBackstoreDimension: function (prop, value) {\n      this.lowerCanvasEl[prop] = value;\n\n      if (this.upperCanvasEl) {\n        this.upperCanvasEl[prop] = value;\n      }\n\n      if (this.cacheCanvasEl) {\n        this.cacheCanvasEl[prop] = value;\n      }\n\n      this[prop] = value;\n\n      return this;\n    },\n\n    /**\n     * Helper for setting css width/height\n     * @private\n     * @param {String} prop property (width|height)\n     * @param {String} value value to set property to\n     * @return {fabric.Canvas} instance\n     * @chainable true\n     */\n    _setCssDimension: function (prop, value) {\n      this.lowerCanvasEl.style[prop] = value;\n\n      if (this.upperCanvasEl) {\n        this.upperCanvasEl.style[prop] = value;\n      }\n\n      if (this.wrapperEl) {\n        this.wrapperEl.style[prop] = value;\n      }\n\n      return this;\n    },\n\n    /**\n     * Returns canvas zoom level\n     * @return {Number}\n     */\n    getZoom: function () {\n      return this.viewportTransform[0];\n    },\n\n    /**\n     * Sets viewport transform of this canvas instance\n     * @param {Array} vpt the transform in the form of context.transform\n     * @return {fabric.Canvas} instance\n     * @chainable true\n     */\n    setViewportTransform: function (vpt) {\n      var activeObject = this._activeObject, object, ignoreVpt = false, skipAbsolute = true, i, len;\n      this.viewportTransform = vpt;\n      for (i = 0, len = this._objects.length; i < len; i++) {\n        object = this._objects[i];\n        object.group || object.setCoords(ignoreVpt, skipAbsolute);\n      }\n      if (activeObject && activeObject.type === 'activeSelection') {\n        activeObject.setCoords(ignoreVpt, skipAbsolute);\n      }\n      this.calcViewportBoundaries();\n      this.renderOnAddRemove && this.requestRenderAll();\n      return this;\n    },\n\n    /**\n     * Sets zoom level of this canvas instance, zoom centered around point\n     * @param {fabric.Point} point to zoom with respect to\n     * @param {Number} value to set zoom to, less than 1 zooms out\n     * @return {fabric.Canvas} instance\n     * @chainable true\n     */\n    zoomToPoint: function (point, value) {\n      // TODO: just change the scale, preserve other transformations\n      var before = point, vpt = this.viewportTransform.slice(0);\n      point = transformPoint(point, invertTransform(this.viewportTransform));\n      vpt[0] = value;\n      vpt[3] = value;\n      var after = transformPoint(point, vpt);\n      vpt[4] += before.x - after.x;\n      vpt[5] += before.y - after.y;\n      return this.setViewportTransform(vpt);\n    },\n\n    /**\n     * Sets zoom level of this canvas instance\n     * @param {Number} value to set zoom to, less than 1 zooms out\n     * @return {fabric.Canvas} instance\n     * @chainable true\n     */\n    setZoom: function (value) {\n      this.zoomToPoint(new fabric.Point(0, 0), value);\n      return this;\n    },\n\n    /**\n     * Pan viewport so as to place point at top left corner of canvas\n     * @param {fabric.Point} point to move to\n     * @return {fabric.Canvas} instance\n     * @chainable true\n     */\n    absolutePan: function (point) {\n      var vpt = this.viewportTransform.slice(0);\n      vpt[4] = -point.x;\n      vpt[5] = -point.y;\n      return this.setViewportTransform(vpt);\n    },\n\n    /**\n     * Pans viewpoint relatively\n     * @param {fabric.Point} point (position vector) to move by\n     * @return {fabric.Canvas} instance\n     * @chainable true\n     */\n    relativePan: function (point) {\n      return this.absolutePan(new fabric.Point(\n        -point.x - this.viewportTransform[4],\n        -point.y - this.viewportTransform[5]\n      ));\n    },\n\n    /**\n     * Returns &lt;canvas> element corresponding to this instance\n     * @return {HTMLCanvasElement}\n     */\n    getElement: function () {\n      return this.lowerCanvasEl;\n    },\n\n    /**\n     * @private\n     * @param {fabric.Object} obj Object that was added\n     */\n    _onObjectAdded: function(obj) {\n      this.stateful && obj.setupState();\n      obj._set('canvas', this);\n      obj.setCoords();\n      this.fire('object:added', { target: obj });\n      obj.fire('added');\n    },\n\n    /**\n     * @private\n     * @param {fabric.Object} obj Object that was removed\n     */\n    _onObjectRemoved: function(obj) {\n      this.fire('object:removed', { target: obj });\n      obj.fire('removed');\n      delete obj.canvas;\n    },\n\n    /**\n     * Clears specified context of canvas element\n     * @param {CanvasRenderingContext2D} ctx Context to clear\n     * @return {fabric.Canvas} thisArg\n     * @chainable\n     */\n    clearContext: function(ctx) {\n      ctx.clearRect(0, 0, this.width, this.height);\n      return this;\n    },\n\n    /**\n     * Returns context of canvas where objects are drawn\n     * @return {CanvasRenderingContext2D}\n     */\n    getContext: function () {\n      return this.contextContainer;\n    },\n\n    /**\n     * Clears all contexts (background, main, top) of an instance\n     * @return {fabric.Canvas} thisArg\n     * @chainable\n     */\n    clear: function () {\n      this._objects.length = 0;\n      this.backgroundImage = null;\n      this.overlayImage = null;\n      this.backgroundColor = '';\n      this.overlayColor = '';\n      if (this._hasITextHandlers) {\n        this.off('mouse:up', this._mouseUpITextHandler);\n        this._iTextInstances = null;\n        this._hasITextHandlers = false;\n      }\n      this.clearContext(this.contextContainer);\n      this.fire('canvas:cleared');\n      this.renderOnAddRemove && this.requestRenderAll();\n      return this;\n    },\n\n    /**\n     * Renders the canvas\n     * @return {fabric.Canvas} instance\n     * @chainable\n     */\n    renderAll: function () {\n      var canvasToDrawOn = this.contextContainer;\n      this.renderCanvas(canvasToDrawOn, this._objects);\n      return this;\n    },\n\n    /**\n     * Function created to be instance bound at initialization\n     * used in requestAnimationFrame rendering\n     * Let the fabricJS call it. If you call it manually you could have more\n     * animationFrame stacking on to of each other\n     * for an imperative rendering, use canvas.renderAll\n     * @private\n     * @return {fabric.Canvas} instance\n     * @chainable\n     */\n    renderAndReset: function() {\n      this.isRendering = 0;\n      this.renderAll();\n    },\n\n    /**\n     * Append a renderAll request to next animation frame.\n     * unless one is already in progress, in that case nothing is done\n     * a boolean flag will avoid appending more.\n     * @return {fabric.Canvas} instance\n     * @chainable\n     */\n    requestRenderAll: function () {\n      if (!this.isRendering) {\n        this.isRendering = fabric.util.requestAnimFrame(this.renderAndResetBound);\n      }\n      return this;\n    },\n\n    /**\n     * Calculate the position of the 4 corner of canvas with current viewportTransform.\n     * helps to determinate when an object is in the current rendering viewport using\n     * object absolute coordinates ( aCoords )\n     * @return {Object} points.tl\n     * @chainable\n     */\n    calcViewportBoundaries: function() {\n      var points = { }, width = this.width, height = this.height,\n          iVpt = invertTransform(this.viewportTransform);\n      points.tl = transformPoint({ x: 0, y: 0 }, iVpt);\n      points.br = transformPoint({ x: width, y: height }, iVpt);\n      points.tr = new fabric.Point(points.br.x, points.tl.y);\n      points.bl = new fabric.Point(points.tl.x, points.br.y);\n      this.vptCoords = points;\n      return points;\n    },\n\n    cancelRequestedRender: function() {\n      if (this.isRendering) {\n        fabric.util.cancelAnimFrame(this.isRendering);\n        this.isRendering = 0;\n      }\n    },\n\n    /**\n     * Renders background, objects, overlay and controls.\n     * @param {CanvasRenderingContext2D} ctx\n     * @param {Array} objects to render\n     * @return {fabric.Canvas} instance\n     * @chainable\n     */\n    renderCanvas: function(ctx, objects) {\n      var v = this.viewportTransform, path = this.clipPath;\n      this.cancelRequestedRender();\n      this.calcViewportBoundaries();\n      this.clearContext(ctx);\n      this.fire('before:render', { ctx: ctx, });\n      if (this.clipTo) {\n        fabric.util.clipContext(this, ctx);\n      }\n      this._renderBackground(ctx);\n\n      ctx.save();\n      //apply viewport transform once for all rendering process\n      ctx.transform(v[0], v[1], v[2], v[3], v[4], v[5]);\n      this._renderObjects(ctx, objects);\n      ctx.restore();\n      if (!this.controlsAboveOverlay && this.interactive) {\n        this.drawControls(ctx);\n      }\n      if (this.clipTo) {\n        ctx.restore();\n      }\n      if (path) {\n        path.canvas = this;\n        // needed to setup a couple of variables\n        path.shouldCache();\n        path._transformDone = true;\n        path.renderCache({ forClipping: true });\n        this.drawClipPathOnCanvas(ctx);\n      }\n      this._renderOverlay(ctx);\n      if (this.controlsAboveOverlay && this.interactive) {\n        this.drawControls(ctx);\n      }\n      this.fire('after:render', { ctx: ctx, });\n    },\n\n    /**\n     * Paint the cached clipPath on the lowerCanvasEl\n     * @param {CanvasRenderingContext2D} ctx Context to render on\n     */\n    drawClipPathOnCanvas: function(ctx) {\n      var v = this.viewportTransform, path = this.clipPath;\n      ctx.save();\n      ctx.transform(v[0], v[1], v[2], v[3], v[4], v[5]);\n      // DEBUG: uncomment this line, comment the following\n      // ctx.globalAlpha = 0.4;\n      ctx.globalCompositeOperation = 'destination-in';\n      path.transform(ctx);\n      ctx.scale(1 / path.zoomX, 1 / path.zoomY);\n      ctx.drawImage(path._cacheCanvas, -path.cacheTranslationX, -path.cacheTranslationY);\n      ctx.restore();\n    },\n\n    /**\n     * @private\n     * @param {CanvasRenderingContext2D} ctx Context to render on\n     * @param {Array} objects to render\n     */\n    _renderObjects: function(ctx, objects) {\n      var i, len;\n      for (i = 0, len = objects.length; i < len; ++i) {\n        objects[i] && objects[i].render(ctx);\n      }\n    },\n\n    /**\n     * @private\n     * @param {CanvasRenderingContext2D} ctx Context to render on\n     * @param {string} property 'background' or 'overlay'\n     */\n    _renderBackgroundOrOverlay: function(ctx, property) {\n      var fill = this[property + 'Color'], object = this[property + 'Image'],\n          v = this.viewportTransform, needsVpt = this[property + 'Vpt'];\n      if (!fill && !object) {\n        return;\n      }\n      if (fill) {\n        ctx.save();\n        ctx.beginPath();\n        ctx.moveTo(0, 0);\n        ctx.lineTo(this.width, 0);\n        ctx.lineTo(this.width, this.height);\n        ctx.lineTo(0, this.height);\n        ctx.closePath();\n        ctx.fillStyle = fill.toLive\n          ? fill.toLive(ctx, this)\n          : fill;\n        if (needsVpt) {\n          ctx.transform(\n            v[0], v[1], v[2], v[3],\n            v[4] + (fill.offsetX || 0),\n            v[5] + (fill.offsetY || 0)\n          );\n        }\n        var m = fill.gradientTransform || fill.patternTransform;\n        m && ctx.transform(m[0], m[1], m[2], m[3], m[4], m[5]);\n        ctx.fill();\n        ctx.restore();\n      }\n      if (object) {\n        ctx.save();\n        if (needsVpt) {\n          ctx.transform(v[0], v[1], v[2], v[3], v[4], v[5]);\n        }\n        object.render(ctx);\n        ctx.restore();\n      }\n    },\n\n    /**\n     * @private\n     * @param {CanvasRenderingContext2D} ctx Context to render on\n     */\n    _renderBackground: function(ctx) {\n      this._renderBackgroundOrOverlay(ctx, 'background');\n    },\n\n    /**\n     * @private\n     * @param {CanvasRenderingContext2D} ctx Context to render on\n     */\n    _renderOverlay: function(ctx) {\n      this._renderBackgroundOrOverlay(ctx, 'overlay');\n    },\n\n    /**\n     * Returns coordinates of a center of canvas.\n     * Returned value is an object with top and left properties\n     * @return {Object} object with \"top\" and \"left\" number values\n     */\n    getCenter: function () {\n      return {\n        top: this.height / 2,\n        left: this.width / 2\n      };\n    },\n\n    /**\n     * Centers object horizontally in the canvas\n     * @param {fabric.Object} object Object to center horizontally\n     * @return {fabric.Canvas} thisArg\n     */\n    centerObjectH: function (object) {\n      return this._centerObject(object, new fabric.Point(this.getCenter().left, object.getCenterPoint().y));\n    },\n\n    /**\n     * Centers object vertically in the canvas\n     * @param {fabric.Object} object Object to center vertically\n     * @return {fabric.Canvas} thisArg\n     * @chainable\n     */\n    centerObjectV: function (object) {\n      return this._centerObject(object, new fabric.Point(object.getCenterPoint().x, this.getCenter().top));\n    },\n\n    /**\n     * Centers object vertically and horizontally in the canvas\n     * @param {fabric.Object} object Object to center vertically and horizontally\n     * @return {fabric.Canvas} thisArg\n     * @chainable\n     */\n    centerObject: function(object) {\n      var center = this.getCenter();\n\n      return this._centerObject(object, new fabric.Point(center.left, center.top));\n    },\n\n    /**\n     * Centers object vertically and horizontally in the viewport\n     * @param {fabric.Object} object Object to center vertically and horizontally\n     * @return {fabric.Canvas} thisArg\n     * @chainable\n     */\n    viewportCenterObject: function(object) {\n      var vpCenter = this.getVpCenter();\n\n      return this._centerObject(object, vpCenter);\n    },\n\n    /**\n     * Centers object horizontally in the viewport, object.top is unchanged\n     * @param {fabric.Object} object Object to center vertically and horizontally\n     * @return {fabric.Canvas} thisArg\n     * @chainable\n     */\n    viewportCenterObjectH: function(object) {\n      var vpCenter = this.getVpCenter();\n      this._centerObject(object, new fabric.Point(vpCenter.x, object.getCenterPoint().y));\n      return this;\n    },\n\n    /**\n     * Centers object Vertically in the viewport, object.top is unchanged\n     * @param {fabric.Object} object Object to center vertically and horizontally\n     * @return {fabric.Canvas} thisArg\n     * @chainable\n     */\n    viewportCenterObjectV: function(object) {\n      var vpCenter = this.getVpCenter();\n\n      return this._centerObject(object, new fabric.Point(object.getCenterPoint().x, vpCenter.y));\n    },\n\n    /**\n     * Calculate the point in canvas that correspond to the center of actual viewport.\n     * @return {fabric.Point} vpCenter, viewport center\n     * @chainable\n     */\n    getVpCenter: function() {\n      var center = this.getCenter(),\n          iVpt = invertTransform(this.viewportTransform);\n      return transformPoint({ x: center.left, y: center.top }, iVpt);\n    },\n\n    /**\n     * @private\n     * @param {fabric.Object} object Object to center\n     * @param {fabric.Point} center Center point\n     * @return {fabric.Canvas} thisArg\n     * @chainable\n     */\n    _centerObject: function(object, center) {\n      object.setPositionByOrigin(center, 'center', 'center');\n      object.setCoords();\n      this.renderOnAddRemove && this.requestRenderAll();\n      return this;\n    },\n\n    /**\n     * Returs dataless JSON representation of canvas\n     * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output\n     * @return {String} json string\n     */\n    toDatalessJSON: function (propertiesToInclude) {\n      return this.toDatalessObject(propertiesToInclude);\n    },\n\n    /**\n     * Returns object representation of canvas\n     * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output\n     * @return {Object} object representation of an instance\n     */\n    toObject: function (propertiesToInclude) {\n      return this._toObjectMethod('toObject', propertiesToInclude);\n    },\n\n    /**\n     * Returns dataless object representation of canvas\n     * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output\n     * @return {Object} object representation of an instance\n     */\n    toDatalessObject: function (propertiesToInclude) {\n      return this._toObjectMethod('toDatalessObject', propertiesToInclude);\n    },\n\n    /**\n     * @private\n     */\n    _toObjectMethod: function (methodName, propertiesToInclude) {\n\n      var clipPath = this.clipPath, data = {\n        version: fabric.version,\n        objects: this._toObjects(methodName, propertiesToInclude),\n      };\n      if (clipPath) {\n        data.clipPath = this._toObject(this.clipPath, methodName, propertiesToInclude);\n      }\n      extend(data, this.__serializeBgOverlay(methodName, propertiesToInclude));\n\n      fabric.util.populateWithProperties(this, data, propertiesToInclude);\n\n      return data;\n    },\n\n    /**\n     * @private\n     */\n    _toObjects: function(methodName, propertiesToInclude) {\n      return this._objects.filter(function(object) {\n        return !object.excludeFromExport;\n      }).map(function(instance) {\n        return this._toObject(instance, methodName, propertiesToInclude);\n      }, this);\n    },\n\n    /**\n     * @private\n     */\n    _toObject: function(instance, methodName, propertiesToInclude) {\n      var originalValue;\n\n      if (!this.includeDefaultValues) {\n        originalValue = instance.includeDefaultValues;\n        instance.includeDefaultValues = false;\n      }\n\n      var object = instance[methodName](propertiesToInclude);\n      if (!this.includeDefaultValues) {\n        instance.includeDefaultValues = originalValue;\n      }\n      return object;\n    },\n\n    /**\n     * @private\n     */\n    __serializeBgOverlay: function(methodName, propertiesToInclude) {\n      var data = { }, bgImage = this.backgroundImage, overlay = this.overlayImage;\n\n      if (this.backgroundColor) {\n        data.background = this.backgroundColor.toObject\n          ? this.backgroundColor.toObject(propertiesToInclude)\n          : this.backgroundColor;\n      }\n\n      if (this.overlayColor) {\n        data.overlay = this.overlayColor.toObject\n          ? this.overlayColor.toObject(propertiesToInclude)\n          : this.overlayColor;\n      }\n      if (bgImage && !bgImage.excludeFromExport) {\n        data.backgroundImage = this._toObject(bgImage, methodName, propertiesToInclude);\n      }\n      if (overlay && !overlay.excludeFromExport) {\n        data.overlayImage = this._toObject(overlay, methodName, propertiesToInclude);\n      }\n\n      return data;\n    },\n\n    /* _TO_SVG_START_ */\n    /**\n     * When true, getSvgTransform() will apply the StaticCanvas.viewportTransform to the SVG transformation. When true,\n     * a zoomed canvas will then produce zoomed SVG output.\n     * @type Boolean\n     * @default\n     */\n    svgViewportTransformation: true,\n\n    /**\n     * Returns SVG representation of canvas\n     * @function\n     * @param {Object} [options] Options object for SVG output\n     * @param {Boolean} [options.suppressPreamble=false] If true xml tag is not included\n     * @param {Object} [options.viewBox] SVG viewbox object\n     * @param {Number} [options.viewBox.x] x-cooridnate of viewbox\n     * @param {Number} [options.viewBox.y] y-coordinate of viewbox\n     * @param {Number} [options.viewBox.width] Width of viewbox\n     * @param {Number} [options.viewBox.height] Height of viewbox\n     * @param {String} [options.encoding=UTF-8] Encoding of SVG output\n     * @param {String} [options.width] desired width of svg with or without units\n     * @param {String} [options.height] desired height of svg with or without units\n     * @param {Function} [reviver] Method for further parsing of svg elements, called after each fabric object converted into svg representation.\n     * @return {String} SVG string\n     * @tutorial {@link http://fabricjs.com/fabric-intro-part-3#serialization}\n     * @see {@link http://jsfiddle.net/fabricjs/jQ3ZZ/|jsFiddle demo}\n     * @example <caption>Normal SVG output</caption>\n     * var svg = canvas.toSVG();\n     * @example <caption>SVG output without preamble (without &lt;?xml ../>)</caption>\n     * var svg = canvas.toSVG({suppressPreamble: true});\n     * @example <caption>SVG output with viewBox attribute</caption>\n     * var svg = canvas.toSVG({\n     *   viewBox: {\n     *     x: 100,\n     *     y: 100,\n     *     width: 200,\n     *     height: 300\n     *   }\n     * });\n     * @example <caption>SVG output with different encoding (default: UTF-8)</caption>\n     * var svg = canvas.toSVG({encoding: 'ISO-8859-1'});\n     * @example <caption>Modify SVG output with reviver function</caption>\n     * var svg = canvas.toSVG(null, function(svg) {\n     *   return svg.replace('stroke-dasharray: ; stroke-linecap: butt; stroke-linejoin: miter; stroke-miterlimit: 10; ', '');\n     * });\n     */\n    toSVG: function(options, reviver) {\n      options || (options = { });\n      options.reviver = reviver;\n      var markup = [];\n\n      this._setSVGPreamble(markup, options);\n      this._setSVGHeader(markup, options);\n      if (this.clipPath) {\n        markup.push('<g clip-path=\"url(#' + this.clipPath.clipPathId + ')\" >\\n');\n      }\n      this._setSVGBgOverlayColor(markup, 'background');\n      this._setSVGBgOverlayImage(markup, 'backgroundImage', reviver);\n      this._setSVGObjects(markup, reviver);\n      if (this.clipPath) {\n        markup.push('</g>\\n');\n      }\n      this._setSVGBgOverlayColor(markup, 'overlay');\n      this._setSVGBgOverlayImage(markup, 'overlayImage', reviver);\n\n      markup.push('</svg>');\n\n      return markup.join('');\n    },\n\n    /**\n     * @private\n     */\n    _setSVGPreamble: function(markup, options) {\n      if (options.suppressPreamble) {\n        return;\n      }\n      markup.push(\n        '<?xml version=\"1.0\" encoding=\"', (options.encoding || 'UTF-8'), '\" standalone=\"no\" ?>\\n',\n        '<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.1//EN\" ',\n        '\"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\">\\n'\n      );\n    },\n\n    /**\n     * @private\n     */\n    _setSVGHeader: function(markup, options) {\n      var width = options.width || this.width,\n          height = options.height || this.height,\n          vpt, viewBox = 'viewBox=\"0 0 ' + this.width + ' ' + this.height + '\" ',\n          NUM_FRACTION_DIGITS = fabric.Object.NUM_FRACTION_DIGITS;\n\n      if (options.viewBox) {\n        viewBox = 'viewBox=\"' +\n                options.viewBox.x + ' ' +\n                options.viewBox.y + ' ' +\n                options.viewBox.width + ' ' +\n                options.viewBox.height + '\" ';\n      }\n      else {\n        if (this.svgViewportTransformation) {\n          vpt = this.viewportTransform;\n          viewBox = 'viewBox=\"' +\n                  toFixed(-vpt[4] / vpt[0], NUM_FRACTION_DIGITS) + ' ' +\n                  toFixed(-vpt[5] / vpt[3], NUM_FRACTION_DIGITS) + ' ' +\n                  toFixed(this.width / vpt[0], NUM_FRACTION_DIGITS) + ' ' +\n                  toFixed(this.height / vpt[3], NUM_FRACTION_DIGITS) + '\" ';\n        }\n      }\n\n      markup.push(\n        '<svg ',\n        'xmlns=\"http://www.w3.org/2000/svg\" ',\n        'xmlns:xlink=\"http://www.w3.org/1999/xlink\" ',\n        'version=\"1.1\" ',\n        'width=\"', width, '\" ',\n        'height=\"', height, '\" ',\n        viewBox,\n        'xml:space=\"preserve\">\\n',\n        '<desc>Created with Fabric.js ', fabric.version, '</desc>\\n',\n        '<defs>\\n',\n        this.createSVGFontFacesMarkup(),\n        this.createSVGRefElementsMarkup(),\n        this.createSVGClipPathMarkup(options),\n        '</defs>\\n'\n      );\n    },\n\n    createSVGClipPathMarkup: function(options) {\n      var clipPath = this.clipPath;\n      if (clipPath) {\n        clipPath.clipPathId = 'CLIPPATH_' + fabric.Object.__uid++;\n        return  '<clipPath id=\"' + clipPath.clipPathId + '\" >\\n' +\n          this.clipPath.toClipPathSVG(options.reviver) +\n          '</clipPath>\\n';\n      }\n      return '';\n    },\n\n    /**\n     * Creates markup containing SVG referenced elements like patterns, gradients etc.\n     * @return {String}\n     */\n    createSVGRefElementsMarkup: function() {\n      var _this = this,\n          markup = ['background', 'overlay'].map(function(prop) {\n            var fill = _this[prop + 'Color'];\n            if (fill && fill.toLive) {\n              var shouldTransform = _this[prop + 'Vpt'], vpt = _this.viewportTransform,\n                  object = {\n                    width: _this.width / (shouldTransform ? vpt[0] : 1),\n                    height: _this.height / (shouldTransform ? vpt[3] : 1)\n                  };\n              return fill.toSVG(\n                object,\n                { additionalTransform: shouldTransform ? fabric.util.matrixToSVG(vpt) : '' }\n              );\n            }\n          });\n      return markup.join('');\n    },\n\n    /**\n     * Creates markup containing SVG font faces,\n     * font URLs for font faces must be collected by developers\n     * and are not extracted from the DOM by fabricjs\n     * @param {Array} objects Array of fabric objects\n     * @return {String}\n     */\n    createSVGFontFacesMarkup: function() {\n      var markup = '', fontList = { }, obj, fontFamily,\n          style, row, rowIndex, _char, charIndex, i, len,\n          fontPaths = fabric.fontPaths, objects = this._objects;\n\n      for (i = 0, len = objects.length; i < len; i++) {\n        obj = objects[i];\n        fontFamily = obj.fontFamily;\n        if (obj.type.indexOf('text') === -1 || fontList[fontFamily] || !fontPaths[fontFamily]) {\n          continue;\n        }\n        fontList[fontFamily] = true;\n        if (!obj.styles) {\n          continue;\n        }\n        style = obj.styles;\n        for (rowIndex in style) {\n          row = style[rowIndex];\n          for (charIndex in row) {\n            _char = row[charIndex];\n            fontFamily = _char.fontFamily;\n            if (!fontList[fontFamily] && fontPaths[fontFamily]) {\n              fontList[fontFamily] = true;\n            }\n          }\n        }\n      }\n\n      for (var j in fontList) {\n        markup += [\n          '\\t\\t@font-face {\\n',\n          '\\t\\t\\tfont-family: \\'', j, '\\';\\n',\n          '\\t\\t\\tsrc: url(\\'', fontPaths[j], '\\');\\n',\n          '\\t\\t}\\n'\n        ].join('');\n      }\n\n      if (markup) {\n        markup = [\n          '\\t<style type=\"text/css\">',\n          '<![CDATA[\\n',\n          markup,\n          ']]>',\n          '</style>\\n'\n        ].join('');\n      }\n\n      return markup;\n    },\n\n    /**\n     * @private\n     */\n    _setSVGObjects: function(markup, reviver) {\n      var instance, i, len, objects = this._objects;\n      for (i = 0, len = objects.length; i < len; i++) {\n        instance = objects[i];\n        if (instance.excludeFromExport) {\n          continue;\n        }\n        this._setSVGObject(markup, instance, reviver);\n      }\n    },\n\n    /**\n     * @private\n     */\n    _setSVGObject: function(markup, instance, reviver) {\n      markup.push(instance.toSVG(reviver));\n    },\n\n    /**\n     * @private\n     */\n    _setSVGBgOverlayImage: function(markup, property, reviver) {\n      if (this[property] && !this[property].excludeFromExport && this[property].toSVG) {\n        markup.push(this[property].toSVG(reviver));\n      }\n    },\n\n    /**\n     * @private\n     */\n    _setSVGBgOverlayColor: function(markup, property) {\n      var filler = this[property + 'Color'], vpt = this.viewportTransform, finalWidth = this.width,\n          finalHeight = this.height;\n      if (!filler) {\n        return;\n      }\n      if (filler.toLive) {\n        var repeat = filler.repeat, iVpt = fabric.util.invertTransform(vpt), shouldInvert = this[property + 'Vpt'],\n            additionalTransform = shouldInvert ? fabric.util.matrixToSVG(iVpt) : '';\n        markup.push(\n          '<rect transform=\"' + additionalTransform + ' translate(', finalWidth / 2, ',', finalHeight / 2, ')\"',\n          ' x=\"', filler.offsetX - finalWidth / 2,\n          '\" y=\"', filler.offsetY - finalHeight / 2, '\" ',\n          'width=\"',\n          (repeat === 'repeat-y' || repeat === 'no-repeat'\n            ? filler.source.width\n            : finalWidth ),\n          '\" height=\"',\n          (repeat === 'repeat-x' || repeat === 'no-repeat'\n            ? filler.source.height\n            : finalHeight),\n          '\" fill=\"url(#SVGID_' + filler.id + ')\"',\n          '></rect>\\n'\n        );\n      }\n      else {\n        markup.push(\n          '<rect x=\"0\" y=\"0\" width=\"100%\" height=\"100%\" ',\n          'fill=\"', filler, '\"',\n          '></rect>\\n'\n        );\n      }\n    },\n    /* _TO_SVG_END_ */\n\n    /**\n     * Moves an object or the objects of a multiple selection\n     * to the bottom of the stack of drawn objects\n     * @param {fabric.Object} object Object to send to back\n     * @return {fabric.Canvas} thisArg\n     * @chainable\n     */\n    sendToBack: function (object) {\n      if (!object) {\n        return this;\n      }\n      var activeSelection = this._activeObject,\n          i, obj, objs;\n      if (object === activeSelection && object.type === 'activeSelection') {\n        objs = activeSelection._objects;\n        for (i = objs.length; i--;) {\n          obj = objs[i];\n          removeFromArray(this._objects, obj);\n          this._objects.unshift(obj);\n        }\n      }\n      else {\n        removeFromArray(this._objects, object);\n        this._objects.unshift(object);\n      }\n      this.renderOnAddRemove && this.requestRenderAll();\n      return this;\n    },\n\n    /**\n     * Moves an object or the objects of a multiple selection\n     * to the top of the stack of drawn objects\n     * @param {fabric.Object} object Object to send\n     * @return {fabric.Canvas} thisArg\n     * @chainable\n     */\n    bringToFront: function (object) {\n      if (!object) {\n        return this;\n      }\n      var activeSelection = this._activeObject,\n          i, obj, objs;\n      if (object === activeSelection && object.type === 'activeSelection') {\n        objs = activeSelection._objects;\n        for (i = 0; i < objs.length; i++) {\n          obj = objs[i];\n          removeFromArray(this._objects, obj);\n          this._objects.push(obj);\n        }\n      }\n      else {\n        removeFromArray(this._objects, object);\n        this._objects.push(object);\n      }\n      this.renderOnAddRemove && this.requestRenderAll();\n      return this;\n    },\n\n    /**\n     * Moves an object or a selection down in stack of drawn objects\n     * An optional paramter, intersecting allowes to move the object in behind\n     * the first intersecting object. Where intersection is calculated with\n     * bounding box. If no intersection is found, there will not be change in the\n     * stack.\n     * @param {fabric.Object} object Object to send\n     * @param {Boolean} [intersecting] If `true`, send object behind next lower intersecting object\n     * @return {fabric.Canvas} thisArg\n     * @chainable\n     */\n    sendBackwards: function (object, intersecting) {\n      if (!object) {\n        return this;\n      }\n      var activeSelection = this._activeObject,\n          i, obj, idx, newIdx, objs, objsMoved = 0;\n\n      if (object === activeSelection && object.type === 'activeSelection') {\n        objs = activeSelection._objects;\n        for (i = 0; i < objs.length; i++) {\n          obj = objs[i];\n          idx = this._objects.indexOf(obj);\n          if (idx > 0 + objsMoved) {\n            newIdx = idx - 1;\n            removeFromArray(this._objects, obj);\n            this._objects.splice(newIdx, 0, obj);\n          }\n          objsMoved++;\n        }\n      }\n      else {\n        idx = this._objects.indexOf(object);\n        if (idx !== 0) {\n          // if object is not on the bottom of stack\n          newIdx = this._findNewLowerIndex(object, idx, intersecting);\n          removeFromArray(this._objects, object);\n          this._objects.splice(newIdx, 0, object);\n        }\n      }\n      this.renderOnAddRemove && this.requestRenderAll();\n      return this;\n    },\n\n    /**\n     * @private\n     */\n    _findNewLowerIndex: function(object, idx, intersecting) {\n      var newIdx, i;\n\n      if (intersecting) {\n        newIdx = idx;\n\n        // traverse down the stack looking for the nearest intersecting object\n        for (i = idx - 1; i >= 0; --i) {\n\n          var isIntersecting = object.intersectsWithObject(this._objects[i]) ||\n                               object.isContainedWithinObject(this._objects[i]) ||\n                               this._objects[i].isContainedWithinObject(object);\n\n          if (isIntersecting) {\n            newIdx = i;\n            break;\n          }\n        }\n      }\n      else {\n        newIdx = idx - 1;\n      }\n\n      return newIdx;\n    },\n\n    /**\n     * Moves an object or a selection up in stack of drawn objects\n     * An optional paramter, intersecting allowes to move the object in front\n     * of the first intersecting object. Where intersection is calculated with\n     * bounding box. If no intersection is found, there will not be change in the\n     * stack.\n     * @param {fabric.Object} object Object to send\n     * @param {Boolean} [intersecting] If `true`, send object in front of next upper intersecting object\n     * @return {fabric.Canvas} thisArg\n     * @chainable\n     */\n    bringForward: function (object, intersecting) {\n      if (!object) {\n        return this;\n      }\n      var activeSelection = this._activeObject,\n          i, obj, idx, newIdx, objs, objsMoved = 0;\n\n      if (object === activeSelection && object.type === 'activeSelection') {\n        objs = activeSelection._objects;\n        for (i = objs.length; i--;) {\n          obj = objs[i];\n          idx = this._objects.indexOf(obj);\n          if (idx < this._objects.length - 1 - objsMoved) {\n            newIdx = idx + 1;\n            removeFromArray(this._objects, obj);\n            this._objects.splice(newIdx, 0, obj);\n          }\n          objsMoved++;\n        }\n      }\n      else {\n        idx = this._objects.indexOf(object);\n        if (idx !== this._objects.length - 1) {\n          // if object is not on top of stack (last item in an array)\n          newIdx = this._findNewUpperIndex(object, idx, intersecting);\n          removeFromArray(this._objects, object);\n          this._objects.splice(newIdx, 0, object);\n        }\n      }\n      this.renderOnAddRemove && this.requestRenderAll();\n      return this;\n    },\n\n    /**\n     * @private\n     */\n    _findNewUpperIndex: function(object, idx, intersecting) {\n      var newIdx, i, len;\n\n      if (intersecting) {\n        newIdx = idx;\n\n        // traverse up the stack looking for the nearest intersecting object\n        for (i = idx + 1, len = this._objects.length; i < len; ++i) {\n\n          var isIntersecting = object.intersectsWithObject(this._objects[i]) ||\n                               object.isContainedWithinObject(this._objects[i]) ||\n                               this._objects[i].isContainedWithinObject(object);\n\n          if (isIntersecting) {\n            newIdx = i;\n            break;\n          }\n        }\n      }\n      else {\n        newIdx = idx + 1;\n      }\n\n      return newIdx;\n    },\n\n    /**\n     * Moves an object to specified level in stack of drawn objects\n     * @param {fabric.Object} object Object to send\n     * @param {Number} index Position to move to\n     * @return {fabric.Canvas} thisArg\n     * @chainable\n     */\n    moveTo: function (object, index) {\n      removeFromArray(this._objects, object);\n      this._objects.splice(index, 0, object);\n      return this.renderOnAddRemove && this.requestRenderAll();\n    },\n\n    /**\n     * Clears a canvas element and dispose objects\n     * @return {fabric.Canvas} thisArg\n     * @chainable\n     */\n    dispose: function () {\n      // cancel eventually ongoing renders\n      if (this.isRendering) {\n        fabric.util.cancelAnimFrame(this.isRendering);\n        this.isRendering = 0;\n      }\n      this.forEachObject(function(object) {\n        object.dispose && object.dispose();\n      });\n      this._objects = [];\n      if (this.backgroundImage && this.backgroundImage.dispose) {\n        this.backgroundImage.dispose();\n      }\n      this.backgroundImage = null;\n      if (this.overlayImage && this.overlayImage.dispose) {\n        this.overlayImage.dispose();\n      }\n      this.overlayImage = null;\n      this._iTextInstances = null;\n      this.contextContainer = null;\n      fabric.util.cleanUpJsdomNode(this.lowerCanvasEl);\n      this.lowerCanvasEl = undefined;\n      return this;\n    },\n\n    /**\n     * Returns a string representation of an instance\n     * @return {String} string representation of an instance\n     */\n    toString: function () {\n      return '#<fabric.Canvas (' + this.complexity() + '): ' +\n               '{ objects: ' + this._objects.length + ' }>';\n    }\n  });\n\n  extend(fabric.StaticCanvas.prototype, fabric.Observable);\n  extend(fabric.StaticCanvas.prototype, fabric.Collection);\n  extend(fabric.StaticCanvas.prototype, fabric.DataURLExporter);\n\n  extend(fabric.StaticCanvas, /** @lends fabric.StaticCanvas */ {\n\n    /**\n     * @static\n     * @type String\n     * @default\n     */\n    EMPTY_JSON: '{\"objects\": [], \"background\": \"white\"}',\n\n    /**\n     * Provides a way to check support of some of the canvas methods\n     * (either those of HTMLCanvasElement itself, or rendering context)\n     *\n     * @param {String} methodName Method to check support for;\n     *                            Could be one of \"setLineDash\"\n     * @return {Boolean | null} `true` if method is supported (or at least exists),\n     *                          `null` if canvas element or context can not be initialized\n     */\n    supports: function (methodName) {\n      var el = createCanvasElement();\n\n      if (!el || !el.getContext) {\n        return null;\n      }\n\n      var ctx = el.getContext('2d');\n      if (!ctx) {\n        return null;\n      }\n\n      switch (methodName) {\n\n        case 'setLineDash':\n          return typeof ctx.setLineDash !== 'undefined';\n\n        default:\n          return null;\n      }\n    }\n  });\n\n  /**\n   * Returns JSON representation of canvas\n   * @function\n   * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output\n   * @return {String} JSON string\n   * @tutorial {@link http://fabricjs.com/fabric-intro-part-3#serialization}\n   * @see {@link http://jsfiddle.net/fabricjs/pec86/|jsFiddle demo}\n   * @example <caption>JSON without additional properties</caption>\n   * var json = canvas.toJSON();\n   * @example <caption>JSON with additional properties included</caption>\n   * var json = canvas.toJSON(['lockMovementX', 'lockMovementY', 'lockRotation', 'lockScalingX', 'lockScalingY', 'lockUniScaling']);\n   * @example <caption>JSON without default values</caption>\n   * canvas.includeDefaultValues = false;\n   * var json = canvas.toJSON();\n   */\n  fabric.StaticCanvas.prototype.toJSON = fabric.StaticCanvas.prototype.toObject;\n\n  if (fabric.isLikelyNode) {\n    fabric.StaticCanvas.prototype.createPNGStream = function() {\n      var impl = getNodeCanvas(this.lowerCanvasEl);\n      return impl && impl.createPNGStream();\n    };\n    fabric.StaticCanvas.prototype.createJPEGStream = function(opts) {\n      var impl = getNodeCanvas(this.lowerCanvasEl);\n      return impl && impl.createJPEGStream(opts);\n    };\n  }\n})();\n\n\n/**\n * BaseBrush class\n * @class fabric.BaseBrush\n * @see {@link http://fabricjs.com/freedrawing|Freedrawing demo}\n */\nfabric.BaseBrush = fabric.util.createClass(/** @lends fabric.BaseBrush.prototype */ {\n\n  /**\n   * Color of a brush\n   * @type String\n   * @default\n   */\n  color: 'rgb(0, 0, 0)',\n\n  /**\n   * Width of a brush, has to be a Number, no string literals\n   * @type Number\n   * @default\n   */\n  width: 1,\n\n  /**\n   * Shadow object representing shadow of this shape.\n   * <b>Backwards incompatibility note:</b> This property replaces \"shadowColor\" (String), \"shadowOffsetX\" (Number),\n   * \"shadowOffsetY\" (Number) and \"shadowBlur\" (Number) since v1.2.12\n   * @type fabric.Shadow\n   * @default\n   */\n  shadow: null,\n\n  /**\n   * Line endings style of a brush (one of \"butt\", \"round\", \"square\")\n   * @type String\n   * @default\n   */\n  strokeLineCap: 'round',\n\n  /**\n   * Corner style of a brush (one of \"bevel\", \"round\", \"miter\")\n   * @type String\n   * @default\n   */\n  strokeLineJoin: 'round',\n\n  /**\n   * Maximum miter length (used for strokeLineJoin = \"miter\") of a brush's\n   * @type Number\n   * @default\n   */\n  strokeMiterLimit:         10,\n\n  /**\n   * Stroke Dash Array.\n   * @type Array\n   * @default\n   */\n  strokeDashArray: null,\n\n  /**\n   * Sets shadow of an object\n   * @param {Object|String} [options] Options object or string (e.g. \"2px 2px 10px rgba(0,0,0,0.2)\")\n   * @return {fabric.Object} thisArg\n   * @chainable\n   */\n  setShadow: function(options) {\n    this.shadow = new fabric.Shadow(options);\n    return this;\n  },\n\n  /**\n   * Sets brush styles\n   * @private\n   */\n  _setBrushStyles: function() {\n    var ctx = this.canvas.contextTop;\n    ctx.strokeStyle = this.color;\n    ctx.lineWidth = this.width;\n    ctx.lineCap = this.strokeLineCap;\n    ctx.miterLimit = this.strokeMiterLimit;\n    ctx.lineJoin = this.strokeLineJoin;\n    if (fabric.StaticCanvas.supports('setLineDash')) {\n      ctx.setLineDash(this.strokeDashArray || []);\n    }\n  },\n\n  /**\n   * Sets the transformation on given context\n   * @param {RenderingContext2d} ctx context to render on\n   * @private\n   */\n  _saveAndTransform: function(ctx) {\n    var v = this.canvas.viewportTransform;\n    ctx.save();\n    ctx.transform(v[0], v[1], v[2], v[3], v[4], v[5]);\n  },\n\n  /**\n   * Sets brush shadow styles\n   * @private\n   */\n  _setShadow: function() {\n    if (!this.shadow) {\n      return;\n    }\n\n    var ctx = this.canvas.contextTop,\n        zoom = this.canvas.getZoom();\n\n    ctx.shadowColor = this.shadow.color;\n    ctx.shadowBlur = this.shadow.blur * zoom;\n    ctx.shadowOffsetX = this.shadow.offsetX * zoom;\n    ctx.shadowOffsetY = this.shadow.offsetY * zoom;\n  },\n\n  needsFullRender: function() {\n    var color = new fabric.Color(this.color);\n    return color.getAlpha() < 1 || !!this.shadow;\n  },\n\n  /**\n   * Removes brush shadow styles\n   * @private\n   */\n  _resetShadow: function() {\n    var ctx = this.canvas.contextTop;\n\n    ctx.shadowColor = '';\n    ctx.shadowBlur = ctx.shadowOffsetX = ctx.shadowOffsetY = 0;\n  }\n});\n\n\n(function() {\n  /**\n   * PencilBrush class\n   * @class fabric.PencilBrush\n   * @extends fabric.BaseBrush\n   */\n  fabric.PencilBrush = fabric.util.createClass(fabric.BaseBrush, /** @lends fabric.PencilBrush.prototype */ {\n\n    /**\n     * Discard points that are less than `decimate` pixel distant from each other\n     * @type Number\n     * @default 0.4\n     */\n    decimate: 0.4,\n\n    /**\n     * Constructor\n     * @param {fabric.Canvas} canvas\n     * @return {fabric.PencilBrush} Instance of a pencil brush\n     */\n    initialize: function(canvas) {\n      this.canvas = canvas;\n      this._points = [];\n    },\n\n    /**\n     * Invoked inside on mouse down and mouse move\n     * @param {Object} pointer\n     */\n    _drawSegment: function (ctx, p1, p2) {\n      var midPoint = p1.midPointFrom(p2);\n      ctx.quadraticCurveTo(p1.x, p1.y, midPoint.x, midPoint.y);\n      return midPoint;\n    },\n\n    /**\n     * Inovoked on mouse down\n     * @param {Object} pointer\n     */\n    onMouseDown: function(pointer, options) {\n      if (!this.canvas._isMainEvent(options.e)) {\n        return;\n      }\n      this._prepareForDrawing(pointer);\n      // capture coordinates immediately\n      // this allows to draw dots (when movement never occurs)\n      this._captureDrawingPath(pointer);\n      this._render();\n    },\n\n    /**\n     * Inovoked on mouse move\n     * @param {Object} pointer\n     */\n    onMouseMove: function(pointer, options) {\n      if (!this.canvas._isMainEvent(options.e)) {\n        return;\n      }\n      if (this._captureDrawingPath(pointer) && this._points.length > 1) {\n        if (this.needsFullRender()) {\n          // redraw curve\n          // clear top canvas\n          this.canvas.clearContext(this.canvas.contextTop);\n          this._render();\n        }\n        else {\n          var points = this._points, length = points.length, ctx = this.canvas.contextTop;\n          // draw the curve update\n          this._saveAndTransform(ctx);\n          if (this.oldEnd) {\n            ctx.beginPath();\n            ctx.moveTo(this.oldEnd.x, this.oldEnd.y);\n          }\n          this.oldEnd = this._drawSegment(ctx, points[length - 2], points[length - 1], true);\n          ctx.stroke();\n          ctx.restore();\n        }\n      }\n    },\n\n    /**\n     * Invoked on mouse up\n     */\n    onMouseUp: function(options) {\n      if (!this.canvas._isMainEvent(options.e)) {\n        return true;\n      }\n      this.oldEnd = undefined;\n      this._finalizeAndAddPath();\n      return false;\n    },\n\n    /**\n     * @private\n     * @param {Object} pointer Actual mouse position related to the canvas.\n     */\n    _prepareForDrawing: function(pointer) {\n\n      var p = new fabric.Point(pointer.x, pointer.y);\n\n      this._reset();\n      this._addPoint(p);\n      this.canvas.contextTop.moveTo(p.x, p.y);\n    },\n\n    /**\n     * @private\n     * @param {fabric.Point} point Point to be added to points array\n     */\n    _addPoint: function(point) {\n      if (this._points.length > 1 && point.eq(this._points[this._points.length - 1])) {\n        return false;\n      }\n      this._points.push(point);\n      return true;\n    },\n\n    /**\n     * Clear points array and set contextTop canvas style.\n     * @private\n     */\n    _reset: function() {\n      this._points = [];\n      this._setBrushStyles();\n      this._setShadow();\n    },\n\n    /**\n     * @private\n     * @param {Object} pointer Actual mouse position related to the canvas.\n     */\n    _captureDrawingPath: function(pointer) {\n      var pointerPoint = new fabric.Point(pointer.x, pointer.y);\n      return this._addPoint(pointerPoint);\n    },\n\n    /**\n     * Draw a smooth path on the topCanvas using quadraticCurveTo\n     * @private\n     */\n    _render: function() {\n      var ctx  = this.canvas.contextTop, i, len,\n          p1 = this._points[0],\n          p2 = this._points[1];\n\n      this._saveAndTransform(ctx);\n      ctx.beginPath();\n      //if we only have 2 points in the path and they are the same\n      //it means that the user only clicked the canvas without moving the mouse\n      //then we should be drawing a dot. A path isn't drawn between two identical dots\n      //that's why we set them apart a bit\n      if (this._points.length === 2 && p1.x === p2.x && p1.y === p2.y) {\n        var width = this.width / 1000;\n        p1 = new fabric.Point(p1.x, p1.y);\n        p2 = new fabric.Point(p2.x, p2.y);\n        p1.x -= width;\n        p2.x += width;\n      }\n      ctx.moveTo(p1.x, p1.y);\n\n      for (i = 1, len = this._points.length; i < len; i++) {\n        // we pick the point between pi + 1 & pi + 2 as the\n        // end point and p1 as our control point.\n        this._drawSegment(ctx, p1, p2);\n        p1 = this._points[i];\n        p2 = this._points[i + 1];\n      }\n      // Draw last line as a straight line while\n      // we wait for the next point to be able to calculate\n      // the bezier control point\n      ctx.lineTo(p1.x, p1.y);\n      ctx.stroke();\n      ctx.restore();\n    },\n\n    /**\n     * Converts points to SVG path\n     * @param {Array} points Array of points\n     * @return {String} SVG path\n     */\n    convertPointsToSVGPath: function(points) {\n      var path = [], i, width = this.width / 1000,\n          p1 = new fabric.Point(points[0].x, points[0].y),\n          p2 = new fabric.Point(points[1].x, points[1].y),\n          len = points.length, multSignX = 1, multSignY = 0, manyPoints = len > 2;\n\n      if (manyPoints) {\n        multSignX = points[2].x < p2.x ? -1 : points[2].x === p2.x ? 0 : 1;\n        multSignY = points[2].y < p2.y ? -1 : points[2].y === p2.y ? 0 : 1;\n      }\n      path.push('M ', p1.x - multSignX * width, ' ', p1.y - multSignY * width, ' ');\n      for (i = 1; i < len; i++) {\n        if (!p1.eq(p2)) {\n          var midPoint = p1.midPointFrom(p2);\n          // p1 is our bezier control point\n          // midpoint is our endpoint\n          // start point is p(i-1) value.\n          path.push('Q ', p1.x, ' ', p1.y, ' ', midPoint.x, ' ', midPoint.y, ' ');\n        }\n        p1 = points[i];\n        if ((i + 1) < points.length) {\n          p2 = points[i + 1];\n        }\n      }\n      if (manyPoints) {\n        multSignX = p1.x > points[i - 2].x ? 1 : p1.x === points[i - 2].x ? 0 : -1;\n        multSignY = p1.y > points[i - 2].y ? 1 : p1.y === points[i - 2].y ? 0 : -1;\n      }\n      path.push('L ', p1.x + multSignX * width, ' ', p1.y + multSignY * width);\n      return path;\n    },\n\n    /**\n     * Creates fabric.Path object to add on canvas\n     * @param {String} pathData Path data\n     * @return {fabric.Path} Path to add on canvas\n     */\n    createPath: function(pathData) {\n      var path = new fabric.Path(pathData, {\n        fill: null,\n        stroke: this.color,\n        strokeWidth: this.width,\n        strokeLineCap: this.strokeLineCap,\n        strokeMiterLimit: this.strokeMiterLimit,\n        strokeLineJoin: this.strokeLineJoin,\n        strokeDashArray: this.strokeDashArray,\n      });\n      if (this.shadow) {\n        this.shadow.affectStroke = true;\n        path.setShadow(this.shadow);\n      }\n\n      return path;\n    },\n\n    /**\n     * Decimate poins array with the decimate value\n     */\n    decimatePoints: function(points, distance) {\n      if (points.length <= 2) {\n        return points;\n      }\n      var zoom = this.canvas.getZoom(), adjustedDistance = Math.pow(distance / zoom, 2),\n          i, l = points.length - 1, lastPoint = points[0], newPoints = [lastPoint],\n          cDistance;\n      for (i = 1; i < l; i++) {\n        cDistance = Math.pow(lastPoint.x - points[i].x, 2) + Math.pow(lastPoint.y - points[i].y, 2);\n        if (cDistance >= adjustedDistance) {\n          lastPoint = points[i];\n          newPoints.push(lastPoint);\n        }\n      }\n      if (newPoints.length === 1) {\n        newPoints.push(new fabric.Point(newPoints[0].x, newPoints[0].y));\n      }\n      return newPoints;\n    },\n\n    /**\n     * On mouseup after drawing the path on contextTop canvas\n     * we use the points captured to create an new fabric path object\n     * and add it to the fabric canvas.\n     */\n    _finalizeAndAddPath: function() {\n      var ctx = this.canvas.contextTop;\n      ctx.closePath();\n      if (this.decimate) {\n        this._points = this.decimatePoints(this._points, this.decimate);\n      }\n      var pathData = this.convertPointsToSVGPath(this._points).join('');\n      if (pathData === 'M 0 0 Q 0 0 0 0 L 0 0') {\n        // do not create 0 width/height paths, as they are\n        // rendered inconsistently across browsers\n        // Firefox 4, for example, renders a dot,\n        // whereas Chrome 10 renders nothing\n        this.canvas.requestRenderAll();\n        return;\n      }\n\n      var path = this.createPath(pathData);\n      this.canvas.clearContext(this.canvas.contextTop);\n      this.canvas.add(path);\n      this.canvas.renderAll();\n      path.setCoords();\n      this._resetShadow();\n\n\n      // fire event 'path' created\n      this.canvas.fire('path:created', { path: path });\n    }\n  });\n})();\n\n\n/**\n * CircleBrush class\n * @class fabric.CircleBrush\n */\nfabric.CircleBrush = fabric.util.createClass(fabric.BaseBrush, /** @lends fabric.CircleBrush.prototype */ {\n\n  /**\n   * Width of a brush\n   * @type Number\n   * @default\n   */\n  width: 10,\n\n  /**\n   * Constructor\n   * @param {fabric.Canvas} canvas\n   * @return {fabric.CircleBrush} Instance of a circle brush\n   */\n  initialize: function(canvas) {\n    this.canvas = canvas;\n    this.points = [];\n  },\n\n  /**\n   * Invoked inside on mouse down and mouse move\n   * @param {Object} pointer\n   */\n  drawDot: function(pointer) {\n    var point = this.addPoint(pointer),\n        ctx = this.canvas.contextTop;\n    this._saveAndTransform(ctx);\n    this.dot(ctx, point);\n    ctx.restore();\n  },\n\n  dot: function(ctx, point) {\n    ctx.fillStyle = point.fill;\n    ctx.beginPath();\n    ctx.arc(point.x, point.y, point.radius, 0, Math.PI * 2, false);\n    ctx.closePath();\n    ctx.fill();\n  },\n\n  /**\n   * Invoked on mouse down\n   */\n  onMouseDown: function(pointer) {\n    this.points.length = 0;\n    this.canvas.clearContext(this.canvas.contextTop);\n    this._setShadow();\n    this.drawDot(pointer);\n  },\n\n  /**\n   * Render the full state of the brush\n   * @private\n   */\n  _render: function() {\n    var ctx  = this.canvas.contextTop, i, len,\n        points = this.points;\n    this._saveAndTransform(ctx);\n    for (i = 0, len = points.length; i < len; i++) {\n      this.dot(ctx, points[i]);\n    }\n    ctx.restore();\n  },\n\n  /**\n   * Invoked on mouse move\n   * @param {Object} pointer\n   */\n  onMouseMove: function(pointer) {\n    if (this.needsFullRender()) {\n      this.canvas.clearContext(this.canvas.contextTop);\n      this.addPoint(pointer);\n      this._render();\n    }\n    else {\n      this.drawDot(pointer);\n    }\n  },\n\n  /**\n   * Invoked on mouse up\n   */\n  onMouseUp: function() {\n    var originalRenderOnAddRemove = this.canvas.renderOnAddRemove, i, len;\n    this.canvas.renderOnAddRemove = false;\n\n    var circles = [];\n\n    for (i = 0, len = this.points.length; i < len; i++) {\n      var point = this.points[i],\n          circle = new fabric.Circle({\n            radius: point.radius,\n            left: point.x,\n            top: point.y,\n            originX: 'center',\n            originY: 'center',\n            fill: point.fill\n          });\n\n      this.shadow && circle.setShadow(this.shadow);\n\n      circles.push(circle);\n    }\n    var group = new fabric.Group(circles);\n    group.canvas = this.canvas;\n\n    this.canvas.add(group);\n    this.canvas.fire('path:created', { path: group });\n\n    this.canvas.clearContext(this.canvas.contextTop);\n    this._resetShadow();\n    this.canvas.renderOnAddRemove = originalRenderOnAddRemove;\n    this.canvas.requestRenderAll();\n  },\n\n  /**\n   * @param {Object} pointer\n   * @return {fabric.Point} Just added pointer point\n   */\n  addPoint: function(pointer) {\n    var pointerPoint = new fabric.Point(pointer.x, pointer.y),\n\n        circleRadius = fabric.util.getRandomInt(\n          Math.max(0, this.width - 20), this.width + 20) / 2,\n\n        circleColor = new fabric.Color(this.color)\n          .setAlpha(fabric.util.getRandomInt(0, 100) / 100)\n          .toRgba();\n\n    pointerPoint.radius = circleRadius;\n    pointerPoint.fill = circleColor;\n\n    this.points.push(pointerPoint);\n\n    return pointerPoint;\n  }\n});\n\n\n/**\n * SprayBrush class\n * @class fabric.SprayBrush\n */\nfabric.SprayBrush = fabric.util.createClass( fabric.BaseBrush, /** @lends fabric.SprayBrush.prototype */ {\n\n  /**\n   * Width of a spray\n   * @type Number\n   * @default\n   */\n  width:              10,\n\n  /**\n   * Density of a spray (number of dots per chunk)\n   * @type Number\n   * @default\n   */\n  density:            20,\n\n  /**\n   * Width of spray dots\n   * @type Number\n   * @default\n   */\n  dotWidth:           1,\n\n  /**\n   * Width variance of spray dots\n   * @type Number\n   * @default\n   */\n  dotWidthVariance:   1,\n\n  /**\n   * Whether opacity of a dot should be random\n   * @type Boolean\n   * @default\n   */\n  randomOpacity:        false,\n\n  /**\n   * Whether overlapping dots (rectangles) should be removed (for performance reasons)\n   * @type Boolean\n   * @default\n   */\n  optimizeOverlapping:  true,\n\n  /**\n   * Constructor\n   * @param {fabric.Canvas} canvas\n   * @return {fabric.SprayBrush} Instance of a spray brush\n   */\n  initialize: function(canvas) {\n    this.canvas = canvas;\n    this.sprayChunks = [];\n  },\n\n  /**\n   * Invoked on mouse down\n   * @param {Object} pointer\n   */\n  onMouseDown: function(pointer) {\n    this.sprayChunks.length = 0;\n    this.canvas.clearContext(this.canvas.contextTop);\n    this._setShadow();\n\n    this.addSprayChunk(pointer);\n    this.render(this.sprayChunkPoints);\n  },\n\n  /**\n   * Invoked on mouse move\n   * @param {Object} pointer\n   */\n  onMouseMove: function(pointer) {\n    this.addSprayChunk(pointer);\n    this.render(this.sprayChunkPoints);\n  },\n\n  /**\n   * Invoked on mouse up\n   */\n  onMouseUp: function() {\n    var originalRenderOnAddRemove = this.canvas.renderOnAddRemove;\n    this.canvas.renderOnAddRemove = false;\n\n    var rects = [];\n\n    for (var i = 0, ilen = this.sprayChunks.length; i < ilen; i++) {\n      var sprayChunk = this.sprayChunks[i];\n\n      for (var j = 0, jlen = sprayChunk.length; j < jlen; j++) {\n\n        var rect = new fabric.Rect({\n          width: sprayChunk[j].width,\n          height: sprayChunk[j].width,\n          left: sprayChunk[j].x + 1,\n          top: sprayChunk[j].y + 1,\n          originX: 'center',\n          originY: 'center',\n          fill: this.color\n        });\n        rects.push(rect);\n      }\n    }\n\n    if (this.optimizeOverlapping) {\n      rects = this._getOptimizedRects(rects);\n    }\n\n    var group = new fabric.Group(rects);\n    this.shadow && group.setShadow(this.shadow);\n    this.canvas.add(group);\n    this.canvas.fire('path:created', { path: group });\n\n    this.canvas.clearContext(this.canvas.contextTop);\n    this._resetShadow();\n    this.canvas.renderOnAddRemove = originalRenderOnAddRemove;\n    this.canvas.requestRenderAll();\n  },\n\n  /**\n   * @private\n   * @param {Array} rects\n   */\n  _getOptimizedRects: function(rects) {\n\n    // avoid creating duplicate rects at the same coordinates\n    var uniqueRects = { }, key, i, len;\n\n    for (i = 0, len = rects.length; i < len; i++) {\n      key = rects[i].left + '' + rects[i].top;\n      if (!uniqueRects[key]) {\n        uniqueRects[key] = rects[i];\n      }\n    }\n    var uniqueRectsArray = [];\n    for (key in uniqueRects) {\n      uniqueRectsArray.push(uniqueRects[key]);\n    }\n\n    return uniqueRectsArray;\n  },\n\n  /**\n   * Render new chunk of spray brush\n   */\n  render: function(sprayChunk) {\n    var ctx = this.canvas.contextTop, i, len;\n    ctx.fillStyle = this.color;\n\n    this._saveAndTransform(ctx);\n\n    for (i = 0, len = sprayChunk.length; i < len; i++) {\n      var point = sprayChunk[i];\n      if (typeof point.opacity !== 'undefined') {\n        ctx.globalAlpha = point.opacity;\n      }\n      ctx.fillRect(point.x, point.y, point.width, point.width);\n    }\n    ctx.restore();\n  },\n\n  /**\n   * Render all spray chunks\n   */\n  _render: function() {\n    var ctx = this.canvas.contextTop, i, ilen;\n    ctx.fillStyle = this.color;\n\n    this._saveAndTransform(ctx);\n\n    for (i = 0, ilen = this.sprayChunks.length; i < ilen; i++) {\n      this.render(this.sprayChunks[i]);\n    }\n    ctx.restore();\n  },\n\n  /**\n   * @param {Object} pointer\n   */\n  addSprayChunk: function(pointer) {\n    this.sprayChunkPoints = [];\n\n    var x, y, width, radius = this.width / 2, i;\n\n    for (i = 0; i < this.density; i++) {\n\n      x = fabric.util.getRandomInt(pointer.x - radius, pointer.x + radius);\n      y = fabric.util.getRandomInt(pointer.y - radius, pointer.y + radius);\n\n      if (this.dotWidthVariance) {\n        width = fabric.util.getRandomInt(\n          // bottom clamp width to 1\n          Math.max(1, this.dotWidth - this.dotWidthVariance),\n          this.dotWidth + this.dotWidthVariance);\n      }\n      else {\n        width = this.dotWidth;\n      }\n\n      var point = new fabric.Point(x, y);\n      point.width = width;\n\n      if (this.randomOpacity) {\n        point.opacity = fabric.util.getRandomInt(0, 100) / 100;\n      }\n\n      this.sprayChunkPoints.push(point);\n    }\n\n    this.sprayChunks.push(this.sprayChunkPoints);\n  }\n});\n\n\n/**\n * PatternBrush class\n * @class fabric.PatternBrush\n * @extends fabric.BaseBrush\n */\nfabric.PatternBrush = fabric.util.createClass(fabric.PencilBrush, /** @lends fabric.PatternBrush.prototype */ {\n\n  getPatternSrc: function() {\n\n    var dotWidth = 20,\n        dotDistance = 5,\n        patternCanvas = fabric.util.createCanvasElement(),\n        patternCtx = patternCanvas.getContext('2d');\n\n    patternCanvas.width = patternCanvas.height = dotWidth + dotDistance;\n\n    patternCtx.fillStyle = this.color;\n    patternCtx.beginPath();\n    patternCtx.arc(dotWidth / 2, dotWidth / 2, dotWidth / 2, 0, Math.PI * 2, false);\n    patternCtx.closePath();\n    patternCtx.fill();\n\n    return patternCanvas;\n  },\n\n  getPatternSrcFunction: function() {\n    return String(this.getPatternSrc).replace('this.color', '\"' + this.color + '\"');\n  },\n\n  /**\n   * Creates \"pattern\" instance property\n   */\n  getPattern: function() {\n    return this.canvas.contextTop.createPattern(this.source || this.getPatternSrc(), 'repeat');\n  },\n\n  /**\n   * Sets brush styles\n   */\n  _setBrushStyles: function() {\n    this.callSuper('_setBrushStyles');\n    this.canvas.contextTop.strokeStyle = this.getPattern();\n  },\n\n  /**\n   * Creates path\n   */\n  createPath: function(pathData) {\n    var path = this.callSuper('createPath', pathData),\n        topLeft = path._getLeftTopCoords().scalarAdd(path.strokeWidth / 2);\n\n    path.stroke = new fabric.Pattern({\n      source: this.source || this.getPatternSrcFunction(),\n      offsetX: -topLeft.x,\n      offsetY: -topLeft.y\n    });\n    return path;\n  }\n});\n\n\n(function() {\n\n  var getPointer = fabric.util.getPointer,\n      degreesToRadians = fabric.util.degreesToRadians,\n      radiansToDegrees = fabric.util.radiansToDegrees,\n      atan2 = Math.atan2,\n      abs = Math.abs,\n      supportLineDash = fabric.StaticCanvas.supports('setLineDash'),\n\n      STROKE_OFFSET = 0.5;\n\n  /**\n   * Canvas class\n   * @class fabric.Canvas\n   * @extends fabric.StaticCanvas\n   * @tutorial {@link http://fabricjs.com/fabric-intro-part-1#canvas}\n   * @see {@link fabric.Canvas#initialize} for constructor definition\n   *\n   * @fires object:modified\n   * @fires object:rotated\n   * @fires object:scaled\n   * @fires object:moved\n   * @fires object:skewed\n   * @fires object:rotating\n   * @fires object:scaling\n   * @fires object:moving\n   * @fires object:skewing\n   * @fires object:selected this event is deprecated. use selection:created\n   *\n   * @fires before:transform\n   * @fires before:selection:cleared\n   * @fires selection:cleared\n   * @fires selection:updated\n   * @fires selection:created\n   *\n   * @fires path:created\n   * @fires mouse:down\n   * @fires mouse:move\n   * @fires mouse:up\n   * @fires mouse:down:before\n   * @fires mouse:move:before\n   * @fires mouse:up:before\n   * @fires mouse:over\n   * @fires mouse:out\n   * @fires mouse:dblclick\n   *\n   * @fires dragover\n   * @fires dragenter\n   * @fires dragleave\n   * @fires drop\n   *\n   */\n  fabric.Canvas = fabric.util.createClass(fabric.StaticCanvas, /** @lends fabric.Canvas.prototype */ {\n\n    /**\n     * Constructor\n     * @param {HTMLElement | String} el &lt;canvas> element to initialize instance on\n     * @param {Object} [options] Options object\n     * @return {Object} thisArg\n     */\n    initialize: function(el, options) {\n      options || (options = { });\n      this.renderAndResetBound = this.renderAndReset.bind(this);\n      this.requestRenderAllBound = this.requestRenderAll.bind(this);\n      this._initStatic(el, options);\n      this._initInteractive();\n      this._createCacheCanvas();\n    },\n\n    /**\n     * When true, objects can be transformed by one side (unproportionally)\n     * @type Boolean\n     * @default\n     */\n    uniScaleTransform:      false,\n\n    /**\n     * Indicates which key enable unproportional scaling\n     * values: 'altKey', 'shiftKey', 'ctrlKey'.\n     * If `null` or 'none' or any other string that is not a modifier key\n     * feature is disabled feature disabled.\n     * @since 1.6.2\n     * @type String\n     * @default\n     */\n    uniScaleKey:           'shiftKey',\n\n    /**\n     * When true, objects use center point as the origin of scale transformation.\n     * <b>Backwards incompatibility note:</b> This property replaces \"centerTransform\" (Boolean).\n     * @since 1.3.4\n     * @type Boolean\n     * @default\n     */\n    centeredScaling:        false,\n\n    /**\n     * When true, objects use center point as the origin of rotate transformation.\n     * <b>Backwards incompatibility note:</b> This property replaces \"centerTransform\" (Boolean).\n     * @since 1.3.4\n     * @type Boolean\n     * @default\n     */\n    centeredRotation:       false,\n\n    /**\n     * Indicates which key enable centered Transform\n     * values: 'altKey', 'shiftKey', 'ctrlKey'.\n     * If `null` or 'none' or any other string that is not a modifier key\n     * feature is disabled feature disabled.\n     * @since 1.6.2\n     * @type String\n     * @default\n     */\n    centeredKey:           'altKey',\n\n    /**\n     * Indicates which key enable alternate action on corner\n     * values: 'altKey', 'shiftKey', 'ctrlKey'.\n     * If `null` or 'none' or any other string that is not a modifier key\n     * feature is disabled feature disabled.\n     * @since 1.6.2\n     * @type String\n     * @default\n     */\n    altActionKey:           'shiftKey',\n\n    /**\n     * Indicates that canvas is interactive. This property should not be changed.\n     * @type Boolean\n     * @default\n     */\n    interactive:            true,\n\n    /**\n     * Indicates whether group selection should be enabled\n     * @type Boolean\n     * @default\n     */\n    selection:              true,\n\n    /**\n     * Indicates which key or keys enable multiple click selection\n     * Pass value as a string or array of strings\n     * values: 'altKey', 'shiftKey', 'ctrlKey'.\n     * If `null` or empty or containing any other string that is not a modifier key\n     * feature is disabled.\n     * @since 1.6.2\n     * @type String|Array\n     * @default\n     */\n    selectionKey:           'shiftKey',\n\n    /**\n     * Indicates which key enable alternative selection\n     * in case of target overlapping with active object\n     * values: 'altKey', 'shiftKey', 'ctrlKey'.\n     * For a series of reason that come from the general expectations on how\n     * things should work, this feature works only for preserveObjectStacking true.\n     * If `null` or 'none' or any other string that is not a modifier key\n     * feature is disabled.\n     * @since 1.6.5\n     * @type null|String\n     * @default\n     */\n    altSelectionKey:           null,\n\n    /**\n     * Color of selection\n     * @type String\n     * @default\n     */\n    selectionColor:         'rgba(100, 100, 255, 0.3)', // blue\n\n    /**\n     * Default dash array pattern\n     * If not empty the selection border is dashed\n     * @type Array\n     */\n    selectionDashArray:     [],\n\n    /**\n     * Color of the border of selection (usually slightly darker than color of selection itself)\n     * @type String\n     * @default\n     */\n    selectionBorderColor:   'rgba(255, 255, 255, 0.3)',\n\n    /**\n     * Width of a line used in object/group selection\n     * @type Number\n     * @default\n     */\n    selectionLineWidth:     1,\n\n    /**\n     * Select only shapes that are fully contained in the dragged selection rectangle.\n     * @type Boolean\n     * @default\n     */\n    selectionFullyContained: false,\n\n    /**\n     * Default cursor value used when hovering over an object on canvas\n     * @type String\n     * @default\n     */\n    hoverCursor:            'move',\n\n    /**\n     * Default cursor value used when moving an object on canvas\n     * @type String\n     * @default\n     */\n    moveCursor:             'move',\n\n    /**\n     * Default cursor value used for the entire canvas\n     * @type String\n     * @default\n     */\n    defaultCursor:          'default',\n\n    /**\n     * Cursor value used during free drawing\n     * @type String\n     * @default\n     */\n    freeDrawingCursor:      'crosshair',\n\n    /**\n     * Cursor value used for rotation point\n     * @type String\n     * @default\n     */\n    rotationCursor:         'crosshair',\n\n    /**\n     * Cursor value used for disabled elements ( corners with disabled action )\n     * @type String\n     * @since 2.0.0\n     * @default\n     */\n    notAllowedCursor:         'not-allowed',\n\n    /**\n     * Default element class that's given to wrapper (div) element of canvas\n     * @type String\n     * @default\n     */\n    containerClass:         'canvas-container',\n\n    /**\n     * When true, object detection happens on per-pixel basis rather than on per-bounding-box\n     * @type Boolean\n     * @default\n     */\n    perPixelTargetFind:     false,\n\n    /**\n     * Number of pixels around target pixel to tolerate (consider active) during object detection\n     * @type Number\n     * @default\n     */\n    targetFindTolerance:    0,\n\n    /**\n     * When true, target detection is skipped when hovering over canvas. This can be used to improve performance.\n     * @type Boolean\n     * @default\n     */\n    skipTargetFind:         false,\n\n    /**\n     * When true, mouse events on canvas (mousedown/mousemove/mouseup) result in free drawing.\n     * After mousedown, mousemove creates a shape,\n     * and then mouseup finalizes it and adds an instance of `fabric.Path` onto canvas.\n     * @tutorial {@link http://fabricjs.com/fabric-intro-part-4#free_drawing}\n     * @type Boolean\n     * @default\n     */\n    isDrawingMode:          false,\n\n    /**\n     * Indicates whether objects should remain in current stack position when selected.\n     * When false objects are brought to top and rendered as part of the selection group\n     * @type Boolean\n     * @default\n     */\n    preserveObjectStacking: false,\n\n    /**\n     * Indicates the angle that an object will lock to while rotating.\n     * @type Number\n     * @since 1.6.7\n     * @default\n     */\n    snapAngle: 0,\n\n    /**\n     * Indicates the distance from the snapAngle the rotation will lock to the snapAngle.\n     * When `null`, the snapThreshold will default to the snapAngle.\n     * @type null|Number\n     * @since 1.6.7\n     * @default\n     */\n    snapThreshold: null,\n\n    /**\n     * Indicates if the right click on canvas can output the context menu or not\n     * @type Boolean\n     * @since 1.6.5\n     * @default\n     */\n    stopContextMenu: false,\n\n    /**\n     * Indicates if the canvas can fire right click events\n     * @type Boolean\n     * @since 1.6.5\n     * @default\n     */\n    fireRightClick: false,\n\n    /**\n     * Indicates if the canvas can fire middle click events\n     * @type Boolean\n     * @since 1.7.8\n     * @default\n     */\n    fireMiddleClick: false,\n\n    /**\n     * @private\n     */\n    _initInteractive: function() {\n      this._currentTransform = null;\n      this._groupSelector = null;\n      this._initWrapperElement();\n      this._createUpperCanvas();\n      this._initEventListeners();\n\n      this._initRetinaScaling();\n\n      this.freeDrawingBrush = fabric.PencilBrush && new fabric.PencilBrush(this);\n\n      this.calcOffset();\n    },\n\n    /**\n     * Divides objects in two groups, one to render immediately\n     * and one to render as activeGroup.\n     * @return {Array} objects to render immediately and pushes the other in the activeGroup.\n     */\n    _chooseObjectsToRender: function() {\n      var activeObjects = this.getActiveObjects(),\n          object, objsToRender, activeGroupObjects;\n\n      if (activeObjects.length > 0 && !this.preserveObjectStacking) {\n        objsToRender = [];\n        activeGroupObjects = [];\n        for (var i = 0, length = this._objects.length; i < length; i++) {\n          object = this._objects[i];\n          if (activeObjects.indexOf(object) === -1 ) {\n            objsToRender.push(object);\n          }\n          else {\n            activeGroupObjects.push(object);\n          }\n        }\n        if (activeObjects.length > 1) {\n          this._activeObject._objects = activeGroupObjects;\n        }\n        objsToRender.push.apply(objsToRender, activeGroupObjects);\n      }\n      else {\n        objsToRender = this._objects;\n      }\n      return objsToRender;\n    },\n\n    /**\n     * Renders both the top canvas and the secondary container canvas.\n     * @return {fabric.Canvas} instance\n     * @chainable\n     */\n    renderAll: function () {\n      if (this.contextTopDirty && !this._groupSelector && !this.isDrawingMode) {\n        this.clearContext(this.contextTop);\n        this.contextTopDirty = false;\n      }\n      if (this.hasLostContext) {\n        this.renderTopLayer(this.contextTop);\n      }\n      var canvasToDrawOn = this.contextContainer;\n      this.renderCanvas(canvasToDrawOn, this._chooseObjectsToRender());\n      return this;\n    },\n\n    renderTopLayer: function(ctx) {\n      ctx.save();\n      if (this.isDrawingMode && this._isCurrentlyDrawing) {\n        this.freeDrawingBrush && this.freeDrawingBrush._render();\n        this.contextTopDirty = true;\n      }\n      // we render the top context - last object\n      if (this.selection && this._groupSelector) {\n        this._drawSelection(ctx);\n        this.contextTopDirty = true;\n      }\n      ctx.restore();\n    },\n\n    /**\n     * Method to render only the top canvas.\n     * Also used to render the group selection box.\n     * @return {fabric.Canvas} thisArg\n     * @chainable\n     */\n    renderTop: function () {\n      var ctx = this.contextTop;\n      this.clearContext(ctx);\n      this.renderTopLayer(ctx);\n      this.fire('after:render');\n      return this;\n    },\n\n    /**\n     * Resets the current transform to its original values and chooses the type of resizing based on the event\n     * @private\n     */\n    _resetCurrentTransform: function() {\n      var t = this._currentTransform;\n\n      t.target.set({\n        scaleX: t.original.scaleX,\n        scaleY: t.original.scaleY,\n        skewX: t.original.skewX,\n        skewY: t.original.skewY,\n        left: t.original.left,\n        top: t.original.top\n      });\n\n      if (this._shouldCenterTransform(t.target)) {\n        if (t.originX !== 'center') {\n          if (t.originX === 'right') {\n            t.mouseXSign = -1;\n          }\n          else {\n            t.mouseXSign = 1;\n          }\n        }\n        if (t.originY !== 'center') {\n          if (t.originY === 'bottom') {\n            t.mouseYSign = -1;\n          }\n          else {\n            t.mouseYSign = 1;\n          }\n        }\n\n        t.originX = 'center';\n        t.originY = 'center';\n      }\n      else {\n        t.originX = t.original.originX;\n        t.originY = t.original.originY;\n      }\n    },\n\n    /**\n     * Checks if point is contained within an area of given object\n     * @param {Event} e Event object\n     * @param {fabric.Object} target Object to test against\n     * @param {Object} [point] x,y object of point coordinates we want to check.\n     * @return {Boolean} true if point is contained within an area of given object\n     */\n    containsPoint: function (e, target, point) {\n      var ignoreZoom = true,\n          pointer = point || this.getPointer(e, ignoreZoom),\n          xy;\n\n      if (target.group && target.group === this._activeObject && target.group.type === 'activeSelection') {\n        xy = this._normalizePointer(target.group, pointer);\n      }\n      else {\n        xy = { x: pointer.x, y: pointer.y };\n      }\n      // http://www.geog.ubc.ca/courses/klink/gis.notes/ncgia/u32.html\n      // http://idav.ucdavis.edu/~okreylos/TAship/Spring2000/PointInPolygon.html\n      return (target.containsPoint(xy) || target._findTargetCorner(pointer));\n    },\n\n    /**\n     * @private\n     */\n    _normalizePointer: function (object, pointer) {\n      var m = object.calcTransformMatrix(),\n          invertedM = fabric.util.invertTransform(m),\n          vptPointer = this.restorePointerVpt(pointer);\n      return fabric.util.transformPoint(vptPointer, invertedM);\n    },\n\n    /**\n     * Returns true if object is transparent at a certain location\n     * @param {fabric.Object} target Object to check\n     * @param {Number} x Left coordinate\n     * @param {Number} y Top coordinate\n     * @return {Boolean}\n     */\n    isTargetTransparent: function (target, x, y) {\n      // in case the target is the activeObject, we cannot execute this optimization\n      // because we need to draw controls too.\n      if (target.shouldCache() && target._cacheCanvas && target !== this._activeObject) {\n        var normalizedPointer = this._normalizePointer(target, {x: x, y: y}),\n            targetRelativeX = Math.max(target.cacheTranslationX + (normalizedPointer.x * target.zoomX), 0),\n            targetRelativeY = Math.max(target.cacheTranslationY + (normalizedPointer.y * target.zoomY), 0);\n\n        var isTransparent = fabric.util.isTransparent(\n          target._cacheContext, Math.round(targetRelativeX), Math.round(targetRelativeY), this.targetFindTolerance);\n\n        return isTransparent;\n      }\n\n      var ctx = this.contextCache,\n          originalColor = target.selectionBackgroundColor, v = this.viewportTransform;\n\n      target.selectionBackgroundColor = '';\n\n      this.clearContext(ctx);\n\n      ctx.save();\n      ctx.transform(v[0], v[1], v[2], v[3], v[4], v[5]);\n      target.render(ctx);\n      ctx.restore();\n\n      target === this._activeObject && target._renderControls(ctx, {\n        hasBorders: false,\n        transparentCorners: false\n      }, {\n        hasBorders: false,\n      });\n\n      target.selectionBackgroundColor = originalColor;\n\n      var isTransparent = fabric.util.isTransparent(\n        ctx, x, y, this.targetFindTolerance);\n\n      return isTransparent;\n    },\n\n    /**\n     * takes an event and determins if selection key has been pressed\n     * @private\n     * @param {Event} e Event object\n     */\n    _isSelectionKeyPressed: function(e) {\n      var selectionKeyPressed = false;\n\n      if (Object.prototype.toString.call(this.selectionKey) === '[object Array]') {\n        selectionKeyPressed = !!this.selectionKey.find(function(key) { return e[key] === true; });\n      }\n      else {\n        selectionKeyPressed = e[this.selectionKey];\n      }\n\n      return selectionKeyPressed;\n    },\n\n    /**\n     * @private\n     * @param {Event} e Event object\n     * @param {fabric.Object} target\n     */\n    _shouldClearSelection: function (e, target) {\n      var activeObjects = this.getActiveObjects(),\n          activeObject = this._activeObject;\n\n      return (\n        !target\n        ||\n        (target &&\n          activeObject &&\n          activeObjects.length > 1 &&\n          activeObjects.indexOf(target) === -1 &&\n          activeObject !== target &&\n          !this._isSelectionKeyPressed(e))\n        ||\n        (target && !target.evented)\n        ||\n        (target &&\n          !target.selectable &&\n          activeObject &&\n          activeObject !== target)\n      );\n    },\n\n    /**\n     * centeredScaling from object can't override centeredScaling from canvas.\n     * this should be fixed, since object setting should take precedence over canvas.\n     * @private\n     * @param {fabric.Object} target\n     */\n    _shouldCenterTransform: function (target) {\n      if (!target) {\n        return;\n      }\n\n      var t = this._currentTransform,\n          centerTransform;\n\n      if (t.action === 'scale' || t.action === 'scaleX' || t.action === 'scaleY') {\n        centerTransform = this.centeredScaling || target.centeredScaling;\n      }\n      else if (t.action === 'rotate') {\n        centerTransform = this.centeredRotation || target.centeredRotation;\n      }\n\n      return centerTransform ? !t.altKey : t.altKey;\n    },\n\n    /**\n     * @private\n     */\n    _getOriginFromCorner: function(target, corner) {\n      var origin = {\n        x: target.originX,\n        y: target.originY\n      };\n\n      if (corner === 'ml' || corner === 'tl' || corner === 'bl') {\n        origin.x = 'right';\n      }\n      else if (corner === 'mr' || corner === 'tr' || corner === 'br') {\n        origin.x = 'left';\n      }\n\n      if (corner === 'tl' || corner === 'mt' || corner === 'tr') {\n        origin.y = 'bottom';\n      }\n      else if (corner === 'bl' || corner === 'mb' || corner === 'br') {\n        origin.y = 'top';\n      }\n\n      return origin;\n    },\n\n    /**\n     * @private\n     * @param {Boolean} alreadySelected true if target is already selected\n     * @param {String} corner a string representing the corner ml, mr, tl ...\n     * @param {Event} e Event object\n     * @param {fabric.Object} [target] inserted back to help overriding. Unused\n     */\n    _getActionFromCorner: function(alreadySelected, corner, e /* target */) {\n      if (!corner || !alreadySelected) {\n        return 'drag';\n      }\n\n      switch (corner) {\n        case 'mtr':\n          return 'rotate';\n        case 'ml':\n        case 'mr':\n          return e[this.altActionKey] ? 'skewY' : 'scaleX';\n        case 'mt':\n        case 'mb':\n          return e[this.altActionKey] ? 'skewX' : 'scaleY';\n        default:\n          return 'scale';\n      }\n    },\n\n    /**\n     * @private\n     * @param {Event} e Event object\n     * @param {fabric.Object} target\n     */\n    _setupCurrentTransform: function (e, target, alreadySelected) {\n      if (!target) {\n        return;\n      }\n\n      var pointer = this.getPointer(e),\n          corner = target._findTargetCorner(this.getPointer(e, true)),\n          action = this._getActionFromCorner(alreadySelected, corner, e, target),\n          origin = this._getOriginFromCorner(target, corner);\n\n      this._currentTransform = {\n        target: target,\n        action: action,\n        corner: corner,\n        scaleX: target.scaleX,\n        scaleY: target.scaleY,\n        skewX: target.skewX,\n        skewY: target.skewY,\n        // used by transation\n        offsetX: pointer.x - target.left,\n        offsetY: pointer.y - target.top,\n        originX: origin.x,\n        originY: origin.y,\n        ex: pointer.x,\n        ey: pointer.y,\n        lastX: pointer.x,\n        lastY: pointer.y,\n        // unsure they are usefull anymore.\n        // left: target.left,\n        // top: target.top,\n        theta: degreesToRadians(target.angle),\n        // end of unsure\n        width: target.width * target.scaleX,\n        mouseXSign: 1,\n        mouseYSign: 1,\n        shiftKey: e.shiftKey,\n        altKey: e[this.centeredKey],\n        original: fabric.util.saveObjectTransform(target),\n      };\n\n      this._currentTransform.original.originX = origin.x;\n      this._currentTransform.original.originY = origin.y;\n\n      this._resetCurrentTransform();\n      this._beforeTransform(e);\n    },\n\n    /**\n     * Translates object by \"setting\" its left/top\n     * @private\n     * @param {Number} x pointer's x coordinate\n     * @param {Number} y pointer's y coordinate\n     * @return {Boolean} true if the translation occurred\n     */\n    _translateObject: function (x, y) {\n      var transform = this._currentTransform,\n          target = transform.target,\n          newLeft = x - transform.offsetX,\n          newTop = y - transform.offsetY,\n          moveX = !target.get('lockMovementX') && target.left !== newLeft,\n          moveY = !target.get('lockMovementY') && target.top !== newTop;\n\n      moveX && target.set('left', newLeft);\n      moveY && target.set('top', newTop);\n      return moveX || moveY;\n    },\n\n    /**\n     * Check if we are increasing a positive skew or lower it,\n     * checking mouse direction and pressed corner.\n     * @private\n     */\n    _changeSkewTransformOrigin: function(mouseMove, t, by) {\n      var property = 'originX', origins = { 0: 'center' },\n          skew = t.target.skewX, originA = 'left', originB = 'right',\n          corner = t.corner === 'mt' || t.corner === 'ml' ? 1 : -1,\n          flipSign = 1;\n\n      mouseMove = mouseMove > 0 ? 1 : -1;\n      if (by === 'y') {\n        skew = t.target.skewY;\n        originA = 'top';\n        originB = 'bottom';\n        property = 'originY';\n      }\n      origins[-1] = originA;\n      origins[1] = originB;\n\n      t.target.flipX && (flipSign *= -1);\n      t.target.flipY && (flipSign *= -1);\n\n      if (skew === 0) {\n        t.skewSign = -corner * mouseMove * flipSign;\n        t[property] = origins[-mouseMove];\n      }\n      else {\n        skew = skew > 0 ? 1 : -1;\n        t.skewSign = skew;\n        t[property] = origins[skew * corner * flipSign];\n      }\n    },\n\n    /**\n     * Skew object by mouse events\n     * @private\n     * @param {Number} x pointer's x coordinate\n     * @param {Number} y pointer's y coordinate\n     * @param {String} by Either 'x' or 'y'\n     * @return {Boolean} true if the skewing occurred\n     */\n    _skewObject: function (x, y, by) {\n      var t = this._currentTransform,\n          target = t.target, skewed = false,\n          lockSkewingX = target.get('lockSkewingX'),\n          lockSkewingY = target.get('lockSkewingY');\n\n      if ((lockSkewingX && by === 'x') || (lockSkewingY && by === 'y')) {\n        return false;\n      }\n\n      // Get the constraint point\n      var center = target.getCenterPoint(),\n          actualMouseByCenter = target.toLocalPoint(new fabric.Point(x, y), 'center', 'center')[by],\n          lastMouseByCenter = target.toLocalPoint(new fabric.Point(t.lastX, t.lastY), 'center', 'center')[by],\n          actualMouseByOrigin, constraintPosition, dim = target._getTransformedDimensions();\n\n      this._changeSkewTransformOrigin(actualMouseByCenter - lastMouseByCenter, t, by);\n      actualMouseByOrigin = target.toLocalPoint(new fabric.Point(x, y), t.originX, t.originY)[by];\n      constraintPosition = target.translateToOriginPoint(center, t.originX, t.originY);\n      // Actually skew the object\n      skewed = this._setObjectSkew(actualMouseByOrigin, t, by, dim);\n      t.lastX = x;\n      t.lastY = y;\n      // Make sure the constraints apply\n      target.setPositionByOrigin(constraintPosition, t.originX, t.originY);\n      return skewed;\n    },\n\n    /**\n     * Set object skew\n     * @private\n     * @return {Boolean} true if the skewing occurred\n     */\n    _setObjectSkew: function(localMouse, transform, by, _dim) {\n      var target = transform.target, newValue, skewed = false,\n          skewSign = transform.skewSign, newDim, dimNoSkew,\n          otherBy, _otherBy, _by, newDimMouse, skewX, skewY;\n\n      if (by === 'x') {\n        otherBy = 'y';\n        _otherBy = 'Y';\n        _by = 'X';\n        skewX = 0;\n        skewY = target.skewY;\n      }\n      else {\n        otherBy = 'x';\n        _otherBy = 'X';\n        _by = 'Y';\n        skewX = target.skewX;\n        skewY = 0;\n      }\n\n      dimNoSkew = target._getTransformedDimensions(skewX, skewY);\n      newDimMouse = 2 * Math.abs(localMouse) - dimNoSkew[by];\n      if (newDimMouse <= 2) {\n        newValue = 0;\n      }\n      else {\n        newValue = skewSign * Math.atan((newDimMouse / target['scale' + _by]) /\n                                        (dimNoSkew[otherBy] / target['scale' + _otherBy]));\n        newValue = fabric.util.radiansToDegrees(newValue);\n      }\n      skewed = target['skew' + _by] !== newValue;\n      target.set('skew' + _by, newValue);\n      if (target['skew' + _otherBy] !== 0) {\n        newDim = target._getTransformedDimensions();\n        newValue = (_dim[otherBy] / newDim[otherBy]) * target['scale' + _otherBy];\n        target.set('scale' + _otherBy, newValue);\n      }\n      return skewed;\n    },\n\n    /**\n     * Scales object by invoking its scaleX/scaleY methods\n     * @private\n     * @param {Number} x pointer's x coordinate\n     * @param {Number} y pointer's y coordinate\n     * @param {String} by Either 'x' or 'y' - specifies dimension constraint by which to scale an object.\n     *                    When not provided, an object is scaled by both dimensions equally\n     * @return {Boolean} true if the scaling occurred\n     */\n    _scaleObject: function (x, y, by) {\n      var t = this._currentTransform,\n          target = t.target,\n          lockScalingX = target.lockScalingX,\n          lockScalingY = target.lockScalingY,\n          lockScalingFlip = target.lockScalingFlip;\n\n      if (lockScalingX && lockScalingY) {\n        return false;\n      }\n\n      // Get the constraint point\n      var constraintPosition = target.translateToOriginPoint(target.getCenterPoint(), t.originX, t.originY),\n          localMouse = target.toLocalPoint(new fabric.Point(x, y), t.originX, t.originY),\n          dim = target._getTransformedDimensions(), scaled = false;\n\n      this._setLocalMouse(localMouse, t);\n\n      // Actually scale the object\n      scaled = this._setObjectScale(localMouse, t, lockScalingX, lockScalingY, by, lockScalingFlip, dim);\n\n      // Make sure the constraints apply\n      target.setPositionByOrigin(constraintPosition, t.originX, t.originY);\n      return scaled;\n    },\n\n    /**\n     * @private\n     * @return {Boolean} true if the scaling occurred\n     */\n    _setObjectScale: function(localMouse, transform, lockScalingX, lockScalingY, by, lockScalingFlip, _dim) {\n      var target = transform.target, forbidScalingX = false, forbidScalingY = false, scaled = false,\n          scaleX = localMouse.x * target.scaleX / _dim.x,\n          scaleY = localMouse.y * target.scaleY / _dim.y,\n          changeX = target.scaleX !== scaleX,\n          changeY = target.scaleY !== scaleY;\n\n      transform.newScaleX = scaleX;\n      transform.newScaleY = scaleY;\n      if (by === 'x' && target instanceof fabric.Textbox) {\n        var w = target.width * (localMouse.x / _dim.x);\n        if (w >= target.getMinWidth()) {\n          scaled = w !== target.width;\n          target.set('width', w);\n          return scaled;\n        }\n        return false;\n      }\n\n      if (lockScalingFlip && scaleX <= 0 && scaleX < target.scaleX) {\n        forbidScalingX = true;\n        localMouse.x = 0;\n      }\n\n      if (lockScalingFlip && scaleY <= 0 && scaleY < target.scaleY) {\n        forbidScalingY = true;\n        localMouse.y = 0;\n      }\n\n      if (by === 'equally' && !lockScalingX && !lockScalingY) {\n        scaled = this._scaleObjectEqually(localMouse, target, transform, _dim);\n      }\n      else if (!by) {\n        forbidScalingX || lockScalingX || (target.set('scaleX', scaleX) && (scaled = scaled || changeX));\n        forbidScalingY || lockScalingY || (target.set('scaleY', scaleY) && (scaled = scaled || changeY));\n      }\n      else if (by === 'x' && !target.get('lockUniScaling')) {\n        forbidScalingX || lockScalingX || (target.set('scaleX', scaleX) && (scaled = changeX));\n      }\n      else if (by === 'y' && !target.get('lockUniScaling')) {\n        forbidScalingY || lockScalingY || (target.set('scaleY', scaleY) && (scaled = changeY));\n      }\n      forbidScalingX || forbidScalingY || this._flipObject(transform, by);\n      return scaled;\n    },\n\n    /**\n     * @private\n     * @return {Boolean} true if the scaling occurred\n     */\n    _scaleObjectEqually: function(localMouse, target, transform, _dim) {\n\n      var dist = localMouse.y + localMouse.x,\n          lastDist = _dim.y * transform.original.scaleY / target.scaleY +\n                     _dim.x * transform.original.scaleX / target.scaleX,\n          scaled, signX = localMouse.x < 0 ? -1 : 1,\n          signY = localMouse.y < 0 ? -1 : 1, newScaleX, newScaleY;\n\n      // We use transform.scaleX/Y instead of target.scaleX/Y\n      // because the object may have a min scale and we'll loose the proportions\n      newScaleX = signX * Math.abs(transform.original.scaleX * dist / lastDist);\n      newScaleY = signY * Math.abs(transform.original.scaleY * dist / lastDist);\n      scaled = newScaleX !== target.scaleX || newScaleY !== target.scaleY;\n      target.set('scaleX', newScaleX);\n      target.set('scaleY', newScaleY);\n      return scaled;\n    },\n\n    /**\n     * @private\n     */\n    _flipObject: function(transform, by) {\n      if (transform.newScaleX < 0 && by !== 'y') {\n        if (transform.originX === 'left') {\n          transform.originX = 'right';\n        }\n        else if (transform.originX === 'right') {\n          transform.originX = 'left';\n        }\n      }\n\n      if (transform.newScaleY < 0 && by !== 'x') {\n        if (transform.originY === 'top') {\n          transform.originY = 'bottom';\n        }\n        else if (transform.originY === 'bottom') {\n          transform.originY = 'top';\n        }\n      }\n    },\n\n    /**\n     * @private\n     */\n    _setLocalMouse: function(localMouse, t) {\n      var target = t.target, zoom = this.getZoom(),\n          padding = target.padding / zoom;\n\n      if (t.originX === 'right') {\n        localMouse.x *= -1;\n      }\n      else if (t.originX === 'center') {\n        localMouse.x *= t.mouseXSign * 2;\n        if (localMouse.x < 0) {\n          t.mouseXSign = -t.mouseXSign;\n        }\n      }\n\n      if (t.originY === 'bottom') {\n        localMouse.y *= -1;\n      }\n      else if (t.originY === 'center') {\n        localMouse.y *= t.mouseYSign * 2;\n        if (localMouse.y < 0) {\n          t.mouseYSign = -t.mouseYSign;\n        }\n      }\n\n      // adjust the mouse coordinates when dealing with padding\n      if (abs(localMouse.x) > padding) {\n        if (localMouse.x < 0) {\n          localMouse.x += padding;\n        }\n        else {\n          localMouse.x -= padding;\n        }\n      }\n      else { // mouse is within the padding, set to 0\n        localMouse.x = 0;\n      }\n\n      if (abs(localMouse.y) > padding) {\n        if (localMouse.y < 0) {\n          localMouse.y += padding;\n        }\n        else {\n          localMouse.y -= padding;\n        }\n      }\n      else {\n        localMouse.y = 0;\n      }\n    },\n\n    /**\n     * Rotates object by invoking its rotate method\n     * @private\n     * @param {Number} x pointer's x coordinate\n     * @param {Number} y pointer's y coordinate\n     * @return {Boolean} true if the rotation occurred\n     */\n    _rotateObject: function (x, y) {\n\n      var t = this._currentTransform,\n          target = t.target, constraintPosition,\n          constraintPosition = target.translateToOriginPoint(target.getCenterPoint(), t.originX, t.originY);\n\n      if (target.lockRotation) {\n        return false;\n      }\n\n      var lastAngle = atan2(t.ey - constraintPosition.y, t.ex - constraintPosition.x),\n          curAngle = atan2(y - constraintPosition.y, x - constraintPosition.x),\n          angle = radiansToDegrees(curAngle - lastAngle + t.theta),\n          hasRotated = true;\n\n      if (target.snapAngle > 0) {\n        var snapAngle  = target.snapAngle,\n            snapThreshold  = target.snapThreshold || snapAngle,\n            rightAngleLocked = Math.ceil(angle / snapAngle) * snapAngle,\n            leftAngleLocked = Math.floor(angle / snapAngle) * snapAngle;\n\n        if (Math.abs(angle - leftAngleLocked) < snapThreshold) {\n          angle = leftAngleLocked;\n        }\n        else if (Math.abs(angle - rightAngleLocked) < snapThreshold) {\n          angle = rightAngleLocked;\n        }\n      }\n\n      // normalize angle to positive value\n      if (angle < 0) {\n        angle = 360 + angle;\n      }\n      angle %= 360;\n\n      if (target.angle === angle) {\n        hasRotated = false;\n      }\n      else {\n        // rotation only happen here\n        target.angle = angle;\n        // Make sure the constraints apply\n        target.setPositionByOrigin(constraintPosition, t.originX, t.originY);\n      }\n\n      return hasRotated;\n    },\n\n    /**\n     * Set the cursor type of the canvas element\n     * @param {String} value Cursor type of the canvas element.\n     * @see http://www.w3.org/TR/css3-ui/#cursor\n     */\n    setCursor: function (value) {\n      this.upperCanvasEl.style.cursor = value;\n    },\n\n    /**\n     * @private\n     * @param {CanvasRenderingContext2D} ctx to draw the selection on\n     */\n    _drawSelection: function (ctx) {\n      var groupSelector = this._groupSelector,\n          left = groupSelector.left,\n          top = groupSelector.top,\n          aleft = abs(left),\n          atop = abs(top);\n\n      if (this.selectionColor) {\n        ctx.fillStyle = this.selectionColor;\n\n        ctx.fillRect(\n          groupSelector.ex - ((left > 0) ? 0 : -left),\n          groupSelector.ey - ((top > 0) ? 0 : -top),\n          aleft,\n          atop\n        );\n      }\n\n      if (!this.selectionLineWidth || !this.selectionBorderColor) {\n        return;\n      }\n      ctx.lineWidth = this.selectionLineWidth;\n      ctx.strokeStyle = this.selectionBorderColor;\n\n      // selection border\n      if (this.selectionDashArray.length > 1 && !supportLineDash) {\n\n        var px = groupSelector.ex + STROKE_OFFSET - ((left > 0) ? 0 : aleft),\n            py = groupSelector.ey + STROKE_OFFSET - ((top > 0) ? 0 : atop);\n\n        ctx.beginPath();\n\n        fabric.util.drawDashedLine(ctx, px, py, px + aleft, py, this.selectionDashArray);\n        fabric.util.drawDashedLine(ctx, px, py + atop - 1, px + aleft, py + atop - 1, this.selectionDashArray);\n        fabric.util.drawDashedLine(ctx, px, py, px, py + atop, this.selectionDashArray);\n        fabric.util.drawDashedLine(ctx, px + aleft - 1, py, px + aleft - 1, py + atop, this.selectionDashArray);\n\n        ctx.closePath();\n        ctx.stroke();\n      }\n      else {\n        fabric.Object.prototype._setLineDash.call(this, ctx, this.selectionDashArray);\n        ctx.strokeRect(\n          groupSelector.ex + STROKE_OFFSET - ((left > 0) ? 0 : aleft),\n          groupSelector.ey + STROKE_OFFSET - ((top > 0) ? 0 : atop),\n          aleft,\n          atop\n        );\n      }\n    },\n\n    /**\n     * Method that determines what object we are clicking on\n     * the skipGroup parameter is for internal use, is needed for shift+click action\n     * 11/09/2018 TODO: would be cool if findTarget could discern between being a full target\n     * or the outside part of the corner.\n     * @param {Event} e mouse event\n     * @param {Boolean} skipGroup when true, activeGroup is skipped and only objects are traversed through\n     * @return {fabric.Object} the target found\n     */\n    findTarget: function (e, skipGroup) {\n      if (this.skipTargetFind) {\n        return;\n      }\n\n      var ignoreZoom = true,\n          pointer = this.getPointer(e, ignoreZoom),\n          activeObject = this._activeObject,\n          aObjects = this.getActiveObjects(),\n          activeTarget, activeTargetSubs;\n\n      // first check current group (if one exists)\n      // active group does not check sub targets like normal groups.\n      // if active group just exits.\n      this.targets = [];\n\n      if (aObjects.length > 1 && !skipGroup && activeObject === this._searchPossibleTargets([activeObject], pointer)) {\n        return activeObject;\n      }\n      // if we hit the corner of an activeObject, let's return that.\n      if (aObjects.length === 1 && activeObject._findTargetCorner(pointer)) {\n        return activeObject;\n      }\n      if (aObjects.length === 1 &&\n        activeObject === this._searchPossibleTargets([activeObject], pointer)) {\n        if (!this.preserveObjectStacking) {\n          return activeObject;\n        }\n        else {\n          activeTarget = activeObject;\n          activeTargetSubs = this.targets;\n          this.targets = [];\n        }\n      }\n      var target = this._searchPossibleTargets(this._objects, pointer);\n      if (e[this.altSelectionKey] && target && activeTarget && target !== activeTarget) {\n        target = activeTarget;\n        this.targets = activeTargetSubs;\n      }\n      return target;\n    },\n\n    /**\n     * Checks point is inside the object.\n     * @param {Object} [pointer] x,y object of point coordinates we want to check.\n     * @param {fabric.Object} obj Object to test against\n     * @param {Object} [globalPointer] x,y object of point coordinates relative to canvas used to search per pixel target.\n     * @return {Boolean} true if point is contained within an area of given object\n     * @private\n     */\n    _checkTarget: function(pointer, obj, globalPointer) {\n      if (obj &&\n          obj.visible &&\n          obj.evented &&\n          this.containsPoint(null, obj, pointer)){\n        if ((this.perPixelTargetFind || obj.perPixelTargetFind) && !obj.isEditing) {\n          var isTransparent = this.isTargetTransparent(obj, globalPointer.x, globalPointer.y);\n          if (!isTransparent) {\n            return true;\n          }\n        }\n        else {\n          return true;\n        }\n      }\n    },\n\n    /**\n     * Function used to search inside objects an object that contains pointer in bounding box or that contains pointerOnCanvas when painted\n     * @param {Array} [objects] objects array to look into\n     * @param {Object} [pointer] x,y object of point coordinates we want to check.\n     * @return {fabric.Object} object that contains pointer\n     * @private\n     */\n    _searchPossibleTargets: function(objects, pointer) {\n      // Cache all targets where their bounding box contains point.\n      var target, i = objects.length, subTarget;\n      // Do not check for currently grouped objects, since we check the parent group itself.\n      // until we call this function specifically to search inside the activeGroup\n      while (i--) {\n        var objToCheck = objects[i];\n        var pointerToUse = objToCheck.group && objToCheck.group.type !== 'activeSelection' ?\n          this._normalizePointer(objToCheck.group, pointer) : pointer;\n        if (this._checkTarget(pointerToUse, objToCheck, pointer)) {\n          target = objects[i];\n          if (target.subTargetCheck && target instanceof fabric.Group) {\n            subTarget = this._searchPossibleTargets(target._objects, pointer);\n            subTarget && this.targets.push(subTarget);\n          }\n          break;\n        }\n      }\n      return target;\n    },\n\n    /**\n     * Returns pointer coordinates without the effect of the viewport\n     * @param {Object} pointer with \"x\" and \"y\" number values\n     * @return {Object} object with \"x\" and \"y\" number values\n     */\n    restorePointerVpt: function(pointer) {\n      return fabric.util.transformPoint(\n        pointer,\n        fabric.util.invertTransform(this.viewportTransform)\n      );\n    },\n\n    /**\n     * Returns pointer coordinates relative to canvas.\n     * Can return coordinates with or without viewportTransform.\n     * ignoreZoom false gives back coordinates that represent\n     * the point clicked on canvas element.\n     * ignoreZoom true gives back coordinates after being processed\n     * by the viewportTransform ( sort of coordinates of what is displayed\n     * on the canvas where you are clicking.\n     * ignoreZoom true = HTMLElement coordinates relative to top,left\n     * ignoreZoom false, default = fabric space coordinates, the same used for shape position\n     * To interact with your shapes top and left you want to use ignoreZoom true\n     * most of the time, while ignoreZoom false will give you coordinates\n     * compatible with the object.oCoords system.\n     * of the time.\n     * @param {Event} e\n     * @param {Boolean} ignoreZoom\n     * @return {Object} object with \"x\" and \"y\" number values\n     */\n    getPointer: function (e, ignoreZoom) {\n      // return cached values if we are in the event processing chain\n      if (this._absolutePointer && !ignoreZoom) {\n        return this._absolutePointer;\n      }\n      if (this._pointer && ignoreZoom) {\n        return this._pointer;\n      }\n\n      var pointer = getPointer(e),\n          upperCanvasEl = this.upperCanvasEl,\n          bounds = upperCanvasEl.getBoundingClientRect(),\n          boundsWidth = bounds.width || 0,\n          boundsHeight = bounds.height || 0,\n          cssScale;\n\n      if (!boundsWidth || !boundsHeight ) {\n        if ('top' in bounds && 'bottom' in bounds) {\n          boundsHeight = Math.abs( bounds.top - bounds.bottom );\n        }\n        if ('right' in bounds && 'left' in bounds) {\n          boundsWidth = Math.abs( bounds.right - bounds.left );\n        }\n      }\n\n      this.calcOffset();\n      pointer.x = pointer.x - this._offset.left;\n      pointer.y = pointer.y - this._offset.top;\n      if (!ignoreZoom) {\n        pointer = this.restorePointerVpt(pointer);\n      }\n\n      if (boundsWidth === 0 || boundsHeight === 0) {\n        // If bounds are not available (i.e. not visible), do not apply scale.\n        cssScale = { width: 1, height: 1 };\n      }\n      else {\n        cssScale = {\n          width: upperCanvasEl.width / boundsWidth,\n          height: upperCanvasEl.height / boundsHeight\n        };\n      }\n\n      return {\n        x: pointer.x * cssScale.width,\n        y: pointer.y * cssScale.height\n      };\n    },\n\n    /**\n     * @private\n     * @throws {CANVAS_INIT_ERROR} If canvas can not be initialized\n     */\n    _createUpperCanvas: function () {\n      var lowerCanvasClass = this.lowerCanvasEl.className.replace(/\\s*lower-canvas\\s*/, '');\n\n      // there is no need to create a new upperCanvas element if we have already one.\n      if (this.upperCanvasEl) {\n        this.upperCanvasEl.className = '';\n      }\n      else {\n        this.upperCanvasEl = this._createCanvasElement();\n      }\n      fabric.util.addClass(this.upperCanvasEl, 'upper-canvas ' + lowerCanvasClass);\n\n      this.wrapperEl.appendChild(this.upperCanvasEl);\n\n      this._copyCanvasStyle(this.lowerCanvasEl, this.upperCanvasEl);\n      this._applyCanvasStyle(this.upperCanvasEl);\n      this.contextTop = this.upperCanvasEl.getContext('2d');\n    },\n\n    /**\n     * @private\n     */\n    _createCacheCanvas: function () {\n      this.cacheCanvasEl = this._createCanvasElement();\n      this.cacheCanvasEl.setAttribute('width', this.width);\n      this.cacheCanvasEl.setAttribute('height', this.height);\n      this.contextCache = this.cacheCanvasEl.getContext('2d');\n    },\n\n    /**\n     * @private\n     */\n    _initWrapperElement: function () {\n      this.wrapperEl = fabric.util.wrapElement(this.lowerCanvasEl, 'div', {\n        'class': this.containerClass\n      });\n      fabric.util.setStyle(this.wrapperEl, {\n        width: this.width + 'px',\n        height: this.height + 'px',\n        position: 'relative'\n      });\n      fabric.util.makeElementUnselectable(this.wrapperEl);\n    },\n\n    /**\n     * @private\n     * @param {HTMLElement} element canvas element to apply styles on\n     */\n    _applyCanvasStyle: function (element) {\n      var width = this.width || element.width,\n          height = this.height || element.height;\n\n      fabric.util.setStyle(element, {\n        position: 'absolute',\n        width: width + 'px',\n        height: height + 'px',\n        left: 0,\n        top: 0,\n        'touch-action': this.allowTouchScrolling ? 'manipulation' : 'none',\n        '-ms-touch-action': this.allowTouchScrolling ? 'manipulation' : 'none'\n      });\n      element.width = width;\n      element.height = height;\n      fabric.util.makeElementUnselectable(element);\n    },\n\n    /**\n     * Copy the entire inline style from one element (fromEl) to another (toEl)\n     * @private\n     * @param {Element} fromEl Element style is copied from\n     * @param {Element} toEl Element copied style is applied to\n     */\n    _copyCanvasStyle: function (fromEl, toEl) {\n      toEl.style.cssText = fromEl.style.cssText;\n    },\n\n    /**\n     * Returns context of canvas where object selection is drawn\n     * @return {CanvasRenderingContext2D}\n     */\n    getSelectionContext: function() {\n      return this.contextTop;\n    },\n\n    /**\n     * Returns &lt;canvas> element on which object selection is drawn\n     * @return {HTMLCanvasElement}\n     */\n    getSelectionElement: function () {\n      return this.upperCanvasEl;\n    },\n\n    /**\n     * Returns currently active object\n     * @return {fabric.Object} active object\n     */\n    getActiveObject: function () {\n      return this._activeObject;\n    },\n\n    /**\n     * Returns an array with the current selected objects\n     * @return {fabric.Object} active object\n     */\n    getActiveObjects: function () {\n      var active = this._activeObject;\n      if (active) {\n        if (active.type === 'activeSelection' && active._objects) {\n          return active._objects.slice(0);\n        }\n        else {\n          return [active];\n        }\n      }\n      return [];\n    },\n\n    /**\n     * @private\n     * @param {fabric.Object} obj Object that was removed\n     */\n    _onObjectRemoved: function(obj) {\n      // removing active object should fire \"selection:cleared\" events\n      if (obj === this._activeObject) {\n        this.fire('before:selection:cleared', { target: obj });\n        this._discardActiveObject();\n        this.fire('selection:cleared', { target: obj });\n        obj.fire('deselected');\n      }\n      if (this._hoveredTarget === obj) {\n        this._hoveredTarget = null;\n      }\n      this.callSuper('_onObjectRemoved', obj);\n    },\n\n    /**\n     * @private\n     * Compares the old activeObject with the current one and fires correct events\n     * @param {fabric.Object} obj old activeObject\n     */\n    _fireSelectionEvents: function(oldObjects, e) {\n      var somethingChanged = false, objects = this.getActiveObjects(),\n          added = [], removed = [], opt = { e: e };\n      oldObjects.forEach(function(oldObject) {\n        if (objects.indexOf(oldObject) === -1) {\n          somethingChanged = true;\n          oldObject.fire('deselected', opt);\n          removed.push(oldObject);\n        }\n      });\n      objects.forEach(function(object) {\n        if (oldObjects.indexOf(object) === -1) {\n          somethingChanged = true;\n          object.fire('selected', opt);\n          added.push(object);\n        }\n      });\n      if (oldObjects.length > 0 && objects.length > 0) {\n        opt.selected = added;\n        opt.deselected = removed;\n        // added for backward compatibility\n        opt.updated = added[0] || removed[0];\n        opt.target = this._activeObject;\n        somethingChanged && this.fire('selection:updated', opt);\n      }\n      else if (objects.length > 0) {\n        // deprecated event\n        if (objects.length === 1) {\n          opt.target = added[0];\n          this.fire('object:selected', opt);\n        }\n        opt.selected = added;\n        // added for backward compatibility\n        opt.target = this._activeObject;\n        this.fire('selection:created', opt);\n      }\n      else if (oldObjects.length > 0) {\n        opt.deselected = removed;\n        this.fire('selection:cleared', opt);\n      }\n    },\n\n    /**\n     * Sets given object as the only active object on canvas\n     * @param {fabric.Object} object Object to set as an active one\n     * @param {Event} [e] Event (passed along when firing \"object:selected\")\n     * @return {fabric.Canvas} thisArg\n     * @chainable\n     */\n    setActiveObject: function (object, e) {\n      var currentActives = this.getActiveObjects();\n      this._setActiveObject(object, e);\n      this._fireSelectionEvents(currentActives, e);\n      return this;\n    },\n\n    /**\n     * @private\n     * @param {Object} object to set as active\n     * @param {Event} [e] Event (passed along when firing \"object:selected\")\n     * @return {Boolean} true if the selection happened\n     */\n    _setActiveObject: function(object, e) {\n      if (this._activeObject === object) {\n        return false;\n      }\n      if (!this._discardActiveObject(e, object)) {\n        return false;\n      }\n      if (object.onSelect({ e: e })) {\n        return false;\n      }\n      this._activeObject = object;\n      return true;\n    },\n\n    /**\n     * @private\n     */\n    _discardActiveObject: function(e, object) {\n      var obj = this._activeObject;\n      if (obj) {\n        // onDeselect return TRUE to cancel selection;\n        if (obj.onDeselect({ e: e, object: object })) {\n          return false;\n        }\n        this._activeObject = null;\n      }\n      return true;\n    },\n\n    /**\n     * Discards currently active object and fire events. If the function is called by fabric\n     * as a consequence of a mouse event, the event is passed as a parameter and\n     * sent to the fire function for the custom events. When used as a method the\n     * e param does not have any application.\n     * @param {event} e\n     * @return {fabric.Canvas} thisArg\n     * @chainable\n     */\n    discardActiveObject: function (e) {\n      var currentActives = this.getActiveObjects(), activeObject = this.getActiveObject();\n      if (currentActives.length) {\n        this.fire('before:selection:cleared', { target: activeObject, e: e });\n      }\n      this._discardActiveObject(e);\n      this._fireSelectionEvents(currentActives, e);\n      return this;\n    },\n\n    /**\n     * Clears a canvas element and removes all event listeners\n     * @return {fabric.Canvas} thisArg\n     * @chainable\n     */\n    dispose: function () {\n      var wrapper = this.wrapperEl;\n      this.removeListeners();\n      wrapper.removeChild(this.upperCanvasEl);\n      wrapper.removeChild(this.lowerCanvasEl);\n      this.contextCache = null;\n      this.contextTop = null;\n      ['upperCanvasEl', 'cacheCanvasEl'].forEach((function(element) {\n        fabric.util.cleanUpJsdomNode(this[element]);\n        this[element] = undefined;\n      }).bind(this));\n      if (wrapper.parentNode) {\n        wrapper.parentNode.replaceChild(this.lowerCanvasEl, this.wrapperEl);\n      }\n      delete this.wrapperEl;\n      fabric.StaticCanvas.prototype.dispose.call(this);\n      return this;\n    },\n\n    /**\n     * Clears all contexts (background, main, top) of an instance\n     * @return {fabric.Canvas} thisArg\n     * @chainable\n     */\n    clear: function () {\n      // this.discardActiveGroup();\n      this.discardActiveObject();\n      this.clearContext(this.contextTop);\n      return this.callSuper('clear');\n    },\n\n    /**\n     * Draws objects' controls (borders/controls)\n     * @param {CanvasRenderingContext2D} ctx Context to render controls on\n     */\n    drawControls: function(ctx) {\n      var activeObject = this._activeObject;\n\n      if (activeObject) {\n        activeObject._renderControls(ctx);\n      }\n    },\n\n    /**\n     * @private\n     */\n    _toObject: function(instance, methodName, propertiesToInclude) {\n      //If the object is part of the current selection group, it should\n      //be transformed appropriately\n      //i.e. it should be serialised as it would appear if the selection group\n      //were to be destroyed.\n      var originalProperties = this._realizeGroupTransformOnObject(instance),\n          object = this.callSuper('_toObject', instance, methodName, propertiesToInclude);\n      //Undo the damage we did by changing all of its properties\n      this._unwindGroupTransformOnObject(instance, originalProperties);\n      return object;\n    },\n\n    /**\n     * Realises an object's group transformation on it\n     * @private\n     * @param {fabric.Object} [instance] the object to transform (gets mutated)\n     * @returns the original values of instance which were changed\n     */\n    _realizeGroupTransformOnObject: function(instance) {\n      if (instance.group && instance.group.type === 'activeSelection' && this._activeObject === instance.group) {\n        var layoutProps = ['angle', 'flipX', 'flipY', 'left', 'scaleX', 'scaleY', 'skewX', 'skewY', 'top'];\n        //Copy all the positionally relevant properties across now\n        var originalValues = {};\n        layoutProps.forEach(function(prop) {\n          originalValues[prop] = instance[prop];\n        });\n        this._activeObject.realizeTransform(instance);\n        return originalValues;\n      }\n      else {\n        return null;\n      }\n    },\n\n    /**\n     * Restores the changed properties of instance\n     * @private\n     * @param {fabric.Object} [instance] the object to un-transform (gets mutated)\n     * @param {Object} [originalValues] the original values of instance, as returned by _realizeGroupTransformOnObject\n     */\n    _unwindGroupTransformOnObject: function(instance, originalValues) {\n      if (originalValues) {\n        instance.set(originalValues);\n      }\n    },\n\n    /**\n     * @private\n     */\n    _setSVGObject: function(markup, instance, reviver) {\n      //If the object is in a selection group, simulate what would happen to that\n      //object when the group is deselected\n      var originalProperties = this._realizeGroupTransformOnObject(instance);\n      this.callSuper('_setSVGObject', markup, instance, reviver);\n      this._unwindGroupTransformOnObject(instance, originalProperties);\n    },\n\n    setViewportTransform: function (vpt) {\n      if (this.renderOnAddRemove && this._activeObject && this._activeObject.isEditing) {\n        this._activeObject.clearContextTop();\n      }\n      fabric.StaticCanvas.prototype.setViewportTransform.call(this, vpt);\n    }\n  });\n\n  // copying static properties manually to work around Opera's bug,\n  // where \"prototype\" property is enumerable and overrides existing prototype\n  for (var prop in fabric.StaticCanvas) {\n    if (prop !== 'prototype') {\n      fabric.Canvas[prop] = fabric.StaticCanvas[prop];\n    }\n  }\n})();\n\n\n(function() {\n\n  var cursorOffset = {\n        mt: 0, // n\n        tr: 1, // ne\n        mr: 2, // e\n        br: 3, // se\n        mb: 4, // s\n        bl: 5, // sw\n        ml: 6, // w\n        tl: 7 // nw\n      },\n      addListener = fabric.util.addListener,\n      removeListener = fabric.util.removeListener,\n      RIGHT_CLICK = 3, MIDDLE_CLICK = 2, LEFT_CLICK = 1,\n      addEventOptions = { passive: false };\n\n  function checkClick(e, value) {\n    return e.button && (e.button === value - 1);\n  }\n\n  fabric.util.object.extend(fabric.Canvas.prototype, /** @lends fabric.Canvas.prototype */ {\n\n    /**\n     * Map of cursor style values for each of the object controls\n     * @private\n     */\n    cursorMap: [\n      'n-resize',\n      'ne-resize',\n      'e-resize',\n      'se-resize',\n      's-resize',\n      'sw-resize',\n      'w-resize',\n      'nw-resize'\n    ],\n\n    /**\n     * Contains the id of the touch event that owns the fabric transform\n     * @type Number\n     * @private\n     */\n    mainTouchId: null,\n\n    /**\n     * Adds mouse listeners to canvas\n     * @private\n     */\n    _initEventListeners: function () {\n      // in case we initialized the class twice. This should not happen normally\n      // but in some kind of applications where the canvas element may be changed\n      // this is a workaround to having double listeners.\n      this.removeListeners();\n      this._bindEvents();\n      this.addOrRemove(addListener, 'add');\n    },\n\n    /**\n     * return an event prefix pointer or mouse.\n     * @private\n     */\n    _getEventPrefix: function () {\n      return this.enablePointerEvents ? 'pointer' : 'mouse';\n    },\n\n    addOrRemove: function(functor, eventjsFunctor) {\n      var canvasElement = this.upperCanvasEl,\n          eventTypePrefix = this._getEventPrefix();\n      functor(fabric.window, 'resize', this._onResize);\n      functor(canvasElement, eventTypePrefix + 'down', this._onMouseDown);\n      functor(canvasElement, eventTypePrefix + 'move', this._onMouseMove, addEventOptions);\n      functor(canvasElement, eventTypePrefix + 'out', this._onMouseOut);\n      functor(canvasElement, eventTypePrefix + 'enter', this._onMouseEnter);\n      functor(canvasElement, 'wheel', this._onMouseWheel);\n      functor(canvasElement, 'contextmenu', this._onContextMenu);\n      functor(canvasElement, 'dblclick', this._onDoubleClick);\n      functor(canvasElement, 'dragover', this._onDragOver);\n      functor(canvasElement, 'dragenter', this._onDragEnter);\n      functor(canvasElement, 'dragleave', this._onDragLeave);\n      functor(canvasElement, 'drop', this._onDrop);\n      if (!this.enablePointerEvents) {\n        functor(canvasElement, 'touchstart', this._onTouchStart, addEventOptions);\n      }\n      if (typeof eventjs !== 'undefined' && eventjsFunctor in eventjs) {\n        eventjs[eventjsFunctor](canvasElement, 'gesture', this._onGesture);\n        eventjs[eventjsFunctor](canvasElement, 'drag', this._onDrag);\n        eventjs[eventjsFunctor](canvasElement, 'orientation', this._onOrientationChange);\n        eventjs[eventjsFunctor](canvasElement, 'shake', this._onShake);\n        eventjs[eventjsFunctor](canvasElement, 'longpress', this._onLongPress);\n      }\n    },\n\n    /**\n     * Removes all event listeners\n     */\n    removeListeners: function() {\n      this.addOrRemove(removeListener, 'remove');\n      // if you dispose on a mouseDown, before mouse up, you need to clean document to...\n      var eventTypePrefix = this._getEventPrefix();\n      removeListener(fabric.document, eventTypePrefix + 'up', this._onMouseUp);\n      removeListener(fabric.document, 'touchend', this._onTouchEnd, addEventOptions);\n      removeListener(fabric.document, eventTypePrefix + 'move', this._onMouseMove, addEventOptions);\n      removeListener(fabric.document, 'touchmove', this._onMouseMove, addEventOptions);\n    },\n\n    /**\n     * @private\n     */\n    _bindEvents: function() {\n      if (this.eventsBound) {\n        // for any reason we pass here twice we do not want to bind events twice.\n        return;\n      }\n      this._onMouseDown = this._onMouseDown.bind(this);\n      this._onTouchStart = this._onTouchStart.bind(this);\n      this._onMouseMove = this._onMouseMove.bind(this);\n      this._onMouseUp = this._onMouseUp.bind(this);\n      this._onTouchEnd = this._onTouchEnd.bind(this);\n      this._onResize = this._onResize.bind(this);\n      this._onGesture = this._onGesture.bind(this);\n      this._onDrag = this._onDrag.bind(this);\n      this._onShake = this._onShake.bind(this);\n      this._onLongPress = this._onLongPress.bind(this);\n      this._onOrientationChange = this._onOrientationChange.bind(this);\n      this._onMouseWheel = this._onMouseWheel.bind(this);\n      this._onMouseOut = this._onMouseOut.bind(this);\n      this._onMouseEnter = this._onMouseEnter.bind(this);\n      this._onContextMenu = this._onContextMenu.bind(this);\n      this._onDoubleClick = this._onDoubleClick.bind(this);\n      this._onDragOver = this._onDragOver.bind(this);\n      this._onDragEnter = this._simpleEventHandler.bind(this, 'dragenter');\n      this._onDragLeave = this._simpleEventHandler.bind(this, 'dragleave');\n      this._onDrop = this._simpleEventHandler.bind(this, 'drop');\n      this.eventsBound = true;\n    },\n\n    /**\n     * @private\n     * @param {Event} [e] Event object fired on Event.js gesture\n     * @param {Event} [self] Inner Event object\n     */\n    _onGesture: function(e, self) {\n      this.__onTransformGesture && this.__onTransformGesture(e, self);\n    },\n\n    /**\n     * @private\n     * @param {Event} [e] Event object fired on Event.js drag\n     * @param {Event} [self] Inner Event object\n     */\n    _onDrag: function(e, self) {\n      this.__onDrag && this.__onDrag(e, self);\n    },\n\n    /**\n     * @private\n     * @param {Event} [e] Event object fired on wheel event\n     */\n    _onMouseWheel: function(e) {\n      this.__onMouseWheel(e);\n    },\n\n    /**\n     * @private\n     * @param {Event} e Event object fired on mousedown\n     */\n    _onMouseOut: function(e) {\n      var target = this._hoveredTarget;\n      this.fire('mouse:out', { target: target, e: e });\n      this._hoveredTarget = null;\n      target && target.fire('mouseout', { e: e });\n      if (this._iTextInstances) {\n        this._iTextInstances.forEach(function(obj) {\n          if (obj.isEditing) {\n            obj.hiddenTextarea.focus();\n          }\n        });\n      }\n    },\n\n    /**\n     * @private\n     * @param {Event} e Event object fired on mouseenter\n     */\n    _onMouseEnter: function(e) {\n      // This find target and consequent 'mouse:over' is used to\n      // clear old instances on hovered target.\n      // calling findTarget has the side effect of killing target.__corner.\n      // as a short term fix we are not firing this if we are currently transforming.\n      // as a long term fix we need to separate the action of finding a target with the\n      // side effects we added to it.\n      if (!this.currentTransform && !this.findTarget(e)) {\n        this.fire('mouse:over', { target: null, e: e });\n        this._hoveredTarget = null;\n      }\n    },\n\n    /**\n     * @private\n     * @param {Event} [e] Event object fired on Event.js orientation change\n     * @param {Event} [self] Inner Event object\n     */\n    _onOrientationChange: function(e, self) {\n      this.__onOrientationChange && this.__onOrientationChange(e, self);\n    },\n\n    /**\n     * @private\n     * @param {Event} [e] Event object fired on Event.js shake\n     * @param {Event} [self] Inner Event object\n     */\n    _onShake: function(e, self) {\n      this.__onShake && this.__onShake(e, self);\n    },\n\n    /**\n     * @private\n     * @param {Event} [e] Event object fired on Event.js shake\n     * @param {Event} [self] Inner Event object\n     */\n    _onLongPress: function(e, self) {\n      this.__onLongPress && this.__onLongPress(e, self);\n    },\n\n    /**\n     * prevent default to allow drop event to be fired\n     * @private\n     * @param {Event} [e] Event object fired on Event.js shake\n     */\n    _onDragOver: function(e) {\n      e.preventDefault();\n      var target = this._simpleEventHandler('dragover', e);\n      this._fireEnterLeaveEvents(target, e);\n    },\n\n    /**\n     * @private\n     * @param {Event} e Event object fired on mousedown\n     */\n    _onContextMenu: function (e) {\n      if (this.stopContextMenu) {\n        e.stopPropagation();\n        e.preventDefault();\n      }\n      return false;\n    },\n\n    /**\n     * @private\n     * @param {Event} e Event object fired on mousedown\n     */\n    _onDoubleClick: function (e) {\n      this._cacheTransformEventData(e);\n      this._handleEvent(e, 'dblclick');\n      this._resetTransformEventData(e);\n    },\n\n    /**\n     * Return a the id of an event.\n     * returns either the pointerId or the identifier or 0 for the mouse event\n     * @private\n     * @param {Event} evt Event object\n     */\n    getPointerId: function(evt) {\n      var changedTouches = evt.changedTouches;\n\n      if (changedTouches) {\n        return changedTouches[0] && changedTouches[0].identifier;\n      }\n\n      if (this.enablePointerEvents) {\n        return evt.pointerId;\n      }\n\n      return -1;\n    },\n\n    /**\n     * Determines if an event has the id of the event that is considered main\n     * @private\n     * @param {evt} event Event object\n     */\n    _isMainEvent: function(evt) {\n      if (evt.isPrimary === true) {\n        return true;\n      }\n      if (evt.isPrimary === false) {\n        return false;\n      }\n      if (evt.type === 'touchend' && evt.touches.length === 0) {\n        return true;\n      }\n      if (evt.changedTouches) {\n        return evt.changedTouches[0].identifier === this.mainTouchId;\n      }\n      return true;\n    },\n\n    /**\n     * @private\n     * @param {Event} e Event object fired on mousedown\n     */\n    _onTouchStart: function(e) {\n      e.preventDefault();\n      if (this.mainTouchId === null) {\n        this.mainTouchId = this.getPointerId(e);\n      }\n      this.__onMouseDown(e);\n      this._resetTransformEventData();\n      var canvasElement = this.upperCanvasEl,\n          eventTypePrefix = this._getEventPrefix();\n      addListener(fabric.document, 'touchend', this._onTouchEnd, addEventOptions);\n      addListener(fabric.document, 'touchmove', this._onMouseMove, addEventOptions);\n      // Unbind mousedown to prevent double triggers from touch devices\n      removeListener(canvasElement, eventTypePrefix + 'down', this._onMouseDown);\n    },\n\n    /**\n     * @private\n     * @param {Event} e Event object fired on mousedown\n     */\n    _onMouseDown: function (e) {\n      this.__onMouseDown(e);\n      this._resetTransformEventData();\n      var canvasElement = this.upperCanvasEl,\n          eventTypePrefix = this._getEventPrefix();\n      removeListener(canvasElement, eventTypePrefix + 'move', this._onMouseMove, addEventOptions);\n      addListener(fabric.document, eventTypePrefix + 'up', this._onMouseUp);\n      addListener(fabric.document, eventTypePrefix + 'move', this._onMouseMove, addEventOptions);\n    },\n\n    /**\n     * @private\n     * @param {Event} e Event object fired on mousedown\n     */\n    _onTouchEnd: function(e) {\n      if (e.touches.length > 0) {\n        // if there are still touches stop here\n        return;\n      }\n      this.__onMouseUp(e);\n      this._resetTransformEventData();\n      this.mainTouchId = null;\n      var eventTypePrefix = this._getEventPrefix();\n      removeListener(fabric.document, 'touchend', this._onTouchEnd, addEventOptions);\n      removeListener(fabric.document, 'touchmove', this._onMouseMove, addEventOptions);\n      var _this = this;\n      if (this._willAddMouseDown) {\n        clearTimeout(this._willAddMouseDown);\n      }\n      this._willAddMouseDown = setTimeout(function() {\n        // Wait 400ms before rebinding mousedown to prevent double triggers\n        // from touch devices\n        addListener(_this.upperCanvasEl, eventTypePrefix + 'down', _this._onMouseDown);\n        _this._willAddMouseDown = 0;\n      }, 400);\n    },\n\n    /**\n     * @private\n     * @param {Event} e Event object fired on mouseup\n     */\n    _onMouseUp: function (e) {\n      this.__onMouseUp(e);\n      this._resetTransformEventData();\n      var canvasElement = this.upperCanvasEl,\n          eventTypePrefix = this._getEventPrefix();\n      if (this._isMainEvent(e)) {\n        removeListener(fabric.document, eventTypePrefix + 'up', this._onMouseUp);\n        removeListener(fabric.document, eventTypePrefix + 'move', this._onMouseMove, addEventOptions);\n        addListener(canvasElement, eventTypePrefix + 'move', this._onMouseMove, addEventOptions);\n      }\n    },\n\n    /**\n     * @private\n     * @param {Event} e Event object fired on mousemove\n     */\n    _onMouseMove: function (e) {\n      !this.allowTouchScrolling && e.preventDefault && e.preventDefault();\n      this.__onMouseMove(e);\n    },\n\n    /**\n     * @private\n     */\n    _onResize: function () {\n      this.calcOffset();\n    },\n\n    /**\n     * Decides whether the canvas should be redrawn in mouseup and mousedown events.\n     * @private\n     * @param {Object} target\n     */\n    _shouldRender: function(target) {\n      var activeObject = this._activeObject;\n\n      if (\n        !!activeObject !== !!target ||\n        (activeObject && target && (activeObject !== target))\n      ) {\n        // this covers: switch of target, from target to no target, selection of target\n        // multiSelection with key and mouse\n        return true;\n      }\n      else if (activeObject && activeObject.isEditing) {\n        // if we mouse up/down over a editing textbox a cursor change,\n        // there is no need to re render\n        return false;\n      }\n      return false;\n    },\n\n    /**\n     * Method that defines the actions when mouse is released on canvas.\n     * The method resets the currentTransform parameters, store the image corner\n     * position in the image object and render the canvas on top.\n     * @private\n     * @param {Event} e Event object fired on mouseup\n     */\n    __onMouseUp: function (e) {\n      var target, transform = this._currentTransform,\n          groupSelector = this._groupSelector, shouldRender = false,\n          isClick = (!groupSelector || (groupSelector.left === 0 && groupSelector.top === 0));\n      this._cacheTransformEventData(e);\n      target = this._target;\n      this._handleEvent(e, 'up:before');\n      // if right/middle click just fire events and return\n      // target undefined will make the _handleEvent search the target\n      if (checkClick(e, RIGHT_CLICK)) {\n        if (this.fireRightClick) {\n          this._handleEvent(e, 'up', RIGHT_CLICK, isClick);\n        }\n        return;\n      }\n\n      if (checkClick(e, MIDDLE_CLICK)) {\n        if (this.fireMiddleClick) {\n          this._handleEvent(e, 'up', MIDDLE_CLICK, isClick);\n        }\n        this._resetTransformEventData();\n        return;\n      }\n\n      if (this.isDrawingMode && this._isCurrentlyDrawing) {\n        this._onMouseUpInDrawingMode(e);\n        return;\n      }\n\n      if (!this._isMainEvent(e)) {\n        return;\n      }\n      if (transform) {\n        this._finalizeCurrentTransform(e);\n        shouldRender = transform.actionPerformed;\n      }\n\n      if (!isClick) {\n        this._maybeGroupObjects(e);\n        shouldRender || (shouldRender = this._shouldRender(target));\n      }\n      if (target) {\n        target.isMoving = false;\n      }\n      this._setCursorFromEvent(e, target);\n      this._handleEvent(e, 'up', LEFT_CLICK, isClick);\n      this._groupSelector = null;\n      this._currentTransform = null;\n      // reset the target information about which corner is selected\n      target && (target.__corner = 0);\n      if (shouldRender) {\n        this.requestRenderAll();\n      }\n      else if (!isClick) {\n        this.renderTop();\n      }\n    },\n\n    /**\n     * @private\n     * Handle event firing for target and subtargets\n     * @param {Event} e event from mouse\n     * @param {String} eventType event to fire (up, down or move)\n     * @return {Fabric.Object} target return the the target found, for internal reasons.\n     */\n    _simpleEventHandler: function(eventType, e) {\n      var target = this.findTarget(e),\n          targets = this.targets,\n          options = {\n            e: e,\n            target: target,\n            subTargets: targets,\n          };\n      this.fire(eventType, options);\n      target && target.fire(eventType, options);\n      if (!targets) {\n        return target;\n      }\n      for (var i = 0; i < targets.length; i++) {\n        targets[i].fire(eventType, options);\n      }\n      return target;\n    },\n\n    /**\n     * @private\n     * Handle event firing for target and subtargets\n     * @param {Event} e event from mouse\n     * @param {String} eventType event to fire (up, down or move)\n     * @param {fabric.Object} targetObj receiving event\n     * @param {Number} [button] button used in the event 1 = left, 2 = middle, 3 = right\n     * @param {Boolean} isClick for left button only, indicates that the mouse up happened without move.\n     */\n    _handleEvent: function(e, eventType, button, isClick) {\n      var target = this._target,\n          targets = this.targets || [],\n          options = {\n            e: e,\n            target: target,\n            subTargets: targets,\n            button: button || LEFT_CLICK,\n            isClick: isClick || false,\n            pointer: this._pointer,\n            absolutePointer: this._absolutePointer,\n            transform: this._currentTransform\n          };\n      this.fire('mouse:' + eventType, options);\n      target && target.fire('mouse' + eventType, options);\n      for (var i = 0; i < targets.length; i++) {\n        targets[i].fire('mouse' + eventType, options);\n      }\n    },\n\n    /**\n     * @private\n     * @param {Event} e send the mouse event that generate the finalize down, so it can be used in the event\n     */\n    _finalizeCurrentTransform: function(e) {\n\n      var transform = this._currentTransform,\n          target = transform.target,\n          eventName,\n          options = {\n            e: e,\n            target: target,\n            transform: transform,\n          };\n\n      if (target._scaling) {\n        target._scaling = false;\n      }\n\n      target.setCoords();\n\n      if (transform.actionPerformed || (this.stateful && target.hasStateChanged())) {\n        if (transform.actionPerformed) {\n          eventName = this._addEventOptions(options, transform);\n          this._fire(eventName, options);\n        }\n        this._fire('modified', options);\n      }\n    },\n\n    /**\n     * Mutate option object in order to add by property and give back the event name.\n     * @private\n     * @param {Object} options to mutate\n     * @param {Object} transform to inspect action from\n     */\n    _addEventOptions: function(options, transform) {\n      // we can probably add more details at low cost\n      // scale change, rotation changes, translation changes\n      var eventName, by;\n      switch (transform.action) {\n        case 'scaleX':\n          eventName = 'scaled';\n          by = 'x';\n          break;\n        case 'scaleY':\n          eventName = 'scaled';\n          by = 'y';\n          break;\n        case 'skewX':\n          eventName = 'skewed';\n          by = 'x';\n          break;\n        case 'skewY':\n          eventName = 'skewed';\n          by = 'y';\n          break;\n        case 'scale':\n          eventName = 'scaled';\n          by = 'equally';\n          break;\n        case 'rotate':\n          eventName = 'rotated';\n          break;\n        case 'drag':\n          eventName = 'moved';\n          break;\n      }\n      options.by = by;\n      return eventName;\n    },\n\n    /**\n     * @private\n     * @param {Event} e Event object fired on mousedown\n     */\n    _onMouseDownInDrawingMode: function(e) {\n      this._isCurrentlyDrawing = true;\n      if (this.getActiveObject()) {\n        this.discardActiveObject(e).requestRenderAll();\n      }\n      if (this.clipTo) {\n        fabric.util.clipContext(this, this.contextTop);\n      }\n      var pointer = this.getPointer(e);\n      this.freeDrawingBrush.onMouseDown(pointer, { e: e, pointer: pointer });\n      this._handleEvent(e, 'down');\n    },\n\n    /**\n     * @private\n     * @param {Event} e Event object fired on mousemove\n     */\n    _onMouseMoveInDrawingMode: function(e) {\n      if (this._isCurrentlyDrawing) {\n        var pointer = this.getPointer(e);\n        this.freeDrawingBrush.onMouseMove(pointer, { e: e, pointer: pointer });\n      }\n      this.setCursor(this.freeDrawingCursor);\n      this._handleEvent(e, 'move');\n    },\n\n    /**\n     * @private\n     * @param {Event} e Event object fired on mouseup\n     */\n    _onMouseUpInDrawingMode: function(e) {\n      if (this.clipTo) {\n        this.contextTop.restore();\n      }\n      var pointer = this.getPointer(e);\n      this._isCurrentlyDrawing = this.freeDrawingBrush.onMouseUp({ e: e, pointer: pointer });\n      this._handleEvent(e, 'up');\n    },\n\n    /**\n     * Method that defines the actions when mouse is clicked on canvas.\n     * The method inits the currentTransform parameters and renders all the\n     * canvas so the current image can be placed on the top canvas and the rest\n     * in on the container one.\n     * @private\n     * @param {Event} e Event object fired on mousedown\n     */\n    __onMouseDown: function (e) {\n      this._cacheTransformEventData(e);\n      this._handleEvent(e, 'down:before');\n      var target = this._target;\n      // if right click just fire events\n      if (checkClick(e, RIGHT_CLICK)) {\n        if (this.fireRightClick) {\n          this._handleEvent(e, 'down', RIGHT_CLICK);\n        }\n        return;\n      }\n\n      if (checkClick(e, MIDDLE_CLICK)) {\n        if (this.fireMiddleClick) {\n          this._handleEvent(e, 'down', MIDDLE_CLICK);\n        }\n        return;\n      }\n\n      if (this.isDrawingMode) {\n        this._onMouseDownInDrawingMode(e);\n        return;\n      }\n\n      if (!this._isMainEvent(e)) {\n        return;\n      }\n\n      // ignore if some object is being transformed at this moment\n      if (this._currentTransform) {\n        return;\n      }\n\n      var pointer = this._pointer;\n      // save pointer for check in __onMouseUp event\n      this._previousPointer = pointer;\n      var shouldRender = this._shouldRender(target),\n          shouldGroup = this._shouldGroup(e, target);\n      if (this._shouldClearSelection(e, target)) {\n        this.discardActiveObject(e);\n      }\n      else if (shouldGroup) {\n        this._handleGrouping(e, target);\n        target = this._activeObject;\n      }\n\n      if (this.selection && (!target ||\n        (!target.selectable && !target.isEditing && target !== this._activeObject))) {\n        this._groupSelector = {\n          ex: pointer.x,\n          ey: pointer.y,\n          top: 0,\n          left: 0\n        };\n      }\n\n      if (target) {\n        var alreadySelected = target === this._activeObject;\n        if (target.selectable) {\n          this.setActiveObject(target, e);\n        }\n        if (target === this._activeObject && (target.__corner || !shouldGroup)) {\n          this._setupCurrentTransform(e, target, alreadySelected);\n        }\n      }\n      this._handleEvent(e, 'down');\n      // we must renderAll so that we update the visuals\n      (shouldRender || shouldGroup) && this.requestRenderAll();\n    },\n\n    /**\n     * reset cache form common information needed during event processing\n     * @private\n     */\n    _resetTransformEventData: function() {\n      this._target = null;\n      this._pointer = null;\n      this._absolutePointer = null;\n    },\n\n    /**\n     * Cache common information needed during event processing\n     * @private\n     * @param {Event} e Event object fired on event\n     */\n    _cacheTransformEventData: function(e) {\n      // reset in order to avoid stale caching\n      this._resetTransformEventData();\n      this._pointer = this.getPointer(e, true);\n      this._absolutePointer = this.restorePointerVpt(this._pointer);\n      this._target = this._currentTransform ? this._currentTransform.target : this.findTarget(e) || null;\n    },\n\n    /**\n     * @private\n     */\n    _beforeTransform: function(e) {\n      var t = this._currentTransform;\n      this.stateful && t.target.saveState();\n      this.fire('before:transform', {\n        e: e,\n        transform: t,\n      });\n      // determine if it's a drag or rotate case\n      if (t.corner) {\n        this.onBeforeScaleRotate(t.target);\n      }\n    },\n\n    /**\n     * Method that defines the actions when mouse is hovering the canvas.\n     * The currentTransform parameter will define whether the user is rotating/scaling/translating\n     * an image or neither of them (only hovering). A group selection is also possible and would cancel\n     * all any other type of action.\n     * In case of an image transformation only the top canvas will be rendered.\n     * @private\n     * @param {Event} e Event object fired on mousemove\n     */\n    __onMouseMove: function (e) {\n      this._handleEvent(e, 'move:before');\n      this._cacheTransformEventData(e);\n      var target, pointer;\n\n      if (this.isDrawingMode) {\n        this._onMouseMoveInDrawingMode(e);\n        return;\n      }\n\n      if (!this._isMainEvent(e)) {\n        return;\n      }\n\n      var groupSelector = this._groupSelector;\n\n      // We initially clicked in an empty area, so we draw a box for multiple selection\n      if (groupSelector) {\n        pointer = this._pointer;\n\n        groupSelector.left = pointer.x - groupSelector.ex;\n        groupSelector.top = pointer.y - groupSelector.ey;\n\n        this.renderTop();\n      }\n      else if (!this._currentTransform) {\n        target = this.findTarget(e) || null;\n        this._setCursorFromEvent(e, target);\n        this._fireOverOutEvents(target, e);\n      }\n      else {\n        this._transformObject(e);\n      }\n      this._handleEvent(e, 'move');\n      this._resetTransformEventData();\n    },\n\n    /**\n     * Manage the mouseout, mouseover events for the fabric object on the canvas\n     * @param {Fabric.Object} target the target where the target from the mousemove event\n     * @param {Event} e Event object fired on mousemove\n     * @private\n     */\n    _fireOverOutEvents: function(target, e) {\n      this.fireSyntheticInOutEvents(target, e, {\n        targetName: '_hoveredTarget',\n        canvasEvtOut: 'mouse:out',\n        evtOut: 'mouseout',\n        canvasEvtIn: 'mouse:over',\n        evtIn: 'mouseover',\n      });\n    },\n\n    /**\n     * Manage the dragEnter, dragLeave events for the fabric objects on the canvas\n     * @param {Fabric.Object} target the target where the target from the onDrag event\n     * @param {Event} e Event object fired on ondrag\n     * @private\n     */\n    _fireEnterLeaveEvents: function(target, e) {\n      this.fireSyntheticInOutEvents(target, e, {\n        targetName: '_draggedoverTarget',\n        evtOut: 'dragleave',\n        evtIn: 'dragenter',\n      });\n    },\n\n    /**\n     * Manage the synthetic in/out events for the fabric objects on the canvas\n     * @param {Fabric.Object} target the target where the target from the supported events\n     * @param {Event} e Event object fired\n     * @param {Object} config configuration for the function to work\n     * @param {String} config.targetName property on the canvas where the old target is stored\n     * @param {String} [config.canvasEvtOut] name of the event to fire at canvas level for out\n     * @param {String} config.evtOut name of the event to fire for out\n     * @param {String} [config.canvasEvtIn] name of the event to fire at canvas level for in\n     * @param {String} config.evtIn name of the event to fire for in\n     * @private\n     */\n    fireSyntheticInOutEvents: function(target, e, config) {\n      var inOpt, outOpt, oldTarget = this[config.targetName], outFires, inFires,\n          targetChanged = oldTarget !== target, canvasEvtIn = config.canvasEvtIn, canvasEvtOut = config.canvasEvtOut;\n      if (targetChanged) {\n        inOpt = { e: e, target: target, previousTarget: oldTarget };\n        outOpt = { e: e, target: oldTarget, nextTarget: target };\n        this[config.targetName] = target;\n      }\n      inFires = target && targetChanged;\n      outFires = oldTarget && targetChanged;\n      if (outFires) {\n        canvasEvtOut && this.fire(canvasEvtOut, outOpt);\n        oldTarget.fire(config.evtOut, outOpt);\n      }\n      if (inFires) {\n        canvasEvtIn && this.fire(canvasEvtIn, inOpt);\n        target.fire(config.evtIn, inOpt);\n      }\n    },\n\n    /**\n     * Method that defines actions when an Event Mouse Wheel\n     * @param {Event} e Event object fired on mouseup\n     */\n    __onMouseWheel: function(e) {\n      this._cacheTransformEventData(e);\n      this._handleEvent(e, 'wheel');\n      this._resetTransformEventData();\n    },\n\n    /**\n     * @private\n     * @param {Event} e Event fired on mousemove\n     */\n    _transformObject: function(e) {\n      var pointer = this.getPointer(e),\n          transform = this._currentTransform;\n\n      transform.reset = false;\n      transform.target.isMoving = true;\n      transform.shiftKey = e.shiftKey;\n      transform.altKey = e[this.centeredKey];\n\n      this._beforeScaleTransform(e, transform);\n      this._performTransformAction(e, transform, pointer);\n\n      transform.actionPerformed && this.requestRenderAll();\n    },\n\n    /**\n     * @private\n     */\n    _performTransformAction: function(e, transform, pointer) {\n      var x = pointer.x,\n          y = pointer.y,\n          action = transform.action,\n          actionPerformed = false,\n          options = {\n            target: transform.target,\n            e: e,\n            transform: transform,\n            pointer: pointer\n          };\n\n      if (action === 'rotate') {\n        (actionPerformed = this._rotateObject(x, y)) && this._fire('rotating', options);\n      }\n      else if (action === 'scale') {\n        (actionPerformed = this._onScale(e, transform, x, y)) && this._fire('scaling', options);\n      }\n      else if (action === 'scaleX') {\n        (actionPerformed = this._scaleObject(x, y, 'x')) && this._fire('scaling', options);\n      }\n      else if (action === 'scaleY') {\n        (actionPerformed = this._scaleObject(x, y, 'y')) && this._fire('scaling', options);\n      }\n      else if (action === 'skewX') {\n        (actionPerformed = this._skewObject(x, y, 'x')) && this._fire('skewing', options);\n      }\n      else if (action === 'skewY') {\n        (actionPerformed = this._skewObject(x, y, 'y')) && this._fire('skewing', options);\n      }\n      else {\n        actionPerformed = this._translateObject(x, y);\n        if (actionPerformed) {\n          this._fire('moving', options);\n          this.setCursor(options.target.moveCursor || this.moveCursor);\n        }\n      }\n      transform.actionPerformed = transform.actionPerformed || actionPerformed;\n    },\n\n    /**\n     * @private\n     */\n    _fire: function(eventName, options) {\n      this.fire('object:' + eventName, options);\n      options.target.fire(eventName, options);\n    },\n\n    /**\n     * @private\n     */\n    _beforeScaleTransform: function(e, transform) {\n      if (transform.action === 'scale' || transform.action === 'scaleX' || transform.action === 'scaleY') {\n        var centerTransform = this._shouldCenterTransform(transform.target);\n\n        // Switch from a normal resize to center-based\n        if ((centerTransform && (transform.originX !== 'center' || transform.originY !== 'center')) ||\n           // Switch from center-based resize to normal one\n           (!centerTransform && transform.originX === 'center' && transform.originY === 'center')\n        ) {\n          this._resetCurrentTransform();\n          transform.reset = true;\n        }\n      }\n    },\n\n    /**\n     * @private\n     * @param {Event} e Event object\n     * @param {Object} transform current transform\n     * @param {Number} x mouse position x from origin\n     * @param {Number} y mouse position y from origin\n     * @return {Boolean} true if the scaling occurred\n     */\n    _onScale: function(e, transform, x, y) {\n      if (this._isUniscalePossible(e, transform.target)) {\n        transform.currentAction = 'scale';\n        return this._scaleObject(x, y);\n      }\n      else {\n        // Switch from a normal resize to proportional\n        if (!transform.reset && transform.currentAction === 'scale') {\n          this._resetCurrentTransform();\n        }\n\n        transform.currentAction = 'scaleEqually';\n        return this._scaleObject(x, y, 'equally');\n      }\n    },\n\n    /**\n     * @private\n     * @param {Event} e Event object\n     * @param {fabric.Object} target current target\n     * @return {Boolean} true if unproportional scaling is possible\n     */\n    _isUniscalePossible: function(e, target) {\n      return (e[this.uniScaleKey] || this.uniScaleTransform) && !target.get('lockUniScaling');\n    },\n\n    /**\n     * Sets the cursor depending on where the canvas is being hovered.\n     * Note: very buggy in Opera\n     * @param {Event} e Event object\n     * @param {Object} target Object that the mouse is hovering, if so.\n     */\n    _setCursorFromEvent: function (e, target) {\n      if (!target) {\n        this.setCursor(this.defaultCursor);\n        return false;\n      }\n      var hoverCursor = target.hoverCursor || this.hoverCursor,\n          activeSelection = this._activeObject && this._activeObject.type === 'activeSelection' ?\n            this._activeObject : null,\n          // only show proper corner when group selection is not active\n          corner = (!activeSelection || !activeSelection.contains(target))\n                    && target._findTargetCorner(this.getPointer(e, true));\n\n      if (!corner) {\n        this.setCursor(hoverCursor);\n      }\n      else {\n        this.setCursor(this.getCornerCursor(corner, target, e));\n      }\n    },\n\n    /**\n     * @private\n     */\n    getCornerCursor: function(corner, target, e) {\n      if (this.actionIsDisabled(corner, target, e)) {\n        return this.notAllowedCursor;\n      }\n      else if (corner in cursorOffset) {\n        return this._getRotatedCornerCursor(corner, target, e);\n      }\n      else if (corner === 'mtr' && target.hasRotatingPoint) {\n        return this.rotationCursor;\n      }\n      else {\n        return this.defaultCursor;\n      }\n    },\n\n    actionIsDisabled: function(corner, target, e) {\n      if (corner === 'mt' || corner === 'mb') {\n        return e[this.altActionKey] ? target.lockSkewingX : target.lockScalingY;\n      }\n      else if (corner === 'ml' || corner === 'mr') {\n        return e[this.altActionKey] ? target.lockSkewingY : target.lockScalingX;\n      }\n      else if (corner === 'mtr') {\n        return target.lockRotation;\n      }\n      else {\n        return this._isUniscalePossible(e, target) ?\n          target.lockScalingX && target.lockScalingY : target.lockScalingX || target.lockScalingY;\n      }\n    },\n\n    /**\n     * @private\n     */\n    _getRotatedCornerCursor: function(corner, target, e) {\n      var n = Math.round((target.angle % 360) / 45);\n\n      if (n < 0) {\n        n += 8; // full circle ahead\n      }\n      n += cursorOffset[corner];\n      if (e[this.altActionKey] && cursorOffset[corner] % 2 === 0) {\n        //if we are holding shift and we are on a mx corner...\n        n += 2;\n      }\n      // normalize n to be from 0 to 7\n      n %= 8;\n\n      return this.cursorMap[n];\n    }\n  });\n})();\n\n\n(function() {\n\n  var min = Math.min,\n      max = Math.max;\n\n  fabric.util.object.extend(fabric.Canvas.prototype, /** @lends fabric.Canvas.prototype */ {\n\n    /**\n     * @private\n     * @param {Event} e Event object\n     * @param {fabric.Object} target\n     * @return {Boolean}\n     */\n    _shouldGroup: function(e, target) {\n      var activeObject = this._activeObject;\n      return activeObject && this._isSelectionKeyPressed(e) && target && target.selectable && this.selection &&\n            (activeObject !== target || activeObject.type === 'activeSelection') && !target.onSelect({ e: e });\n    },\n\n    /**\n     * @private\n     * @param {Event} e Event object\n     * @param {fabric.Object} target\n     */\n    _handleGrouping: function (e, target) {\n      var activeObject = this._activeObject;\n      // avoid multi select when shift click on a corner\n      if (activeObject.__corner) {\n        return;\n      }\n      if (target === activeObject) {\n        // if it's a group, find target again, using activeGroup objects\n        target = this.findTarget(e, true);\n        // if even object is not found or we are on activeObjectCorner, bail out\n        if (!target || !target.selectable) {\n          return;\n        }\n      }\n      if (activeObject && activeObject.type === 'activeSelection') {\n        this._updateActiveSelection(target, e);\n      }\n      else {\n        this._createActiveSelection(target, e);\n      }\n    },\n\n    /**\n     * @private\n     */\n    _updateActiveSelection: function(target, e) {\n      var activeSelection = this._activeObject,\n          currentActiveObjects = activeSelection._objects.slice(0);\n      if (activeSelection.contains(target)) {\n        activeSelection.removeWithUpdate(target);\n        this._hoveredTarget = target;\n        if (activeSelection.size() === 1) {\n          // activate last remaining object\n          this._setActiveObject(activeSelection.item(0), e);\n        }\n      }\n      else {\n        activeSelection.addWithUpdate(target);\n        this._hoveredTarget = activeSelection;\n      }\n      this._fireSelectionEvents(currentActiveObjects, e);\n    },\n\n    /**\n     * @private\n     */\n    _createActiveSelection: function(target, e) {\n      var currentActives = this.getActiveObjects(), group = this._createGroup(target);\n      this._hoveredTarget = group;\n      this._setActiveObject(group, e);\n      this._fireSelectionEvents(currentActives, e);\n    },\n\n    /**\n     * @private\n     * @param {Object} target\n     */\n    _createGroup: function(target) {\n      var objects = this._objects,\n          isActiveLower = objects.indexOf(this._activeObject) < objects.indexOf(target),\n          groupObjects = isActiveLower\n            ? [this._activeObject, target]\n            : [target, this._activeObject];\n      this._activeObject.isEditing && this._activeObject.exitEditing();\n      return new fabric.ActiveSelection(groupObjects, {\n        canvas: this\n      });\n    },\n\n    /**\n     * @private\n     * @param {Event} e mouse event\n     */\n    _groupSelectedObjects: function (e) {\n\n      var group = this._collectObjects(e),\n          aGroup;\n\n      // do not create group for 1 element only\n      if (group.length === 1) {\n        this.setActiveObject(group[0], e);\n      }\n      else if (group.length > 1) {\n        aGroup = new fabric.ActiveSelection(group.reverse(), {\n          canvas: this\n        });\n        this.setActiveObject(aGroup, e);\n      }\n    },\n\n    /**\n     * @private\n     */\n    _collectObjects: function(e) {\n      var group = [],\n          currentObject,\n          x1 = this._groupSelector.ex,\n          y1 = this._groupSelector.ey,\n          x2 = x1 + this._groupSelector.left,\n          y2 = y1 + this._groupSelector.top,\n          selectionX1Y1 = new fabric.Point(min(x1, x2), min(y1, y2)),\n          selectionX2Y2 = new fabric.Point(max(x1, x2), max(y1, y2)),\n          allowIntersect = !this.selectionFullyContained,\n          isClick = x1 === x2 && y1 === y2;\n      // we iterate reverse order to collect top first in case of click.\n      for (var i = this._objects.length; i--; ) {\n        currentObject = this._objects[i];\n\n        if (!currentObject || !currentObject.selectable || !currentObject.visible) {\n          continue;\n        }\n\n        if ((allowIntersect && currentObject.intersectsWithRect(selectionX1Y1, selectionX2Y2)) ||\n            currentObject.isContainedWithinRect(selectionX1Y1, selectionX2Y2) ||\n            (allowIntersect && currentObject.containsPoint(selectionX1Y1)) ||\n            (allowIntersect && currentObject.containsPoint(selectionX2Y2))\n        ) {\n          group.push(currentObject);\n          // only add one object if it's a click\n          if (isClick) {\n            break;\n          }\n        }\n      }\n\n      if (group.length > 1) {\n        group = group.filter(function(object) {\n          return !object.onSelect({ e: e });\n        });\n      }\n\n      return group;\n    },\n\n    /**\n     * @private\n     */\n    _maybeGroupObjects: function(e) {\n      if (this.selection && this._groupSelector) {\n        this._groupSelectedObjects(e);\n      }\n      this.setCursor(this.defaultCursor);\n      // clear selection and current transformation\n      this._groupSelector = null;\n    }\n  });\n\n})();\n\n\n(function () {\n  fabric.util.object.extend(fabric.StaticCanvas.prototype, /** @lends fabric.StaticCanvas.prototype */ {\n\n    /**\n     * Exports canvas element to a dataurl image. Note that when multiplier is used, cropping is scaled appropriately\n     * @param {Object} [options] Options object\n     * @param {String} [options.format=png] The format of the output image. Either \"jpeg\" or \"png\"\n     * @param {Number} [options.quality=1] Quality level (0..1). Only used for jpeg.\n     * @param {Number} [options.multiplier=1] Multiplier to scale by, to have consistent\n     * @param {Number} [options.left] Cropping left offset. Introduced in v1.2.14\n     * @param {Number} [options.top] Cropping top offset. Introduced in v1.2.14\n     * @param {Number} [options.width] Cropping width. Introduced in v1.2.14\n     * @param {Number} [options.height] Cropping height. Introduced in v1.2.14\n     * @param {Boolean} [options.enableRetinaScaling] Enable retina scaling for clone image. Introduce in 2.0.0\n     * @return {String} Returns a data: URL containing a representation of the object in the format specified by options.format\n     * @see {@link http://jsfiddle.net/fabricjs/NfZVb/|jsFiddle demo}\n     * @example <caption>Generate jpeg dataURL with lower quality</caption>\n     * var dataURL = canvas.toDataURL({\n     *   format: 'jpeg',\n     *   quality: 0.8\n     * });\n     * @example <caption>Generate cropped png dataURL (clipping of canvas)</caption>\n     * var dataURL = canvas.toDataURL({\n     *   format: 'png',\n     *   left: 100,\n     *   top: 100,\n     *   width: 200,\n     *   height: 200\n     * });\n     * @example <caption>Generate double scaled png dataURL</caption>\n     * var dataURL = canvas.toDataURL({\n     *   format: 'png',\n     *   multiplier: 2\n     * });\n     */\n    toDataURL: function (options) {\n      options || (options = { });\n\n      var format = options.format || 'png',\n          quality = options.quality || 1,\n          multiplier = (options.multiplier || 1) * (options.enableRetinaScaling ? this.getRetinaScaling() : 1),\n          canvasEl = this.toCanvasElement(multiplier, options);\n      return fabric.util.toDataURL(canvasEl, format, quality);\n    },\n\n    /**\n     * Create a new HTMLCanvas element painted with the current canvas content.\n     * No need to resize the actual one or repaint it.\n     * Will transfer object ownership to a new canvas, paint it, and set everything back.\n     * This is an intermediary step used to get to a dataUrl but also it is useful to\n     * create quick image copies of a canvas without passing for the dataUrl string\n     * @param {Number} [multiplier] a zoom factor.\n     * @param {Object} [cropping] Cropping informations\n     * @param {Number} [cropping.left] Cropping left offset.\n     * @param {Number} [cropping.top] Cropping top offset.\n     * @param {Number} [cropping.width] Cropping width.\n     * @param {Number} [cropping.height] Cropping height.\n     */\n    toCanvasElement: function(multiplier, cropping) {\n      multiplier = multiplier || 1;\n      cropping = cropping || { };\n      var scaledWidth = (cropping.width || this.width) * multiplier,\n          scaledHeight = (cropping.height || this.height) * multiplier,\n          zoom = this.getZoom(),\n          originalWidth = this.width,\n          originalHeight = this.height,\n          newZoom = zoom * multiplier,\n          vp = this.viewportTransform,\n          translateX = (vp[4] - (cropping.left || 0)) * multiplier,\n          translateY = (vp[5] - (cropping.top || 0)) * multiplier,\n          originalInteractive = this.interactive,\n          newVp = [newZoom, 0, 0, newZoom, translateX, translateY],\n          originalRetina = this.enableRetinaScaling,\n          canvasEl = fabric.util.createCanvasElement(),\n          originalContextTop = this.contextTop;\n      canvasEl.width = scaledWidth;\n      canvasEl.height = scaledHeight;\n      this.contextTop = null;\n      this.enableRetinaScaling = false;\n      this.interactive = false;\n      this.viewportTransform = newVp;\n      this.width = scaledWidth;\n      this.height = scaledHeight;\n      this.calcViewportBoundaries();\n      this.renderCanvas(canvasEl.getContext('2d'), this._objects);\n      this.viewportTransform = vp;\n      this.width = originalWidth;\n      this.height = originalHeight;\n      this.calcViewportBoundaries();\n      this.interactive = originalInteractive;\n      this.enableRetinaScaling = originalRetina;\n      this.contextTop = originalContextTop;\n      return canvasEl;\n    },\n  });\n\n})();\n\n\nfabric.util.object.extend(fabric.StaticCanvas.prototype, /** @lends fabric.StaticCanvas.prototype */ {\n\n  /**\n   * Populates canvas with data from the specified dataless JSON.\n   * JSON format must conform to the one of {@link fabric.Canvas#toDatalessJSON}\n   * @deprecated since 1.2.2\n   * @param {String|Object} json JSON string or object\n   * @param {Function} callback Callback, invoked when json is parsed\n   *                            and corresponding objects (e.g: {@link fabric.Image})\n   *                            are initialized\n   * @param {Function} [reviver] Method for further parsing of JSON elements, called after each fabric object created.\n   * @return {fabric.Canvas} instance\n   * @chainable\n   * @tutorial {@link http://fabricjs.com/fabric-intro-part-3#deserialization}\n   */\n  loadFromDatalessJSON: function (json, callback, reviver) {\n    return this.loadFromJSON(json, callback, reviver);\n  },\n\n  /**\n   * Populates canvas with data from the specified JSON.\n   * JSON format must conform to the one of {@link fabric.Canvas#toJSON}\n   * @param {String|Object} json JSON string or object\n   * @param {Function} callback Callback, invoked when json is parsed\n   *                            and corresponding objects (e.g: {@link fabric.Image})\n   *                            are initialized\n   * @param {Function} [reviver] Method for further parsing of JSON elements, called after each fabric object created.\n   * @return {fabric.Canvas} instance\n   * @chainable\n   * @tutorial {@link http://fabricjs.com/fabric-intro-part-3#deserialization}\n   * @see {@link http://jsfiddle.net/fabricjs/fmgXt/|jsFiddle demo}\n   * @example <caption>loadFromJSON</caption>\n   * canvas.loadFromJSON(json, canvas.renderAll.bind(canvas));\n   * @example <caption>loadFromJSON with reviver</caption>\n   * canvas.loadFromJSON(json, canvas.renderAll.bind(canvas), function(o, object) {\n   *   // `o` = json object\n   *   // `object` = fabric.Object instance\n   *   // ... do some stuff ...\n   * });\n   */\n  loadFromJSON: function (json, callback, reviver) {\n    if (!json) {\n      return;\n    }\n\n    // serialize if it wasn't already\n    var serialized = (typeof json === 'string')\n      ? JSON.parse(json)\n      : fabric.util.object.clone(json);\n\n    var _this = this,\n        clipPath = serialized.clipPath,\n        renderOnAddRemove = this.renderOnAddRemove;\n\n    this.renderOnAddRemove = false;\n\n    delete serialized.clipPath;\n\n    this._enlivenObjects(serialized.objects, function (enlivenedObjects) {\n      _this.clear();\n      _this._setBgOverlay(serialized, function () {\n        if (clipPath) {\n          _this._enlivenObjects([clipPath], function (enlivenedCanvasClip) {\n            _this.clipPath = enlivenedCanvasClip[0];\n            _this.__setupCanvas.call(_this, serialized, enlivenedObjects, renderOnAddRemove, callback);\n          });\n        }\n        else {\n          _this.__setupCanvas.call(_this, serialized, enlivenedObjects, renderOnAddRemove, callback);\n        }\n      });\n    }, reviver);\n    return this;\n  },\n\n  /**\n   * @private\n   * @param {Object} serialized Object with background and overlay information\n   * @param {Array} restored canvas objects\n   * @param {Function} cached renderOnAddRemove callback\n   * @param {Function} callback Invoked after all background and overlay images/patterns loaded\n   */\n  __setupCanvas: function(serialized, enlivenedObjects, renderOnAddRemove, callback) {\n    var _this = this;\n    enlivenedObjects.forEach(function(obj, index) {\n      // we splice the array just in case some custom classes restored from JSON\n      // will add more object to canvas at canvas init.\n      _this.insertAt(obj, index);\n    });\n    this.renderOnAddRemove = renderOnAddRemove;\n    // remove parts i cannot set as options\n    delete serialized.objects;\n    delete serialized.backgroundImage;\n    delete serialized.overlayImage;\n    delete serialized.background;\n    delete serialized.overlay;\n    // this._initOptions does too many things to just\n    // call it. Normally loading an Object from JSON\n    // create the Object instance. Here the Canvas is\n    // already an instance and we are just loading things over it\n    this._setOptions(serialized);\n    this.renderAll();\n    callback && callback();\n  },\n\n  /**\n   * @private\n   * @param {Object} serialized Object with background and overlay information\n   * @param {Function} callback Invoked after all background and overlay images/patterns loaded\n   */\n  _setBgOverlay: function(serialized, callback) {\n    var loaded = {\n      backgroundColor: false,\n      overlayColor: false,\n      backgroundImage: false,\n      overlayImage: false\n    };\n\n    if (!serialized.backgroundImage && !serialized.overlayImage && !serialized.background && !serialized.overlay) {\n      callback && callback();\n      return;\n    }\n\n    var cbIfLoaded = function () {\n      if (loaded.backgroundImage && loaded.overlayImage && loaded.backgroundColor && loaded.overlayColor) {\n        callback && callback();\n      }\n    };\n\n    this.__setBgOverlay('backgroundImage', serialized.backgroundImage, loaded, cbIfLoaded);\n    this.__setBgOverlay('overlayImage', serialized.overlayImage, loaded, cbIfLoaded);\n    this.__setBgOverlay('backgroundColor', serialized.background, loaded, cbIfLoaded);\n    this.__setBgOverlay('overlayColor', serialized.overlay, loaded, cbIfLoaded);\n  },\n\n  /**\n   * @private\n   * @param {String} property Property to set (backgroundImage, overlayImage, backgroundColor, overlayColor)\n   * @param {(Object|String)} value Value to set\n   * @param {Object} loaded Set loaded property to true if property is set\n   * @param {Object} callback Callback function to invoke after property is set\n   */\n  __setBgOverlay: function(property, value, loaded, callback) {\n    var _this = this;\n\n    if (!value) {\n      loaded[property] = true;\n      callback && callback();\n      return;\n    }\n\n    if (property === 'backgroundImage' || property === 'overlayImage') {\n      fabric.util.enlivenObjects([value], function(enlivedObject){\n        _this[property] = enlivedObject[0];\n        loaded[property] = true;\n        callback && callback();\n      });\n    }\n    else {\n      this['set' + fabric.util.string.capitalize(property, true)](value, function() {\n        loaded[property] = true;\n        callback && callback();\n      });\n    }\n  },\n\n  /**\n   * @private\n   * @param {Array} objects\n   * @param {Function} callback\n   * @param {Function} [reviver]\n   */\n  _enlivenObjects: function (objects, callback, reviver) {\n    if (!objects || objects.length === 0) {\n      callback && callback([]);\n      return;\n    }\n\n    fabric.util.enlivenObjects(objects, function(enlivenedObjects) {\n      callback && callback(enlivenedObjects);\n    }, null, reviver);\n  },\n\n  /**\n   * @private\n   * @param {String} format\n   * @param {Function} callback\n   */\n  _toDataURL: function (format, callback) {\n    this.clone(function (clone) {\n      callback(clone.toDataURL(format));\n    });\n  },\n\n  /**\n   * @private\n   * @param {String} format\n   * @param {Number} multiplier\n   * @param {Function} callback\n   */\n  _toDataURLWithMultiplier: function (format, multiplier, callback) {\n    this.clone(function (clone) {\n      callback(clone.toDataURLWithMultiplier(format, multiplier));\n    });\n  },\n\n  /**\n   * Clones canvas instance\n   * @param {Object} [callback] Receives cloned instance as a first argument\n   * @param {Array} [properties] Array of properties to include in the cloned canvas and children\n   */\n  clone: function (callback, properties) {\n    var data = JSON.stringify(this.toJSON(properties));\n    this.cloneWithoutData(function(clone) {\n      clone.loadFromJSON(data, function() {\n        callback && callback(clone);\n      });\n    });\n  },\n\n  /**\n   * Clones canvas instance without cloning existing data.\n   * This essentially copies canvas dimensions, clipping properties, etc.\n   * but leaves data empty (so that you can populate it with your own)\n   * @param {Object} [callback] Receives cloned instance as a first argument\n   */\n  cloneWithoutData: function(callback) {\n    var el = fabric.util.createCanvasElement();\n\n    el.width = this.width;\n    el.height = this.height;\n\n    var clone = new fabric.Canvas(el);\n    clone.clipTo = this.clipTo;\n    if (this.backgroundImage) {\n      clone.setBackgroundImage(this.backgroundImage.src, function() {\n        clone.renderAll();\n        callback && callback(clone);\n      });\n      clone.backgroundImageOpacity = this.backgroundImageOpacity;\n      clone.backgroundImageStretch = this.backgroundImageStretch;\n    }\n    else {\n      callback && callback(clone);\n    }\n  }\n});\n\n\n(function(global) {\n\n  'use strict';\n\n  var fabric = global.fabric || (global.fabric = { }),\n      extend = fabric.util.object.extend,\n      clone = fabric.util.object.clone,\n      toFixed = fabric.util.toFixed,\n      capitalize = fabric.util.string.capitalize,\n      degreesToRadians = fabric.util.degreesToRadians,\n      supportsLineDash = fabric.StaticCanvas.supports('setLineDash'),\n      objectCaching = !fabric.isLikelyNode,\n      ALIASING_LIMIT = 2;\n\n  if (fabric.Object) {\n    return;\n  }\n\n  /**\n   * Root object class from which all 2d shape classes inherit from\n   * @class fabric.Object\n   * @tutorial {@link http://fabricjs.com/fabric-intro-part-1#objects}\n   * @see {@link fabric.Object#initialize} for constructor definition\n   *\n   * @fires added\n   * @fires removed\n   *\n   * @fires selected\n   * @fires deselected\n   * @fires modified\n   * @fires modified\n   * @fires moved\n   * @fires scaled\n   * @fires rotated\n   * @fires skewed\n   *\n   * @fires rotating\n   * @fires scaling\n   * @fires moving\n   * @fires skewing\n   *\n   * @fires mousedown\n   * @fires mouseup\n   * @fires mouseover\n   * @fires mouseout\n   * @fires mousewheel\n   * @fires mousedblclick\n   *\n   * @fires dragover\n   * @fires dragenter\n   * @fires dragleave\n   * @fires drop\n   */\n  fabric.Object = fabric.util.createClass(fabric.CommonMethods, /** @lends fabric.Object.prototype */ {\n\n    /**\n     * Type of an object (rect, circle, path, etc.).\n     * Note that this property is meant to be read-only and not meant to be modified.\n     * If you modify, certain parts of Fabric (such as JSON loading) won't work correctly.\n     * @type String\n     * @default\n     */\n    type:                     'object',\n\n    /**\n     * Horizontal origin of transformation of an object (one of \"left\", \"right\", \"center\")\n     * See http://jsfiddle.net/1ow02gea/244/ on how originX/originY affect objects in groups\n     * @type String\n     * @default\n     */\n    originX:                  'left',\n\n    /**\n     * Vertical origin of transformation of an object (one of \"top\", \"bottom\", \"center\")\n     * See http://jsfiddle.net/1ow02gea/244/ on how originX/originY affect objects in groups\n     * @type String\n     * @default\n     */\n    originY:                  'top',\n\n    /**\n     * Top position of an object. Note that by default it's relative to object top. You can change this by setting originY={top/center/bottom}\n     * @type Number\n     * @default\n     */\n    top:                      0,\n\n    /**\n     * Left position of an object. Note that by default it's relative to object left. You can change this by setting originX={left/center/right}\n     * @type Number\n     * @default\n     */\n    left:                     0,\n\n    /**\n     * Object width\n     * @type Number\n     * @default\n     */\n    width:                    0,\n\n    /**\n     * Object height\n     * @type Number\n     * @default\n     */\n    height:                   0,\n\n    /**\n     * Object scale factor (horizontal)\n     * @type Number\n     * @default\n     */\n    scaleX:                   1,\n\n    /**\n     * Object scale factor (vertical)\n     * @type Number\n     * @default\n     */\n    scaleY:                   1,\n\n    /**\n     * When true, an object is rendered as flipped horizontally\n     * @type Boolean\n     * @default\n     */\n    flipX:                    false,\n\n    /**\n     * When true, an object is rendered as flipped vertically\n     * @type Boolean\n     * @default\n     */\n    flipY:                    false,\n\n    /**\n     * Opacity of an object\n     * @type Number\n     * @default\n     */\n    opacity:                  1,\n\n    /**\n     * Angle of rotation of an object (in degrees)\n     * @type Number\n     * @default\n     */\n    angle:                    0,\n\n    /**\n     * Angle of skew on x axes of an object (in degrees)\n     * @type Number\n     * @default\n     */\n    skewX:                    0,\n\n    /**\n     * Angle of skew on y axes of an object (in degrees)\n     * @type Number\n     * @default\n     */\n    skewY:                    0,\n\n    /**\n     * Size of object's controlling corners (in pixels)\n     * @type Number\n     * @default\n     */\n    cornerSize:               13,\n\n    /**\n     * When true, object's controlling corners are rendered as transparent inside (i.e. stroke instead of fill)\n     * @type Boolean\n     * @default\n     */\n    transparentCorners:       true,\n\n    /**\n     * Default cursor value used when hovering over this object on canvas\n     * @type String\n     * @default\n     */\n    hoverCursor:              null,\n\n    /**\n     * Default cursor value used when moving this object on canvas\n     * @type String\n     * @default\n     */\n    moveCursor:               null,\n\n    /**\n     * Padding between object and its controlling borders (in pixels)\n     * @type Number\n     * @default\n     */\n    padding:                  0,\n\n    /**\n     * Color of controlling borders of an object (when it's active)\n     * @type String\n     * @default\n     */\n    borderColor:              'rgba(102,153,255,0.75)',\n\n    /**\n     * Array specifying dash pattern of an object's borders (hasBorder must be true)\n     * @since 1.6.2\n     * @type Array\n     */\n    borderDashArray:          null,\n\n    /**\n     * Color of controlling corners of an object (when it's active)\n     * @type String\n     * @default\n     */\n    cornerColor:              'rgba(102,153,255,0.5)',\n\n    /**\n     * Color of controlling corners of an object (when it's active and transparentCorners false)\n     * @since 1.6.2\n     * @type String\n     * @default\n     */\n    cornerStrokeColor:        null,\n\n    /**\n     * Specify style of control, 'rect' or 'circle'\n     * @since 1.6.2\n     * @type String\n     */\n    cornerStyle:          'rect',\n\n    /**\n     * Array specifying dash pattern of an object's control (hasBorder must be true)\n     * @since 1.6.2\n     * @type Array\n     */\n    cornerDashArray:          null,\n\n    /**\n     * When true, this object will use center point as the origin of transformation\n     * when being scaled via the controls.\n     * <b>Backwards incompatibility note:</b> This property replaces \"centerTransform\" (Boolean).\n     * @since 1.3.4\n     * @type Boolean\n     * @default\n     */\n    centeredScaling:          false,\n\n    /**\n     * When true, this object will use center point as the origin of transformation\n     * when being rotated via the controls.\n     * <b>Backwards incompatibility note:</b> This property replaces \"centerTransform\" (Boolean).\n     * @since 1.3.4\n     * @type Boolean\n     * @default\n     */\n    centeredRotation:         true,\n\n    /**\n     * Color of object's fill\n     * takes css colors https://www.w3.org/TR/css-color-3/\n     * @type String\n     * @default\n     */\n    fill:                     'rgb(0,0,0)',\n\n    /**\n     * Fill rule used to fill an object\n     * accepted values are nonzero, evenodd\n     * <b>Backwards incompatibility note:</b> This property was used for setting globalCompositeOperation until v1.4.12 (use `fabric.Object#globalCompositeOperation` instead)\n     * @type String\n     * @default\n     */\n    fillRule:                 'nonzero',\n\n    /**\n     * Composite rule used for canvas globalCompositeOperation\n     * @type String\n     * @default\n     */\n    globalCompositeOperation: 'source-over',\n\n    /**\n     * Background color of an object.\n     * takes css colors https://www.w3.org/TR/css-color-3/\n     * @type String\n     * @default\n     */\n    backgroundColor:          '',\n\n    /**\n     * Selection Background color of an object. colored layer behind the object when it is active.\n     * does not mix good with globalCompositeOperation methods.\n     * @type String\n     * @default\n     */\n    selectionBackgroundColor:          '',\n\n    /**\n     * When defined, an object is rendered via stroke and this property specifies its color\n     * takes css colors https://www.w3.org/TR/css-color-3/\n     * @type String\n     * @default\n     */\n    stroke:                   null,\n\n    /**\n     * Width of a stroke used to render this object\n     * @type Number\n     * @default\n     */\n    strokeWidth:              1,\n\n    /**\n     * Array specifying dash pattern of an object's stroke (stroke must be defined)\n     * @type Array\n     */\n    strokeDashArray:          null,\n\n    /**\n     * Line offset of an object's stroke\n     * @type Number\n     * @default\n     */\n    strokeDashOffset: 0,\n\n    /**\n     * Line endings style of an object's stroke (one of \"butt\", \"round\", \"square\")\n     * @type String\n     * @default\n     */\n    strokeLineCap:            'butt',\n\n    /**\n     * Corner style of an object's stroke (one of \"bevil\", \"round\", \"miter\")\n     * @type String\n     * @default\n     */\n    strokeLineJoin:           'miter',\n\n    /**\n     * Maximum miter length (used for strokeLineJoin = \"miter\") of an object's stroke\n     * @type Number\n     * @default\n     */\n    strokeMiterLimit:         4,\n\n    /**\n     * Shadow object representing shadow of this shape\n     * @type fabric.Shadow\n     * @default\n     */\n    shadow:                   null,\n\n    /**\n     * Opacity of object's controlling borders when object is active and moving\n     * @type Number\n     * @default\n     */\n    borderOpacityWhenMoving:  0.4,\n\n    /**\n     * Scale factor of object's controlling borders\n     * @type Number\n     * @default\n     */\n    borderScaleFactor:        1,\n\n    /**\n     * Transform matrix (similar to SVG's transform matrix)\n     * This property has been depreacted. Since caching and and qrDecompose this\n     * property can be handled with the standard top,left,scaleX,scaleY,angle and skewX.\n     * A documentation example on how to parse and merge a transformMatrix will be provided before\n     * completely removing it in fabric 4.0\n     * If you are starting a project now, DO NOT use it.\n     * @deprecated since 3.2.0\n     * @type Array\n     */\n    transformMatrix:          null,\n\n    /**\n     * Minimum allowed scale value of an object\n     * @type Number\n     * @default\n     */\n    minScaleLimit:            0,\n\n    /**\n     * When set to `false`, an object can not be selected for modification (using either point-click-based or group-based selection).\n     * But events still fire on it.\n     * @type Boolean\n     * @default\n     */\n    selectable:               true,\n\n    /**\n     * When set to `false`, an object can not be a target of events. All events propagate through it. Introduced in v1.3.4\n     * @type Boolean\n     * @default\n     */\n    evented:                  true,\n\n    /**\n     * When set to `false`, an object is not rendered on canvas\n     * @type Boolean\n     * @default\n     */\n    visible:                  true,\n\n    /**\n     * When set to `false`, object's controls are not displayed and can not be used to manipulate object\n     * @type Boolean\n     * @default\n     */\n    hasControls:              true,\n\n    /**\n     * When set to `false`, object's controlling borders are not rendered\n     * @type Boolean\n     * @default\n     */\n    hasBorders:               true,\n\n    /**\n     * When set to `false`, object's controlling rotating point will not be visible or selectable\n     * @type Boolean\n     * @default\n     */\n    hasRotatingPoint:         true,\n\n    /**\n     * Offset for object's controlling rotating point (when enabled via `hasRotatingPoint`)\n     * @type Number\n     * @default\n     */\n    rotatingPointOffset:      40,\n\n    /**\n     * When set to `true`, objects are \"found\" on canvas on per-pixel basis rather than according to bounding box\n     * @type Boolean\n     * @default\n     */\n    perPixelTargetFind:       false,\n\n    /**\n     * When `false`, default object's values are not included in its serialization\n     * @type Boolean\n     * @default\n     */\n    includeDefaultValues:     true,\n\n    /**\n     * Function that determines clipping of an object (context is passed as a first argument).\n     * If you are using code minification, ctx argument can be minified/manglied you should use\n     * as a workaround `var ctx = arguments[0];` in the function;\n     * Note that context origin is at the object's center point (not left/top corner)\n     * @deprecated since 2.0.0\n     * @type Function\n     */\n    clipTo:                   null,\n\n    /**\n     * When `true`, object horizontal movement is locked\n     * @type Boolean\n     * @default\n     */\n    lockMovementX:            false,\n\n    /**\n     * When `true`, object vertical movement is locked\n     * @type Boolean\n     * @default\n     */\n    lockMovementY:            false,\n\n    /**\n     * When `true`, object rotation is locked\n     * @type Boolean\n     * @default\n     */\n    lockRotation:             false,\n\n    /**\n     * When `true`, object horizontal scaling is locked\n     * @type Boolean\n     * @default\n     */\n    lockScalingX:             false,\n\n    /**\n     * When `true`, object vertical scaling is locked\n     * @type Boolean\n     * @default\n     */\n    lockScalingY:             false,\n\n    /**\n     * When `true`, object non-uniform scaling is locked\n     * @type Boolean\n     * @default\n     */\n    lockUniScaling:           false,\n\n    /**\n     * When `true`, object horizontal skewing is locked\n     * @type Boolean\n     * @default\n     */\n    lockSkewingX:             false,\n\n    /**\n     * When `true`, object vertical skewing is locked\n     * @type Boolean\n     * @default\n     */\n    lockSkewingY:             false,\n\n    /**\n     * When `true`, object cannot be flipped by scaling into negative values\n     * @type Boolean\n     * @default\n     */\n    lockScalingFlip:          false,\n\n    /**\n     * When `true`, object is not exported in OBJECT/JSON\n     * @since 1.6.3\n     * @type Boolean\n     * @default\n     */\n    excludeFromExport:        false,\n\n    /**\n     * When `true`, object is cached on an additional canvas.\n     * When `false`, object is not cached unless necessary ( clipPath )\n     * default to true\n     * @since 1.7.0\n     * @type Boolean\n     * @default true\n     */\n    objectCaching:            objectCaching,\n\n    /**\n     * When `true`, object properties are checked for cache invalidation. In some particular\n     * situation you may want this to be disabled ( spray brush, very big, groups)\n     * or if your application does not allow you to modify properties for groups child you want\n     * to disable it for groups.\n     * default to false\n     * since 1.7.0\n     * @type Boolean\n     * @default false\n     */\n    statefullCache:            false,\n\n    /**\n     * When `true`, cache does not get updated during scaling. The picture will get blocky if scaled\n     * too much and will be redrawn with correct details at the end of scaling.\n     * this setting is performance and application dependant.\n     * default to true\n     * since 1.7.0\n     * @type Boolean\n     * @default true\n     */\n    noScaleCache:              true,\n\n    /**\n     * When `false`, the stoke width will scale with the object.\n     * When `true`, the stroke will always match the exact pixel size entered for stroke width.\n     * default to false\n     * @since 2.6.0\n     * @type Boolean\n     * @default false\n     * @type Boolean\n     * @default false\n     */\n    strokeUniform:              false,\n\n    /**\n     * When set to `true`, object's cache will be rerendered next render call.\n     * since 1.7.0\n     * @type Boolean\n     * @default true\n     */\n    dirty:                true,\n\n    /**\n     * keeps the value of the last hovered corner during mouse move.\n     * 0 is no corner, or 'mt', 'ml', 'mtr' etc..\n     * It should be private, but there is no harm in using it as\n     * a read-only property.\n     * @type number|string|any\n     * @default 0\n     */\n    __corner: 0,\n\n    /**\n     * Determines if the fill or the stroke is drawn first (one of \"fill\" or \"stroke\")\n     * @type String\n     * @default\n     */\n    paintFirst:           'fill',\n\n    /**\n     * List of properties to consider when checking if state\n     * of an object is changed (fabric.Object#hasStateChanged)\n     * as well as for history (undo/redo) purposes\n     * @type Array\n     */\n    stateProperties: (\n      'top left width height scaleX scaleY flipX flipY originX originY transformMatrix ' +\n      'stroke strokeWidth strokeDashArray strokeLineCap strokeDashOffset strokeLineJoin strokeMiterLimit ' +\n      'angle opacity fill globalCompositeOperation shadow clipTo visible backgroundColor ' +\n      'skewX skewY fillRule paintFirst clipPath strokeUniform'\n    ).split(' '),\n\n    /**\n     * List of properties to consider when checking if cache needs refresh\n     * Those properties are checked by statefullCache ON ( or lazy mode if we want ) or from single\n     * calls to Object.set(key, value). If the key is in this list, the object is marked as dirty\n     * and refreshed at the next render\n     * @type Array\n     */\n    cacheProperties: (\n      'fill stroke strokeWidth strokeDashArray width height paintFirst strokeUniform' +\n      ' strokeLineCap strokeDashOffset strokeLineJoin strokeMiterLimit backgroundColor clipPath'\n    ).split(' '),\n\n    /**\n     * a fabricObject that, without stroke define a clipping area with their shape. filled in black\n     * the clipPath object gets used when the object has rendered, and the context is placed in the center\n     * of the object cacheCanvas.\n     * If you want 0,0 of a clipPath to align with an object center, use clipPath.originX/Y to 'center'\n     * @type fabric.Object\n     */\n    clipPath: undefined,\n\n    /**\n     * Meaningful ONLY when the object is used as clipPath.\n     * if true, the clipPath will make the object clip to the outside of the clipPath\n     * since 2.4.0\n     * @type boolean\n     * @default false\n     */\n    inverted: false,\n\n    /**\n     * Meaningful ONLY when the object is used as clipPath.\n     * if true, the clipPath will have its top and left relative to canvas, and will\n     * not be influenced by the object transform. This will make the clipPath relative\n     * to the canvas, but clipping just a particular object.\n     * WARNING this is beta, this feature may change or be renamed.\n     * since 2.4.0\n     * @type boolean\n     * @default false\n     */\n    absolutePositioned: false,\n\n    /**\n     * Constructor\n     * @param {Object} [options] Options object\n     */\n    initialize: function(options) {\n      if (options) {\n        this.setOptions(options);\n      }\n    },\n\n    /**\n     * Create a the canvas used to keep the cached copy of the object\n     * @private\n     */\n    _createCacheCanvas: function() {\n      this._cacheProperties = {};\n      this._cacheCanvas = fabric.util.createCanvasElement();\n      this._cacheContext = this._cacheCanvas.getContext('2d');\n      this._updateCacheCanvas();\n      // if canvas gets created, is empty, so dirty.\n      this.dirty = true;\n    },\n\n    /**\n     * Limit the cache dimensions so that X * Y do not cross fabric.perfLimitSizeTotal\n     * and each side do not cross fabric.cacheSideLimit\n     * those numbers are configurable so that you can get as much detail as you want\n     * making bargain with performances.\n     * @param {Object} dims\n     * @param {Object} dims.width width of canvas\n     * @param {Object} dims.height height of canvas\n     * @param {Object} dims.zoomX zoomX zoom value to unscale the canvas before drawing cache\n     * @param {Object} dims.zoomY zoomY zoom value to unscale the canvas before drawing cache\n     * @return {Object}.width width of canvas\n     * @return {Object}.height height of canvas\n     * @return {Object}.zoomX zoomX zoom value to unscale the canvas before drawing cache\n     * @return {Object}.zoomY zoomY zoom value to unscale the canvas before drawing cache\n     */\n    _limitCacheSize: function(dims) {\n      var perfLimitSizeTotal = fabric.perfLimitSizeTotal,\n          width = dims.width, height = dims.height,\n          max = fabric.maxCacheSideLimit, min = fabric.minCacheSideLimit;\n      if (width <= max && height <= max && width * height <= perfLimitSizeTotal) {\n        if (width < min) {\n          dims.width = min;\n        }\n        if (height < min) {\n          dims.height = min;\n        }\n        return dims;\n      }\n      var ar = width / height, limitedDims = fabric.util.limitDimsByArea(ar, perfLimitSizeTotal),\n          capValue = fabric.util.capValue,\n          x = capValue(min, limitedDims.x, max),\n          y = capValue(min, limitedDims.y, max);\n      if (width > x) {\n        dims.zoomX /= width / x;\n        dims.width = x;\n        dims.capped = true;\n      }\n      if (height > y) {\n        dims.zoomY /= height / y;\n        dims.height = y;\n        dims.capped = true;\n      }\n      return dims;\n    },\n\n    /**\n     * Return the dimension and the zoom level needed to create a cache canvas\n     * big enough to host the object to be cached.\n     * @private\n     * @return {Object}.x width of object to be cached\n     * @return {Object}.y height of object to be cached\n     * @return {Object}.width width of canvas\n     * @return {Object}.height height of canvas\n     * @return {Object}.zoomX zoomX zoom value to unscale the canvas before drawing cache\n     * @return {Object}.zoomY zoomY zoom value to unscale the canvas before drawing cache\n     */\n    _getCacheCanvasDimensions: function() {\n      var objectScale = this.getTotalObjectScaling(),\n          // caculate dimensions without skewing\n          dim = this._getTransformedDimensions(0, 0),\n          neededX = dim.x * objectScale.scaleX / this.scaleX,\n          neededY = dim.y * objectScale.scaleY / this.scaleY;\n      return {\n        // for sure this ALIASING_LIMIT is slightly creating problem\n        // in situation in which the cache canvas gets an upper limit\n        // also objectScale contains already scaleX and scaleY\n        width: neededX + ALIASING_LIMIT,\n        height: neededY + ALIASING_LIMIT,\n        zoomX: objectScale.scaleX,\n        zoomY: objectScale.scaleY,\n        x: neededX,\n        y: neededY\n      };\n    },\n\n    /**\n     * Update width and height of the canvas for cache\n     * returns true or false if canvas needed resize.\n     * @private\n     * @return {Boolean} true if the canvas has been resized\n     */\n    _updateCacheCanvas: function() {\n      var targetCanvas = this.canvas;\n      if (this.noScaleCache && targetCanvas && targetCanvas._currentTransform) {\n        var target = targetCanvas._currentTransform.target,\n            action = targetCanvas._currentTransform.action;\n        if (this === target && action.slice && action.slice(0, 5) === 'scale') {\n          return false;\n        }\n      }\n      var canvas = this._cacheCanvas,\n          dims = this._limitCacheSize(this._getCacheCanvasDimensions()),\n          minCacheSize = fabric.minCacheSideLimit,\n          width = dims.width, height = dims.height, drawingWidth, drawingHeight,\n          zoomX = dims.zoomX, zoomY = dims.zoomY,\n          dimensionsChanged = width !== this.cacheWidth || height !== this.cacheHeight,\n          zoomChanged = this.zoomX !== zoomX || this.zoomY !== zoomY,\n          shouldRedraw = dimensionsChanged || zoomChanged,\n          additionalWidth = 0, additionalHeight = 0, shouldResizeCanvas = false;\n      if (dimensionsChanged) {\n        var canvasWidth = this._cacheCanvas.width,\n            canvasHeight = this._cacheCanvas.height,\n            sizeGrowing = width > canvasWidth || height > canvasHeight,\n            sizeShrinking = (width < canvasWidth * 0.9 || height < canvasHeight * 0.9) &&\n              canvasWidth > minCacheSize && canvasHeight > minCacheSize;\n        shouldResizeCanvas = sizeGrowing || sizeShrinking;\n        if (sizeGrowing && !dims.capped && (width > minCacheSize || height > minCacheSize)) {\n          additionalWidth = width * 0.1;\n          additionalHeight = height * 0.1;\n        }\n      }\n      if (shouldRedraw) {\n        if (shouldResizeCanvas) {\n          canvas.width = Math.ceil(width + additionalWidth);\n          canvas.height = Math.ceil(height + additionalHeight);\n        }\n        else {\n          this._cacheContext.setTransform(1, 0, 0, 1, 0, 0);\n          this._cacheContext.clearRect(0, 0, canvas.width, canvas.height);\n        }\n        drawingWidth = dims.x / 2;\n        drawingHeight = dims.y / 2;\n        this.cacheTranslationX = Math.round(canvas.width / 2 - drawingWidth) + drawingWidth;\n        this.cacheTranslationY = Math.round(canvas.height / 2 - drawingHeight) + drawingHeight;\n        this.cacheWidth = width;\n        this.cacheHeight = height;\n        this._cacheContext.translate(this.cacheTranslationX, this.cacheTranslationY);\n        this._cacheContext.scale(zoomX, zoomY);\n        this.zoomX = zoomX;\n        this.zoomY = zoomY;\n        return true;\n      }\n      return false;\n    },\n\n    /**\n     * Sets object's properties from options\n     * @param {Object} [options] Options object\n     */\n    setOptions: function(options) {\n      this._setOptions(options);\n      this._initGradient(options.fill, 'fill');\n      this._initGradient(options.stroke, 'stroke');\n      this._initClipping(options);\n      this._initPattern(options.fill, 'fill');\n      this._initPattern(options.stroke, 'stroke');\n    },\n\n    /**\n     * Transforms context when rendering an object\n     * @param {CanvasRenderingContext2D} ctx Context\n     */\n    transform: function(ctx) {\n      var m;\n      if (this.group && !this.group._transformDone) {\n        m = this.calcTransformMatrix();\n      }\n      else {\n        m = this.calcOwnMatrix();\n      }\n      ctx.transform(m[0], m[1], m[2], m[3], m[4], m[5]);\n    },\n\n    /**\n     * Returns an object representation of an instance\n     * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output\n     * @return {Object} Object representation of an instance\n     */\n    toObject: function(propertiesToInclude) {\n      var NUM_FRACTION_DIGITS = fabric.Object.NUM_FRACTION_DIGITS,\n\n          object = {\n            type:                     this.type,\n            version:                  fabric.version,\n            originX:                  this.originX,\n            originY:                  this.originY,\n            left:                     toFixed(this.left, NUM_FRACTION_DIGITS),\n            top:                      toFixed(this.top, NUM_FRACTION_DIGITS),\n            width:                    toFixed(this.width, NUM_FRACTION_DIGITS),\n            height:                   toFixed(this.height, NUM_FRACTION_DIGITS),\n            fill:                     (this.fill && this.fill.toObject) ? this.fill.toObject() : this.fill,\n            stroke:                   (this.stroke && this.stroke.toObject) ? this.stroke.toObject() : this.stroke,\n            strokeWidth:              toFixed(this.strokeWidth, NUM_FRACTION_DIGITS),\n            strokeDashArray:          this.strokeDashArray ? this.strokeDashArray.concat() : this.strokeDashArray,\n            strokeLineCap:            this.strokeLineCap,\n            strokeDashOffset:         this.strokeDashOffset,\n            strokeLineJoin:           this.strokeLineJoin,\n            strokeMiterLimit:         toFixed(this.strokeMiterLimit, NUM_FRACTION_DIGITS),\n            scaleX:                   toFixed(this.scaleX, NUM_FRACTION_DIGITS),\n            scaleY:                   toFixed(this.scaleY, NUM_FRACTION_DIGITS),\n            angle:                    toFixed(this.angle, NUM_FRACTION_DIGITS),\n            flipX:                    this.flipX,\n            flipY:                    this.flipY,\n            opacity:                  toFixed(this.opacity, NUM_FRACTION_DIGITS),\n            shadow:                   (this.shadow && this.shadow.toObject) ? this.shadow.toObject() : this.shadow,\n            visible:                  this.visible,\n            clipTo:                   this.clipTo && String(this.clipTo),\n            backgroundColor:          this.backgroundColor,\n            fillRule:                 this.fillRule,\n            paintFirst:               this.paintFirst,\n            globalCompositeOperation: this.globalCompositeOperation,\n            transformMatrix:          this.transformMatrix ? this.transformMatrix.concat() : null,\n            skewX:                    toFixed(this.skewX, NUM_FRACTION_DIGITS),\n            skewY:                    toFixed(this.skewY, NUM_FRACTION_DIGITS),\n          };\n\n      if (this.clipPath) {\n        object.clipPath = this.clipPath.toObject(propertiesToInclude);\n        object.clipPath.inverted = this.clipPath.inverted;\n        object.clipPath.absolutePositioned = this.clipPath.absolutePositioned;\n      }\n\n      fabric.util.populateWithProperties(this, object, propertiesToInclude);\n      if (!this.includeDefaultValues) {\n        object = this._removeDefaultValues(object);\n      }\n\n      return object;\n    },\n\n    /**\n     * Returns (dataless) object representation of an instance\n     * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output\n     * @return {Object} Object representation of an instance\n     */\n    toDatalessObject: function(propertiesToInclude) {\n      // will be overwritten by subclasses\n      return this.toObject(propertiesToInclude);\n    },\n\n    /**\n     * @private\n     * @param {Object} object\n     */\n    _removeDefaultValues: function(object) {\n      var prototype = fabric.util.getKlass(object.type).prototype,\n          stateProperties = prototype.stateProperties;\n      stateProperties.forEach(function(prop) {\n        if (prop === 'left' || prop === 'top') {\n          return;\n        }\n        if (object[prop] === prototype[prop]) {\n          delete object[prop];\n        }\n        var isArray = Object.prototype.toString.call(object[prop]) === '[object Array]' &&\n                      Object.prototype.toString.call(prototype[prop]) === '[object Array]';\n\n        // basically a check for [] === []\n        if (isArray && object[prop].length === 0 && prototype[prop].length === 0) {\n          delete object[prop];\n        }\n      });\n\n      return object;\n    },\n\n    /**\n     * Returns a string representation of an instance\n     * @return {String}\n     */\n    toString: function() {\n      return '#<fabric.' + capitalize(this.type) + '>';\n    },\n\n    /**\n     * Return the object scale factor counting also the group scaling\n     * @return {Object} object with scaleX and scaleY properties\n     */\n    getObjectScaling: function() {\n      var scaleX = this.scaleX, scaleY = this.scaleY;\n      if (this.group) {\n        var scaling = this.group.getObjectScaling();\n        scaleX *= scaling.scaleX;\n        scaleY *= scaling.scaleY;\n      }\n      return { scaleX: scaleX, scaleY: scaleY };\n    },\n\n    /**\n     * Return the object scale factor counting also the group scaling, zoom and retina\n     * @return {Object} object with scaleX and scaleY properties\n     */\n    getTotalObjectScaling: function() {\n      var scale = this.getObjectScaling(), scaleX = scale.scaleX, scaleY = scale.scaleY;\n      if (this.canvas) {\n        var zoom = this.canvas.getZoom();\n        var retina = this.canvas.getRetinaScaling();\n        scaleX *= zoom * retina;\n        scaleY *= zoom * retina;\n      }\n      return { scaleX: scaleX, scaleY: scaleY };\n    },\n\n    /**\n     * Return the object opacity counting also the group property\n     * @return {Number}\n     */\n    getObjectOpacity: function() {\n      var opacity = this.opacity;\n      if (this.group) {\n        opacity *= this.group.getObjectOpacity();\n      }\n      return opacity;\n    },\n\n    /**\n     * @private\n     * @param {String} key\n     * @param {*} value\n     * @return {fabric.Object} thisArg\n     */\n    _set: function(key, value) {\n      var shouldConstrainValue = (key === 'scaleX' || key === 'scaleY'),\n          isChanged = this[key] !== value, groupNeedsUpdate = false;\n\n      if (shouldConstrainValue) {\n        value = this._constrainScale(value);\n      }\n      if (key === 'scaleX' && value < 0) {\n        this.flipX = !this.flipX;\n        value *= -1;\n      }\n      else if (key === 'scaleY' && value < 0) {\n        this.flipY = !this.flipY;\n        value *= -1;\n      }\n      else if (key === 'shadow' && value && !(value instanceof fabric.Shadow)) {\n        value = new fabric.Shadow(value);\n      }\n      else if (key === 'dirty' && this.group) {\n        this.group.set('dirty', value);\n      }\n\n      this[key] = value;\n\n      if (isChanged) {\n        groupNeedsUpdate = this.group && this.group.isOnACache();\n        if (this.cacheProperties.indexOf(key) > -1) {\n          this.dirty = true;\n          groupNeedsUpdate && this.group.set('dirty', true);\n        }\n        else if (groupNeedsUpdate && this.stateProperties.indexOf(key) > -1) {\n          this.group.set('dirty', true);\n        }\n      }\n\n      return this;\n    },\n\n    /**\n     * This callback function is called by the parent group of an object every\n     * time a non-delegated property changes on the group. It is passed the key\n     * and value as parameters. Not adding in this function's signature to avoid\n     * Travis build error about unused variables.\n     */\n    setOnGroup: function() {\n      // implemented by sub-classes, as needed.\n    },\n\n    /**\n     * Retrieves viewportTransform from Object's canvas if possible\n     * @method getViewportTransform\n     * @memberOf fabric.Object.prototype\n     * @return {Array}\n     */\n    getViewportTransform: function() {\n      if (this.canvas && this.canvas.viewportTransform) {\n        return this.canvas.viewportTransform;\n      }\n      return fabric.iMatrix.concat();\n    },\n\n    /*\n     * @private\n     * return if the object would be visible in rendering\n     * @memberOf fabric.Object.prototype\n     * @return {Boolean}\n     */\n    isNotVisible: function() {\n      return this.opacity === 0 ||\n        (this.width === 0 && this.height === 0 && this.strokeWidth === 0) ||\n        !this.visible;\n    },\n\n    /**\n     * Renders an object on a specified context\n     * @param {CanvasRenderingContext2D} ctx Context to render on\n     */\n    render: function(ctx) {\n      // do not render if width/height are zeros or object is not visible\n      if (this.isNotVisible()) {\n        return;\n      }\n      if (this.canvas && this.canvas.skipOffscreen && !this.group && !this.isOnScreen()) {\n        return;\n      }\n      ctx.save();\n      this._setupCompositeOperation(ctx);\n      this.drawSelectionBackground(ctx);\n      this.transform(ctx);\n      this._setOpacity(ctx);\n      this._setShadow(ctx, this);\n      if (this.transformMatrix) {\n        ctx.transform.apply(ctx, this.transformMatrix);\n      }\n      this.clipTo && fabric.util.clipContext(this, ctx);\n      if (this.shouldCache()) {\n        this.renderCache();\n        this.drawCacheOnCanvas(ctx);\n      }\n      else {\n        this._removeCacheCanvas();\n        this.dirty = false;\n        this.drawObject(ctx);\n        if (this.objectCaching && this.statefullCache) {\n          this.saveState({ propertySet: 'cacheProperties' });\n        }\n      }\n      this.clipTo && ctx.restore();\n      ctx.restore();\n    },\n\n    renderCache: function(options) {\n      options = options || {};\n      if (!this._cacheCanvas) {\n        this._createCacheCanvas();\n      }\n      if (this.isCacheDirty()) {\n        this.statefullCache && this.saveState({ propertySet: 'cacheProperties' });\n        this.drawObject(this._cacheContext, options.forClipping);\n        this.dirty = false;\n      }\n    },\n\n    /**\n     * Remove cacheCanvas and its dimensions from the objects\n     */\n    _removeCacheCanvas: function() {\n      this._cacheCanvas = null;\n      this.cacheWidth = 0;\n      this.cacheHeight = 0;\n    },\n\n    /**\n     * return true if the object will draw a stroke\n     * Does not consider text styles. This is just a shortcut used at rendering time\n     * We want it to be an aproximation and be fast.\n     * wrote to avoid extra caching, it has to return true when stroke happens,\n     * can guess when it will not happen at 100% chance, does not matter if it misses\n     * some use case where the stroke is invisible.\n     * @since 3.0.0\n     * @returns Boolean\n     */\n    hasStroke: function() {\n      return this.stroke && this.stroke !== 'transparent' && this.strokeWidth !== 0;\n    },\n\n    /**\n     * return true if the object will draw a fill\n     * Does not consider text styles. This is just a shortcut used at rendering time\n     * We want it to be an aproximation and be fast.\n     * wrote to avoid extra caching, it has to return true when fill happens,\n     * can guess when it will not happen at 100% chance, does not matter if it misses\n     * some use case where the fill is invisible.\n     * @since 3.0.0\n     * @returns Boolean\n     */\n    hasFill: function() {\n      return this.fill && this.fill !== 'transparent';\n    },\n\n    /**\n     * When set to `true`, force the object to have its own cache, even if it is inside a group\n     * it may be needed when your object behave in a particular way on the cache and always needs\n     * its own isolated canvas to render correctly.\n     * Created to be overridden\n     * since 1.7.12\n     * @returns Boolean\n     */\n    needsItsOwnCache: function() {\n      if (this.paintFirst === 'stroke' &&\n        this.hasFill() && this.hasStroke() && typeof this.shadow === 'object') {\n        return true;\n      }\n      if (this.clipPath) {\n        return true;\n      }\n      return false;\n    },\n\n    /**\n     * Decide if the object should cache or not. Create its own cache level\n     * objectCaching is a global flag, wins over everything\n     * needsItsOwnCache should be used when the object drawing method requires\n     * a cache step. None of the fabric classes requires it.\n     * Generally you do not cache objects in groups because the group outside is cached.\n     * Read as: cache if is needed, or if the feature is enabled but we are not already caching.\n     * @return {Boolean}\n     */\n    shouldCache: function() {\n      this.ownCaching = this.needsItsOwnCache() || (\n        this.objectCaching &&\n        (!this.group || !this.group.isOnACache())\n      );\n      return this.ownCaching;\n    },\n\n    /**\n     * Check if this object or a child object will cast a shadow\n     * used by Group.shouldCache to know if child has a shadow recursively\n     * @return {Boolean}\n     */\n    willDrawShadow: function() {\n      return !!this.shadow && (this.shadow.offsetX !== 0 || this.shadow.offsetY !== 0);\n    },\n\n    /**\n     * Execute the drawing operation for an object clipPath\n     * @param {CanvasRenderingContext2D} ctx Context to render on\n     */\n    drawClipPathOnCache: function(ctx) {\n      var path = this.clipPath;\n      ctx.save();\n      // DEBUG: uncomment this line, comment the following\n      // ctx.globalAlpha = 0.4\n      if (path.inverted) {\n        ctx.globalCompositeOperation = 'destination-out';\n      }\n      else {\n        ctx.globalCompositeOperation = 'destination-in';\n      }\n      //ctx.scale(1 / 2, 1 / 2);\n      if (path.absolutePositioned) {\n        var m = fabric.util.invertTransform(this.calcTransformMatrix());\n        ctx.transform(m[0], m[1], m[2], m[3], m[4], m[5]);\n      }\n      path.transform(ctx);\n      ctx.scale(1 / path.zoomX, 1 / path.zoomY);\n      ctx.drawImage(path._cacheCanvas, -path.cacheTranslationX, -path.cacheTranslationY);\n      ctx.restore();\n    },\n\n    /**\n     * Execute the drawing operation for an object on a specified context\n     * @param {CanvasRenderingContext2D} ctx Context to render on\n     */\n    drawObject: function(ctx, forClipping) {\n      var originalFill = this.fill, originalStroke = this.stroke;\n      if (forClipping) {\n        this.fill = 'black';\n        this.stroke = '';\n        this._setClippingProperties(ctx);\n      }\n      else {\n        this._renderBackground(ctx);\n        this._setStrokeStyles(ctx, this);\n        this._setFillStyles(ctx, this);\n      }\n      this._render(ctx);\n      this._drawClipPath(ctx);\n      this.fill = originalFill;\n      this.stroke = originalStroke;\n    },\n\n    _drawClipPath: function(ctx) {\n      var path = this.clipPath;\n      if (!path) { return; }\n      // needed to setup a couple of variables\n      // path canvas gets overridden with this one.\n      // TODO find a better solution?\n      path.canvas = this.canvas;\n      path.shouldCache();\n      path._transformDone = true;\n      path.renderCache({ forClipping: true });\n      this.drawClipPathOnCache(ctx);\n    },\n\n    /**\n     * Paint the cached copy of the object on the target context.\n     * @param {CanvasRenderingContext2D} ctx Context to render on\n     */\n    drawCacheOnCanvas: function(ctx) {\n      ctx.scale(1 / this.zoomX, 1 / this.zoomY);\n      ctx.drawImage(this._cacheCanvas, -this.cacheTranslationX, -this.cacheTranslationY);\n    },\n\n    /**\n     * Check if cache is dirty\n     * @param {Boolean} skipCanvas skip canvas checks because this object is painted\n     * on parent canvas.\n     */\n    isCacheDirty: function(skipCanvas) {\n      if (this.isNotVisible()) {\n        return false;\n      }\n      if (this._cacheCanvas && !skipCanvas && this._updateCacheCanvas()) {\n        // in this case the context is already cleared.\n        return true;\n      }\n      else {\n        if (this.dirty ||\n          (this.clipPath && this.clipPath.absolutePositioned) ||\n          (this.statefullCache && this.hasStateChanged('cacheProperties'))\n        ) {\n          if (this._cacheCanvas && !skipCanvas) {\n            var width = this.cacheWidth / this.zoomX;\n            var height = this.cacheHeight / this.zoomY;\n            this._cacheContext.clearRect(-width / 2, -height / 2, width, height);\n          }\n          return true;\n        }\n      }\n      return false;\n    },\n\n    /**\n     * Draws a background for the object big as its untransformed dimensions\n     * @private\n     * @param {CanvasRenderingContext2D} ctx Context to render on\n     */\n    _renderBackground: function(ctx) {\n      if (!this.backgroundColor) {\n        return;\n      }\n      var dim = this._getNonTransformedDimensions();\n      ctx.fillStyle = this.backgroundColor;\n\n      ctx.fillRect(\n        -dim.x / 2,\n        -dim.y / 2,\n        dim.x,\n        dim.y\n      );\n      // if there is background color no other shadows\n      // should be casted\n      this._removeShadow(ctx);\n    },\n\n    /**\n     * @private\n     * @param {CanvasRenderingContext2D} ctx Context to render on\n     */\n    _setOpacity: function(ctx) {\n      if (this.group && !this.group._transformDone) {\n        ctx.globalAlpha = this.getObjectOpacity();\n      }\n      else {\n        ctx.globalAlpha *= this.opacity;\n      }\n    },\n\n    _setStrokeStyles: function(ctx, decl) {\n      if (decl.stroke) {\n        ctx.lineWidth = decl.strokeWidth;\n        ctx.lineCap = decl.strokeLineCap;\n        ctx.lineDashOffset = decl.strokeDashOffset;\n        ctx.lineJoin = decl.strokeLineJoin;\n        ctx.miterLimit = decl.strokeMiterLimit;\n        ctx.strokeStyle = decl.stroke.toLive\n          ? decl.stroke.toLive(ctx, this)\n          : decl.stroke;\n      }\n    },\n\n    _setFillStyles: function(ctx, decl) {\n      if (decl.fill) {\n        ctx.fillStyle = decl.fill.toLive\n          ? decl.fill.toLive(ctx, this)\n          : decl.fill;\n      }\n    },\n\n    _setClippingProperties: function(ctx) {\n      ctx.globalAlpha = 1;\n      ctx.strokeStyle = 'transparent';\n      ctx.fillStyle = '#000000';\n    },\n\n    /**\n     * @private\n     * Sets line dash\n     * @param {CanvasRenderingContext2D} ctx Context to set the dash line on\n     * @param {Array} dashArray array representing dashes\n     * @param {Function} alternative function to call if browser does not support lineDash\n     */\n    _setLineDash: function(ctx, dashArray, alternative) {\n      if (!dashArray) {\n        return;\n      }\n      // Spec requires the concatenation of two copies the dash list when the number of elements is odd\n      if (1 & dashArray.length) {\n        dashArray.push.apply(dashArray, dashArray);\n      }\n      if (supportsLineDash) {\n        ctx.setLineDash(dashArray);\n      }\n      else {\n        alternative && alternative(ctx);\n      }\n      if (this.strokeUniform) {\n        ctx.setLineDash(ctx.getLineDash().map(function(value) { return value * ctx.lineWidth; }));\n      }\n    },\n\n    /**\n     * Renders controls and borders for the object\n     * @param {CanvasRenderingContext2D} ctx Context to render on\n     * @param {Object} [styleOverride] properties to override the object style\n     */\n    _renderControls: function(ctx, styleOverride) {\n      var vpt = this.getViewportTransform(),\n          matrix = this.calcTransformMatrix(),\n          options, drawBorders, drawControls;\n      styleOverride = styleOverride || { };\n      drawBorders = typeof styleOverride.hasBorders !== 'undefined' ? styleOverride.hasBorders : this.hasBorders;\n      drawControls = typeof styleOverride.hasControls !== 'undefined' ? styleOverride.hasControls : this.hasControls;\n      matrix = fabric.util.multiplyTransformMatrices(vpt, matrix);\n      options = fabric.util.qrDecompose(matrix);\n      ctx.save();\n      ctx.translate(options.translateX, options.translateY);\n      ctx.lineWidth = 1 * this.borderScaleFactor;\n      if (!this.group) {\n        ctx.globalAlpha = this.isMoving ? this.borderOpacityWhenMoving : 1;\n      }\n      if (styleOverride.forActiveSelection) {\n        ctx.rotate(degreesToRadians(options.angle));\n        drawBorders && this.drawBordersInGroup(ctx, options, styleOverride);\n      }\n      else {\n        ctx.rotate(degreesToRadians(this.angle));\n        drawBorders && this.drawBorders(ctx, styleOverride);\n      }\n      drawControls && this.drawControls(ctx, styleOverride);\n      ctx.restore();\n    },\n\n    /**\n     * @private\n     * @param {CanvasRenderingContext2D} ctx Context to render on\n     */\n    _setShadow: function(ctx) {\n      if (!this.shadow) {\n        return;\n      }\n\n      var shadow = this.shadow, canvas = this.canvas, scaling,\n          multX = (canvas && canvas.viewportTransform[0]) || 1,\n          multY = (canvas && canvas.viewportTransform[3]) || 1;\n      if (shadow.nonScaling) {\n        scaling = { scaleX: 1, scaleY: 1 };\n      }\n      else {\n        scaling = this.getObjectScaling();\n      }\n      if (canvas && canvas._isRetinaScaling()) {\n        multX *= fabric.devicePixelRatio;\n        multY *= fabric.devicePixelRatio;\n      }\n      ctx.shadowColor = shadow.color;\n      ctx.shadowBlur = shadow.blur * fabric.browserShadowBlurConstant *\n        (multX + multY) * (scaling.scaleX + scaling.scaleY) / 4;\n      ctx.shadowOffsetX = shadow.offsetX * multX * scaling.scaleX;\n      ctx.shadowOffsetY = shadow.offsetY * multY * scaling.scaleY;\n    },\n\n    /**\n     * @private\n     * @param {CanvasRenderingContext2D} ctx Context to render on\n     */\n    _removeShadow: function(ctx) {\n      if (!this.shadow) {\n        return;\n      }\n\n      ctx.shadowColor = '';\n      ctx.shadowBlur = ctx.shadowOffsetX = ctx.shadowOffsetY = 0;\n    },\n\n    /**\n     * @private\n     * @param {CanvasRenderingContext2D} ctx Context to render on\n     * @param {Object} filler fabric.Pattern or fabric.Gradient\n     * @return {Object} offset.offsetX offset for text rendering\n     * @return {Object} offset.offsetY offset for text rendering\n     */\n    _applyPatternGradientTransform: function(ctx, filler) {\n      if (!filler || !filler.toLive) {\n        return { offsetX: 0, offsetY: 0 };\n      }\n      var t = filler.gradientTransform || filler.patternTransform;\n      var offsetX = -this.width / 2 + filler.offsetX || 0,\n          offsetY = -this.height / 2 + filler.offsetY || 0;\n      ctx.translate(offsetX, offsetY);\n      if (t) {\n        ctx.transform(t[0], t[1], t[2], t[3], t[4], t[5]);\n      }\n      return { offsetX: offsetX, offsetY: offsetY };\n    },\n\n    /**\n     * @private\n     * @param {CanvasRenderingContext2D} ctx Context to render on\n     */\n    _renderPaintInOrder: function(ctx) {\n      if (this.paintFirst === 'stroke') {\n        this._renderStroke(ctx);\n        this._renderFill(ctx);\n      }\n      else {\n        this._renderFill(ctx);\n        this._renderStroke(ctx);\n      }\n    },\n\n    /**\n     * @private\n     * function that actually render something on the context.\n     * empty here to allow Obects to work on tests to benchmark fabric functionalites\n     * not related to rendering\n     * @param {CanvasRenderingContext2D} ctx Context to render on\n     */\n    _render: function(/* ctx */) {\n\n    },\n\n    /**\n     * @private\n     * @param {CanvasRenderingContext2D} ctx Context to render on\n     */\n    _renderFill: function(ctx) {\n      if (!this.fill) {\n        return;\n      }\n\n      ctx.save();\n      this._applyPatternGradientTransform(ctx, this.fill);\n      if (this.fillRule === 'evenodd') {\n        ctx.fill('evenodd');\n      }\n      else {\n        ctx.fill();\n      }\n      ctx.restore();\n    },\n\n    _renderStroke: function(ctx) {\n      if (!this.stroke || this.strokeWidth === 0) {\n        return;\n      }\n\n      if (this.shadow && !this.shadow.affectStroke) {\n        this._removeShadow(ctx);\n      }\n\n      ctx.save();\n      if (this.strokeUniform) {\n        ctx.scale(1 / this.scaleX, 1 / this.scaleY);\n      }\n      this._setLineDash(ctx, this.strokeDashArray, this._renderDashedStroke);\n      this._applyPatternGradientTransform(ctx, this.stroke);\n      ctx.stroke();\n      ctx.restore();\n    },\n\n    /**\n     * This function is an helper for svg import. it returns the center of the object in the svg\n     * untransformed coordinates\n     * @private\n     * @return {Object} center point from element coordinates\n     */\n    _findCenterFromElement: function() {\n      return { x: this.left + this.width / 2, y: this.top + this.height / 2 };\n    },\n\n    /**\n     * This function is an helper for svg import. it decompose the transformMatrix\n     * and assign properties to object.\n     * untransformed coordinates\n     * @private\n     * @chainable\n     */\n    _assignTransformMatrixProps: function() {\n      if (this.transformMatrix) {\n        var options = fabric.util.qrDecompose(this.transformMatrix);\n        this.flipX = false;\n        this.flipY = false;\n        this.set('scaleX', options.scaleX);\n        this.set('scaleY', options.scaleY);\n        this.angle = options.angle;\n        this.skewX = options.skewX;\n        this.skewY = 0;\n      }\n    },\n\n    /**\n     * This function is an helper for svg import. it removes the transform matrix\n     * and set to object properties that fabricjs can handle\n     * @private\n     * @param {Object} preserveAspectRatioOptions\n     * @return {thisArg}\n     */\n    _removeTransformMatrix: function(preserveAspectRatioOptions) {\n      var center = this._findCenterFromElement();\n      if (this.transformMatrix) {\n        this._assignTransformMatrixProps();\n        center = fabric.util.transformPoint(center, this.transformMatrix);\n      }\n      this.transformMatrix = null;\n      if (preserveAspectRatioOptions) {\n        this.scaleX *= preserveAspectRatioOptions.scaleX;\n        this.scaleY *= preserveAspectRatioOptions.scaleY;\n        this.cropX = preserveAspectRatioOptions.cropX;\n        this.cropY = preserveAspectRatioOptions.cropY;\n        center.x += preserveAspectRatioOptions.offsetLeft;\n        center.y += preserveAspectRatioOptions.offsetTop;\n        this.width = preserveAspectRatioOptions.width;\n        this.height = preserveAspectRatioOptions.height;\n      }\n      this.setPositionByOrigin(center, 'center', 'center');\n    },\n\n    /**\n     * Clones an instance, using a callback method will work for every object.\n     * @param {Function} callback Callback is invoked with a clone as a first argument\n     * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output\n     */\n    clone: function(callback, propertiesToInclude) {\n      var objectForm = this.toObject(propertiesToInclude);\n      if (this.constructor.fromObject) {\n        this.constructor.fromObject(objectForm, callback);\n      }\n      else {\n        fabric.Object._fromObject('Object', objectForm, callback);\n      }\n    },\n\n    /**\n     * Creates an instance of fabric.Image out of an object\n     * could make use of both toDataUrl or toCanvasElement.\n     * @param {Function} callback callback, invoked with an instance as a first argument\n     * @param {Object} [options] for clone as image, passed to toDataURL\n     * @param {String} [options.format=png] The format of the output image. Either \"jpeg\" or \"png\"\n     * @param {Number} [options.quality=1] Quality level (0..1). Only used for jpeg.\n     * @param {Number} [options.multiplier=1] Multiplier to scale by\n     * @param {Number} [options.left] Cropping left offset. Introduced in v1.2.14\n     * @param {Number} [options.top] Cropping top offset. Introduced in v1.2.14\n     * @param {Number} [options.width] Cropping width. Introduced in v1.2.14\n     * @param {Number} [options.height] Cropping height. Introduced in v1.2.14\n     * @param {Boolean} [options.enableRetinaScaling] Enable retina scaling for clone image. Introduce in 1.6.4\n     * @param {Boolean} [options.withoutTransform] Remove current object transform ( no scale , no angle, no flip, no skew ). Introduced in 2.3.4\n     * @param {Boolean} [options.withoutShadow] Remove current object shadow. Introduced in 2.4.2\n     * @return {fabric.Object} thisArg\n     */\n    cloneAsImage: function(callback, options) {\n      var canvasEl = this.toCanvasElement(options);\n      if (callback) {\n        callback(new fabric.Image(canvasEl));\n      }\n      return this;\n    },\n\n    /**\n     * Converts an object into a HTMLCanvas element\n     * @param {Object} options Options object\n     * @param {Number} [options.multiplier=1] Multiplier to scale by\n     * @param {Number} [options.left] Cropping left offset. Introduced in v1.2.14\n     * @param {Number} [options.top] Cropping top offset. Introduced in v1.2.14\n     * @param {Number} [options.width] Cropping width. Introduced in v1.2.14\n     * @param {Number} [options.height] Cropping height. Introduced in v1.2.14\n     * @param {Boolean} [options.enableRetinaScaling] Enable retina scaling for clone image. Introduce in 1.6.4\n     * @param {Boolean} [options.withoutTransform] Remove current object transform ( no scale , no angle, no flip, no skew ). Introduced in 2.3.4\n     * @param {Boolean} [options.withoutShadow] Remove current object shadow. Introduced in 2.4.2\n     * @return {String} Returns a data: URL containing a representation of the object in the format specified by options.format\n     */\n    toCanvasElement: function(options) {\n      options || (options = { });\n\n      var utils = fabric.util, origParams = utils.saveObjectTransform(this),\n          originalShadow = this.shadow, abs = Math.abs,\n          multiplier = (options.multiplier || 1) * (options.enableRetinaScaling ? fabric.devicePixelRatio : 1);\n\n      if (options.withoutTransform) {\n        utils.resetObjectTransform(this);\n      }\n      if (options.withoutShadow) {\n        this.shadow = null;\n      }\n\n      var el = fabric.util.createCanvasElement(),\n          // skip canvas zoom and calculate with setCoords now.\n          boundingRect = this.getBoundingRect(true, true),\n          shadow = this.shadow, scaling,\n          shadowOffset = { x: 0, y: 0 }, shadowBlur;\n\n      if (shadow) {\n        shadowBlur = shadow.blur;\n        if (shadow.nonScaling) {\n          scaling = { scaleX: 1, scaleY: 1 };\n        }\n        else {\n          scaling = this.getObjectScaling();\n        }\n        shadowOffset.x = 2 * Math.round(abs(shadow.offsetX) + shadowBlur) * (abs(scaling.scaleX));\n        shadowOffset.y = 2 * Math.round(abs(shadow.offsetY) + shadowBlur) * (abs(scaling.scaleY));\n      }\n      el.width = boundingRect.width + shadowOffset.x;\n      el.height = boundingRect.height + shadowOffset.y;\n      el.width += el.width % 2 ? 2 - el.width % 2 : 0;\n      el.height += el.height % 2 ? 2 - el.height % 2 : 0;\n      var canvas = new fabric.StaticCanvas(el, {\n        enableRetinaScaling: false,\n        renderOnAddRemove: false,\n        skipOffscreen: false,\n      });\n      if (options.format === 'jpeg') {\n        canvas.backgroundColor = '#fff';\n      }\n      this.setPositionByOrigin(new fabric.Point(canvas.width / 2, canvas.height / 2), 'center', 'center');\n\n      var originalCanvas = this.canvas;\n      canvas.add(this);\n      var canvasEl = canvas.toCanvasElement(multiplier || 1, options);\n      this.shadow = originalShadow;\n      this.canvas = originalCanvas;\n      this.set(origParams).setCoords();\n      // canvas.dispose will call image.dispose that will nullify the elements\n      // since this canvas is a simple element for the process, we remove references\n      // to objects in this way in order to avoid object trashing.\n      canvas._objects = [];\n      canvas.dispose();\n      canvas = null;\n\n      return canvasEl;\n    },\n\n    /**\n     * Converts an object into a data-url-like string\n     * @param {Object} options Options object\n     * @param {String} [options.format=png] The format of the output image. Either \"jpeg\" or \"png\"\n     * @param {Number} [options.quality=1] Quality level (0..1). Only used for jpeg.\n     * @param {Number} [options.multiplier=1] Multiplier to scale by\n     * @param {Number} [options.left] Cropping left offset. Introduced in v1.2.14\n     * @param {Number} [options.top] Cropping top offset. Introduced in v1.2.14\n     * @param {Number} [options.width] Cropping width. Introduced in v1.2.14\n     * @param {Number} [options.height] Cropping height. Introduced in v1.2.14\n     * @param {Boolean} [options.enableRetinaScaling] Enable retina scaling for clone image. Introduce in 1.6.4\n     * @param {Boolean} [options.withoutTransform] Remove current object transform ( no scale , no angle, no flip, no skew ). Introduced in 2.3.4\n     * @param {Boolean} [options.withoutShadow] Remove current object shadow. Introduced in 2.4.2\n     * @return {String} Returns a data: URL containing a representation of the object in the format specified by options.format\n     */\n    toDataURL: function(options) {\n      options || (options = { });\n      return fabric.util.toDataURL(this.toCanvasElement(options), options.format || 'png', options.quality || 1);\n    },\n\n    /**\n     * Returns true if specified type is identical to the type of an instance\n     * @param {String} type Type to check against\n     * @return {Boolean}\n     */\n    isType: function(type) {\n      return this.type === type;\n    },\n\n    /**\n     * Returns complexity of an instance\n     * @return {Number} complexity of this instance (is 1 unless subclassed)\n     */\n    complexity: function() {\n      return 1;\n    },\n\n    /**\n     * Returns a JSON representation of an instance\n     * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output\n     * @return {Object} JSON\n     */\n    toJSON: function(propertiesToInclude) {\n      // delegate, not alias\n      return this.toObject(propertiesToInclude);\n    },\n\n    /**\n     * Sets gradient (fill or stroke) of an object\n     * <b>Backwards incompatibility note:</b> This method was named \"setGradientFill\" until v1.1.0\n     * @param {String} property Property name 'stroke' or 'fill'\n     * @param {Object} [options] Options object\n     * @param {String} [options.type] Type of gradient 'radial' or 'linear'\n     * @param {Number} [options.x1=0] x-coordinate of start point\n     * @param {Number} [options.y1=0] y-coordinate of start point\n     * @param {Number} [options.x2=0] x-coordinate of end point\n     * @param {Number} [options.y2=0] y-coordinate of end point\n     * @param {Number} [options.r1=0] Radius of start point (only for radial gradients)\n     * @param {Number} [options.r2=0] Radius of end point (only for radial gradients)\n     * @param {Object} [options.colorStops] Color stops object eg. {0: 'ff0000', 1: '000000'}\n     * @param {Object} [options.gradientTransform] transformMatrix for gradient\n     * @return {fabric.Object} thisArg\n     * @chainable\n     * @see {@link http://jsfiddle.net/fabricjs/58y8b/|jsFiddle demo}\n     * @example <caption>Set linear gradient</caption>\n     * object.setGradient('fill', {\n     *   type: 'linear',\n     *   x1: -object.width / 2,\n     *   y1: 0,\n     *   x2: object.width / 2,\n     *   y2: 0,\n     *   colorStops: {\n     *     0: 'red',\n     *     0.5: '#005555',\n     *     1: 'rgba(0,0,255,0.5)'\n     *   }\n     * });\n     * canvas.renderAll();\n     * @example <caption>Set radial gradient</caption>\n     * object.setGradient('fill', {\n     *   type: 'radial',\n     *   x1: 0,\n     *   y1: 0,\n     *   x2: 0,\n     *   y2: 0,\n     *   r1: object.width / 2,\n     *   r2: 10,\n     *   colorStops: {\n     *     0: 'red',\n     *     0.5: '#005555',\n     *     1: 'rgba(0,0,255,0.5)'\n     *   }\n     * });\n     * canvas.renderAll();\n     */\n    setGradient: function(property, options) {\n      options || (options = { });\n\n      var gradient = { colorStops: [] };\n\n      gradient.type = options.type || (options.r1 || options.r2 ? 'radial' : 'linear');\n      gradient.coords = {\n        x1: options.x1,\n        y1: options.y1,\n        x2: options.x2,\n        y2: options.y2\n      };\n\n      if (options.r1 || options.r2) {\n        gradient.coords.r1 = options.r1;\n        gradient.coords.r2 = options.r2;\n      }\n\n      gradient.gradientTransform = options.gradientTransform;\n      fabric.Gradient.prototype.addColorStop.call(gradient, options.colorStops);\n\n      return this.set(property, fabric.Gradient.forObject(this, gradient));\n    },\n\n    /**\n     * Sets pattern fill of an object\n     * @param {Object} options Options object\n     * @param {(String|HTMLImageElement)} options.source Pattern source\n     * @param {String} [options.repeat=repeat] Repeat property of a pattern (one of repeat, repeat-x, repeat-y or no-repeat)\n     * @param {Number} [options.offsetX=0] Pattern horizontal offset from object's left/top corner\n     * @param {Number} [options.offsetY=0] Pattern vertical offset from object's left/top corner\n     * @param {Function} [callback] Callback to invoke when image set as a pattern\n     * @return {fabric.Object} thisArg\n     * @chainable\n     * @see {@link http://jsfiddle.net/fabricjs/QT3pa/|jsFiddle demo}\n     * @example <caption>Set pattern</caption>\n     * object.setPatternFill({\n     *   source: 'http://fabricjs.com/assets/escheresque_ste.png',\n     *   repeat: 'repeat'\n     * },canvas.renderAll.bind(canvas));\n     */\n    setPatternFill: function(options, callback) {\n      return this.set('fill', new fabric.Pattern(options, callback));\n    },\n\n    /**\n     * Sets {@link fabric.Object#shadow|shadow} of an object\n     * @param {Object|String} [options] Options object or string (e.g. \"2px 2px 10px rgba(0,0,0,0.2)\")\n     * @param {String} [options.color=rgb(0,0,0)] Shadow color\n     * @param {Number} [options.blur=0] Shadow blur\n     * @param {Number} [options.offsetX=0] Shadow horizontal offset\n     * @param {Number} [options.offsetY=0] Shadow vertical offset\n     * @return {fabric.Object} thisArg\n     * @chainable\n     * @see {@link http://jsfiddle.net/fabricjs/7gvJG/|jsFiddle demo}\n     * @example <caption>Set shadow with string notation</caption>\n     * object.setShadow('2px 2px 10px rgba(0,0,0,0.2)');\n     * canvas.renderAll();\n     * @example <caption>Set shadow with object notation</caption>\n     * object.setShadow({\n     *   color: 'red',\n     *   blur: 10,\n     *   offsetX: 20,\n     *   offsetY: 20\n     * });\n     * canvas.renderAll();\n     */\n    setShadow: function(options) {\n      return this.set('shadow', options ? new fabric.Shadow(options) : null);\n    },\n\n    /**\n     * Sets \"color\" of an instance (alias of `set('fill', &hellip;)`)\n     * @param {String} color Color value\n     * @return {fabric.Object} thisArg\n     * @chainable\n     */\n    setColor: function(color) {\n      this.set('fill', color);\n      return this;\n    },\n\n    /**\n     * Sets \"angle\" of an instance with centered rotation\n     * @param {Number} angle Angle value (in degrees)\n     * @return {fabric.Object} thisArg\n     * @chainable\n     */\n    rotate: function(angle) {\n      var shouldCenterOrigin = (this.originX !== 'center' || this.originY !== 'center') && this.centeredRotation;\n\n      if (shouldCenterOrigin) {\n        this._setOriginToCenter();\n      }\n\n      this.set('angle', angle);\n\n      if (shouldCenterOrigin) {\n        this._resetOrigin();\n      }\n\n      return this;\n    },\n\n    /**\n     * Centers object horizontally on canvas to which it was added last.\n     * You might need to call `setCoords` on an object after centering, to update controls area.\n     * @return {fabric.Object} thisArg\n     * @chainable\n     */\n    centerH: function () {\n      this.canvas && this.canvas.centerObjectH(this);\n      return this;\n    },\n\n    /**\n     * Centers object horizontally on current viewport of canvas to which it was added last.\n     * You might need to call `setCoords` on an object after centering, to update controls area.\n     * @return {fabric.Object} thisArg\n     * @chainable\n     */\n    viewportCenterH: function () {\n      this.canvas && this.canvas.viewportCenterObjectH(this);\n      return this;\n    },\n\n    /**\n     * Centers object vertically on canvas to which it was added last.\n     * You might need to call `setCoords` on an object after centering, to update controls area.\n     * @return {fabric.Object} thisArg\n     * @chainable\n     */\n    centerV: function () {\n      this.canvas && this.canvas.centerObjectV(this);\n      return this;\n    },\n\n    /**\n     * Centers object vertically on current viewport of canvas to which it was added last.\n     * You might need to call `setCoords` on an object after centering, to update controls area.\n     * @return {fabric.Object} thisArg\n     * @chainable\n     */\n    viewportCenterV: function () {\n      this.canvas && this.canvas.viewportCenterObjectV(this);\n      return this;\n    },\n\n    /**\n     * Centers object vertically and horizontally on canvas to which is was added last\n     * You might need to call `setCoords` on an object after centering, to update controls area.\n     * @return {fabric.Object} thisArg\n     * @chainable\n     */\n    center: function () {\n      this.canvas && this.canvas.centerObject(this);\n      return this;\n    },\n\n    /**\n     * Centers object on current viewport of canvas to which it was added last.\n     * You might need to call `setCoords` on an object after centering, to update controls area.\n     * @return {fabric.Object} thisArg\n     * @chainable\n     */\n    viewportCenter: function () {\n      this.canvas && this.canvas.viewportCenterObject(this);\n      return this;\n    },\n\n    /**\n     * Returns coordinates of a pointer relative to an object\n     * @param {Event} e Event to operate upon\n     * @param {Object} [pointer] Pointer to operate upon (instead of event)\n     * @return {Object} Coordinates of a pointer (x, y)\n     */\n    getLocalPointer: function(e, pointer) {\n      pointer = pointer || this.canvas.getPointer(e);\n      var pClicked = new fabric.Point(pointer.x, pointer.y),\n          objectLeftTop = this._getLeftTopCoords();\n      if (this.angle) {\n        pClicked = fabric.util.rotatePoint(\n          pClicked, objectLeftTop, degreesToRadians(-this.angle));\n      }\n      return {\n        x: pClicked.x - objectLeftTop.x,\n        y: pClicked.y - objectLeftTop.y\n      };\n    },\n\n    /**\n     * Sets canvas globalCompositeOperation for specific object\n     * custom composition operation for the particular object can be specified using globalCompositeOperation property\n     * @param {CanvasRenderingContext2D} ctx Rendering canvas context\n     */\n    _setupCompositeOperation: function (ctx) {\n      if (this.globalCompositeOperation) {\n        ctx.globalCompositeOperation = this.globalCompositeOperation;\n      }\n    }\n  });\n\n  fabric.util.createAccessors && fabric.util.createAccessors(fabric.Object);\n\n  extend(fabric.Object.prototype, fabric.Observable);\n\n  /**\n   * Defines the number of fraction digits to use when serializing object values.\n   * You can use it to increase/decrease precision of such values like left, top, scaleX, scaleY, etc.\n   * @static\n   * @memberOf fabric.Object\n   * @constant\n   * @type Number\n   */\n  fabric.Object.NUM_FRACTION_DIGITS = 2;\n\n  fabric.Object._fromObject = function(className, object, callback, extraParam) {\n    var klass = fabric[className];\n    object = clone(object, true);\n    fabric.util.enlivenPatterns([object.fill, object.stroke], function(patterns) {\n      if (typeof patterns[0] !== 'undefined') {\n        object.fill = patterns[0];\n      }\n      if (typeof patterns[1] !== 'undefined') {\n        object.stroke = patterns[1];\n      }\n      fabric.util.enlivenObjects([object.clipPath], function(enlivedProps) {\n        object.clipPath = enlivedProps[0];\n        var instance = extraParam ? new klass(object[extraParam], object) : new klass(object);\n        callback && callback(instance);\n      });\n    });\n  };\n\n  /**\n   * Unique id used internally when creating SVG elements\n   * @static\n   * @memberOf fabric.Object\n   * @type Number\n   */\n  fabric.Object.__uid = 0;\n\n})(typeof exports !== 'undefined' ? exports : this);\n\n\n(function() {\n\n  var degreesToRadians = fabric.util.degreesToRadians,\n      originXOffset = {\n        left: -0.5,\n        center: 0,\n        right: 0.5\n      },\n      originYOffset = {\n        top: -0.5,\n        center: 0,\n        bottom: 0.5\n      };\n\n  fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prototype */ {\n\n    /**\n     * Translates the coordinates from a set of origin to another (based on the object's dimensions)\n     * @param {fabric.Point} point The point which corresponds to the originX and originY params\n     * @param {String} fromOriginX Horizontal origin: 'left', 'center' or 'right'\n     * @param {String} fromOriginY Vertical origin: 'top', 'center' or 'bottom'\n     * @param {String} toOriginX Horizontal origin: 'left', 'center' or 'right'\n     * @param {String} toOriginY Vertical origin: 'top', 'center' or 'bottom'\n     * @return {fabric.Point}\n     */\n    translateToGivenOrigin: function(point, fromOriginX, fromOriginY, toOriginX, toOriginY) {\n      var x = point.x,\n          y = point.y,\n          offsetX, offsetY, dim;\n\n      if (typeof fromOriginX === 'string') {\n        fromOriginX = originXOffset[fromOriginX];\n      }\n      else {\n        fromOriginX -= 0.5;\n      }\n\n      if (typeof toOriginX === 'string') {\n        toOriginX = originXOffset[toOriginX];\n      }\n      else {\n        toOriginX -= 0.5;\n      }\n\n      offsetX = toOriginX - fromOriginX;\n\n      if (typeof fromOriginY === 'string') {\n        fromOriginY = originYOffset[fromOriginY];\n      }\n      else {\n        fromOriginY -= 0.5;\n      }\n\n      if (typeof toOriginY === 'string') {\n        toOriginY = originYOffset[toOriginY];\n      }\n      else {\n        toOriginY -= 0.5;\n      }\n\n      offsetY = toOriginY - fromOriginY;\n\n      if (offsetX || offsetY) {\n        dim = this._getTransformedDimensions();\n        x = point.x + offsetX * dim.x;\n        y = point.y + offsetY * dim.y;\n      }\n\n      return new fabric.Point(x, y);\n    },\n\n    /**\n     * Translates the coordinates from origin to center coordinates (based on the object's dimensions)\n     * @param {fabric.Point} point The point which corresponds to the originX and originY params\n     * @param {String} originX Horizontal origin: 'left', 'center' or 'right'\n     * @param {String} originY Vertical origin: 'top', 'center' or 'bottom'\n     * @return {fabric.Point}\n     */\n    translateToCenterPoint: function(point, originX, originY) {\n      var p = this.translateToGivenOrigin(point, originX, originY, 'center', 'center');\n      if (this.angle) {\n        return fabric.util.rotatePoint(p, point, degreesToRadians(this.angle));\n      }\n      return p;\n    },\n\n    /**\n     * Translates the coordinates from center to origin coordinates (based on the object's dimensions)\n     * @param {fabric.Point} center The point which corresponds to center of the object\n     * @param {String} originX Horizontal origin: 'left', 'center' or 'right'\n     * @param {String} originY Vertical origin: 'top', 'center' or 'bottom'\n     * @return {fabric.Point}\n     */\n    translateToOriginPoint: function(center, originX, originY) {\n      var p = this.translateToGivenOrigin(center, 'center', 'center', originX, originY);\n      if (this.angle) {\n        return fabric.util.rotatePoint(p, center, degreesToRadians(this.angle));\n      }\n      return p;\n    },\n\n    /**\n     * Returns the real center coordinates of the object\n     * @return {fabric.Point}\n     */\n    getCenterPoint: function() {\n      var leftTop = new fabric.Point(this.left, this.top);\n      return this.translateToCenterPoint(leftTop, this.originX, this.originY);\n    },\n\n    /**\n     * Returns the coordinates of the object based on center coordinates\n     * @param {fabric.Point} point The point which corresponds to the originX and originY params\n     * @return {fabric.Point}\n     */\n    // getOriginPoint: function(center) {\n    //   return this.translateToOriginPoint(center, this.originX, this.originY);\n    // },\n\n    /**\n     * Returns the coordinates of the object as if it has a different origin\n     * @param {String} originX Horizontal origin: 'left', 'center' or 'right'\n     * @param {String} originY Vertical origin: 'top', 'center' or 'bottom'\n     * @return {fabric.Point}\n     */\n    getPointByOrigin: function(originX, originY) {\n      var center = this.getCenterPoint();\n      return this.translateToOriginPoint(center, originX, originY);\n    },\n\n    /**\n     * Returns the point in local coordinates\n     * @param {fabric.Point} point The point relative to the global coordinate system\n     * @param {String} originX Horizontal origin: 'left', 'center' or 'right'\n     * @param {String} originY Vertical origin: 'top', 'center' or 'bottom'\n     * @return {fabric.Point}\n     */\n    toLocalPoint: function(point, originX, originY) {\n      var center = this.getCenterPoint(),\n          p, p2;\n\n      if (typeof originX !== 'undefined' && typeof originY !== 'undefined' ) {\n        p = this.translateToGivenOrigin(center, 'center', 'center', originX, originY);\n      }\n      else {\n        p = new fabric.Point(this.left, this.top);\n      }\n\n      p2 = new fabric.Point(point.x, point.y);\n      if (this.angle) {\n        p2 = fabric.util.rotatePoint(p2, center, -degreesToRadians(this.angle));\n      }\n      return p2.subtractEquals(p);\n    },\n\n    /**\n     * Returns the point in global coordinates\n     * @param {fabric.Point} The point relative to the local coordinate system\n     * @return {fabric.Point}\n     */\n    // toGlobalPoint: function(point) {\n    //   return fabric.util.rotatePoint(point, this.getCenterPoint(), degreesToRadians(this.angle)).addEquals(new fabric.Point(this.left, this.top));\n    // },\n\n    /**\n     * Sets the position of the object taking into consideration the object's origin\n     * @param {fabric.Point} pos The new position of the object\n     * @param {String} originX Horizontal origin: 'left', 'center' or 'right'\n     * @param {String} originY Vertical origin: 'top', 'center' or 'bottom'\n     * @return {void}\n     */\n    setPositionByOrigin: function(pos, originX, originY) {\n      var center = this.translateToCenterPoint(pos, originX, originY),\n          position = this.translateToOriginPoint(center, this.originX, this.originY);\n      this.set('left', position.x);\n      this.set('top', position.y);\n    },\n\n    /**\n     * @param {String} to One of 'left', 'center', 'right'\n     */\n    adjustPosition: function(to) {\n      var angle = degreesToRadians(this.angle),\n          hypotFull = this.getScaledWidth(),\n          xFull = fabric.util.cos(angle) * hypotFull,\n          yFull = fabric.util.sin(angle) * hypotFull,\n          offsetFrom, offsetTo;\n\n      //TODO: this function does not consider mixed situation like top, center.\n      if (typeof this.originX === 'string') {\n        offsetFrom = originXOffset[this.originX];\n      }\n      else {\n        offsetFrom = this.originX - 0.5;\n      }\n      if (typeof to === 'string') {\n        offsetTo = originXOffset[to];\n      }\n      else {\n        offsetTo = to - 0.5;\n      }\n      this.left += xFull * (offsetTo - offsetFrom);\n      this.top += yFull * (offsetTo - offsetFrom);\n      this.setCoords();\n      this.originX = to;\n    },\n\n    /**\n     * Sets the origin/position of the object to it's center point\n     * @private\n     * @return {void}\n     */\n    _setOriginToCenter: function() {\n      this._originalOriginX = this.originX;\n      this._originalOriginY = this.originY;\n\n      var center = this.getCenterPoint();\n\n      this.originX = 'center';\n      this.originY = 'center';\n\n      this.left = center.x;\n      this.top = center.y;\n    },\n\n    /**\n     * Resets the origin/position of the object to it's original origin\n     * @private\n     * @return {void}\n     */\n    _resetOrigin: function() {\n      var originPoint = this.translateToOriginPoint(\n        this.getCenterPoint(),\n        this._originalOriginX,\n        this._originalOriginY);\n\n      this.originX = this._originalOriginX;\n      this.originY = this._originalOriginY;\n\n      this.left = originPoint.x;\n      this.top = originPoint.y;\n\n      this._originalOriginX = null;\n      this._originalOriginY = null;\n    },\n\n    /**\n     * @private\n     */\n    _getLeftTopCoords: function() {\n      return this.translateToOriginPoint(this.getCenterPoint(), 'left', 'top');\n    },\n  });\n\n})();\n\n\n(function() {\n\n  function getCoords(coords) {\n    return [\n      new fabric.Point(coords.tl.x, coords.tl.y),\n      new fabric.Point(coords.tr.x, coords.tr.y),\n      new fabric.Point(coords.br.x, coords.br.y),\n      new fabric.Point(coords.bl.x, coords.bl.y)\n    ];\n  }\n\n  var degreesToRadians = fabric.util.degreesToRadians,\n      multiplyMatrices = fabric.util.multiplyTransformMatrices,\n      transformPoint = fabric.util.transformPoint;\n\n  fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prototype */ {\n\n    /**\n     * Describe object's corner position in canvas element coordinates.\n     * properties are tl,mt,tr,ml,mr,bl,mb,br,mtr for the main controls.\n     * each property is an object with x, y and corner.\n     * The `corner` property contains in a similar manner the 4 points of the\n     * interactive area of the corner.\n     * The coordinates depends from this properties: width, height, scaleX, scaleY\n     * skewX, skewY, angle, strokeWidth, viewportTransform, top, left, padding.\n     * The coordinates get updated with @method setCoords.\n     * You can calculate them without updating with @method calcCoords;\n     * @memberOf fabric.Object.prototype\n     */\n    oCoords: null,\n\n    /**\n     * Describe object's corner position in canvas object absolute coordinates\n     * properties are tl,tr,bl,br and describe the four main corner.\n     * each property is an object with x, y, instance of Fabric.Point.\n     * The coordinates depends from this properties: width, height, scaleX, scaleY\n     * skewX, skewY, angle, strokeWidth, top, left.\n     * Those coordinates are useful to understand where an object is. They get updated\n     * with oCoords but they do not need to be updated when zoom or panning change.\n     * The coordinates get updated with @method setCoords.\n     * You can calculate them without updating with @method calcCoords(true);\n     * @memberOf fabric.Object.prototype\n     */\n    aCoords: null,\n\n    /**\n     * storage for object transform matrix\n     */\n    ownMatrixCache: null,\n\n    /**\n     * storage for object full transform matrix\n     */\n    matrixCache: null,\n\n    /**\n     * return correct set of coordinates for intersection\n     */\n    getCoords: function(absolute, calculate) {\n      if (!this.oCoords) {\n        this.setCoords();\n      }\n      var coords = absolute ? this.aCoords : this.oCoords;\n      return getCoords(calculate ? this.calcCoords(absolute) : coords);\n    },\n\n    /**\n     * Checks if object intersects with an area formed by 2 points\n     * @param {Object} pointTL top-left point of area\n     * @param {Object} pointBR bottom-right point of area\n     * @param {Boolean} [absolute] use coordinates without viewportTransform\n     * @param {Boolean} [calculate] use coordinates of current position instead of .oCoords\n     * @return {Boolean} true if object intersects with an area formed by 2 points\n     */\n    intersectsWithRect: function(pointTL, pointBR, absolute, calculate) {\n      var coords = this.getCoords(absolute, calculate),\n          intersection = fabric.Intersection.intersectPolygonRectangle(\n            coords,\n            pointTL,\n            pointBR\n          );\n      return intersection.status === 'Intersection';\n    },\n\n    /**\n     * Checks if object intersects with another object\n     * @param {Object} other Object to test\n     * @param {Boolean} [absolute] use coordinates without viewportTransform\n     * @param {Boolean} [calculate] use coordinates of current position instead of .oCoords\n     * @return {Boolean} true if object intersects with another object\n     */\n    intersectsWithObject: function(other, absolute, calculate) {\n      var intersection = fabric.Intersection.intersectPolygonPolygon(\n        this.getCoords(absolute, calculate),\n        other.getCoords(absolute, calculate)\n      );\n\n      return intersection.status === 'Intersection'\n        || other.isContainedWithinObject(this, absolute, calculate)\n        || this.isContainedWithinObject(other, absolute, calculate);\n    },\n\n    /**\n     * Checks if object is fully contained within area of another object\n     * @param {Object} other Object to test\n     * @param {Boolean} [absolute] use coordinates without viewportTransform\n     * @param {Boolean} [calculate] use coordinates of current position instead of .oCoords\n     * @return {Boolean} true if object is fully contained within area of another object\n     */\n    isContainedWithinObject: function(other, absolute, calculate) {\n      var points = this.getCoords(absolute, calculate),\n          i = 0, lines = other._getImageLines(\n            calculate ? other.calcCoords(absolute) : absolute ? other.aCoords : other.oCoords\n          );\n      for (; i < 4; i++) {\n        if (!other.containsPoint(points[i], lines)) {\n          return false;\n        }\n      }\n      return true;\n    },\n\n    /**\n     * Checks if object is fully contained within area formed by 2 points\n     * @param {Object} pointTL top-left point of area\n     * @param {Object} pointBR bottom-right point of area\n     * @param {Boolean} [absolute] use coordinates without viewportTransform\n     * @param {Boolean} [calculate] use coordinates of current position instead of .oCoords\n     * @return {Boolean} true if object is fully contained within area formed by 2 points\n     */\n    isContainedWithinRect: function(pointTL, pointBR, absolute, calculate) {\n      var boundingRect = this.getBoundingRect(absolute, calculate);\n\n      return (\n        boundingRect.left >= pointTL.x &&\n        boundingRect.left + boundingRect.width <= pointBR.x &&\n        boundingRect.top >= pointTL.y &&\n        boundingRect.top + boundingRect.height <= pointBR.y\n      );\n    },\n\n    /**\n     * Checks if point is inside the object\n     * @param {fabric.Point} point Point to check against\n     * @param {Object} [lines] object returned from @method _getImageLines\n     * @param {Boolean} [absolute] use coordinates without viewportTransform\n     * @param {Boolean} [calculate] use coordinates of current position instead of .oCoords\n     * @return {Boolean} true if point is inside the object\n     */\n    containsPoint: function(point, lines, absolute, calculate) {\n      var lines = lines || this._getImageLines(\n            calculate ? this.calcCoords(absolute) : absolute ? this.aCoords : this.oCoords\n          ),\n          xPoints = this._findCrossPoints(point, lines);\n\n      // if xPoints is odd then point is inside the object\n      return (xPoints !== 0 && xPoints % 2 === 1);\n    },\n\n    /**\n     * Checks if object is contained within the canvas with current viewportTransform\n     * the check is done stopping at first point that appears on screen\n     * @param {Boolean} [calculate] use coordinates of current position instead of .aCoords\n     * @return {Boolean} true if object is fully or partially contained within canvas\n     */\n    isOnScreen: function(calculate) {\n      if (!this.canvas) {\n        return false;\n      }\n      var pointTL = this.canvas.vptCoords.tl, pointBR = this.canvas.vptCoords.br;\n      var points = this.getCoords(true, calculate), point;\n      for (var i = 0; i < 4; i++) {\n        point = points[i];\n        if (point.x <= pointBR.x && point.x >= pointTL.x && point.y <= pointBR.y && point.y >= pointTL.y) {\n          return true;\n        }\n      }\n      // no points on screen, check intersection with absolute coordinates\n      if (this.intersectsWithRect(pointTL, pointBR, true, calculate)) {\n        return true;\n      }\n      return this._containsCenterOfCanvas(pointTL, pointBR, calculate);\n    },\n\n    /**\n     * Checks if the object contains the midpoint between canvas extremities\n     * Does not make sense outside the context of isOnScreen and isPartiallyOnScreen\n     * @private\n     * @param {Fabric.Point} pointTL Top Left point\n     * @param {Fabric.Point} pointBR Top Right point\n     * @param {Boolean} calculate use coordinates of current position instead of .oCoords\n     * @return {Boolean} true if the object contains the point\n     */\n    _containsCenterOfCanvas: function(pointTL, pointBR, calculate) {\n      // worst case scenario the object is so big that contains the screen\n      var centerPoint = { x: (pointTL.x + pointBR.x) / 2, y: (pointTL.y + pointBR.y) / 2 };\n      if (this.containsPoint(centerPoint, null, true, calculate)) {\n        return true;\n      }\n      return false;\n    },\n\n    /**\n     * Checks if object is partially contained within the canvas with current viewportTransform\n     * @param {Boolean} [calculate] use coordinates of current position instead of .oCoords\n     * @return {Boolean} true if object is partially contained within canvas\n     */\n    isPartiallyOnScreen: function(calculate) {\n      if (!this.canvas) {\n        return false;\n      }\n      var pointTL = this.canvas.vptCoords.tl, pointBR = this.canvas.vptCoords.br;\n      if (this.intersectsWithRect(pointTL, pointBR, true, calculate)) {\n        return true;\n      }\n      return this._containsCenterOfCanvas(pointTL, pointBR, calculate);\n    },\n\n    /**\n     * Method that returns an object with the object edges in it, given the coordinates of the corners\n     * @private\n     * @param {Object} oCoords Coordinates of the object corners\n     */\n    _getImageLines: function(oCoords) {\n      return {\n        topline: {\n          o: oCoords.tl,\n          d: oCoords.tr\n        },\n        rightline: {\n          o: oCoords.tr,\n          d: oCoords.br\n        },\n        bottomline: {\n          o: oCoords.br,\n          d: oCoords.bl\n        },\n        leftline: {\n          o: oCoords.bl,\n          d: oCoords.tl\n        }\n      };\n    },\n\n    /**\n     * Helper method to determine how many cross points are between the 4 object edges\n     * and the horizontal line determined by a point on canvas\n     * @private\n     * @param {fabric.Point} point Point to check\n     * @param {Object} lines Coordinates of the object being evaluated\n     */\n    // remove yi, not used but left code here just in case.\n    _findCrossPoints: function(point, lines) {\n      var b1, b2, a1, a2, xi, // yi,\n          xcount = 0,\n          iLine;\n\n      for (var lineKey in lines) {\n        iLine = lines[lineKey];\n        // optimisation 1: line below point. no cross\n        if ((iLine.o.y < point.y) && (iLine.d.y < point.y)) {\n          continue;\n        }\n        // optimisation 2: line above point. no cross\n        if ((iLine.o.y >= point.y) && (iLine.d.y >= point.y)) {\n          continue;\n        }\n        // optimisation 3: vertical line case\n        if ((iLine.o.x === iLine.d.x) && (iLine.o.x >= point.x)) {\n          xi = iLine.o.x;\n          // yi = point.y;\n        }\n        // calculate the intersection point\n        else {\n          b1 = 0;\n          b2 = (iLine.d.y - iLine.o.y) / (iLine.d.x - iLine.o.x);\n          a1 = point.y - b1 * point.x;\n          a2 = iLine.o.y - b2 * iLine.o.x;\n\n          xi = -(a1 - a2) / (b1 - b2);\n          // yi = a1 + b1 * xi;\n        }\n        // dont count xi < point.x cases\n        if (xi >= point.x) {\n          xcount += 1;\n        }\n        // optimisation 4: specific for square images\n        if (xcount === 2) {\n          break;\n        }\n      }\n      return xcount;\n    },\n\n    /**\n     * Returns coordinates of object's bounding rectangle (left, top, width, height)\n     * the box is intended as aligned to axis of canvas.\n     * @param {Boolean} [absolute] use coordinates without viewportTransform\n     * @param {Boolean} [calculate] use coordinates of current position instead of .oCoords / .aCoords\n     * @return {Object} Object with left, top, width, height properties\n     */\n    getBoundingRect: function(absolute, calculate) {\n      var coords = this.getCoords(absolute, calculate);\n      return fabric.util.makeBoundingBoxFromPoints(coords);\n    },\n\n    /**\n     * Returns width of an object's bounding box counting transformations\n     * before 2.0 it was named getWidth();\n     * @return {Number} width value\n     */\n    getScaledWidth: function() {\n      return this._getTransformedDimensions().x;\n    },\n\n    /**\n     * Returns height of an object bounding box counting transformations\n     * before 2.0 it was named getHeight();\n     * @return {Number} height value\n     */\n    getScaledHeight: function() {\n      return this._getTransformedDimensions().y;\n    },\n\n    /**\n     * Makes sure the scale is valid and modifies it if necessary\n     * @private\n     * @param {Number} value\n     * @return {Number}\n     */\n    _constrainScale: function(value) {\n      if (Math.abs(value) < this.minScaleLimit) {\n        if (value < 0) {\n          return -this.minScaleLimit;\n        }\n        else {\n          return this.minScaleLimit;\n        }\n      }\n      else if (value === 0) {\n        return 0.0001;\n      }\n      return value;\n    },\n\n    /**\n     * Scales an object (equally by x and y)\n     * @param {Number} value Scale factor\n     * @return {fabric.Object} thisArg\n     * @chainable\n     */\n    scale: function(value) {\n      this._set('scaleX', value);\n      this._set('scaleY', value);\n      return this.setCoords();\n    },\n\n    /**\n     * Scales an object to a given width, with respect to bounding box (scaling by x/y equally)\n     * @param {Number} value New width value\n     * @param {Boolean} absolute ignore viewport\n     * @return {fabric.Object} thisArg\n     * @chainable\n     */\n    scaleToWidth: function(value, absolute) {\n      // adjust to bounding rect factor so that rotated shapes would fit as well\n      var boundingRectFactor = this.getBoundingRect(absolute).width / this.getScaledWidth();\n      return this.scale(value / this.width / boundingRectFactor);\n    },\n\n    /**\n     * Scales an object to a given height, with respect to bounding box (scaling by x/y equally)\n     * @param {Number} value New height value\n     * @param {Boolean} absolute ignore viewport\n     * @return {fabric.Object} thisArg\n     * @chainable\n     */\n    scaleToHeight: function(value, absolute) {\n      // adjust to bounding rect factor so that rotated shapes would fit as well\n      var boundingRectFactor = this.getBoundingRect(absolute).height / this.getScaledHeight();\n      return this.scale(value / this.height / boundingRectFactor);\n    },\n\n    /**\n     * Calculates and returns the .coords of an object.\n     * @return {Object} Object with tl, tr, br, bl ....\n     * @chainable\n     */\n    calcCoords: function(absolute) {\n      var rotateMatrix = this._calcRotateMatrix(),\n          translateMatrix = this._calcTranslateMatrix(),\n          startMatrix = multiplyMatrices(translateMatrix, rotateMatrix),\n          vpt = this.getViewportTransform(),\n          finalMatrix = absolute ? startMatrix : multiplyMatrices(vpt, startMatrix),\n          dim = this._getTransformedDimensions(),\n          w = dim.x / 2, h = dim.y / 2,\n          tl = transformPoint({ x: -w, y: -h }, finalMatrix),\n          tr = transformPoint({ x: w, y: -h }, finalMatrix),\n          bl = transformPoint({ x: -w, y: h }, finalMatrix),\n          br = transformPoint({ x: w, y: h }, finalMatrix);\n      if (!absolute) {\n        var padding = this.padding, angle = degreesToRadians(this.angle),\n            cos = fabric.util.cos(angle), sin = fabric.util.sin(angle),\n            cosP = cos * padding, sinP = sin * padding, cosPSinP = cosP + sinP,\n            cosPMinusSinP = cosP - sinP;\n        if (padding) {\n          tl.x -= cosPMinusSinP;\n          tl.y -= cosPSinP;\n          tr.x += cosPSinP;\n          tr.y -= cosPMinusSinP;\n          bl.x -= cosPSinP;\n          bl.y += cosPMinusSinP;\n          br.x += cosPMinusSinP;\n          br.y += cosPSinP;\n        }\n        var ml  = new fabric.Point((tl.x + bl.x) / 2, (tl.y + bl.y) / 2),\n            mt  = new fabric.Point((tr.x + tl.x) / 2, (tr.y + tl.y) / 2),\n            mr  = new fabric.Point((br.x + tr.x) / 2, (br.y + tr.y) / 2),\n            mb  = new fabric.Point((br.x + bl.x) / 2, (br.y + bl.y) / 2),\n            mtr = new fabric.Point(mt.x + sin * this.rotatingPointOffset, mt.y - cos * this.rotatingPointOffset);\n      }\n\n      // if (!absolute) {\n      //   var canvas = this.canvas;\n      //   setTimeout(function() {\n      //     canvas.contextTop.clearRect(0, 0, 700, 700);\n      //     canvas.contextTop.fillStyle = 'green';\n      //     canvas.contextTop.fillRect(mb.x, mb.y, 3, 3);\n      //     canvas.contextTop.fillRect(bl.x, bl.y, 3, 3);\n      //     canvas.contextTop.fillRect(br.x, br.y, 3, 3);\n      //     canvas.contextTop.fillRect(tl.x, tl.y, 3, 3);\n      //     canvas.contextTop.fillRect(tr.x, tr.y, 3, 3);\n      //     canvas.contextTop.fillRect(ml.x, ml.y, 3, 3);\n      //     canvas.contextTop.fillRect(mr.x, mr.y, 3, 3);\n      //     canvas.contextTop.fillRect(mt.x, mt.y, 3, 3);\n      //     canvas.contextTop.fillRect(mtr.x, mtr.y, 3, 3);\n      //   }, 50);\n      // }\n\n      var coords = {\n        // corners\n        tl: tl, tr: tr, br: br, bl: bl,\n      };\n      if (!absolute) {\n        // middle\n        coords.ml = ml;\n        coords.mt = mt;\n        coords.mr = mr;\n        coords.mb = mb;\n        // rotating point\n        coords.mtr = mtr;\n      }\n      return coords;\n    },\n\n    /**\n     * Sets corner position coordinates based on current angle, width and height.\n     * See {@link https://github.com/kangax/fabric.js/wiki/When-to-call-setCoords|When-to-call-setCoords}\n     * @param {Boolean} [ignoreZoom] set oCoords with or without the viewport transform.\n     * @param {Boolean} [skipAbsolute] skip calculation of aCoords, useful in setViewportTransform\n     * @return {fabric.Object} thisArg\n     * @chainable\n     */\n    setCoords: function(ignoreZoom, skipAbsolute) {\n      this.oCoords = this.calcCoords(ignoreZoom);\n      if (!skipAbsolute) {\n        this.aCoords = this.calcCoords(true);\n      }\n\n      // set coordinates of the draggable boxes in the corners used to scale/rotate the image\n      ignoreZoom || (this._setCornerCoords && this._setCornerCoords());\n\n      return this;\n    },\n\n    /**\n     * calculate rotation matrix of an object\n     * @return {Array} rotation matrix for the object\n     */\n    _calcRotateMatrix: function() {\n      if (this.angle) {\n        var theta = degreesToRadians(this.angle), cos = fabric.util.cos(theta), sin = fabric.util.sin(theta);\n        return [cos, sin, -sin, cos, 0, 0];\n      }\n      return fabric.iMatrix.concat();\n    },\n\n    /**\n     * calculate the translation matrix for an object transform\n     * @return {Array} rotation matrix for the object\n     */\n    _calcTranslateMatrix: function() {\n      var center = this.getCenterPoint();\n      return [1, 0, 0, 1, center.x, center.y];\n    },\n\n    transformMatrixKey: function(skipGroup) {\n      var sep = '_', prefix = '';\n      if (!skipGroup && this.group) {\n        prefix = this.group.transformMatrixKey(skipGroup) + sep;\n      };\n      return prefix + this.top + sep + this.left + sep + this.scaleX + sep + this.scaleY +\n        sep + this.skewX + sep + this.skewY + sep + this.angle + sep + this.originX + sep + this.originY +\n        sep + this.width + sep + this.height + sep + this.strokeWidth + this.flipX + this.flipY;\n    },\n\n    /**\n     * calculate transform matrix that represents the current transformations from the\n     * object's properties.\n     * @param {Boolean} [skipGroup] return transform matrix for object not counting parent transformations\n     * @return {Array} transform matrix for the object\n     */\n    calcTransformMatrix: function(skipGroup) {\n      if (skipGroup) {\n        return this.calcOwnMatrix();\n      }\n      var key = this.transformMatrixKey(), cache = this.matrixCache || (this.matrixCache = {});\n      if (cache.key === key) {\n        return cache.value;\n      }\n      var matrix = this.calcOwnMatrix();\n      if (this.group) {\n        matrix = multiplyMatrices(this.group.calcTransformMatrix(), matrix);\n      }\n      cache.key = key;\n      cache.value = matrix;\n      return matrix;\n    },\n\n    calcOwnMatrix: function() {\n      var key = this.transformMatrixKey(true), cache = this.ownMatrixCache || (this.ownMatrixCache = {});\n      if (cache.key === key) {\n        return cache.value;\n      }\n      var matrix = this._calcTranslateMatrix(),\n          rotateMatrix,\n          dimensionMatrix = this._calcDimensionsTransformMatrix(this.skewX, this.skewY, true);\n      if (this.angle) {\n        rotateMatrix = this._calcRotateMatrix();\n        matrix = multiplyMatrices(matrix, rotateMatrix);\n      }\n      matrix = multiplyMatrices(matrix, dimensionMatrix);\n      cache.key = key;\n      cache.value = matrix;\n      return matrix;\n    },\n\n    _calcDimensionsTransformMatrix: function(skewX, skewY, flipping) {\n      var skewMatrix,\n          scaleX = this.scaleX * (flipping && this.flipX ? -1 : 1),\n          scaleY = this.scaleY * (flipping && this.flipY ? -1 : 1),\n          scaleMatrix = [scaleX, 0, 0, scaleY, 0, 0];\n      if (skewX) {\n        skewMatrix = [1, 0, Math.tan(degreesToRadians(skewX)), 1];\n        scaleMatrix = multiplyMatrices(scaleMatrix, skewMatrix, true);\n      }\n      if (skewY) {\n        skewMatrix = [1, Math.tan(degreesToRadians(skewY)), 0, 1];\n        scaleMatrix = multiplyMatrices(scaleMatrix, skewMatrix, true);\n      }\n      return scaleMatrix;\n    },\n\n\n    /*\n     * Calculate object dimensions from its properties\n     * @private\n     * @return {Object} .x width dimension\n     * @return {Object} .y height dimension\n     */\n    _getNonTransformedDimensions: function() {\n      var strokeWidth = this.strokeWidth,\n          w = this.width + strokeWidth,\n          h = this.height + strokeWidth;\n      return { x: w, y: h };\n    },\n\n    /*\n     * Calculate object bounding box dimensions from its properties scale, skew.\n     * @param {Number} skewX, a value to override current skewX\n     * @param {Number} skewY, a value to override current skewY\n     * @private\n     * @return {Object} .x width dimension\n     * @return {Object} .y height dimension\n     */\n    _getTransformedDimensions: function(skewX, skewY) {\n      if (typeof skewX === 'undefined') {\n        skewX = this.skewX;\n      }\n      if (typeof skewY === 'undefined') {\n        skewY = this.skewY;\n      }\n      var dimensions = this._getNonTransformedDimensions(), dimX, dimY,\n          noSkew = skewX === 0 && skewY === 0;\n\n      if (this.strokeUniform) {\n        dimX = this.width;\n        dimY = this.height;\n      }\n      else {\n        dimX = dimensions.x;\n        dimY = dimensions.y;\n      }\n      if (noSkew) {\n        return this._finalizeDimensions(dimX * this.scaleX, dimY * this.scaleY);\n      }\n      else {\n        dimX /= 2;\n        dimY /= 2;\n      }\n      var points = [\n            {\n              x: -dimX,\n              y: -dimY\n            },\n            {\n              x: dimX,\n              y: -dimY\n            },\n            {\n              x: -dimX,\n              y: dimY\n            },\n            {\n              x: dimX,\n              y: dimY\n            }],\n          i, transformMatrix = this._calcDimensionsTransformMatrix(skewX, skewY, false),\n          bbox;\n      for (i = 0; i < points.length; i++) {\n        points[i] = fabric.util.transformPoint(points[i], transformMatrix);\n      }\n      bbox = fabric.util.makeBoundingBoxFromPoints(points);\n      return this._finalizeDimensions(bbox.width, bbox.height);\n    },\n\n    /*\n     * Calculate object bounding box dimensions from its properties scale, skew.\n     * @param Number width width of the bbox\n     * @param Number height height of the bbox\n     * @private\n     * @return {Object} .x finalized width dimension\n     * @return {Object} .y finalized height dimension\n     */\n    _finalizeDimensions: function(width, height) {\n      return this.strokeUniform ?\n        { x: width + this.strokeWidth, y: height + this.strokeWidth }\n        :\n        { x: width, y: height };\n    },\n    /*\n     * Calculate object dimensions for controls, including padding and canvas zoom.\n     * private\n     */\n    _calculateCurrentDimensions: function()  {\n      var vpt = this.getViewportTransform(),\n          dim = this._getTransformedDimensions(),\n          p = fabric.util.transformPoint(dim, vpt, true);\n\n      return p.scalarAdd(2 * this.padding);\n    },\n  });\n})();\n\n\nfabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prototype */ {\n\n  /**\n   * Moves an object to the bottom of the stack of drawn objects\n   * @return {fabric.Object} thisArg\n   * @chainable\n   */\n  sendToBack: function() {\n    if (this.group) {\n      fabric.StaticCanvas.prototype.sendToBack.call(this.group, this);\n    }\n    else {\n      this.canvas.sendToBack(this);\n    }\n    return this;\n  },\n\n  /**\n   * Moves an object to the top of the stack of drawn objects\n   * @return {fabric.Object} thisArg\n   * @chainable\n   */\n  bringToFront: function() {\n    if (this.group) {\n      fabric.StaticCanvas.prototype.bringToFront.call(this.group, this);\n    }\n    else {\n      this.canvas.bringToFront(this);\n    }\n    return this;\n  },\n\n  /**\n   * Moves an object down in stack of drawn objects\n   * @param {Boolean} [intersecting] If `true`, send object behind next lower intersecting object\n   * @return {fabric.Object} thisArg\n   * @chainable\n   */\n  sendBackwards: function(intersecting) {\n    if (this.group) {\n      fabric.StaticCanvas.prototype.sendBackwards.call(this.group, this, intersecting);\n    }\n    else {\n      this.canvas.sendBackwards(this, intersecting);\n    }\n    return this;\n  },\n\n  /**\n   * Moves an object up in stack of drawn objects\n   * @param {Boolean} [intersecting] If `true`, send object in front of next upper intersecting object\n   * @return {fabric.Object} thisArg\n   * @chainable\n   */\n  bringForward: function(intersecting) {\n    if (this.group) {\n      fabric.StaticCanvas.prototype.bringForward.call(this.group, this, intersecting);\n    }\n    else {\n      this.canvas.bringForward(this, intersecting);\n    }\n    return this;\n  },\n\n  /**\n   * Moves an object to specified level in stack of drawn objects\n   * @param {Number} index New position of object\n   * @return {fabric.Object} thisArg\n   * @chainable\n   */\n  moveTo: function(index) {\n    if (this.group && this.group.type !== 'activeSelection') {\n      fabric.StaticCanvas.prototype.moveTo.call(this.group, this, index);\n    }\n    else {\n      this.canvas.moveTo(this, index);\n    }\n    return this;\n  }\n});\n\n\n/* _TO_SVG_START_ */\n(function() {\n  function getSvgColorString(prop, value) {\n    if (!value) {\n      return prop + ': none; ';\n    }\n    else if (value.toLive) {\n      return prop + ': url(#SVGID_' + value.id + '); ';\n    }\n    else {\n      var color = new fabric.Color(value),\n          str = prop + ': ' + color.toRgb() + '; ',\n          opacity = color.getAlpha();\n      if (opacity !== 1) {\n        //change the color in rgb + opacity\n        str += prop + '-opacity: ' + opacity.toString() + '; ';\n      }\n      return str;\n    }\n  }\n\n  var toFixed = fabric.util.toFixed;\n\n  fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prototype */ {\n    /**\n     * Returns styles-string for svg-export\n     * @param {Boolean} skipShadow a boolean to skip shadow filter output\n     * @return {String}\n     */\n    getSvgStyles: function(skipShadow) {\n\n      var fillRule = this.fillRule ? this.fillRule : 'nonzero',\n          strokeWidth = this.strokeWidth ? this.strokeWidth : '0',\n          strokeDashArray = this.strokeDashArray ? this.strokeDashArray.join(' ') : 'none',\n          strokeDashOffset = this.strokeDashOffset ? this.strokeDashOffset : '0',\n          strokeLineCap = this.strokeLineCap ? this.strokeLineCap : 'butt',\n          strokeLineJoin = this.strokeLineJoin ? this.strokeLineJoin : 'miter',\n          strokeMiterLimit = this.strokeMiterLimit ? this.strokeMiterLimit : '4',\n          opacity = typeof this.opacity !== 'undefined' ? this.opacity : '1',\n          visibility = this.visible ? '' : ' visibility: hidden;',\n          filter = skipShadow ? '' : this.getSvgFilter(),\n          fill = getSvgColorString('fill', this.fill),\n          stroke = getSvgColorString('stroke', this.stroke);\n\n      return [\n        stroke,\n        'stroke-width: ', strokeWidth, '; ',\n        'stroke-dasharray: ', strokeDashArray, '; ',\n        'stroke-linecap: ', strokeLineCap, '; ',\n        'stroke-dashoffset: ', strokeDashOffset, '; ',\n        'stroke-linejoin: ', strokeLineJoin, '; ',\n        'stroke-miterlimit: ', strokeMiterLimit, '; ',\n        fill,\n        'fill-rule: ', fillRule, '; ',\n        'opacity: ', opacity, ';',\n        filter,\n        visibility\n      ].join('');\n    },\n\n    /**\n     * Returns styles-string for svg-export\n     * @param {Object} style the object from which to retrieve style properties\n     * @param {Boolean} useWhiteSpace a boolean to include an additional attribute in the style.\n     * @return {String}\n     */\n    getSvgSpanStyles: function(style, useWhiteSpace) {\n      var term = '; ';\n      var fontFamily = style.fontFamily ?\n        'font-family: ' + (((style.fontFamily.indexOf('\\'') === -1 && style.fontFamily.indexOf('\"') === -1) ?\n          '\\'' + style.fontFamily  + '\\'' : style.fontFamily)) + term : '';\n      var strokeWidth = style.strokeWidth ? 'stroke-width: ' + style.strokeWidth + term : '',\n          fontFamily = fontFamily,\n          fontSize = style.fontSize ? 'font-size: ' + style.fontSize + 'px' + term : '',\n          fontStyle = style.fontStyle ? 'font-style: ' + style.fontStyle + term : '',\n          fontWeight = style.fontWeight ? 'font-weight: ' + style.fontWeight + term : '',\n          fill = style.fill ? getSvgColorString('fill', style.fill) : '',\n          stroke = style.stroke ? getSvgColorString('stroke', style.stroke) : '',\n          textDecoration = this.getSvgTextDecoration(style),\n          deltaY = style.deltaY ? 'baseline-shift: ' + (-style.deltaY) + '; ' : '';\n      if (textDecoration) {\n        textDecoration = 'text-decoration: ' + textDecoration + term;\n      }\n\n      return [\n        stroke,\n        strokeWidth,\n        fontFamily,\n        fontSize,\n        fontStyle,\n        fontWeight,\n        textDecoration,\n        fill,\n        deltaY,\n        useWhiteSpace ? 'white-space: pre; ' : ''\n      ].join('');\n    },\n\n    /**\n     * Returns text-decoration property for svg-export\n     * @param {Object} style the object from which to retrieve style properties\n     * @return {String}\n     */\n    getSvgTextDecoration: function(style) {\n      if ('overline' in style || 'underline' in style || 'linethrough' in style) {\n        return (style.overline ? 'overline ' : '') +\n          (style.underline ? 'underline ' : '') + (style.linethrough ? 'line-through ' : '');\n      }\n      return '';\n    },\n\n    /**\n     * Returns filter for svg shadow\n     * @return {String}\n     */\n    getSvgFilter: function() {\n      return this.shadow ? 'filter: url(#SVGID_' + this.shadow.id + ');' : '';\n    },\n\n    /**\n     * Returns id attribute for svg output\n     * @return {String}\n     */\n    getSvgCommons: function() {\n      return [\n        this.id ? 'id=\"' + this.id + '\" ' : '',\n        this.clipPath ? 'clip-path=\"url(#' + this.clipPath.clipPathId + ')\" ' : '',\n      ].join('');\n    },\n\n    /**\n     * Returns transform-string for svg-export\n     * @param {Boolean} use the full transform or the single object one.\n     * @return {String}\n     */\n    getSvgTransform: function(full, additionalTransform) {\n      var transform = full ? this.calcTransformMatrix() : this.calcOwnMatrix(),\n          svgTransform = 'transform=\"' + fabric.util.matrixToSVG(transform);\n      return svgTransform +\n        (additionalTransform || '') + this.getSvgTransformMatrix() + '\" ';\n    },\n\n    /**\n     * Returns transform-string for svg-export from the transform matrix of single elements\n     * @return {String}\n     */\n    getSvgTransformMatrix: function() {\n      return this.transformMatrix ? ' ' + fabric.util.matrixToSVG(this.transformMatrix) : '';\n    },\n\n    _setSVGBg: function(textBgRects) {\n      if (this.backgroundColor) {\n        var NUM_FRACTION_DIGITS = fabric.Object.NUM_FRACTION_DIGITS;\n        textBgRects.push(\n          '\\t\\t<rect ',\n          this._getFillAttributes(this.backgroundColor),\n          ' x=\"',\n          toFixed(-this.width / 2, NUM_FRACTION_DIGITS),\n          '\" y=\"',\n          toFixed(-this.height / 2, NUM_FRACTION_DIGITS),\n          '\" width=\"',\n          toFixed(this.width, NUM_FRACTION_DIGITS),\n          '\" height=\"',\n          toFixed(this.height, NUM_FRACTION_DIGITS),\n          '\"></rect>\\n');\n      }\n    },\n\n    /**\n     * Returns svg representation of an instance\n     * @param {Function} [reviver] Method for further parsing of svg representation.\n     * @return {String} svg representation of an instance\n     */\n    toSVG: function(reviver) {\n      return this._createBaseSVGMarkup(this._toSVG(reviver), { reviver: reviver });\n    },\n\n    /**\n     * Returns svg clipPath representation of an instance\n     * @param {Function} [reviver] Method for further parsing of svg representation.\n     * @return {String} svg representation of an instance\n     */\n    toClipPathSVG: function(reviver) {\n      return '\\t' + this._createBaseClipPathSVGMarkup(this._toSVG(reviver), { reviver: reviver });\n    },\n\n    /**\n     * @private\n     */\n    _createBaseClipPathSVGMarkup: function(objectMarkup, options) {\n      options = options || {};\n      var reviver = options.reviver,\n          additionalTransform = options.additionalTransform || '',\n          commonPieces = [\n            this.getSvgTransform(true, additionalTransform),\n            this.getSvgCommons(),\n          ].join(''),\n          // insert commons in the markup, style and svgCommons\n          index = objectMarkup.indexOf('COMMON_PARTS');\n      objectMarkup[index] = commonPieces;\n      return reviver ? reviver(objectMarkup.join('')) : objectMarkup.join('');\n    },\n\n    /**\n     * @private\n     */\n    _createBaseSVGMarkup: function(objectMarkup, options) {\n      options = options || {};\n      var noStyle = options.noStyle,\n          reviver = options.reviver,\n          styleInfo = noStyle ? '' : 'style=\"' + this.getSvgStyles() + '\" ',\n          shadowInfo = options.withShadow ? 'style=\"' + this.getSvgFilter() + '\" ' : '',\n          clipPath = this.clipPath,\n          vectorEffect = this.strokeUniform ? 'vector-effect=\"non-scaling-stroke\" ' : '',\n          absoluteClipPath = clipPath && clipPath.absolutePositioned,\n          stroke = this.stroke, fill = this.fill, shadow = this.shadow,\n          commonPieces, markup = [], clipPathMarkup,\n          // insert commons in the markup, style and svgCommons\n          index = objectMarkup.indexOf('COMMON_PARTS'),\n          additionalTransform = options.additionalTransform;\n      if (clipPath) {\n        clipPath.clipPathId = 'CLIPPATH_' + fabric.Object.__uid++;\n        clipPathMarkup = '<clipPath id=\"' + clipPath.clipPathId + '\" >\\n' +\n          clipPath.toClipPathSVG(reviver) +\n          '</clipPath>\\n';\n      }\n      if (absoluteClipPath) {\n        markup.push(\n          '<g ', shadowInfo, this.getSvgCommons(), ' >\\n'\n        );\n      }\n      markup.push(\n        '<g ',\n        this.getSvgTransform(false),\n        !absoluteClipPath ? shadowInfo + this.getSvgCommons() : '',\n        ' >\\n'\n      );\n      commonPieces = [\n        styleInfo,\n        vectorEffect,\n        noStyle ? '' : this.addPaintOrder(), ' ',\n        additionalTransform ? 'transform=\"' + additionalTransform + '\" ' : '',\n      ].join('');\n      objectMarkup[index] = commonPieces;\n      if (fill && fill.toLive) {\n        markup.push(fill.toSVG(this));\n      }\n      if (stroke && stroke.toLive) {\n        markup.push(stroke.toSVG(this));\n      }\n      if (shadow) {\n        markup.push(shadow.toSVG(this));\n      }\n      if (clipPath) {\n        markup.push(clipPathMarkup);\n      }\n      markup.push(objectMarkup.join(''));\n      markup.push('</g>\\n');\n      absoluteClipPath && markup.push('</g>\\n');\n      return reviver ? reviver(markup.join('')) : markup.join('');\n    },\n\n    addPaintOrder: function() {\n      return this.paintFirst !== 'fill' ? ' paint-order=\"' + this.paintFirst + '\" ' : '';\n    }\n  });\n})();\n/* _TO_SVG_END_ */\n\n\n(function() {\n\n  var extend = fabric.util.object.extend,\n      originalSet = 'stateProperties';\n\n  /*\n    Depends on `stateProperties`\n  */\n  function saveProps(origin, destination, props) {\n    var tmpObj = { }, deep = true;\n    props.forEach(function(prop) {\n      tmpObj[prop] = origin[prop];\n    });\n    extend(origin[destination], tmpObj, deep);\n  }\n\n  function _isEqual(origValue, currentValue, firstPass) {\n    if (origValue === currentValue) {\n      // if the objects are identical, return\n      return true;\n    }\n    else if (Array.isArray(origValue)) {\n      if (!Array.isArray(currentValue) || origValue.length !== currentValue.length) {\n        return false;\n      }\n      for (var i = 0, len = origValue.length; i < len; i++) {\n        if (!_isEqual(origValue[i], currentValue[i])) {\n          return false;\n        }\n      }\n      return true;\n    }\n    else if (origValue && typeof origValue === 'object') {\n      var keys = Object.keys(origValue), key;\n      if (!currentValue ||\n          typeof currentValue !== 'object' ||\n          (!firstPass && keys.length !== Object.keys(currentValue).length)\n      ) {\n        return false;\n      }\n      for (var i = 0, len = keys.length; i < len; i++) {\n        key = keys[i];\n        // since clipPath is in the statefull cache list and the clipPath objects\n        // would be iterated as an object, this would lead to possible infinite recursion\n        if (key === 'canvas') {\n          continue;\n        }\n        if (!_isEqual(origValue[key], currentValue[key])) {\n          return false;\n        }\n      }\n      return true;\n    }\n  }\n\n\n  fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prototype */ {\n\n    /**\n     * Returns true if object state (one of its state properties) was changed\n     * @param {String} [propertySet] optional name for the set of property we want to save\n     * @return {Boolean} true if instance' state has changed since `{@link fabric.Object#saveState}` was called\n     */\n    hasStateChanged: function(propertySet) {\n      propertySet = propertySet || originalSet;\n      var dashedPropertySet = '_' + propertySet;\n      if (Object.keys(this[dashedPropertySet]).length < this[propertySet].length) {\n        return true;\n      }\n      return !_isEqual(this[dashedPropertySet], this, true);\n    },\n\n    /**\n     * Saves state of an object\n     * @param {Object} [options] Object with additional `stateProperties` array to include when saving state\n     * @return {fabric.Object} thisArg\n     */\n    saveState: function(options) {\n      var propertySet = options && options.propertySet || originalSet,\n          destination = '_' + propertySet;\n      if (!this[destination]) {\n        return this.setupState(options);\n      }\n      saveProps(this, destination, this[propertySet]);\n      if (options && options.stateProperties) {\n        saveProps(this, destination, options.stateProperties);\n      }\n      return this;\n    },\n\n    /**\n     * Setups state of an object\n     * @param {Object} [options] Object with additional `stateProperties` array to include when saving state\n     * @return {fabric.Object} thisArg\n     */\n    setupState: function(options) {\n      options = options || { };\n      var propertySet = options.propertySet || originalSet;\n      options.propertySet = propertySet;\n      this['_' + propertySet] = { };\n      this.saveState(options);\n      return this;\n    }\n  });\n})();\n\n\n(function() {\n\n  var degreesToRadians = fabric.util.degreesToRadians;\n\n  fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prototype */ {\n\n    /**\n     * The object interactivity controls.\n     * @private\n     */\n    _controlsVisibility: null,\n\n    /**\n     * Determines which corner has been clicked\n     * @private\n     * @param {Object} pointer The pointer indicating the mouse position\n     * @return {String|Boolean} corner code (tl, tr, bl, br, etc.), or false if nothing is found\n     */\n    _findTargetCorner: function(pointer) {\n      // objects in group, anykind, are not self modificable,\n      // must not return an hovered corner.\n      if (!this.hasControls || this.group || (!this.canvas || this.canvas._activeObject !== this)) {\n        return false;\n      }\n\n      var ex = pointer.x,\n          ey = pointer.y,\n          xPoints,\n          lines;\n      this.__corner = 0;\n      for (var i in this.oCoords) {\n\n        if (!this.isControlVisible(i)) {\n          continue;\n        }\n\n        if (i === 'mtr' && !this.hasRotatingPoint) {\n          continue;\n        }\n\n        if (this.get('lockUniScaling') &&\n           (i === 'mt' || i === 'mr' || i === 'mb' || i === 'ml')) {\n          continue;\n        }\n\n        lines = this._getImageLines(this.oCoords[i].corner);\n\n        // debugging\n\n        // canvas.contextTop.fillRect(lines.bottomline.d.x, lines.bottomline.d.y, 2, 2);\n        // canvas.contextTop.fillRect(lines.bottomline.o.x, lines.bottomline.o.y, 2, 2);\n\n        // canvas.contextTop.fillRect(lines.leftline.d.x, lines.leftline.d.y, 2, 2);\n        // canvas.contextTop.fillRect(lines.leftline.o.x, lines.leftline.o.y, 2, 2);\n\n        // canvas.contextTop.fillRect(lines.topline.d.x, lines.topline.d.y, 2, 2);\n        // canvas.contextTop.fillRect(lines.topline.o.x, lines.topline.o.y, 2, 2);\n\n        // canvas.contextTop.fillRect(lines.rightline.d.x, lines.rightline.d.y, 2, 2);\n        // canvas.contextTop.fillRect(lines.rightline.o.x, lines.rightline.o.y, 2, 2);\n\n        xPoints = this._findCrossPoints({ x: ex, y: ey }, lines);\n        if (xPoints !== 0 && xPoints % 2 === 1) {\n          this.__corner = i;\n          return i;\n        }\n      }\n      return false;\n    },\n\n    /**\n     * Sets the coordinates of the draggable boxes in the corners of\n     * the image used to scale/rotate it.\n     * @private\n     */\n    _setCornerCoords: function() {\n      var coords = this.oCoords,\n          newTheta = degreesToRadians(45 - this.angle),\n          /* Math.sqrt(2 * Math.pow(this.cornerSize, 2)) / 2, */\n          /* 0.707106 stands for sqrt(2)/2 */\n          cornerHypotenuse = this.cornerSize * 0.707106,\n          cosHalfOffset = cornerHypotenuse * fabric.util.cos(newTheta),\n          sinHalfOffset = cornerHypotenuse * fabric.util.sin(newTheta),\n          x, y;\n\n      for (var point in coords) {\n        x = coords[point].x;\n        y = coords[point].y;\n        coords[point].corner = {\n          tl: {\n            x: x - sinHalfOffset,\n            y: y - cosHalfOffset\n          },\n          tr: {\n            x: x + cosHalfOffset,\n            y: y - sinHalfOffset\n          },\n          bl: {\n            x: x - cosHalfOffset,\n            y: y + sinHalfOffset\n          },\n          br: {\n            x: x + sinHalfOffset,\n            y: y + cosHalfOffset\n          }\n        };\n      }\n    },\n\n    /**\n     * Draws a colored layer behind the object, inside its selection borders.\n     * Requires public options: padding, selectionBackgroundColor\n     * this function is called when the context is transformed\n     * has checks to be skipped when the object is on a staticCanvas\n     * @param {CanvasRenderingContext2D} ctx Context to draw on\n     * @return {fabric.Object} thisArg\n     * @chainable\n     */\n    drawSelectionBackground: function(ctx) {\n      if (!this.selectionBackgroundColor ||\n        (this.canvas && !this.canvas.interactive) ||\n        (this.canvas && this.canvas._activeObject !== this)\n      ) {\n        return this;\n      }\n      ctx.save();\n      var center = this.getCenterPoint(), wh = this._calculateCurrentDimensions(),\n          vpt = this.canvas.viewportTransform;\n      ctx.translate(center.x, center.y);\n      ctx.scale(1 / vpt[0], 1 / vpt[3]);\n      ctx.rotate(degreesToRadians(this.angle));\n      ctx.fillStyle = this.selectionBackgroundColor;\n      ctx.fillRect(-wh.x / 2, -wh.y / 2, wh.x, wh.y);\n      ctx.restore();\n      return this;\n    },\n\n    /**\n     * Draws borders of an object's bounding box.\n     * Requires public properties: width, height\n     * Requires public options: padding, borderColor\n     * @param {CanvasRenderingContext2D} ctx Context to draw on\n     * @param {Object} styleOverride object to override the object style\n     * @return {fabric.Object} thisArg\n     * @chainable\n     */\n    drawBorders: function(ctx, styleOverride) {\n      styleOverride = styleOverride || {};\n      var wh = this._calculateCurrentDimensions(),\n          strokeWidth = 1 / this.borderScaleFactor,\n          width = wh.x + strokeWidth,\n          height = wh.y + strokeWidth,\n          drawRotatingPoint = typeof styleOverride.hasRotatingPoint !== 'undefined' ?\n            styleOverride.hasRotatingPoint : this.hasRotatingPoint,\n          hasControls = typeof styleOverride.hasControls !== 'undefined' ?\n            styleOverride.hasControls : this.hasControls,\n          rotatingPointOffset = typeof styleOverride.rotatingPointOffset !== 'undefined' ?\n            styleOverride.rotatingPointOffset : this.rotatingPointOffset;\n\n      ctx.save();\n      ctx.strokeStyle = styleOverride.borderColor || this.borderColor;\n      this._setLineDash(ctx, styleOverride.borderDashArray || this.borderDashArray, null);\n\n      ctx.strokeRect(\n        -width / 2,\n        -height / 2,\n        width,\n        height\n      );\n\n      if (drawRotatingPoint && this.isControlVisible('mtr') && hasControls) {\n\n        var rotateHeight = -height / 2;\n\n        ctx.beginPath();\n        ctx.moveTo(0, rotateHeight);\n        ctx.lineTo(0, rotateHeight - rotatingPointOffset);\n        ctx.stroke();\n      }\n\n      ctx.restore();\n      return this;\n    },\n\n    /**\n     * Draws borders of an object's bounding box when it is inside a group.\n     * Requires public properties: width, height\n     * Requires public options: padding, borderColor\n     * @param {CanvasRenderingContext2D} ctx Context to draw on\n     * @param {object} options object representing current object parameters\n     * @param {Object} styleOverride object to override the object style\n     * @return {fabric.Object} thisArg\n     * @chainable\n     */\n    drawBordersInGroup: function(ctx, options, styleOverride) {\n      styleOverride = styleOverride || {};\n      var p = this._getNonTransformedDimensions(),\n          matrix = fabric.util.customTransformMatrix(options.scaleX, options.scaleY, options.skewX),\n          wh = fabric.util.transformPoint(p, matrix),\n          strokeWidth = 1 / this.borderScaleFactor,\n          width = wh.x + strokeWidth,\n          height = wh.y + strokeWidth;\n\n      ctx.save();\n      this._setLineDash(ctx, styleOverride.borderDashArray || this.borderDashArray, null);\n      ctx.strokeStyle = styleOverride.borderColor || this.borderColor;\n\n      ctx.strokeRect(\n        -width / 2,\n        -height / 2,\n        width,\n        height\n      );\n\n      ctx.restore();\n      return this;\n    },\n\n    /**\n     * Draws corners of an object's bounding box.\n     * Requires public properties: width, height\n     * Requires public options: cornerSize, padding\n     * @param {CanvasRenderingContext2D} ctx Context to draw on\n     * @param {Object} styleOverride object to override the object style\n     * @return {fabric.Object} thisArg\n     * @chainable\n     */\n    drawControls: function(ctx, styleOverride) {\n      styleOverride = styleOverride || {};\n      var wh = this._calculateCurrentDimensions(),\n          width = wh.x,\n          height = wh.y,\n          scaleOffset = styleOverride.cornerSize || this.cornerSize,\n          left = -(width + scaleOffset) / 2,\n          top = -(height + scaleOffset) / 2,\n          transparentCorners = typeof styleOverride.transparentCorners !== 'undefined' ?\n            styleOverride.transparentCorners : this.transparentCorners,\n          hasRotatingPoint = typeof styleOverride.hasRotatingPoint !== 'undefined' ?\n            styleOverride.hasRotatingPoint : this.hasRotatingPoint,\n          methodName = transparentCorners ? 'stroke' : 'fill';\n\n      ctx.save();\n      ctx.strokeStyle = ctx.fillStyle = styleOverride.cornerColor || this.cornerColor;\n      if (!this.transparentCorners) {\n        ctx.strokeStyle = styleOverride.cornerStrokeColor || this.cornerStrokeColor;\n      }\n      this._setLineDash(ctx, styleOverride.cornerDashArray || this.cornerDashArray, null);\n\n      // top-left\n      this._drawControl('tl', ctx, methodName,\n        left,\n        top, styleOverride);\n\n      // top-right\n      this._drawControl('tr', ctx, methodName,\n        left + width,\n        top, styleOverride);\n\n      // bottom-left\n      this._drawControl('bl', ctx, methodName,\n        left,\n        top + height, styleOverride);\n\n      // bottom-right\n      this._drawControl('br', ctx, methodName,\n        left + width,\n        top + height, styleOverride);\n\n      if (!this.get('lockUniScaling')) {\n\n        // middle-top\n        this._drawControl('mt', ctx, methodName,\n          left + width / 2,\n          top, styleOverride);\n\n        // middle-bottom\n        this._drawControl('mb', ctx, methodName,\n          left + width / 2,\n          top + height, styleOverride);\n\n        // middle-right\n        this._drawControl('mr', ctx, methodName,\n          left + width,\n          top + height / 2, styleOverride);\n\n        // middle-left\n        this._drawControl('ml', ctx, methodName,\n          left,\n          top + height / 2, styleOverride);\n      }\n\n      // middle-top-rotate\n      if (hasRotatingPoint) {\n        this._drawControl('mtr', ctx, methodName,\n          left + width / 2,\n          top - this.rotatingPointOffset, styleOverride);\n      }\n\n      ctx.restore();\n\n      return this;\n    },\n\n    /**\n     * @private\n     */\n    _drawControl: function(control, ctx, methodName, left, top, styleOverride) {\n      styleOverride = styleOverride || {};\n      if (!this.isControlVisible(control)) {\n        return;\n      }\n      var size = this.cornerSize, stroke = !this.transparentCorners && this.cornerStrokeColor;\n      switch (styleOverride.cornerStyle || this.cornerStyle) {\n        case 'circle':\n          ctx.beginPath();\n          ctx.arc(left + size / 2, top + size / 2, size / 2, 0, 2 * Math.PI, false);\n          ctx[methodName]();\n          if (stroke) {\n            ctx.stroke();\n          }\n          break;\n        default:\n          this.transparentCorners || ctx.clearRect(left, top, size, size);\n          ctx[methodName + 'Rect'](left, top, size, size);\n          if (stroke) {\n            ctx.strokeRect(left, top, size, size);\n          }\n      }\n    },\n\n    /**\n     * Returns true if the specified control is visible, false otherwise.\n     * @param {String} controlName The name of the control. Possible values are 'tl', 'tr', 'br', 'bl', 'ml', 'mt', 'mr', 'mb', 'mtr'.\n     * @returns {Boolean} true if the specified control is visible, false otherwise\n     */\n    isControlVisible: function(controlName) {\n      return this._getControlsVisibility()[controlName];\n    },\n\n    /**\n     * Sets the visibility of the specified control.\n     * @param {String} controlName The name of the control. Possible values are 'tl', 'tr', 'br', 'bl', 'ml', 'mt', 'mr', 'mb', 'mtr'.\n     * @param {Boolean} visible true to set the specified control visible, false otherwise\n     * @return {fabric.Object} thisArg\n     * @chainable\n     */\n    setControlVisible: function(controlName, visible) {\n      this._getControlsVisibility()[controlName] = visible;\n      return this;\n    },\n\n    /**\n     * Sets the visibility state of object controls.\n     * @param {Object} [options] Options object\n     * @param {Boolean} [options.bl] true to enable the bottom-left control, false to disable it\n     * @param {Boolean} [options.br] true to enable the bottom-right control, false to disable it\n     * @param {Boolean} [options.mb] true to enable the middle-bottom control, false to disable it\n     * @param {Boolean} [options.ml] true to enable the middle-left control, false to disable it\n     * @param {Boolean} [options.mr] true to enable the middle-right control, false to disable it\n     * @param {Boolean} [options.mt] true to enable the middle-top control, false to disable it\n     * @param {Boolean} [options.tl] true to enable the top-left control, false to disable it\n     * @param {Boolean} [options.tr] true to enable the top-right control, false to disable it\n     * @param {Boolean} [options.mtr] true to enable the middle-top-rotate control, false to disable it\n     * @return {fabric.Object} thisArg\n     * @chainable\n     */\n    setControlsVisibility: function(options) {\n      options || (options = { });\n\n      for (var p in options) {\n        this.setControlVisible(p, options[p]);\n      }\n      return this;\n    },\n\n    /**\n     * Returns the instance of the control visibility set for this object.\n     * @private\n     * @returns {Object}\n     */\n    _getControlsVisibility: function() {\n      if (!this._controlsVisibility) {\n        this._controlsVisibility = {\n          tl: true,\n          tr: true,\n          br: true,\n          bl: true,\n          ml: true,\n          mt: true,\n          mr: true,\n          mb: true,\n          mtr: true\n        };\n      }\n      return this._controlsVisibility;\n    },\n\n    /**\n     * This callback function is called every time _discardActiveObject or _setActiveObject\n     * try to to deselect this object. If the function returns true, the process is cancelled\n     * @param {Object} [options] options sent from the upper functions\n     * @param {Event} [options.e] event if the process is generated by an event\n     */\n    onDeselect: function() {\n      // implemented by sub-classes, as needed.\n    },\n\n\n    /**\n     * This callback function is called every time _discardActiveObject or _setActiveObject\n     * try to to select this object. If the function returns true, the process is cancelled\n     * @param {Object} [options] options sent from the upper functions\n     * @param {Event} [options.e] event if the process is generated by an event\n     */\n    onSelect: function() {\n      // implemented by sub-classes, as needed.\n    }\n  });\n})();\n\n\nfabric.util.object.extend(fabric.StaticCanvas.prototype, /** @lends fabric.StaticCanvas.prototype */ {\n\n  /**\n   * Animation duration (in ms) for fx* methods\n   * @type Number\n   * @default\n   */\n  FX_DURATION: 500,\n\n  /**\n   * Centers object horizontally with animation.\n   * @param {fabric.Object} object Object to center\n   * @param {Object} [callbacks] Callbacks object with optional \"onComplete\" and/or \"onChange\" properties\n   * @param {Function} [callbacks.onComplete] Invoked on completion\n   * @param {Function} [callbacks.onChange] Invoked on every step of animation\n   * @return {fabric.Canvas} thisArg\n   * @chainable\n   */\n  fxCenterObjectH: function (object, callbacks) {\n    callbacks = callbacks || { };\n\n    var empty = function() { },\n        onComplete = callbacks.onComplete || empty,\n        onChange = callbacks.onChange || empty,\n        _this = this;\n\n    fabric.util.animate({\n      startValue: object.left,\n      endValue: this.getCenter().left,\n      duration: this.FX_DURATION,\n      onChange: function(value) {\n        object.set('left', value);\n        _this.requestRenderAll();\n        onChange();\n      },\n      onComplete: function() {\n        object.setCoords();\n        onComplete();\n      }\n    });\n\n    return this;\n  },\n\n  /**\n   * Centers object vertically with animation.\n   * @param {fabric.Object} object Object to center\n   * @param {Object} [callbacks] Callbacks object with optional \"onComplete\" and/or \"onChange\" properties\n   * @param {Function} [callbacks.onComplete] Invoked on completion\n   * @param {Function} [callbacks.onChange] Invoked on every step of animation\n   * @return {fabric.Canvas} thisArg\n   * @chainable\n   */\n  fxCenterObjectV: function (object, callbacks) {\n    callbacks = callbacks || { };\n\n    var empty = function() { },\n        onComplete = callbacks.onComplete || empty,\n        onChange = callbacks.onChange || empty,\n        _this = this;\n\n    fabric.util.animate({\n      startValue: object.top,\n      endValue: this.getCenter().top,\n      duration: this.FX_DURATION,\n      onChange: function(value) {\n        object.set('top', value);\n        _this.requestRenderAll();\n        onChange();\n      },\n      onComplete: function() {\n        object.setCoords();\n        onComplete();\n      }\n    });\n\n    return this;\n  },\n\n  /**\n   * Same as `fabric.Canvas#remove` but animated\n   * @param {fabric.Object} object Object to remove\n   * @param {Object} [callbacks] Callbacks object with optional \"onComplete\" and/or \"onChange\" properties\n   * @param {Function} [callbacks.onComplete] Invoked on completion\n   * @param {Function} [callbacks.onChange] Invoked on every step of animation\n   * @return {fabric.Canvas} thisArg\n   * @chainable\n   */\n  fxRemove: function (object, callbacks) {\n    callbacks = callbacks || { };\n\n    var empty = function() { },\n        onComplete = callbacks.onComplete || empty,\n        onChange = callbacks.onChange || empty,\n        _this = this;\n\n    fabric.util.animate({\n      startValue: object.opacity,\n      endValue: 0,\n      duration: this.FX_DURATION,\n      onChange: function(value) {\n        object.set('opacity', value);\n        _this.requestRenderAll();\n        onChange();\n      },\n      onComplete: function () {\n        _this.remove(object);\n        onComplete();\n      }\n    });\n\n    return this;\n  }\n});\n\nfabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prototype */ {\n  /**\n   * Animates object's properties\n   * @param {String|Object} property Property to animate (if string) or properties to animate (if object)\n   * @param {Number|Object} value Value to animate property to (if string was given first) or options object\n   * @return {fabric.Object} thisArg\n   * @tutorial {@link http://fabricjs.com/fabric-intro-part-2#animation}\n   * @chainable\n   *\n   * As object — multiple properties\n   *\n   * object.animate({ left: ..., top: ... });\n   * object.animate({ left: ..., top: ... }, { duration: ... });\n   *\n   * As string — one property\n   *\n   * object.animate('left', ...);\n   * object.animate('left', { duration: ... });\n   *\n   */\n  animate: function() {\n    if (arguments[0] && typeof arguments[0] === 'object') {\n      var propsToAnimate = [], prop, skipCallbacks;\n      for (prop in arguments[0]) {\n        propsToAnimate.push(prop);\n      }\n      for (var i = 0, len = propsToAnimate.length; i < len; i++) {\n        prop = propsToAnimate[i];\n        skipCallbacks = i !== len - 1;\n        this._animate(prop, arguments[0][prop], arguments[1], skipCallbacks);\n      }\n    }\n    else {\n      this._animate.apply(this, arguments);\n    }\n    return this;\n  },\n\n  /**\n   * @private\n   * @param {String} property Property to animate\n   * @param {String} to Value to animate to\n   * @param {Object} [options] Options object\n   * @param {Boolean} [skipCallbacks] When true, callbacks like onchange and oncomplete are not invoked\n   */\n  _animate: function(property, to, options, skipCallbacks) {\n    var _this = this, propPair;\n\n    to = to.toString();\n\n    if (!options) {\n      options = { };\n    }\n    else {\n      options = fabric.util.object.clone(options);\n    }\n\n    if (~property.indexOf('.')) {\n      propPair = property.split('.');\n    }\n\n    var currentValue = propPair\n      ? this.get(propPair[0])[propPair[1]]\n      : this.get(property);\n\n    if (!('from' in options)) {\n      options.from = currentValue;\n    }\n\n    if (~to.indexOf('=')) {\n      to = currentValue + parseFloat(to.replace('=', ''));\n    }\n    else {\n      to = parseFloat(to);\n    }\n\n    fabric.util.animate({\n      startValue: options.from,\n      endValue: to,\n      byValue: options.by,\n      easing: options.easing,\n      duration: options.duration,\n      abort: options.abort && function() {\n        return options.abort.call(_this);\n      },\n      onChange: function(value, valueProgress, timeProgress) {\n        if (propPair) {\n          _this[propPair[0]][propPair[1]] = value;\n        }\n        else {\n          _this.set(property, value);\n        }\n        if (skipCallbacks) {\n          return;\n        }\n        options.onChange && options.onChange(value, valueProgress, timeProgress);\n      },\n      onComplete: function(value, valueProgress, timeProgress) {\n        if (skipCallbacks) {\n          return;\n        }\n\n        _this.setCoords();\n        options.onComplete && options.onComplete(value, valueProgress, timeProgress);\n      }\n    });\n  }\n});\n\n\n(function(global) {\n\n  'use strict';\n\n  var fabric = global.fabric || (global.fabric = { }),\n      extend = fabric.util.object.extend,\n      clone = fabric.util.object.clone,\n      coordProps = { x1: 1, x2: 1, y1: 1, y2: 1 },\n      supportsLineDash = fabric.StaticCanvas.supports('setLineDash');\n\n  if (fabric.Line) {\n    fabric.warn('fabric.Line is already defined');\n    return;\n  }\n\n  /**\n   * Line class\n   * @class fabric.Line\n   * @extends fabric.Object\n   * @see {@link fabric.Line#initialize} for constructor definition\n   */\n  fabric.Line = fabric.util.createClass(fabric.Object, /** @lends fabric.Line.prototype */ {\n\n    /**\n     * Type of an object\n     * @type String\n     * @default\n     */\n    type: 'line',\n\n    /**\n     * x value or first line edge\n     * @type Number\n     * @default\n     */\n    x1: 0,\n\n    /**\n     * y value or first line edge\n     * @type Number\n     * @default\n     */\n    y1: 0,\n\n    /**\n     * x value or second line edge\n     * @type Number\n     * @default\n     */\n    x2: 0,\n\n    /**\n     * y value or second line edge\n     * @type Number\n     * @default\n     */\n    y2: 0,\n\n    cacheProperties: fabric.Object.prototype.cacheProperties.concat('x1', 'x2', 'y1', 'y2'),\n\n    /**\n     * Constructor\n     * @param {Array} [points] Array of points\n     * @param {Object} [options] Options object\n     * @return {fabric.Line} thisArg\n     */\n    initialize: function(points, options) {\n      if (!points) {\n        points = [0, 0, 0, 0];\n      }\n\n      this.callSuper('initialize', options);\n\n      this.set('x1', points[0]);\n      this.set('y1', points[1]);\n      this.set('x2', points[2]);\n      this.set('y2', points[3]);\n\n      this._setWidthHeight(options);\n    },\n\n    /**\n     * @private\n     * @param {Object} [options] Options\n     */\n    _setWidthHeight: function(options) {\n      options || (options = { });\n\n      this.width = Math.abs(this.x2 - this.x1);\n      this.height = Math.abs(this.y2 - this.y1);\n\n      this.left = 'left' in options\n        ? options.left\n        : this._getLeftToOriginX();\n\n      this.top = 'top' in options\n        ? options.top\n        : this._getTopToOriginY();\n    },\n\n    /**\n     * @private\n     * @param {String} key\n     * @param {*} value\n     */\n    _set: function(key, value) {\n      this.callSuper('_set', key, value);\n      if (typeof coordProps[key] !== 'undefined') {\n        this._setWidthHeight();\n      }\n      return this;\n    },\n\n    /**\n     * @private\n     * @return {Number} leftToOriginX Distance from left edge of canvas to originX of Line.\n     */\n    _getLeftToOriginX: makeEdgeToOriginGetter(\n      { // property names\n        origin: 'originX',\n        axis1: 'x1',\n        axis2: 'x2',\n        dimension: 'width'\n      },\n      { // possible values of origin\n        nearest: 'left',\n        center: 'center',\n        farthest: 'right'\n      }\n    ),\n\n    /**\n     * @private\n     * @return {Number} topToOriginY Distance from top edge of canvas to originY of Line.\n     */\n    _getTopToOriginY: makeEdgeToOriginGetter(\n      { // property names\n        origin: 'originY',\n        axis1: 'y1',\n        axis2: 'y2',\n        dimension: 'height'\n      },\n      { // possible values of origin\n        nearest: 'top',\n        center: 'center',\n        farthest: 'bottom'\n      }\n    ),\n\n    /**\n     * @private\n     * @param {CanvasRenderingContext2D} ctx Context to render on\n     */\n    _render: function(ctx) {\n      ctx.beginPath();\n\n      if (!this.strokeDashArray || this.strokeDashArray && supportsLineDash) {\n        // move from center (of virtual box) to its left/top corner\n        // we can't assume x1, y1 is top left and x2, y2 is bottom right\n        var p = this.calcLinePoints();\n        ctx.moveTo(p.x1, p.y1);\n        ctx.lineTo(p.x2, p.y2);\n      }\n\n      ctx.lineWidth = this.strokeWidth;\n\n      // TODO: test this\n      // make sure setting \"fill\" changes color of a line\n      // (by copying fillStyle to strokeStyle, since line is stroked, not filled)\n      var origStrokeStyle = ctx.strokeStyle;\n      ctx.strokeStyle = this.stroke || ctx.fillStyle;\n      this.stroke && this._renderStroke(ctx);\n      ctx.strokeStyle = origStrokeStyle;\n    },\n\n    /**\n     * @private\n     * @param {CanvasRenderingContext2D} ctx Context to render on\n     */\n    _renderDashedStroke: function(ctx) {\n      var p = this.calcLinePoints();\n\n      ctx.beginPath();\n      fabric.util.drawDashedLine(ctx, p.x1, p.y1, p.x2, p.y2, this.strokeDashArray);\n      ctx.closePath();\n    },\n\n    /**\n     * This function is an helper for svg import. it returns the center of the object in the svg\n     * untransformed coordinates\n     * @private\n     * @return {Object} center point from element coordinates\n     */\n    _findCenterFromElement: function() {\n      return {\n        x: (this.x1 + this.x2) / 2,\n        y: (this.y1 + this.y2) / 2,\n      };\n    },\n\n    /**\n     * Returns object representation of an instance\n     * @methd toObject\n     * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output\n     * @return {Object} object representation of an instance\n     */\n    toObject: function(propertiesToInclude) {\n      return extend(this.callSuper('toObject', propertiesToInclude), this.calcLinePoints());\n    },\n\n    /*\n     * Calculate object dimensions from its properties\n     * @private\n     */\n    _getNonTransformedDimensions: function() {\n      var dim = this.callSuper('_getNonTransformedDimensions');\n      if (this.strokeLineCap === 'butt') {\n        if (this.width === 0) {\n          dim.y -= this.strokeWidth;\n        }\n        if (this.height === 0) {\n          dim.x -= this.strokeWidth;\n        }\n      }\n      return dim;\n    },\n\n    /**\n     * Recalculates line points given width and height\n     * @private\n     */\n    calcLinePoints: function() {\n      var xMult = this.x1 <= this.x2 ? -1 : 1,\n          yMult = this.y1 <= this.y2 ? -1 : 1,\n          x1 = (xMult * this.width * 0.5),\n          y1 = (yMult * this.height * 0.5),\n          x2 = (xMult * this.width * -0.5),\n          y2 = (yMult * this.height * -0.5);\n\n      return {\n        x1: x1,\n        x2: x2,\n        y1: y1,\n        y2: y2\n      };\n    },\n\n    /* _TO_SVG_START_ */\n    /**\n     * Returns svg representation of an instance\n     * @return {Array} an array of strings with the specific svg representation\n     * of the instance\n     */\n    _toSVG: function() {\n      var p = this.calcLinePoints();\n      return [\n        '<line ', 'COMMON_PARTS',\n        'x1=\"', p.x1,\n        '\" y1=\"', p.y1,\n        '\" x2=\"', p.x2,\n        '\" y2=\"', p.y2,\n        '\" />\\n'\n      ];\n    },\n    /* _TO_SVG_END_ */\n  });\n\n  /* _FROM_SVG_START_ */\n  /**\n   * List of attribute names to account for when parsing SVG element (used by {@link fabric.Line.fromElement})\n   * @static\n   * @memberOf fabric.Line\n   * @see http://www.w3.org/TR/SVG/shapes.html#LineElement\n   */\n  fabric.Line.ATTRIBUTE_NAMES = fabric.SHARED_ATTRIBUTES.concat('x1 y1 x2 y2'.split(' '));\n\n  /**\n   * Returns fabric.Line instance from an SVG element\n   * @static\n   * @memberOf fabric.Line\n   * @param {SVGElement} element Element to parse\n   * @param {Object} [options] Options object\n   * @param {Function} [callback] callback function invoked after parsing\n   */\n  fabric.Line.fromElement = function(element, callback, options) {\n    options = options || { };\n    var parsedAttributes = fabric.parseAttributes(element, fabric.Line.ATTRIBUTE_NAMES),\n        points = [\n          parsedAttributes.x1 || 0,\n          parsedAttributes.y1 || 0,\n          parsedAttributes.x2 || 0,\n          parsedAttributes.y2 || 0\n        ];\n    callback(new fabric.Line(points, extend(parsedAttributes, options)));\n  };\n  /* _FROM_SVG_END_ */\n\n  /**\n   * Returns fabric.Line instance from an object representation\n   * @static\n   * @memberOf fabric.Line\n   * @param {Object} object Object to create an instance from\n   * @param {function} [callback] invoked with new instance as first argument\n   */\n  fabric.Line.fromObject = function(object, callback) {\n    function _callback(instance) {\n      delete instance.points;\n      callback && callback(instance);\n    };\n    var options = clone(object, true);\n    options.points = [object.x1, object.y1, object.x2, object.y2];\n    fabric.Object._fromObject('Line', options, _callback, 'points');\n  };\n\n  /**\n   * Produces a function that calculates distance from canvas edge to Line origin.\n   */\n  function makeEdgeToOriginGetter(propertyNames, originValues) {\n    var origin = propertyNames.origin,\n        axis1 = propertyNames.axis1,\n        axis2 = propertyNames.axis2,\n        dimension = propertyNames.dimension,\n        nearest = originValues.nearest,\n        center = originValues.center,\n        farthest = originValues.farthest;\n\n    return function() {\n      switch (this.get(origin)) {\n        case nearest:\n          return Math.min(this.get(axis1), this.get(axis2));\n        case center:\n          return Math.min(this.get(axis1), this.get(axis2)) + (0.5 * this.get(dimension));\n        case farthest:\n          return Math.max(this.get(axis1), this.get(axis2));\n      }\n    };\n\n  }\n\n})(typeof exports !== 'undefined' ? exports : this);\n\n\n(function(global) {\n\n  'use strict';\n\n  var fabric = global.fabric || (global.fabric = { }),\n      pi = Math.PI;\n\n  if (fabric.Circle) {\n    fabric.warn('fabric.Circle is already defined.');\n    return;\n  }\n\n  /**\n   * Circle class\n   * @class fabric.Circle\n   * @extends fabric.Object\n   * @see {@link fabric.Circle#initialize} for constructor definition\n   */\n  fabric.Circle = fabric.util.createClass(fabric.Object, /** @lends fabric.Circle.prototype */ {\n\n    /**\n     * Type of an object\n     * @type String\n     * @default\n     */\n    type: 'circle',\n\n    /**\n     * Radius of this circle\n     * @type Number\n     * @default\n     */\n    radius: 0,\n\n    /**\n     * Start angle of the circle, moving clockwise\n     * deprectated type, this should be in degree, this was an oversight.\n     * probably will change to degrees in next major version\n     * @type Number\n     * @default 0\n     */\n    startAngle: 0,\n\n    /**\n     * End angle of the circle\n     * deprectated type, this should be in degree, this was an oversight.\n     * probably will change to degrees in next major version\n     * @type Number\n     * @default 2Pi\n     */\n    endAngle: pi * 2,\n\n    cacheProperties: fabric.Object.prototype.cacheProperties.concat('radius', 'startAngle', 'endAngle'),\n\n    /**\n     * @private\n     * @param {String} key\n     * @param {*} value\n     * @return {fabric.Circle} thisArg\n     */\n    _set: function(key, value) {\n      this.callSuper('_set', key, value);\n\n      if (key === 'radius') {\n        this.setRadius(value);\n      }\n\n      return this;\n    },\n\n    /**\n     * Returns object representation of an instance\n     * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output\n     * @return {Object} object representation of an instance\n     */\n    toObject: function(propertiesToInclude) {\n      return this.callSuper('toObject', ['radius', 'startAngle', 'endAngle'].concat(propertiesToInclude));\n    },\n\n    /* _TO_SVG_START_ */\n\n    /**\n     * Returns svg representation of an instance\n     * @return {Array} an array of strings with the specific svg representation\n     * of the instance\n     */\n    _toSVG: function() {\n      var svgString, x = 0, y = 0,\n          angle = (this.endAngle - this.startAngle) % ( 2 * pi);\n\n      if (angle === 0) {\n        svgString = [\n          '<circle ', 'COMMON_PARTS',\n          'cx=\"' + x + '\" cy=\"' + y + '\" ',\n          'r=\"', this.radius,\n          '\" />\\n'\n        ];\n      }\n      else {\n        var startX = fabric.util.cos(this.startAngle) * this.radius,\n            startY = fabric.util.sin(this.startAngle) * this.radius,\n            endX = fabric.util.cos(this.endAngle) * this.radius,\n            endY = fabric.util.sin(this.endAngle) * this.radius,\n            largeFlag = angle > pi ? '1' : '0';\n        svgString = [\n          '<path d=\"M ' + startX + ' ' + startY,\n          ' A ' + this.radius + ' ' + this.radius,\n          ' 0 ', +largeFlag + ' 1', ' ' + endX + ' ' + endY,\n          '\" ', 'COMMON_PARTS', ' />\\n'\n        ];\n      }\n      return svgString;\n    },\n    /* _TO_SVG_END_ */\n\n    /**\n     * @private\n     * @param {CanvasRenderingContext2D} ctx context to render on\n     */\n    _render: function(ctx) {\n      ctx.beginPath();\n      ctx.arc(\n        0,\n        0,\n        this.radius,\n        this.startAngle,\n        this.endAngle, false);\n      this._renderPaintInOrder(ctx);\n    },\n\n    /**\n     * Returns horizontal radius of an object (according to how an object is scaled)\n     * @return {Number}\n     */\n    getRadiusX: function() {\n      return this.get('radius') * this.get('scaleX');\n    },\n\n    /**\n     * Returns vertical radius of an object (according to how an object is scaled)\n     * @return {Number}\n     */\n    getRadiusY: function() {\n      return this.get('radius') * this.get('scaleY');\n    },\n\n    /**\n     * Sets radius of an object (and updates width accordingly)\n     * @return {fabric.Circle} thisArg\n     */\n    setRadius: function(value) {\n      this.radius = value;\n      return this.set('width', value * 2).set('height', value * 2);\n    },\n  });\n\n  /* _FROM_SVG_START_ */\n  /**\n   * List of attribute names to account for when parsing SVG element (used by {@link fabric.Circle.fromElement})\n   * @static\n   * @memberOf fabric.Circle\n   * @see: http://www.w3.org/TR/SVG/shapes.html#CircleElement\n   */\n  fabric.Circle.ATTRIBUTE_NAMES = fabric.SHARED_ATTRIBUTES.concat('cx cy r'.split(' '));\n\n  /**\n   * Returns {@link fabric.Circle} instance from an SVG element\n   * @static\n   * @memberOf fabric.Circle\n   * @param {SVGElement} element Element to parse\n   * @param {Function} [callback] Options callback invoked after parsing is finished\n   * @param {Object} [options] Options object\n   * @throws {Error} If value of `r` attribute is missing or invalid\n   */\n  fabric.Circle.fromElement = function(element, callback) {\n    var parsedAttributes = fabric.parseAttributes(element, fabric.Circle.ATTRIBUTE_NAMES);\n\n    if (!isValidRadius(parsedAttributes)) {\n      throw new Error('value of `r` attribute is required and can not be negative');\n    }\n\n    parsedAttributes.left = (parsedAttributes.left || 0) - parsedAttributes.radius;\n    parsedAttributes.top = (parsedAttributes.top || 0) - parsedAttributes.radius;\n    callback(new fabric.Circle(parsedAttributes));\n  };\n\n  /**\n   * @private\n   */\n  function isValidRadius(attributes) {\n    return (('radius' in attributes) && (attributes.radius >= 0));\n  }\n  /* _FROM_SVG_END_ */\n\n  /**\n   * Returns {@link fabric.Circle} instance from an object representation\n   * @static\n   * @memberOf fabric.Circle\n   * @param {Object} object Object to create an instance from\n   * @param {function} [callback] invoked with new instance as first argument\n   * @return {Object} Instance of fabric.Circle\n   */\n  fabric.Circle.fromObject = function(object, callback) {\n    return fabric.Object._fromObject('Circle', object, callback);\n  };\n\n})(typeof exports !== 'undefined' ? exports : this);\n\n\n(function(global) {\n\n  'use strict';\n\n  var fabric = global.fabric || (global.fabric = { });\n\n  if (fabric.Triangle) {\n    fabric.warn('fabric.Triangle is already defined');\n    return;\n  }\n\n  /**\n   * Triangle class\n   * @class fabric.Triangle\n   * @extends fabric.Object\n   * @return {fabric.Triangle} thisArg\n   * @see {@link fabric.Triangle#initialize} for constructor definition\n   */\n  fabric.Triangle = fabric.util.createClass(fabric.Object, /** @lends fabric.Triangle.prototype */ {\n\n    /**\n     * Type of an object\n     * @type String\n     * @default\n     */\n    type: 'triangle',\n\n    /**\n     * Width is set to 100 to compensate the old initialize code that was setting it to 100\n     * @type Number\n     * @default\n     */\n    width: 100,\n\n    /**\n     * Height is set to 100 to compensate the old initialize code that was setting it to 100\n     * @type Number\n     * @default\n     */\n    height: 100,\n\n    /**\n     * @private\n     * @param {CanvasRenderingContext2D} ctx Context to render on\n     */\n    _render: function(ctx) {\n      var widthBy2 = this.width / 2,\n          heightBy2 = this.height / 2;\n\n      ctx.beginPath();\n      ctx.moveTo(-widthBy2, heightBy2);\n      ctx.lineTo(0, -heightBy2);\n      ctx.lineTo(widthBy2, heightBy2);\n      ctx.closePath();\n\n      this._renderPaintInOrder(ctx);\n    },\n\n    /**\n     * @private\n     * @param {CanvasRenderingContext2D} ctx Context to render on\n     */\n    _renderDashedStroke: function(ctx) {\n      var widthBy2 = this.width / 2,\n          heightBy2 = this.height / 2;\n\n      ctx.beginPath();\n      fabric.util.drawDashedLine(ctx, -widthBy2, heightBy2, 0, -heightBy2, this.strokeDashArray);\n      fabric.util.drawDashedLine(ctx, 0, -heightBy2, widthBy2, heightBy2, this.strokeDashArray);\n      fabric.util.drawDashedLine(ctx, widthBy2, heightBy2, -widthBy2, heightBy2, this.strokeDashArray);\n      ctx.closePath();\n    },\n\n    /* _TO_SVG_START_ */\n    /**\n     * Returns svg representation of an instance\n     * @return {Array} an array of strings with the specific svg representation\n     * of the instance\n     */\n    _toSVG: function() {\n      var widthBy2 = this.width / 2,\n          heightBy2 = this.height / 2,\n          points = [\n            -widthBy2 + ' ' + heightBy2,\n            '0 ' + -heightBy2,\n            widthBy2 + ' ' + heightBy2\n          ].join(',');\n      return [\n        '<polygon ', 'COMMON_PARTS',\n        'points=\"', points,\n        '\" />'\n      ];\n    },\n    /* _TO_SVG_END_ */\n  });\n\n  /**\n   * Returns {@link fabric.Triangle} instance from an object representation\n   * @static\n   * @memberOf fabric.Triangle\n   * @param {Object} object Object to create an instance from\n   * @param {function} [callback] invoked with new instance as first argument\n   */\n  fabric.Triangle.fromObject = function(object, callback) {\n    return fabric.Object._fromObject('Triangle', object, callback);\n  };\n\n})(typeof exports !== 'undefined' ? exports : this);\n\n\n(function(global) {\n\n  'use strict';\n\n  var fabric = global.fabric || (global.fabric = { }),\n      piBy2   = Math.PI * 2;\n\n  if (fabric.Ellipse) {\n    fabric.warn('fabric.Ellipse is already defined.');\n    return;\n  }\n\n  /**\n   * Ellipse class\n   * @class fabric.Ellipse\n   * @extends fabric.Object\n   * @return {fabric.Ellipse} thisArg\n   * @see {@link fabric.Ellipse#initialize} for constructor definition\n   */\n  fabric.Ellipse = fabric.util.createClass(fabric.Object, /** @lends fabric.Ellipse.prototype */ {\n\n    /**\n     * Type of an object\n     * @type String\n     * @default\n     */\n    type: 'ellipse',\n\n    /**\n     * Horizontal radius\n     * @type Number\n     * @default\n     */\n    rx:   0,\n\n    /**\n     * Vertical radius\n     * @type Number\n     * @default\n     */\n    ry:   0,\n\n    cacheProperties: fabric.Object.prototype.cacheProperties.concat('rx', 'ry'),\n\n    /**\n     * Constructor\n     * @param {Object} [options] Options object\n     * @return {fabric.Ellipse} thisArg\n     */\n    initialize: function(options) {\n      this.callSuper('initialize', options);\n      this.set('rx', options && options.rx || 0);\n      this.set('ry', options && options.ry || 0);\n    },\n\n    /**\n     * @private\n     * @param {String} key\n     * @param {*} value\n     * @return {fabric.Ellipse} thisArg\n     */\n    _set: function(key, value) {\n      this.callSuper('_set', key, value);\n      switch (key) {\n\n        case 'rx':\n          this.rx = value;\n          this.set('width', value * 2);\n          break;\n\n        case 'ry':\n          this.ry = value;\n          this.set('height', value * 2);\n          break;\n\n      }\n      return this;\n    },\n\n    /**\n     * Returns horizontal radius of an object (according to how an object is scaled)\n     * @return {Number}\n     */\n    getRx: function() {\n      return this.get('rx') * this.get('scaleX');\n    },\n\n    /**\n     * Returns Vertical radius of an object (according to how an object is scaled)\n     * @return {Number}\n     */\n    getRy: function() {\n      return this.get('ry') * this.get('scaleY');\n    },\n\n    /**\n     * Returns object representation of an instance\n     * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output\n     * @return {Object} object representation of an instance\n     */\n    toObject: function(propertiesToInclude) {\n      return this.callSuper('toObject', ['rx', 'ry'].concat(propertiesToInclude));\n    },\n\n    /* _TO_SVG_START_ */\n    /**\n     * Returns svg representation of an instance\n     * @return {Array} an array of strings with the specific svg representation\n     * of the instance\n     */\n    _toSVG: function() {\n      return [\n        '<ellipse ', 'COMMON_PARTS',\n        'cx=\"0\" cy=\"0\" ',\n        'rx=\"', this.rx,\n        '\" ry=\"', this.ry,\n        '\" />\\n'\n      ];\n    },\n    /* _TO_SVG_END_ */\n\n    /**\n     * @private\n     * @param {CanvasRenderingContext2D} ctx context to render on\n     */\n    _render: function(ctx) {\n      ctx.beginPath();\n      ctx.save();\n      ctx.transform(1, 0, 0, this.ry / this.rx, 0, 0);\n      ctx.arc(\n        0,\n        0,\n        this.rx,\n        0,\n        piBy2,\n        false);\n      ctx.restore();\n      this._renderPaintInOrder(ctx);\n    },\n  });\n\n  /* _FROM_SVG_START_ */\n  /**\n   * List of attribute names to account for when parsing SVG element (used by {@link fabric.Ellipse.fromElement})\n   * @static\n   * @memberOf fabric.Ellipse\n   * @see http://www.w3.org/TR/SVG/shapes.html#EllipseElement\n   */\n  fabric.Ellipse.ATTRIBUTE_NAMES = fabric.SHARED_ATTRIBUTES.concat('cx cy rx ry'.split(' '));\n\n  /**\n   * Returns {@link fabric.Ellipse} instance from an SVG element\n   * @static\n   * @memberOf fabric.Ellipse\n   * @param {SVGElement} element Element to parse\n   * @param {Function} [callback] Options callback invoked after parsing is finished\n   * @return {fabric.Ellipse}\n   */\n  fabric.Ellipse.fromElement = function(element, callback) {\n\n    var parsedAttributes = fabric.parseAttributes(element, fabric.Ellipse.ATTRIBUTE_NAMES);\n\n    parsedAttributes.left = (parsedAttributes.left || 0) - parsedAttributes.rx;\n    parsedAttributes.top = (parsedAttributes.top || 0) - parsedAttributes.ry;\n    callback(new fabric.Ellipse(parsedAttributes));\n  };\n  /* _FROM_SVG_END_ */\n\n  /**\n   * Returns {@link fabric.Ellipse} instance from an object representation\n   * @static\n   * @memberOf fabric.Ellipse\n   * @param {Object} object Object to create an instance from\n   * @param {function} [callback] invoked with new instance as first argument\n   * @return {fabric.Ellipse}\n   */\n  fabric.Ellipse.fromObject = function(object, callback) {\n    return fabric.Object._fromObject('Ellipse', object, callback);\n  };\n\n})(typeof exports !== 'undefined' ? exports : this);\n\n\n(function(global) {\n\n  'use strict';\n\n  var fabric = global.fabric || (global.fabric = { }),\n      extend = fabric.util.object.extend;\n\n  if (fabric.Rect) {\n    fabric.warn('fabric.Rect is already defined');\n    return;\n  }\n\n  /**\n   * Rectangle class\n   * @class fabric.Rect\n   * @extends fabric.Object\n   * @return {fabric.Rect} thisArg\n   * @see {@link fabric.Rect#initialize} for constructor definition\n   */\n  fabric.Rect = fabric.util.createClass(fabric.Object, /** @lends fabric.Rect.prototype */ {\n\n    /**\n     * List of properties to consider when checking if state of an object is changed ({@link fabric.Object#hasStateChanged})\n     * as well as for history (undo/redo) purposes\n     * @type Array\n     */\n    stateProperties: fabric.Object.prototype.stateProperties.concat('rx', 'ry'),\n\n    /**\n     * Type of an object\n     * @type String\n     * @default\n     */\n    type: 'rect',\n\n    /**\n     * Horizontal border radius\n     * @type Number\n     * @default\n     */\n    rx:   0,\n\n    /**\n     * Vertical border radius\n     * @type Number\n     * @default\n     */\n    ry:   0,\n\n    cacheProperties: fabric.Object.prototype.cacheProperties.concat('rx', 'ry'),\n\n    /**\n     * Constructor\n     * @param {Object} [options] Options object\n     * @return {Object} thisArg\n     */\n    initialize: function(options) {\n      this.callSuper('initialize', options);\n      this._initRxRy();\n    },\n\n    /**\n     * Initializes rx/ry attributes\n     * @private\n     */\n    _initRxRy: function() {\n      if (this.rx && !this.ry) {\n        this.ry = this.rx;\n      }\n      else if (this.ry && !this.rx) {\n        this.rx = this.ry;\n      }\n    },\n\n    /**\n     * @private\n     * @param {CanvasRenderingContext2D} ctx Context to render on\n     */\n    _render: function(ctx) {\n\n      // 1x1 case (used in spray brush) optimization was removed because\n      // with caching and higher zoom level this makes more damage than help\n\n      var rx = this.rx ? Math.min(this.rx, this.width / 2) : 0,\n          ry = this.ry ? Math.min(this.ry, this.height / 2) : 0,\n          w = this.width,\n          h = this.height,\n          x = -this.width / 2,\n          y = -this.height / 2,\n          isRounded = rx !== 0 || ry !== 0,\n          /* \"magic number\" for bezier approximations of arcs (http://itc.ktu.lt/itc354/Riskus354.pdf) */\n          k = 1 - 0.5522847498;\n      ctx.beginPath();\n\n      ctx.moveTo(x + rx, y);\n\n      ctx.lineTo(x + w - rx, y);\n      isRounded && ctx.bezierCurveTo(x + w - k * rx, y, x + w, y + k * ry, x + w, y + ry);\n\n      ctx.lineTo(x + w, y + h - ry);\n      isRounded && ctx.bezierCurveTo(x + w, y + h - k * ry, x + w - k * rx, y + h, x + w - rx, y + h);\n\n      ctx.lineTo(x + rx, y + h);\n      isRounded && ctx.bezierCurveTo(x + k * rx, y + h, x, y + h - k * ry, x, y + h - ry);\n\n      ctx.lineTo(x, y + ry);\n      isRounded && ctx.bezierCurveTo(x, y + k * ry, x + k * rx, y, x + rx, y);\n\n      ctx.closePath();\n\n      this._renderPaintInOrder(ctx);\n    },\n\n    /**\n     * @private\n     * @param {CanvasRenderingContext2D} ctx Context to render on\n     */\n    _renderDashedStroke: function(ctx) {\n      var x = -this.width / 2,\n          y = -this.height / 2,\n          w = this.width,\n          h = this.height;\n\n      ctx.beginPath();\n      fabric.util.drawDashedLine(ctx, x, y, x + w, y, this.strokeDashArray);\n      fabric.util.drawDashedLine(ctx, x + w, y, x + w, y + h, this.strokeDashArray);\n      fabric.util.drawDashedLine(ctx, x + w, y + h, x, y + h, this.strokeDashArray);\n      fabric.util.drawDashedLine(ctx, x, y + h, x, y, this.strokeDashArray);\n      ctx.closePath();\n    },\n\n    /**\n     * Returns object representation of an instance\n     * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output\n     * @return {Object} object representation of an instance\n     */\n    toObject: function(propertiesToInclude) {\n      return this.callSuper('toObject', ['rx', 'ry'].concat(propertiesToInclude));\n    },\n\n    /* _TO_SVG_START_ */\n    /**\n     * Returns svg representation of an instance\n     * @return {Array} an array of strings with the specific svg representation\n     * of the instance\n     */\n    _toSVG: function() {\n      var x = -this.width / 2, y = -this.height / 2;\n      return [\n        '<rect ', 'COMMON_PARTS',\n        'x=\"', x, '\" y=\"', y,\n        '\" rx=\"', this.rx, '\" ry=\"', this.ry,\n        '\" width=\"', this.width, '\" height=\"', this.height,\n        '\" />\\n'\n      ];\n    },\n    /* _TO_SVG_END_ */\n  });\n\n  /* _FROM_SVG_START_ */\n  /**\n   * List of attribute names to account for when parsing SVG element (used by `fabric.Rect.fromElement`)\n   * @static\n   * @memberOf fabric.Rect\n   * @see: http://www.w3.org/TR/SVG/shapes.html#RectElement\n   */\n  fabric.Rect.ATTRIBUTE_NAMES = fabric.SHARED_ATTRIBUTES.concat('x y rx ry width height'.split(' '));\n\n  /**\n   * Returns {@link fabric.Rect} instance from an SVG element\n   * @static\n   * @memberOf fabric.Rect\n   * @param {SVGElement} element Element to parse\n   * @param {Function} callback callback function invoked after parsing\n   * @param {Object} [options] Options object\n   */\n  fabric.Rect.fromElement = function(element, callback, options) {\n    if (!element) {\n      return callback(null);\n    }\n    options = options || { };\n\n    var parsedAttributes = fabric.parseAttributes(element, fabric.Rect.ATTRIBUTE_NAMES);\n\n    parsedAttributes.left = parsedAttributes.left || 0;\n    parsedAttributes.top  = parsedAttributes.top  || 0;\n    parsedAttributes.height  = parsedAttributes.height || 0;\n    parsedAttributes.width  = parsedAttributes.width || 0;\n    var rect = new fabric.Rect(extend((options ? fabric.util.object.clone(options) : { }), parsedAttributes));\n    rect.visible = rect.visible && rect.width > 0 && rect.height > 0;\n    callback(rect);\n  };\n  /* _FROM_SVG_END_ */\n\n  /**\n   * Returns {@link fabric.Rect} instance from an object representation\n   * @static\n   * @memberOf fabric.Rect\n   * @param {Object} object Object to create an instance from\n   * @param {Function} [callback] Callback to invoke when an fabric.Rect instance is created\n   */\n  fabric.Rect.fromObject = function(object, callback) {\n    return fabric.Object._fromObject('Rect', object, callback);\n  };\n\n})(typeof exports !== 'undefined' ? exports : this);\n\n\n(function(global) {\n\n  'use strict';\n\n  var fabric = global.fabric || (global.fabric = { }),\n      extend = fabric.util.object.extend,\n      min = fabric.util.array.min,\n      max = fabric.util.array.max,\n      toFixed = fabric.util.toFixed;\n\n  if (fabric.Polyline) {\n    fabric.warn('fabric.Polyline is already defined');\n    return;\n  }\n\n  /**\n   * Polyline class\n   * @class fabric.Polyline\n   * @extends fabric.Object\n   * @see {@link fabric.Polyline#initialize} for constructor definition\n   */\n  fabric.Polyline = fabric.util.createClass(fabric.Object, /** @lends fabric.Polyline.prototype */ {\n\n    /**\n     * Type of an object\n     * @type String\n     * @default\n     */\n    type: 'polyline',\n\n    /**\n     * Points array\n     * @type Array\n     * @default\n     */\n    points: null,\n\n    cacheProperties: fabric.Object.prototype.cacheProperties.concat('points'),\n\n    /**\n     * Constructor\n     * @param {Array} points Array of points (where each point is an object with x and y)\n     * @param {Object} [options] Options object\n     * @return {fabric.Polyline} thisArg\n     * @example\n     * var poly = new fabric.Polyline([\n     *     { x: 10, y: 10 },\n     *     { x: 50, y: 30 },\n     *     { x: 40, y: 70 },\n     *     { x: 60, y: 50 },\n     *     { x: 100, y: 150 },\n     *     { x: 40, y: 100 }\n     *   ], {\n     *   stroke: 'red',\n     *   left: 100,\n     *   top: 100\n     * });\n     */\n    initialize: function(points, options) {\n      options = options || {};\n      this.points = points || [];\n      this.callSuper('initialize', options);\n      this._setPositionDimensions(options);\n    },\n\n    _setPositionDimensions: function(options) {\n      var calcDim = this._calcDimensions(options), correctLeftTop;\n      this.width = calcDim.width;\n      this.height = calcDim.height;\n      if (!options.fromSVG) {\n        correctLeftTop = this.translateToGivenOrigin(\n          { x: calcDim.left - this.strokeWidth / 2, y: calcDim.top - this.strokeWidth / 2 },\n          'left',\n          'top',\n          this.originX,\n          this.originY\n        );\n      }\n      if (typeof options.left === 'undefined') {\n        this.left = options.fromSVG ? calcDim.left : correctLeftTop.x;\n      }\n      if (typeof options.top === 'undefined') {\n        this.top = options.fromSVG ? calcDim.top : correctLeftTop.y;\n      }\n      this.pathOffset = {\n        x: calcDim.left + this.width / 2,\n        y: calcDim.top + this.height / 2\n      };\n    },\n\n    /**\n     * Calculate the polygon min and max point from points array,\n     * returning an object with left, top, widht, height to measure the\n     * polygon size\n     * @return {Object} object.left X coordinate of the polygon leftmost point\n     * @return {Object} object.top Y coordinate of the polygon topmost point\n     * @return {Object} object.width distance between X coordinates of the polygon leftmost and rightmost point\n     * @return {Object} object.height distance between Y coordinates of the polygon topmost and bottommost point\n     * @private\n     */\n    _calcDimensions: function() {\n\n      var points = this.points,\n          minX = min(points, 'x') || 0,\n          minY = min(points, 'y') || 0,\n          maxX = max(points, 'x') || 0,\n          maxY = max(points, 'y') || 0,\n          width = (maxX - minX),\n          height = (maxY - minY);\n\n      return {\n        left: minX,\n        top: minY,\n        width: width,\n        height: height\n      };\n    },\n\n    /**\n     * Returns object representation of an instance\n     * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output\n     * @return {Object} Object representation of an instance\n     */\n    toObject: function(propertiesToInclude) {\n      return extend(this.callSuper('toObject', propertiesToInclude), {\n        points: this.points.concat()\n      });\n    },\n\n    /* _TO_SVG_START_ */\n    /**\n     * Returns svg representation of an instance\n     * @return {Array} an array of strings with the specific svg representation\n     * of the instance\n     */\n    _toSVG: function() {\n      var points = [], diffX = this.pathOffset.x, diffY = this.pathOffset.y,\n          NUM_FRACTION_DIGITS = fabric.Object.NUM_FRACTION_DIGITS;\n\n      for (var i = 0, len = this.points.length; i < len; i++) {\n        points.push(\n          toFixed(this.points[i].x - diffX, NUM_FRACTION_DIGITS), ',',\n          toFixed(this.points[i].y - diffY, NUM_FRACTION_DIGITS), ' '\n        );\n      }\n      return [\n        '<' + this.type + ' ', 'COMMON_PARTS',\n        'points=\"', points.join(''),\n        '\" />\\n'\n      ];\n    },\n    /* _TO_SVG_END_ */\n\n\n    /**\n     * @private\n     * @param {CanvasRenderingContext2D} ctx Context to render on\n     */\n    commonRender: function(ctx) {\n      var point, len = this.points.length,\n          x = this.pathOffset.x,\n          y = this.pathOffset.y;\n\n      if (!len || isNaN(this.points[len - 1].y)) {\n        // do not draw if no points or odd points\n        // NaN comes from parseFloat of a empty string in parser\n        return false;\n      }\n      ctx.beginPath();\n      ctx.moveTo(this.points[0].x - x, this.points[0].y - y);\n      for (var i = 0; i < len; i++) {\n        point = this.points[i];\n        ctx.lineTo(point.x - x, point.y - y);\n      }\n      return true;\n    },\n\n    /**\n     * @private\n     * @param {CanvasRenderingContext2D} ctx Context to render on\n     */\n    _render: function(ctx) {\n      if (!this.commonRender(ctx)) {\n        return;\n      }\n      this._renderPaintInOrder(ctx);\n    },\n\n    /**\n     * @private\n     * @param {CanvasRenderingContext2D} ctx Context to render on\n     */\n    _renderDashedStroke: function(ctx) {\n      var p1, p2;\n\n      ctx.beginPath();\n      for (var i = 0, len = this.points.length; i < len; i++) {\n        p1 = this.points[i];\n        p2 = this.points[i + 1] || p1;\n        fabric.util.drawDashedLine(ctx, p1.x, p1.y, p2.x, p2.y, this.strokeDashArray);\n      }\n    },\n\n    /**\n     * Returns complexity of an instance\n     * @return {Number} complexity of this instance\n     */\n    complexity: function() {\n      return this.get('points').length;\n    }\n  });\n\n  /* _FROM_SVG_START_ */\n  /**\n   * List of attribute names to account for when parsing SVG element (used by {@link fabric.Polyline.fromElement})\n   * @static\n   * @memberOf fabric.Polyline\n   * @see: http://www.w3.org/TR/SVG/shapes.html#PolylineElement\n   */\n  fabric.Polyline.ATTRIBUTE_NAMES = fabric.SHARED_ATTRIBUTES.concat();\n\n  /**\n   * Returns fabric.Polyline instance from an SVG element\n   * @static\n   * @memberOf fabric.Polyline\n   * @param {SVGElement} element Element to parser\n   * @param {Function} callback callback function invoked after parsing\n   * @param {Object} [options] Options object\n   */\n  fabric.Polyline.fromElementGenerator = function(_class) {\n    return function(element, callback, options) {\n      if (!element) {\n        return callback(null);\n      }\n      options || (options = { });\n\n      var points = fabric.parsePointsAttribute(element.getAttribute('points')),\n          parsedAttributes = fabric.parseAttributes(element, fabric[_class].ATTRIBUTE_NAMES);\n      parsedAttributes.fromSVG = true;\n      callback(new fabric[_class](points, extend(parsedAttributes, options)));\n    };\n  };\n\n  fabric.Polyline.fromElement = fabric.Polyline.fromElementGenerator('Polyline');\n\n  /* _FROM_SVG_END_ */\n\n  /**\n   * Returns fabric.Polyline instance from an object representation\n   * @static\n   * @memberOf fabric.Polyline\n   * @param {Object} object Object to create an instance from\n   * @param {Function} [callback] Callback to invoke when an fabric.Path instance is created\n   */\n  fabric.Polyline.fromObject = function(object, callback) {\n    return fabric.Object._fromObject('Polyline', object, callback, 'points');\n  };\n\n})(typeof exports !== 'undefined' ? exports : this);\n\n\n(function(global) {\n\n  'use strict';\n\n  var fabric = global.fabric || (global.fabric = { });\n\n  if (fabric.Polygon) {\n    fabric.warn('fabric.Polygon is already defined');\n    return;\n  }\n\n  /**\n   * Polygon class\n   * @class fabric.Polygon\n   * @extends fabric.Polyline\n   * @see {@link fabric.Polygon#initialize} for constructor definition\n   */\n  fabric.Polygon = fabric.util.createClass(fabric.Polyline, /** @lends fabric.Polygon.prototype */ {\n\n    /**\n     * Type of an object\n     * @type String\n     * @default\n     */\n    type: 'polygon',\n\n    /**\n     * @private\n     * @param {CanvasRenderingContext2D} ctx Context to render on\n     */\n    _render: function(ctx) {\n      if (!this.commonRender(ctx)) {\n        return;\n      }\n      ctx.closePath();\n      this._renderPaintInOrder(ctx);\n    },\n\n    /**\n     * @private\n     * @param {CanvasRenderingContext2D} ctx Context to render on\n     */\n    _renderDashedStroke: function(ctx) {\n      this.callSuper('_renderDashedStroke', ctx);\n      ctx.closePath();\n    },\n  });\n\n  /* _FROM_SVG_START_ */\n  /**\n   * List of attribute names to account for when parsing SVG element (used by `fabric.Polygon.fromElement`)\n   * @static\n   * @memberOf fabric.Polygon\n   * @see: http://www.w3.org/TR/SVG/shapes.html#PolygonElement\n   */\n  fabric.Polygon.ATTRIBUTE_NAMES = fabric.SHARED_ATTRIBUTES.concat();\n\n  /**\n   * Returns {@link fabric.Polygon} instance from an SVG element\n   * @static\n   * @memberOf fabric.Polygon\n   * @param {SVGElement} element Element to parse\n   * @param {Function} callback callback function invoked after parsing\n   * @param {Object} [options] Options object\n   */\n  fabric.Polygon.fromElement = fabric.Polyline.fromElementGenerator('Polygon');\n  /* _FROM_SVG_END_ */\n\n  /**\n   * Returns fabric.Polygon instance from an object representation\n   * @static\n   * @memberOf fabric.Polygon\n   * @param {Object} object Object to create an instance from\n   * @param {Function} [callback] Callback to invoke when an fabric.Path instance is created\n   */\n  fabric.Polygon.fromObject = function(object, callback) {\n    return fabric.Object._fromObject('Polygon', object, callback, 'points');\n  };\n\n})(typeof exports !== 'undefined' ? exports : this);\n\n\n(function(global) {\n\n  'use strict';\n\n  var fabric = global.fabric || (global.fabric = { }),\n      min = fabric.util.array.min,\n      max = fabric.util.array.max,\n      extend = fabric.util.object.extend,\n      _toString = Object.prototype.toString,\n      drawArc = fabric.util.drawArc,\n      toFixed = fabric.util.toFixed,\n      commandLengths = {\n        m: 2,\n        l: 2,\n        h: 1,\n        v: 1,\n        c: 6,\n        s: 4,\n        q: 4,\n        t: 2,\n        a: 7\n      },\n      repeatedCommands = {\n        m: 'l',\n        M: 'L'\n      };\n\n  if (fabric.Path) {\n    fabric.warn('fabric.Path is already defined');\n    return;\n  }\n\n  /**\n   * Path class\n   * @class fabric.Path\n   * @extends fabric.Object\n   * @tutorial {@link http://fabricjs.com/fabric-intro-part-1#path_and_pathgroup}\n   * @see {@link fabric.Path#initialize} for constructor definition\n   */\n  fabric.Path = fabric.util.createClass(fabric.Object, /** @lends fabric.Path.prototype */ {\n\n    /**\n     * Type of an object\n     * @type String\n     * @default\n     */\n    type: 'path',\n\n    /**\n     * Array of path points\n     * @type Array\n     * @default\n     */\n    path: null,\n\n    cacheProperties: fabric.Object.prototype.cacheProperties.concat('path', 'fillRule'),\n\n    stateProperties: fabric.Object.prototype.stateProperties.concat('path'),\n\n    /**\n     * Constructor\n     * @param {Array|String} path Path data (sequence of coordinates and corresponding \"command\" tokens)\n     * @param {Object} [options] Options object\n     * @return {fabric.Path} thisArg\n     */\n    initialize: function(path, options) {\n      options = options || { };\n      this.callSuper('initialize', options);\n\n      if (!path) {\n        path = [];\n      }\n\n      var fromArray = _toString.call(path) === '[object Array]';\n\n      this.path = fromArray\n        ? path\n        // one of commands (m,M,l,L,q,Q,c,C,etc.) followed by non-command characters (i.e. command values)\n        : path.match && path.match(/[mzlhvcsqta][^mzlhvcsqta]*/gi);\n\n      if (!this.path) {\n        return;\n      }\n\n      if (!fromArray) {\n        this.path = this._parsePath();\n      }\n\n      fabric.Polyline.prototype._setPositionDimensions.call(this, options);\n    },\n\n    /**\n     * @private\n     * @param {CanvasRenderingContext2D} ctx context to render path on\n     */\n    _renderPathCommands: function(ctx) {\n      var current, // current instruction\n          previous = null,\n          subpathStartX = 0,\n          subpathStartY = 0,\n          x = 0, // current x\n          y = 0, // current y\n          controlX = 0, // current control point x\n          controlY = 0, // current control point y\n          tempX,\n          tempY,\n          l = -this.pathOffset.x,\n          t = -this.pathOffset.y;\n\n      ctx.beginPath();\n\n      for (var i = 0, len = this.path.length; i < len; ++i) {\n\n        current = this.path[i];\n\n        switch (current[0]) { // first letter\n\n          case 'l': // lineto, relative\n            x += current[1];\n            y += current[2];\n            ctx.lineTo(x + l, y + t);\n            break;\n\n          case 'L': // lineto, absolute\n            x = current[1];\n            y = current[2];\n            ctx.lineTo(x + l, y + t);\n            break;\n\n          case 'h': // horizontal lineto, relative\n            x += current[1];\n            ctx.lineTo(x + l, y + t);\n            break;\n\n          case 'H': // horizontal lineto, absolute\n            x = current[1];\n            ctx.lineTo(x + l, y + t);\n            break;\n\n          case 'v': // vertical lineto, relative\n            y += current[1];\n            ctx.lineTo(x + l, y + t);\n            break;\n\n          case 'V': // verical lineto, absolute\n            y = current[1];\n            ctx.lineTo(x + l, y + t);\n            break;\n\n          case 'm': // moveTo, relative\n            x += current[1];\n            y += current[2];\n            subpathStartX = x;\n            subpathStartY = y;\n            ctx.moveTo(x + l, y + t);\n            break;\n\n          case 'M': // moveTo, absolute\n            x = current[1];\n            y = current[2];\n            subpathStartX = x;\n            subpathStartY = y;\n            ctx.moveTo(x + l, y + t);\n            break;\n\n          case 'c': // bezierCurveTo, relative\n            tempX = x + current[5];\n            tempY = y + current[6];\n            controlX = x + current[3];\n            controlY = y + current[4];\n            ctx.bezierCurveTo(\n              x + current[1] + l, // x1\n              y + current[2] + t, // y1\n              controlX + l, // x2\n              controlY + t, // y2\n              tempX + l,\n              tempY + t\n            );\n            x = tempX;\n            y = tempY;\n            break;\n\n          case 'C': // bezierCurveTo, absolute\n            x = current[5];\n            y = current[6];\n            controlX = current[3];\n            controlY = current[4];\n            ctx.bezierCurveTo(\n              current[1] + l,\n              current[2] + t,\n              controlX + l,\n              controlY + t,\n              x + l,\n              y + t\n            );\n            break;\n\n          case 's': // shorthand cubic bezierCurveTo, relative\n\n            // transform to absolute x,y\n            tempX = x + current[3];\n            tempY = y + current[4];\n\n            if (previous[0].match(/[CcSs]/) === null) {\n              // If there is no previous command or if the previous command was not a C, c, S, or s,\n              // the control point is coincident with the current point\n              controlX = x;\n              controlY = y;\n            }\n            else {\n              // calculate reflection of previous control points\n              controlX = 2 * x - controlX;\n              controlY = 2 * y - controlY;\n            }\n\n            ctx.bezierCurveTo(\n              controlX + l,\n              controlY + t,\n              x + current[1] + l,\n              y + current[2] + t,\n              tempX + l,\n              tempY + t\n            );\n            // set control point to 2nd one of this command\n            // \"... the first control point is assumed to be\n            // the reflection of the second control point on\n            // the previous command relative to the current point.\"\n            controlX = x + current[1];\n            controlY = y + current[2];\n\n            x = tempX;\n            y = tempY;\n            break;\n\n          case 'S': // shorthand cubic bezierCurveTo, absolute\n            tempX = current[3];\n            tempY = current[4];\n            if (previous[0].match(/[CcSs]/) === null) {\n              // If there is no previous command or if the previous command was not a C, c, S, or s,\n              // the control point is coincident with the current point\n              controlX = x;\n              controlY = y;\n            }\n            else {\n              // calculate reflection of previous control points\n              controlX = 2 * x - controlX;\n              controlY = 2 * y - controlY;\n            }\n            ctx.bezierCurveTo(\n              controlX + l,\n              controlY + t,\n              current[1] + l,\n              current[2] + t,\n              tempX + l,\n              tempY + t\n            );\n            x = tempX;\n            y = tempY;\n\n            // set control point to 2nd one of this command\n            // \"... the first control point is assumed to be\n            // the reflection of the second control point on\n            // the previous command relative to the current point.\"\n            controlX = current[1];\n            controlY = current[2];\n\n            break;\n\n          case 'q': // quadraticCurveTo, relative\n            // transform to absolute x,y\n            tempX = x + current[3];\n            tempY = y + current[4];\n\n            controlX = x + current[1];\n            controlY = y + current[2];\n\n            ctx.quadraticCurveTo(\n              controlX + l,\n              controlY + t,\n              tempX + l,\n              tempY + t\n            );\n            x = tempX;\n            y = tempY;\n            break;\n\n          case 'Q': // quadraticCurveTo, absolute\n            tempX = current[3];\n            tempY = current[4];\n\n            ctx.quadraticCurveTo(\n              current[1] + l,\n              current[2] + t,\n              tempX + l,\n              tempY + t\n            );\n            x = tempX;\n            y = tempY;\n            controlX = current[1];\n            controlY = current[2];\n            break;\n\n          case 't': // shorthand quadraticCurveTo, relative\n\n            // transform to absolute x,y\n            tempX = x + current[1];\n            tempY = y + current[2];\n\n            if (previous[0].match(/[QqTt]/) === null) {\n              // If there is no previous command or if the previous command was not a Q, q, T or t,\n              // assume the control point is coincident with the current point\n              controlX = x;\n              controlY = y;\n            }\n            else {\n              // calculate reflection of previous control point\n              controlX = 2 * x - controlX;\n              controlY = 2 * y - controlY;\n            }\n\n            ctx.quadraticCurveTo(\n              controlX + l,\n              controlY + t,\n              tempX + l,\n              tempY + t\n            );\n            x = tempX;\n            y = tempY;\n\n            break;\n\n          case 'T':\n            tempX = current[1];\n            tempY = current[2];\n\n            if (previous[0].match(/[QqTt]/) === null) {\n              // If there is no previous command or if the previous command was not a Q, q, T or t,\n              // assume the control point is coincident with the current point\n              controlX = x;\n              controlY = y;\n            }\n            else {\n              // calculate reflection of previous control point\n              controlX = 2 * x - controlX;\n              controlY = 2 * y - controlY;\n            }\n            ctx.quadraticCurveTo(\n              controlX + l,\n              controlY + t,\n              tempX + l,\n              tempY + t\n            );\n            x = tempX;\n            y = tempY;\n            break;\n\n          case 'a':\n            // TODO: optimize this\n            drawArc(ctx, x + l, y + t, [\n              current[1],\n              current[2],\n              current[3],\n              current[4],\n              current[5],\n              current[6] + x + l,\n              current[7] + y + t\n            ]);\n            x += current[6];\n            y += current[7];\n            break;\n\n          case 'A':\n            // TODO: optimize this\n            drawArc(ctx, x + l, y + t, [\n              current[1],\n              current[2],\n              current[3],\n              current[4],\n              current[5],\n              current[6] + l,\n              current[7] + t\n            ]);\n            x = current[6];\n            y = current[7];\n            break;\n\n          case 'z':\n          case 'Z':\n            x = subpathStartX;\n            y = subpathStartY;\n            ctx.closePath();\n            break;\n        }\n        previous = current;\n      }\n    },\n\n    /**\n     * @private\n     * @param {CanvasRenderingContext2D} ctx context to render path on\n     */\n    _render: function(ctx) {\n      this._renderPathCommands(ctx);\n      this._renderPaintInOrder(ctx);\n    },\n\n    /**\n     * Returns string representation of an instance\n     * @return {String} string representation of an instance\n     */\n    toString: function() {\n      return '#<fabric.Path (' + this.complexity() +\n        '): { \"top\": ' + this.top + ', \"left\": ' + this.left + ' }>';\n    },\n\n    /**\n     * Returns object representation of an instance\n     * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output\n     * @return {Object} object representation of an instance\n     */\n    toObject: function(propertiesToInclude) {\n      return extend(this.callSuper('toObject', propertiesToInclude), {\n        path: this.path.map(function(item) { return item.slice(); }),\n      });\n    },\n\n    /**\n     * Returns dataless object representation of an instance\n     * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output\n     * @return {Object} object representation of an instance\n     */\n    toDatalessObject: function(propertiesToInclude) {\n      var o = this.toObject(['sourcePath'].concat(propertiesToInclude));\n      if (o.sourcePath) {\n        delete o.path;\n      }\n      return o;\n    },\n\n    /* _TO_SVG_START_ */\n    /**\n     * Returns svg representation of an instance\n     * @return {Array} an array of strings with the specific svg representation\n     * of the instance\n     */\n    _toSVG: function() {\n      var path = this.path.map(function(path) {\n        return path.join(' ');\n      }).join(' ');\n      return [\n        '<path ', 'COMMON_PARTS',\n        'd=\"', path,\n        '\" stroke-linecap=\"round\" ',\n        '/>\\n'\n      ];\n    },\n\n    _getOffsetTransform: function() {\n      var digits = fabric.Object.NUM_FRACTION_DIGITS;\n      return ' translate(' + toFixed(-this.pathOffset.x, digits) + ', ' +\n          toFixed(-this.pathOffset.y, digits) + ')';\n    },\n\n    /**\n     * Returns svg clipPath representation of an instance\n     * @param {Function} [reviver] Method for further parsing of svg representation.\n     * @return {String} svg representation of an instance\n     */\n    toClipPathSVG: function(reviver) {\n      var additionalTransform = this._getOffsetTransform();\n      return '\\t' + this._createBaseClipPathSVGMarkup(\n        this._toSVG(), { reviver: reviver, additionalTransform: additionalTransform }\n      );\n    },\n\n    /**\n     * Returns svg representation of an instance\n     * @param {Function} [reviver] Method for further parsing of svg representation.\n     * @return {String} svg representation of an instance\n     */\n    toSVG: function(reviver) {\n      var additionalTransform = this._getOffsetTransform();\n      return this._createBaseSVGMarkup(this._toSVG(), { reviver: reviver, additionalTransform: additionalTransform  });\n    },\n    /* _TO_SVG_END_ */\n\n    /**\n     * Returns number representation of an instance complexity\n     * @return {Number} complexity of this instance\n     */\n    complexity: function() {\n      return this.path.length;\n    },\n\n    /**\n     * @private\n     */\n    _parsePath: function() {\n      var result = [],\n          coords = [],\n          currentPath,\n          parsed,\n          re = /([-+]?((\\d+\\.\\d+)|((\\d+)|(\\.\\d+)))(?:e[-+]?\\d+)?)/ig,\n          match,\n          coordsStr;\n\n      for (var i = 0, coordsParsed, len = this.path.length; i < len; i++) {\n        currentPath = this.path[i];\n\n        coordsStr = currentPath.slice(1).trim();\n        coords.length = 0;\n\n        while ((match = re.exec(coordsStr))) {\n          coords.push(match[0]);\n        }\n\n        coordsParsed = [currentPath.charAt(0)];\n\n        for (var j = 0, jlen = coords.length; j < jlen; j++) {\n          parsed = parseFloat(coords[j]);\n          if (!isNaN(parsed)) {\n            coordsParsed.push(parsed);\n          }\n        }\n\n        var command = coordsParsed[0],\n            commandLength = commandLengths[command.toLowerCase()],\n            repeatedCommand = repeatedCommands[command] || command;\n\n        if (coordsParsed.length - 1 > commandLength) {\n          for (var k = 1, klen = coordsParsed.length; k < klen; k += commandLength) {\n            result.push([command].concat(coordsParsed.slice(k, k + commandLength)));\n            command = repeatedCommand;\n          }\n        }\n        else {\n          result.push(coordsParsed);\n        }\n      }\n\n      return result;\n    },\n\n    /**\n     * @private\n     */\n    _calcDimensions: function() {\n\n      var aX = [],\n          aY = [],\n          current, // current instruction\n          previous = null,\n          subpathStartX = 0,\n          subpathStartY = 0,\n          x = 0, // current x\n          y = 0, // current y\n          controlX = 0, // current control point x\n          controlY = 0, // current control point y\n          tempX,\n          tempY,\n          bounds;\n\n      for (var i = 0, len = this.path.length; i < len; ++i) {\n\n        current = this.path[i];\n\n        switch (current[0]) { // first letter\n\n          case 'l': // lineto, relative\n            x += current[1];\n            y += current[2];\n            bounds = [];\n            break;\n\n          case 'L': // lineto, absolute\n            x = current[1];\n            y = current[2];\n            bounds = [];\n            break;\n\n          case 'h': // horizontal lineto, relative\n            x += current[1];\n            bounds = [];\n            break;\n\n          case 'H': // horizontal lineto, absolute\n            x = current[1];\n            bounds = [];\n            break;\n\n          case 'v': // vertical lineto, relative\n            y += current[1];\n            bounds = [];\n            break;\n\n          case 'V': // verical lineto, absolute\n            y = current[1];\n            bounds = [];\n            break;\n\n          case 'm': // moveTo, relative\n            x += current[1];\n            y += current[2];\n            subpathStartX = x;\n            subpathStartY = y;\n            bounds = [];\n            break;\n\n          case 'M': // moveTo, absolute\n            x = current[1];\n            y = current[2];\n            subpathStartX = x;\n            subpathStartY = y;\n            bounds = [];\n            break;\n\n          case 'c': // bezierCurveTo, relative\n            tempX = x + current[5];\n            tempY = y + current[6];\n            controlX = x + current[3];\n            controlY = y + current[4];\n            bounds = fabric.util.getBoundsOfCurve(x, y,\n              x + current[1], // x1\n              y + current[2], // y1\n              controlX, // x2\n              controlY, // y2\n              tempX,\n              tempY\n            );\n            x = tempX;\n            y = tempY;\n            break;\n\n          case 'C': // bezierCurveTo, absolute\n            controlX = current[3];\n            controlY = current[4];\n            bounds = fabric.util.getBoundsOfCurve(x, y,\n              current[1],\n              current[2],\n              controlX,\n              controlY,\n              current[5],\n              current[6]\n            );\n            x = current[5];\n            y = current[6];\n            break;\n\n          case 's': // shorthand cubic bezierCurveTo, relative\n\n            // transform to absolute x,y\n            tempX = x + current[3];\n            tempY = y + current[4];\n\n            if (previous[0].match(/[CcSs]/) === null) {\n              // If there is no previous command or if the previous command was not a C, c, S, or s,\n              // the control point is coincident with the current point\n              controlX = x;\n              controlY = y;\n            }\n            else {\n              // calculate reflection of previous control points\n              controlX = 2 * x - controlX;\n              controlY = 2 * y - controlY;\n            }\n\n            bounds = fabric.util.getBoundsOfCurve(x, y,\n              controlX,\n              controlY,\n              x + current[1],\n              y + current[2],\n              tempX,\n              tempY\n            );\n            // set control point to 2nd one of this command\n            // \"... the first control point is assumed to be\n            // the reflection of the second control point on\n            // the previous command relative to the current point.\"\n            controlX = x + current[1];\n            controlY = y + current[2];\n            x = tempX;\n            y = tempY;\n            break;\n\n          case 'S': // shorthand cubic bezierCurveTo, absolute\n            tempX = current[3];\n            tempY = current[4];\n            if (previous[0].match(/[CcSs]/) === null) {\n              // If there is no previous command or if the previous command was not a C, c, S, or s,\n              // the control point is coincident with the current point\n              controlX = x;\n              controlY = y;\n            }\n            else {\n              // calculate reflection of previous control points\n              controlX = 2 * x - controlX;\n              controlY = 2 * y - controlY;\n            }\n            bounds = fabric.util.getBoundsOfCurve(x, y,\n              controlX,\n              controlY,\n              current[1],\n              current[2],\n              tempX,\n              tempY\n            );\n            x = tempX;\n            y = tempY;\n            // set control point to 2nd one of this command\n            // \"... the first control point is assumed to be\n            // the reflection of the second control point on\n            // the previous command relative to the current point.\"\n            controlX = current[1];\n            controlY = current[2];\n            break;\n\n          case 'q': // quadraticCurveTo, relative\n            // transform to absolute x,y\n            tempX = x + current[3];\n            tempY = y + current[4];\n            controlX = x + current[1];\n            controlY = y + current[2];\n            bounds = fabric.util.getBoundsOfCurve(x, y,\n              controlX,\n              controlY,\n              controlX,\n              controlY,\n              tempX,\n              tempY\n            );\n            x = tempX;\n            y = tempY;\n            break;\n\n          case 'Q': // quadraticCurveTo, absolute\n            controlX = current[1];\n            controlY = current[2];\n            bounds = fabric.util.getBoundsOfCurve(x, y,\n              controlX,\n              controlY,\n              controlX,\n              controlY,\n              current[3],\n              current[4]\n            );\n            x = current[3];\n            y = current[4];\n            break;\n\n          case 't': // shorthand quadraticCurveTo, relative\n            // transform to absolute x,y\n            tempX = x + current[1];\n            tempY = y + current[2];\n            if (previous[0].match(/[QqTt]/) === null) {\n              // If there is no previous command or if the previous command was not a Q, q, T or t,\n              // assume the control point is coincident with the current point\n              controlX = x;\n              controlY = y;\n            }\n            else {\n              // calculate reflection of previous control point\n              controlX = 2 * x - controlX;\n              controlY = 2 * y - controlY;\n            }\n\n            bounds = fabric.util.getBoundsOfCurve(x, y,\n              controlX,\n              controlY,\n              controlX,\n              controlY,\n              tempX,\n              tempY\n            );\n            x = tempX;\n            y = tempY;\n\n            break;\n\n          case 'T':\n            tempX = current[1];\n            tempY = current[2];\n\n            if (previous[0].match(/[QqTt]/) === null) {\n              // If there is no previous command or if the previous command was not a Q, q, T or t,\n              // assume the control point is coincident with the current point\n              controlX = x;\n              controlY = y;\n            }\n            else {\n              // calculate reflection of previous control point\n              controlX = 2 * x - controlX;\n              controlY = 2 * y - controlY;\n            }\n            bounds = fabric.util.getBoundsOfCurve(x, y,\n              controlX,\n              controlY,\n              controlX,\n              controlY,\n              tempX,\n              tempY\n            );\n            x = tempX;\n            y = tempY;\n            break;\n\n          case 'a':\n            // TODO: optimize this\n            bounds = fabric.util.getBoundsOfArc(x, y,\n              current[1],\n              current[2],\n              current[3],\n              current[4],\n              current[5],\n              current[6] + x,\n              current[7] + y\n            );\n            x += current[6];\n            y += current[7];\n            break;\n\n          case 'A':\n            // TODO: optimize this\n            bounds = fabric.util.getBoundsOfArc(x, y,\n              current[1],\n              current[2],\n              current[3],\n              current[4],\n              current[5],\n              current[6],\n              current[7]\n            );\n            x = current[6];\n            y = current[7];\n            break;\n\n          case 'z':\n          case 'Z':\n            x = subpathStartX;\n            y = subpathStartY;\n            break;\n        }\n        previous = current;\n        bounds.forEach(function (point) {\n          aX.push(point.x);\n          aY.push(point.y);\n        });\n        aX.push(x);\n        aY.push(y);\n      }\n\n      var minX = min(aX) || 0,\n          minY = min(aY) || 0,\n          maxX = max(aX) || 0,\n          maxY = max(aY) || 0,\n          deltaX = maxX - minX,\n          deltaY = maxY - minY;\n\n      return {\n        left: minX,\n        top: minY,\n        width: deltaX,\n        height: deltaY\n      };\n    }\n  });\n\n  /**\n   * Creates an instance of fabric.Path from an object\n   * @static\n   * @memberOf fabric.Path\n   * @param {Object} object\n   * @param {Function} [callback] Callback to invoke when an fabric.Path instance is created\n   */\n  fabric.Path.fromObject = function(object, callback) {\n    if (typeof object.sourcePath === 'string') {\n      var pathUrl = object.sourcePath;\n      fabric.loadSVGFromURL(pathUrl, function (elements) {\n        var path = elements[0];\n        path.setOptions(object);\n        callback && callback(path);\n      });\n    }\n    else {\n      fabric.Object._fromObject('Path', object, callback, 'path');\n    }\n  };\n\n  /* _FROM_SVG_START_ */\n  /**\n   * List of attribute names to account for when parsing SVG element (used by `fabric.Path.fromElement`)\n   * @static\n   * @memberOf fabric.Path\n   * @see http://www.w3.org/TR/SVG/paths.html#PathElement\n   */\n  fabric.Path.ATTRIBUTE_NAMES = fabric.SHARED_ATTRIBUTES.concat(['d']);\n\n  /**\n   * Creates an instance of fabric.Path from an SVG <path> element\n   * @static\n   * @memberOf fabric.Path\n   * @param {SVGElement} element to parse\n   * @param {Function} callback Callback to invoke when an fabric.Path instance is created\n   * @param {Object} [options] Options object\n   * @param {Function} [callback] Options callback invoked after parsing is finished\n   */\n  fabric.Path.fromElement = function(element, callback, options) {\n    var parsedAttributes = fabric.parseAttributes(element, fabric.Path.ATTRIBUTE_NAMES);\n    parsedAttributes.fromSVG = true;\n    callback(new fabric.Path(parsedAttributes.d, extend(parsedAttributes, options)));\n  };\n  /* _FROM_SVG_END_ */\n\n})(typeof exports !== 'undefined' ? exports : this);\n\n\n(function(global) {\n\n  'use strict';\n\n  var fabric = global.fabric || (global.fabric = { }),\n      min = fabric.util.array.min,\n      max = fabric.util.array.max;\n\n  if (fabric.Group) {\n    return;\n  }\n\n  /**\n   * Group class\n   * @class fabric.Group\n   * @extends fabric.Object\n   * @mixes fabric.Collection\n   * @tutorial {@link http://fabricjs.com/fabric-intro-part-3#groups}\n   * @see {@link fabric.Group#initialize} for constructor definition\n   */\n  fabric.Group = fabric.util.createClass(fabric.Object, fabric.Collection, /** @lends fabric.Group.prototype */ {\n\n    /**\n     * Type of an object\n     * @type String\n     * @default\n     */\n    type: 'group',\n\n    /**\n     * Width of stroke\n     * @type Number\n     * @default\n     */\n    strokeWidth: 0,\n\n    /**\n     * Indicates if click events should also check for subtargets\n     * @type Boolean\n     * @default\n     */\n    subTargetCheck: false,\n\n    /**\n     * Groups are container, do not render anything on theyr own, ence no cache properties\n     * @type Array\n     * @default\n     */\n    cacheProperties: [],\n\n    /**\n     * setOnGroup is a method used for TextBox that is no more used since 2.0.0 The behavior is still\n     * available setting this boolean to true.\n     * @type Boolean\n     * @since 2.0.0\n     * @default\n     */\n    useSetOnGroup: false,\n\n    /**\n     * Constructor\n     * @param {Object} objects Group objects\n     * @param {Object} [options] Options object\n     * @param {Boolean} [isAlreadyGrouped] if true, objects have been grouped already.\n     * @return {Object} thisArg\n     */\n    initialize: function(objects, options, isAlreadyGrouped) {\n      options = options || {};\n      this._objects = [];\n      // if objects enclosed in a group have been grouped already,\n      // we cannot change properties of objects.\n      // Thus we need to set options to group without objects,\n      isAlreadyGrouped && this.callSuper('initialize', options);\n      this._objects = objects || [];\n      for (var i = this._objects.length; i--; ) {\n        this._objects[i].group = this;\n      }\n\n      if (!isAlreadyGrouped) {\n        var center = options && options.centerPoint;\n        // we want to set origins before calculating the bounding box.\n        // so that the topleft can be set with that in mind.\n        // if specific top and left are passed, are overwritten later\n        // with the callSuper('initialize', options)\n        if (options.originX !== undefined) {\n          this.originX = options.originX;\n        }\n        if (options.originY !== undefined) {\n          this.originY = options.originY;\n        }\n        // if coming from svg i do not want to calc bounds.\n        // i assume width and height are passed along options\n        center || this._calcBounds();\n        this._updateObjectsCoords(center);\n        delete options.centerPoint;\n        this.callSuper('initialize', options);\n      }\n      else {\n        this._updateObjectsACoords();\n      }\n\n      this.setCoords();\n    },\n\n    /**\n     * @private\n     * @param {Boolean} [skipCoordsChange] if true, coordinates of objects enclosed in a group do not change\n     */\n    _updateObjectsACoords: function() {\n      var ignoreZoom = true, skipAbsolute = true;\n      for (var i = this._objects.length; i--; ){\n        this._objects[i].setCoords(ignoreZoom, skipAbsolute);\n      }\n    },\n\n    /**\n     * @private\n     * @param {Boolean} [skipCoordsChange] if true, coordinates of objects enclosed in a group do not change\n     */\n    _updateObjectsCoords: function(center) {\n      var center = center || this.getCenterPoint();\n      for (var i = this._objects.length; i--; ){\n        this._updateObjectCoords(this._objects[i], center);\n      }\n    },\n\n    /**\n     * @private\n     * @param {Object} object\n     * @param {fabric.Point} center, current center of group.\n     */\n    _updateObjectCoords: function(object, center) {\n      var objectLeft = object.left,\n          objectTop = object.top,\n          ignoreZoom = true, skipAbsolute = true;\n\n      object.set({\n        left: objectLeft - center.x,\n        top: objectTop - center.y\n      });\n      object.group = this;\n      object.setCoords(ignoreZoom, skipAbsolute);\n    },\n\n    /**\n     * Returns string represenation of a group\n     * @return {String}\n     */\n    toString: function() {\n      return '#<fabric.Group: (' + this.complexity() + ')>';\n    },\n\n    /**\n     * Adds an object to a group; Then recalculates group's dimension, position.\n     * @param {Object} object\n     * @return {fabric.Group} thisArg\n     * @chainable\n     */\n    addWithUpdate: function(object) {\n      this._restoreObjectsState();\n      fabric.util.resetObjectTransform(this);\n      if (object) {\n        this._objects.push(object);\n        object.group = this;\n        object._set('canvas', this.canvas);\n      }\n      this._calcBounds();\n      this._updateObjectsCoords();\n      this.setCoords();\n      this.dirty = true;\n      return this;\n    },\n\n    /**\n     * Removes an object from a group; Then recalculates group's dimension, position.\n     * @param {Object} object\n     * @return {fabric.Group} thisArg\n     * @chainable\n     */\n    removeWithUpdate: function(object) {\n      this._restoreObjectsState();\n      fabric.util.resetObjectTransform(this);\n\n      this.remove(object);\n      this._calcBounds();\n      this._updateObjectsCoords();\n      this.setCoords();\n      this.dirty = true;\n      return this;\n    },\n\n    /**\n     * @private\n     */\n    _onObjectAdded: function(object) {\n      this.dirty = true;\n      object.group = this;\n      object._set('canvas', this.canvas);\n    },\n\n    /**\n     * @private\n     */\n    _onObjectRemoved: function(object) {\n      this.dirty = true;\n      delete object.group;\n    },\n\n    /**\n     * @private\n     */\n    _set: function(key, value) {\n      var i = this._objects.length;\n      if (this.useSetOnGroup) {\n        while (i--) {\n          this._objects[i].setOnGroup(key, value);\n        }\n      }\n      if (key === 'canvas') {\n        while (i--) {\n          this._objects[i]._set(key, value);\n        }\n      }\n      fabric.Object.prototype._set.call(this, key, value);\n    },\n\n    /**\n     * Returns object representation of an instance\n     * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output\n     * @return {Object} object representation of an instance\n     */\n    toObject: function(propertiesToInclude) {\n      var _includeDefaultValues = this.includeDefaultValues;\n      var objsToObject = this._objects.map(function(obj) {\n        var originalDefaults = obj.includeDefaultValues;\n        obj.includeDefaultValues = _includeDefaultValues;\n        var _obj = obj.toObject(propertiesToInclude);\n        obj.includeDefaultValues = originalDefaults;\n        return _obj;\n      });\n      var obj = fabric.Object.prototype.toObject.call(this, propertiesToInclude);\n      obj.objects = objsToObject;\n      return obj;\n    },\n\n    /**\n     * Returns object representation of an instance, in dataless mode.\n     * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output\n     * @return {Object} object representation of an instance\n     */\n    toDatalessObject: function(propertiesToInclude) {\n      var objsToObject, sourcePath = this.sourcePath;\n      if (sourcePath) {\n        objsToObject = sourcePath;\n      }\n      else {\n        var _includeDefaultValues = this.includeDefaultValues;\n        objsToObject = this._objects.map(function(obj) {\n          var originalDefaults = obj.includeDefaultValues;\n          obj.includeDefaultValues = _includeDefaultValues;\n          var _obj = obj.toDatalessObject(propertiesToInclude);\n          obj.includeDefaultValues = originalDefaults;\n          return _obj;\n        });\n      }\n      var obj = fabric.Object.prototype.toDatalessObject.call(this, propertiesToInclude);\n      obj.objects = objsToObject;\n      return obj;\n    },\n\n    /**\n     * Renders instance on a given context\n     * @param {CanvasRenderingContext2D} ctx context to render instance on\n     */\n    render: function(ctx) {\n      this._transformDone = true;\n      this.callSuper('render', ctx);\n      this._transformDone = false;\n    },\n\n    /**\n     * Decide if the object should cache or not. Create its own cache level\n     * needsItsOwnCache should be used when the object drawing method requires\n     * a cache step. None of the fabric classes requires it.\n     * Generally you do not cache objects in groups because the group is already cached.\n     * @return {Boolean}\n     */\n    shouldCache: function() {\n      var ownCache = fabric.Object.prototype.shouldCache.call(this);\n      if (ownCache) {\n        for (var i = 0, len = this._objects.length; i < len; i++) {\n          if (this._objects[i].willDrawShadow()) {\n            this.ownCaching = false;\n            return false;\n          }\n        }\n      }\n      return ownCache;\n    },\n\n    /**\n     * Check if this object or a child object will cast a shadow\n     * @return {Boolean}\n     */\n    willDrawShadow: function() {\n      if (this.shadow) {\n        return fabric.Object.prototype.willDrawShadow.call(this);\n      }\n      for (var i = 0, len = this._objects.length; i < len; i++) {\n        if (this._objects[i].willDrawShadow()) {\n          return true;\n        }\n      }\n      return false;\n    },\n\n    /**\n     * Check if this group or its parent group are caching, recursively up\n     * @return {Boolean}\n     */\n    isOnACache: function() {\n      return this.ownCaching || (this.group && this.group.isOnACache());\n    },\n\n    /**\n     * Execute the drawing operation for an object on a specified context\n     * @param {CanvasRenderingContext2D} ctx Context to render on\n     */\n    drawObject: function(ctx) {\n      for (var i = 0, len = this._objects.length; i < len; i++) {\n        this._objects[i].render(ctx);\n      }\n      this._drawClipPath(ctx);\n    },\n\n    /**\n     * Check if cache is dirty\n     */\n    isCacheDirty: function(skipCanvas) {\n      if (this.callSuper('isCacheDirty', skipCanvas)) {\n        return true;\n      }\n      if (!this.statefullCache) {\n        return false;\n      }\n      for (var i = 0, len = this._objects.length; i < len; i++) {\n        if (this._objects[i].isCacheDirty(true)) {\n          if (this._cacheCanvas) {\n            // if this group has not a cache canvas there is nothing to clean\n            var x = this.cacheWidth / this.zoomX, y = this.cacheHeight / this.zoomY;\n            this._cacheContext.clearRect(-x / 2, -y / 2, x, y);\n          }\n          return true;\n        }\n      }\n      return false;\n    },\n\n    /**\n     * Retores original state of each of group objects (original state is that which was before group was created).\n     * @private\n     * @return {fabric.Group} thisArg\n     * @chainable\n     */\n    _restoreObjectsState: function() {\n      this._objects.forEach(this._restoreObjectState, this);\n      return this;\n    },\n\n    /**\n     * Realises the transform from this group onto the supplied object\n     * i.e. it tells you what would happen if the supplied object was in\n     * the group, and then the group was destroyed. It mutates the supplied\n     * object.\n     * @param {fabric.Object} object\n     * @return {fabric.Object} transformedObject\n     */\n    realizeTransform: function(object) {\n      var matrix = object.calcTransformMatrix(),\n          options = fabric.util.qrDecompose(matrix),\n          center = new fabric.Point(options.translateX, options.translateY);\n      object.flipX = false;\n      object.flipY = false;\n      object.set('scaleX', options.scaleX);\n      object.set('scaleY', options.scaleY);\n      object.skewX = options.skewX;\n      object.skewY = options.skewY;\n      object.angle = options.angle;\n      object.setPositionByOrigin(center, 'center', 'center');\n      return object;\n    },\n\n    /**\n     * Restores original state of a specified object in group\n     * @private\n     * @param {fabric.Object} object\n     * @return {fabric.Group} thisArg\n     */\n    _restoreObjectState: function(object) {\n      this.realizeTransform(object);\n      object.setCoords();\n      delete object.group;\n      return this;\n    },\n\n    /**\n     * Destroys a group (restoring state of its objects)\n     * @return {fabric.Group} thisArg\n     * @chainable\n     */\n    destroy: function() {\n      // when group is destroyed objects needs to get a repaint to be eventually\n      // displayed on canvas.\n      this._objects.forEach(function(object) {\n        object.set('dirty', true);\n      });\n      return this._restoreObjectsState();\n    },\n\n    /**\n     * make a group an active selection, remove the group from canvas\n     * the group has to be on canvas for this to work.\n     * @return {fabric.ActiveSelection} thisArg\n     * @chainable\n     */\n    toActiveSelection: function() {\n      if (!this.canvas) {\n        return;\n      }\n      var objects = this._objects, canvas = this.canvas;\n      this._objects = [];\n      var options = this.toObject();\n      delete options.objects;\n      var activeSelection = new fabric.ActiveSelection([]);\n      activeSelection.set(options);\n      activeSelection.type = 'activeSelection';\n      canvas.remove(this);\n      objects.forEach(function(object) {\n        object.group = activeSelection;\n        object.dirty = true;\n        canvas.add(object);\n      });\n      activeSelection.canvas = canvas;\n      activeSelection._objects = objects;\n      canvas._activeObject = activeSelection;\n      activeSelection.setCoords();\n      return activeSelection;\n    },\n\n    /**\n     * Destroys a group (restoring state of its objects)\n     * @return {fabric.Group} thisArg\n     * @chainable\n     */\n    ungroupOnCanvas: function() {\n      return this._restoreObjectsState();\n    },\n\n    /**\n     * Sets coordinates of all objects inside group\n     * @return {fabric.Group} thisArg\n     * @chainable\n     */\n    setObjectsCoords: function() {\n      var ignoreZoom = true, skipAbsolute = true;\n      this.forEachObject(function(object) {\n        object.setCoords(ignoreZoom, skipAbsolute);\n      });\n      return this;\n    },\n\n    /**\n     * @private\n     */\n    _calcBounds: function(onlyWidthHeight) {\n      var aX = [],\n          aY = [],\n          o, prop,\n          props = ['tr', 'br', 'bl', 'tl'],\n          i = 0, iLen = this._objects.length,\n          j, jLen = props.length,\n          ignoreZoom = true;\n\n      for ( ; i < iLen; ++i) {\n        o = this._objects[i];\n        o.setCoords(ignoreZoom);\n        for (j = 0; j < jLen; j++) {\n          prop = props[j];\n          aX.push(o.oCoords[prop].x);\n          aY.push(o.oCoords[prop].y);\n        }\n      }\n\n      this._getBounds(aX, aY, onlyWidthHeight);\n    },\n\n    /**\n     * @private\n     */\n    _getBounds: function(aX, aY, onlyWidthHeight) {\n      var minXY = new fabric.Point(min(aX), min(aY)),\n          maxXY = new fabric.Point(max(aX), max(aY)),\n          top = minXY.y || 0, left = minXY.x || 0,\n          width = (maxXY.x - minXY.x) || 0,\n          height = (maxXY.y - minXY.y) || 0;\n      this.width = width;\n      this.height = height;\n      if (!onlyWidthHeight) {\n        // the bounding box always finds the topleft most corner.\n        // whatever is the group origin, we set up here the left/top position.\n        this.setPositionByOrigin({ x: left, y: top }, 'left', 'top');\n      }\n    },\n\n    /* _TO_SVG_START_ */\n    /**\n     * Returns svg representation of an instance\n     * @param {Function} [reviver] Method for further parsing of svg representation.\n     * @return {String} svg representation of an instance\n     */\n    _toSVG: function(reviver) {\n      var svgString = ['<g ', 'COMMON_PARTS', ' >\\n'];\n\n      for (var i = 0, len = this._objects.length; i < len; i++) {\n        svgString.push('\\t\\t', this._objects[i].toSVG(reviver));\n      }\n      svgString.push('</g>\\n');\n      return svgString;\n    },\n\n    /**\n     * Returns styles-string for svg-export, specific version for group\n     * @return {String}\n     */\n    getSvgStyles: function() {\n      var opacity = typeof this.opacity !== 'undefined' && this.opacity !== 1 ?\n            'opacity: ' + this.opacity + ';' : '',\n          visibility = this.visible ? '' : ' visibility: hidden;';\n      return [\n        opacity,\n        this.getSvgFilter(),\n        visibility\n      ].join('');\n    },\n\n    /**\n     * Returns svg clipPath representation of an instance\n     * @param {Function} [reviver] Method for further parsing of svg representation.\n     * @return {String} svg representation of an instance\n     */\n    toClipPathSVG: function(reviver) {\n      var svgString = [];\n\n      for (var i = 0, len = this._objects.length; i < len; i++) {\n        svgString.push('\\t', this._objects[i].toClipPathSVG(reviver));\n      }\n\n      return this._createBaseClipPathSVGMarkup(svgString, { reviver: reviver });\n    },\n    /* _TO_SVG_END_ */\n  });\n\n  /**\n   * Returns {@link fabric.Group} instance from an object representation\n   * @static\n   * @memberOf fabric.Group\n   * @param {Object} object Object to create a group from\n   * @param {Function} [callback] Callback to invoke when an group instance is created\n   */\n  fabric.Group.fromObject = function(object, callback) {\n    fabric.util.enlivenObjects(object.objects, function(enlivenedObjects) {\n      fabric.util.enlivenObjects([object.clipPath], function(enlivedClipPath) {\n        var options = fabric.util.object.clone(object, true);\n        options.clipPath = enlivedClipPath[0];\n        delete options.objects;\n        callback && callback(new fabric.Group(enlivenedObjects, options, true));\n      });\n    });\n  };\n\n})(typeof exports !== 'undefined' ? exports : this);\n\n\n(function(global) {\n\n  'use strict';\n\n  var fabric = global.fabric || (global.fabric = { });\n\n  if (fabric.ActiveSelection) {\n    return;\n  }\n\n  /**\n   * Group class\n   * @class fabric.ActiveSelection\n   * @extends fabric.Group\n   * @tutorial {@link http://fabricjs.com/fabric-intro-part-3#groups}\n   * @see {@link fabric.ActiveSelection#initialize} for constructor definition\n   */\n  fabric.ActiveSelection = fabric.util.createClass(fabric.Group, /** @lends fabric.ActiveSelection.prototype */ {\n\n    /**\n     * Type of an object\n     * @type String\n     * @default\n     */\n    type: 'activeSelection',\n\n    /**\n     * Constructor\n     * @param {Object} objects ActiveSelection objects\n     * @param {Object} [options] Options object\n     * @return {Object} thisArg\n     */\n    initialize: function(objects, options) {\n      options = options || {};\n      this._objects = objects || [];\n      for (var i = this._objects.length; i--; ) {\n        this._objects[i].group = this;\n      }\n\n      if (options.originX) {\n        this.originX = options.originX;\n      }\n      if (options.originY) {\n        this.originY = options.originY;\n      }\n      this._calcBounds();\n      this._updateObjectsCoords();\n      fabric.Object.prototype.initialize.call(this, options);\n      this.setCoords();\n    },\n\n    /**\n     * Change te activeSelection to a normal group,\n     * High level function that automatically adds it to canvas as\n     * active object. no events fired.\n     * @since 2.0.0\n     * @return {fabric.Group}\n     */\n    toGroup: function() {\n      var objects = this._objects.concat();\n      this._objects = [];\n      var options = fabric.Object.prototype.toObject.call(this);\n      var newGroup = new fabric.Group([]);\n      delete options.type;\n      newGroup.set(options);\n      objects.forEach(function(object) {\n        object.canvas.remove(object);\n        object.group = newGroup;\n      });\n      newGroup._objects = objects;\n      if (!this.canvas) {\n        return newGroup;\n      }\n      var canvas = this.canvas;\n      canvas.add(newGroup);\n      canvas._activeObject = newGroup;\n      newGroup.setCoords();\n      return newGroup;\n    },\n\n    /**\n     * If returns true, deselection is cancelled.\n     * @since 2.0.0\n     * @return {Boolean} [cancel]\n     */\n    onDeselect: function() {\n      this.destroy();\n      return false;\n    },\n\n    /**\n     * Returns string representation of a group\n     * @return {String}\n     */\n    toString: function() {\n      return '#<fabric.ActiveSelection: (' + this.complexity() + ')>';\n    },\n\n    /**\n     * Decide if the object should cache or not. Create its own cache level\n     * objectCaching is a global flag, wins over everything\n     * needsItsOwnCache should be used when the object drawing method requires\n     * a cache step. None of the fabric classes requires it.\n     * Generally you do not cache objects in groups because the group outside is cached.\n     * @return {Boolean}\n     */\n    shouldCache: function() {\n      return false;\n    },\n\n    /**\n     * Check if this group or its parent group are caching, recursively up\n     * @return {Boolean}\n     */\n    isOnACache: function() {\n      return false;\n    },\n\n    /**\n     * Renders controls and borders for the object\n     * @param {CanvasRenderingContext2D} ctx Context to render on\n     * @param {Object} [styleOverride] properties to override the object style\n     * @param {Object} [childrenOverride] properties to override the children overrides\n     */\n    _renderControls: function(ctx, styleOverride, childrenOverride) {\n      ctx.save();\n      ctx.globalAlpha = this.isMoving ? this.borderOpacityWhenMoving : 1;\n      this.callSuper('_renderControls', ctx, styleOverride);\n      childrenOverride = childrenOverride || { };\n      if (typeof childrenOverride.hasControls === 'undefined') {\n        childrenOverride.hasControls = false;\n      }\n      if (typeof childrenOverride.hasRotatingPoint === 'undefined') {\n        childrenOverride.hasRotatingPoint = false;\n      }\n      childrenOverride.forActiveSelection = true;\n      for (var i = 0, len = this._objects.length; i < len; i++) {\n        this._objects[i]._renderControls(ctx, childrenOverride);\n      }\n      ctx.restore();\n    },\n  });\n\n  /**\n   * Returns {@link fabric.ActiveSelection} instance from an object representation\n   * @static\n   * @memberOf fabric.ActiveSelection\n   * @param {Object} object Object to create a group from\n   * @param {Function} [callback] Callback to invoke when an ActiveSelection instance is created\n   */\n  fabric.ActiveSelection.fromObject = function(object, callback) {\n    fabric.util.enlivenObjects(object.objects, function(enlivenedObjects) {\n      delete object.objects;\n      callback && callback(new fabric.ActiveSelection(enlivenedObjects, object, true));\n    });\n  };\n\n})(typeof exports !== 'undefined' ? exports : this);\n\n\n(function(global) {\n\n  'use strict';\n\n  var extend = fabric.util.object.extend;\n\n  if (!global.fabric) {\n    global.fabric = { };\n  }\n\n  if (global.fabric.Image) {\n    fabric.warn('fabric.Image is already defined.');\n    return;\n  }\n\n  /**\n   * Image class\n   * @class fabric.Image\n   * @extends fabric.Object\n   * @tutorial {@link http://fabricjs.com/fabric-intro-part-1#images}\n   * @see {@link fabric.Image#initialize} for constructor definition\n   */\n  fabric.Image = fabric.util.createClass(fabric.Object, /** @lends fabric.Image.prototype */ {\n\n    /**\n     * Type of an object\n     * @type String\n     * @default\n     */\n    type: 'image',\n\n    /**\n     * crossOrigin value (one of \"\", \"anonymous\", \"use-credentials\")\n     * @see https://developer.mozilla.org/en-US/docs/HTML/CORS_settings_attributes\n     * @type String\n     * @default\n     */\n    crossOrigin: '',\n\n    /**\n     * Width of a stroke.\n     * For image quality a stroke multiple of 2 gives better results.\n     * @type Number\n     * @default\n     */\n    strokeWidth: 0,\n\n    /**\n     * When calling {@link fabric.Image.getSrc}, return value from element src with `element.getAttribute('src')`.\n     * This allows for relative urls as image src.\n     * @since 2.7.0\n     * @type Boolean\n     * @default\n     */\n    srcFromAttribute: false,\n\n    /**\n     * private\n     * contains last value of scaleX to detect\n     * if the Image got resized after the last Render\n     * @type Number\n     */\n    _lastScaleX: 1,\n\n    /**\n     * private\n     * contains last value of scaleY to detect\n     * if the Image got resized after the last Render\n     * @type Number\n     */\n    _lastScaleY: 1,\n\n    /**\n     * private\n     * contains last value of scaling applied by the apply filter chain\n     * @type Number\n     */\n    _filterScalingX: 1,\n\n    /**\n     * private\n     * contains last value of scaling applied by the apply filter chain\n     * @type Number\n     */\n    _filterScalingY: 1,\n\n    /**\n     * minimum scale factor under which any resizeFilter is triggered to resize the image\n     * 0 will disable the automatic resize. 1 will trigger automatically always.\n     * number bigger than 1 are not implemented yet.\n     * @type Number\n     */\n    minimumScaleTrigger: 0.5,\n\n    /**\n     * List of properties to consider when checking if\n     * state of an object is changed ({@link fabric.Object#hasStateChanged})\n     * as well as for history (undo/redo) purposes\n     * @type Array\n     */\n    stateProperties: fabric.Object.prototype.stateProperties.concat('cropX', 'cropY'),\n\n    /**\n     * key used to retrieve the texture representing this image\n     * @since 2.0.0\n     * @type String\n     * @default\n     */\n    cacheKey: '',\n\n    /**\n     * Image crop in pixels from original image size.\n     * @since 2.0.0\n     * @type Number\n     * @default\n     */\n    cropX: 0,\n\n    /**\n     * Image crop in pixels from original image size.\n     * @since 2.0.0\n     * @type Number\n     * @default\n     */\n    cropY: 0,\n\n    /**\n     * Constructor\n     * @param {HTMLImageElement | String} element Image element\n     * @param {Object} [options] Options object\n     * @param {function} [callback] callback function to call after eventual filters applied.\n     * @return {fabric.Image} thisArg\n     */\n    initialize: function(element, options) {\n      options || (options = { });\n      this.filters = [];\n      this.cacheKey = 'texture' + fabric.Object.__uid++;\n      this.callSuper('initialize', options);\n      this._initElement(element, options);\n    },\n\n    /**\n     * Returns image element which this instance if based on\n     * @return {HTMLImageElement} Image element\n     */\n    getElement: function() {\n      return this._element || {};\n    },\n\n    /**\n     * Sets image element for this instance to a specified one.\n     * If filters defined they are applied to new image.\n     * You might need to call `canvas.renderAll` and `object.setCoords` after replacing, to render new image and update controls area.\n     * @param {HTMLImageElement} element\n     * @param {Object} [options] Options object\n     * @return {fabric.Image} thisArg\n     * @chainable\n     */\n    setElement: function(element, options) {\n      this.removeTexture(this.cacheKey);\n      this.removeTexture(this.cacheKey + '_filtered');\n      this._element = element;\n      this._originalElement = element;\n      this._initConfig(options);\n      if (this.filters.length !== 0) {\n        this.applyFilters();\n      }\n      // resizeFilters work on the already filtered copy.\n      // we need to apply resizeFilters AFTER normal filters.\n      // applyResizeFilters is run more often than normal fiters\n      // and is triggered by user interactions rather than dev code\n      if (this.resizeFilter) {\n        this.applyResizeFilters();\n      }\n      return this;\n    },\n\n    /**\n     * Delete a single texture if in webgl mode\n     */\n    removeTexture: function(key) {\n      var backend = fabric.filterBackend;\n      if (backend && backend.evictCachesForKey) {\n        backend.evictCachesForKey(key);\n      }\n    },\n\n    /**\n     * Delete textures, reference to elements and eventually JSDOM cleanup\n     */\n    dispose: function() {\n      this.removeTexture(this.cacheKey);\n      this.removeTexture(this.cacheKey + '_filtered');\n      this._cacheContext = undefined;\n      ['_originalElement', '_element', '_filteredEl', '_cacheCanvas'].forEach((function(element) {\n        fabric.util.cleanUpJsdomNode(this[element]);\n        this[element] = undefined;\n      }).bind(this));\n    },\n\n    /**\n     * Sets crossOrigin value (on an instance and corresponding image element)\n     * @return {fabric.Image} thisArg\n     * @chainable\n     */\n    setCrossOrigin: function(value) {\n      this.crossOrigin = value;\n      this._element.crossOrigin = value;\n\n      return this;\n    },\n\n    /**\n     * Returns original size of an image\n     * @return {Object} Object with \"width\" and \"height\" properties\n     */\n    getOriginalSize: function() {\n      var element = this.getElement();\n      return {\n        width: element.naturalWidth || element.width,\n        height: element.naturalHeight || element.height\n      };\n    },\n\n    /**\n     * @private\n     * @param {CanvasRenderingContext2D} ctx Context to render on\n     */\n    _stroke: function(ctx) {\n      if (!this.stroke || this.strokeWidth === 0) {\n        return;\n      }\n      var w = this.width / 2, h = this.height / 2;\n      ctx.beginPath();\n      ctx.moveTo(-w, -h);\n      ctx.lineTo(w, -h);\n      ctx.lineTo(w, h);\n      ctx.lineTo(-w, h);\n      ctx.lineTo(-w, -h);\n      ctx.closePath();\n    },\n\n    /**\n     * @private\n     * @param {CanvasRenderingContext2D} ctx Context to render on\n     */\n    _renderDashedStroke: function(ctx) {\n      var x = -this.width / 2,\n          y = -this.height / 2,\n          w = this.width,\n          h = this.height;\n\n      ctx.save();\n      this._setStrokeStyles(ctx, this);\n\n      ctx.beginPath();\n      fabric.util.drawDashedLine(ctx, x, y, x + w, y, this.strokeDashArray);\n      fabric.util.drawDashedLine(ctx, x + w, y, x + w, y + h, this.strokeDashArray);\n      fabric.util.drawDashedLine(ctx, x + w, y + h, x, y + h, this.strokeDashArray);\n      fabric.util.drawDashedLine(ctx, x, y + h, x, y, this.strokeDashArray);\n      ctx.closePath();\n      ctx.restore();\n    },\n\n    /**\n     * Returns object representation of an instance\n     * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output\n     * @return {Object} Object representation of an instance\n     */\n    toObject: function(propertiesToInclude) {\n      var filters = [];\n\n      this.filters.forEach(function(filterObj) {\n        if (filterObj) {\n          filters.push(filterObj.toObject());\n        }\n      });\n      var object = extend(\n        this.callSuper(\n          'toObject',\n          ['crossOrigin', 'cropX', 'cropY'].concat(propertiesToInclude)\n        ), {\n          src: this.getSrc(),\n          filters: filters,\n        });\n      if (this.resizeFilter) {\n        object.resizeFilter = this.resizeFilter.toObject();\n      }\n      return object;\n    },\n\n    /**\n     * Returns true if an image has crop applied, inspecting values of cropX,cropY,width,hight.\n     * @return {Boolean}\n     */\n    hasCrop: function() {\n      return this.cropX || this.cropY || this.width < this._element.width || this.height < this._element.height;\n    },\n\n    /* _TO_SVG_START_ */\n    /**\n     * Returns svg representation of an instance\n     * @return {Array} an array of strings with the specific svg representation\n     * of the instance\n     */\n    _toSVG: function() {\n      var svgString = [], imageMarkup = [], strokeSvg,\n          x = -this.width / 2, y = -this.height / 2, clipPath = '';\n      if (this.hasCrop()) {\n        var clipPathId = fabric.Object.__uid++;\n        svgString.push(\n          '<clipPath id=\"imageCrop_' + clipPathId + '\">\\n',\n          '\\t<rect x=\"' + x + '\" y=\"' + y + '\" width=\"' + this.width + '\" height=\"' + this.height + '\" />\\n',\n          '</clipPath>\\n'\n        );\n        clipPath = ' clip-path=\"url(#imageCrop_' + clipPathId + ')\" ';\n      }\n      imageMarkup.push('\\t<image ', 'COMMON_PARTS', 'xlink:href=\"', this.getSvgSrc(true),\n        '\" x=\"', x - this.cropX, '\" y=\"', y - this.cropY,\n        // we're essentially moving origin of transformation from top/left corner to the center of the shape\n        // by wrapping it in container <g> element with actual transformation, then offsetting object to the top/left\n        // so that object's center aligns with container's left/top\n        '\" width=\"', this._element.width || this._element.naturalWidth,\n        '\" height=\"', this._element.height || this._element.height,\n        '\"', clipPath,\n        '></image>\\n');\n\n      if (this.stroke || this.strokeDashArray) {\n        var origFill = this.fill;\n        this.fill = null;\n        strokeSvg = [\n          '\\t<rect ',\n          'x=\"', x, '\" y=\"', y,\n          '\" width=\"', this.width, '\" height=\"', this.height,\n          '\" style=\"', this.getSvgStyles(),\n          '\"/>\\n'\n        ];\n        this.fill = origFill;\n      }\n      if (this.paintFirst !== 'fill') {\n        svgString = svgString.concat(strokeSvg, imageMarkup);\n      }\n      else {\n        svgString = svgString.concat(imageMarkup, strokeSvg);\n      }\n      return svgString;\n    },\n    /* _TO_SVG_END_ */\n\n    /**\n     * Returns source of an image\n     * @param {Boolean} filtered indicates if the src is needed for svg\n     * @return {String} Source of an image\n     */\n    getSrc: function(filtered) {\n      var element = filtered ? this._element : this._originalElement;\n      if (element) {\n        if (element.toDataURL) {\n          return element.toDataURL();\n        }\n\n        if (this.srcFromAttribute) {\n          return element.getAttribute('src');\n        }\n        else {\n          return element.src;\n        }\n      }\n      else {\n        return this.src || '';\n      }\n    },\n\n    /**\n     * Sets source of an image\n     * @param {String} src Source string (URL)\n     * @param {Function} [callback] Callback is invoked when image has been loaded (and all filters have been applied)\n     * @param {Object} [options] Options object\n     * @return {fabric.Image} thisArg\n     * @chainable\n     */\n    setSrc: function(src, callback, options) {\n      fabric.util.loadImage(src, function(img) {\n        this.setElement(img, options);\n        this._setWidthHeight();\n        callback && callback(this);\n      }, this, options && options.crossOrigin);\n      return this;\n    },\n\n    /**\n     * Returns string representation of an instance\n     * @return {String} String representation of an instance\n     */\n    toString: function() {\n      return '#<fabric.Image: { src: \"' + this.getSrc() + '\" }>';\n    },\n\n    applyResizeFilters: function() {\n      var filter = this.resizeFilter,\n          minimumScale = this.minimumScaleTrigger,\n          objectScale = this.getTotalObjectScaling(),\n          scaleX = objectScale.scaleX,\n          scaleY = objectScale.scaleY,\n          elementToFilter = this._filteredEl || this._originalElement;\n      if (this.group) {\n        this.set('dirty', true);\n      }\n      if (!filter || (scaleX > minimumScale && scaleY > minimumScale)) {\n        this._element = elementToFilter;\n        this._filterScalingX = 1;\n        this._filterScalingY = 1;\n        this._lastScaleX = scaleX;\n        this._lastScaleY = scaleY;\n        return;\n      }\n      if (!fabric.filterBackend) {\n        fabric.filterBackend = fabric.initFilterBackend();\n      }\n      var canvasEl = fabric.util.createCanvasElement(),\n          cacheKey = this._filteredEl ? (this.cacheKey + '_filtered') : this.cacheKey,\n          sourceWidth = elementToFilter.width, sourceHeight = elementToFilter.height;\n      canvasEl.width = sourceWidth;\n      canvasEl.height = sourceHeight;\n      this._element = canvasEl;\n      this._lastScaleX = filter.scaleX = scaleX;\n      this._lastScaleY = filter.scaleY = scaleY;\n      fabric.filterBackend.applyFilters(\n        [filter], elementToFilter, sourceWidth, sourceHeight, this._element, cacheKey);\n      this._filterScalingX = canvasEl.width / this._originalElement.width;\n      this._filterScalingY = canvasEl.height / this._originalElement.height;\n    },\n\n    /**\n     * Applies filters assigned to this image (from \"filters\" array) or from filter param\n     * @method applyFilters\n     * @param {Array} filters to be applied\n     * @param {Boolean} forResizing specify if the filter operation is a resize operation\n     * @return {thisArg} return the fabric.Image object\n     * @chainable\n     */\n    applyFilters: function(filters) {\n\n      filters = filters || this.filters || [];\n      filters = filters.filter(function(filter) { return filter && !filter.isNeutralState(); });\n      this.set('dirty', true);\n\n      // needs to clear out or WEBGL will not resize correctly\n      this.removeTexture(this.cacheKey + '_filtered');\n\n      if (filters.length === 0) {\n        this._element = this._originalElement;\n        this._filteredEl = null;\n        this._filterScalingX = 1;\n        this._filterScalingY = 1;\n        return this;\n      }\n\n      var imgElement = this._originalElement,\n          sourceWidth = imgElement.naturalWidth || imgElement.width,\n          sourceHeight = imgElement.naturalHeight || imgElement.height;\n\n      if (this._element === this._originalElement) {\n        // if the element is the same we need to create a new element\n        var canvasEl = fabric.util.createCanvasElement();\n        canvasEl.width = sourceWidth;\n        canvasEl.height = sourceHeight;\n        this._element = canvasEl;\n        this._filteredEl = canvasEl;\n      }\n      else {\n        // clear the existing element to get new filter data\n        // also dereference the eventual resized _element\n        this._element = this._filteredEl;\n        this._filteredEl.getContext('2d').clearRect(0, 0, sourceWidth, sourceHeight);\n        // we also need to resize again at next renderAll, so remove saved _lastScaleX/Y\n        this._lastScaleX = 1;\n        this._lastScaleY = 1;\n      }\n      if (!fabric.filterBackend) {\n        fabric.filterBackend = fabric.initFilterBackend();\n      }\n      fabric.filterBackend.applyFilters(\n        filters, this._originalElement, sourceWidth, sourceHeight, this._element, this.cacheKey);\n      if (this._originalElement.width !== this._element.width ||\n        this._originalElement.height !== this._element.height) {\n        this._filterScalingX = this._element.width / this._originalElement.width;\n        this._filterScalingY = this._element.height / this._originalElement.height;\n      }\n      return this;\n    },\n\n    /**\n     * @private\n     * @param {CanvasRenderingContext2D} ctx Context to render on\n     */\n    _render: function(ctx) {\n      if (this.isMoving !== true && this.resizeFilter && this._needsResize()) {\n        this.applyResizeFilters();\n      }\n      this._stroke(ctx);\n      this._renderPaintInOrder(ctx);\n    },\n\n    /**\n     * Decide if the object should cache or not. Create its own cache level\n     * needsItsOwnCache should be used when the object drawing method requires\n     * a cache step. None of the fabric classes requires it.\n     * Generally you do not cache objects in groups because the group outside is cached.\n     * This is the special image version where we would like to avoid caching where possible.\n     * Essentially images do not benefit from caching. They may require caching, and in that\n     * case we do it. Also caching an image usually ends in a loss of details.\n     * A full performance audit should be done.\n     * @return {Boolean}\n     */\n    shouldCache: function() {\n      return this.needsItsOwnCache();\n    },\n\n    _renderFill: function(ctx) {\n      var elementToDraw = this._element,\n          w = this.width, h = this.height,\n          sW = Math.min(elementToDraw.naturalWidth || elementToDraw.width, w * this._filterScalingX),\n          sH = Math.min(elementToDraw.naturalHeight || elementToDraw.height, h * this._filterScalingY),\n          x = -w / 2, y = -h / 2,\n          sX = Math.max(0, this.cropX * this._filterScalingX),\n          sY = Math.max(0, this.cropY * this._filterScalingY);\n\n      elementToDraw && ctx.drawImage(elementToDraw, sX, sY, sW, sH, x, y, w, h);\n    },\n\n    /**\n     * @private, needed to check if image needs resize\n     */\n    _needsResize: function() {\n      var scale = this.getTotalObjectScaling();\n      return (scale.scaleX !== this._lastScaleX || scale.scaleY !== this._lastScaleY);\n    },\n\n    /**\n     * @private\n     */\n    _resetWidthHeight: function() {\n      this.set(this.getOriginalSize());\n    },\n\n    /**\n     * The Image class's initialization method. This method is automatically\n     * called by the constructor.\n     * @private\n     * @param {HTMLImageElement|String} element The element representing the image\n     * @param {Object} [options] Options object\n     */\n    _initElement: function(element, options) {\n      this.setElement(fabric.util.getById(element), options);\n      fabric.util.addClass(this.getElement(), fabric.Image.CSS_CANVAS);\n    },\n\n    /**\n     * @private\n     * @param {Object} [options] Options object\n     */\n    _initConfig: function(options) {\n      options || (options = { });\n      this.setOptions(options);\n      this._setWidthHeight(options);\n      if (this._element && this.crossOrigin) {\n        this._element.crossOrigin = this.crossOrigin;\n      }\n    },\n\n    /**\n     * @private\n     * @param {Array} filters to be initialized\n     * @param {Function} callback Callback to invoke when all fabric.Image.filters instances are created\n     */\n    _initFilters: function(filters, callback) {\n      if (filters && filters.length) {\n        fabric.util.enlivenObjects(filters, function(enlivenedObjects) {\n          callback && callback(enlivenedObjects);\n        }, 'fabric.Image.filters');\n      }\n      else {\n        callback && callback();\n      }\n    },\n\n    /**\n     * @private\n     * Set the width and the height of the image object, using the element or the\n     * options.\n     * @param {Object} [options] Object with width/height properties\n     */\n    _setWidthHeight: function(options) {\n      options || (options = { });\n      var el = this.getElement();\n      this.width = options.width || el.naturalWidth || el.width || 0;\n      this.height = options.height || el.naturalHeight || el.height || 0;\n    },\n\n    /**\n     * Calculate offset for center and scale factor for the image in order to respect\n     * the preserveAspectRatio attribute\n     * @private\n     * @return {Object}\n     */\n    parsePreserveAspectRatioAttribute: function() {\n      var pAR = fabric.util.parsePreserveAspectRatioAttribute(this.preserveAspectRatio || ''),\n          rWidth = this._element.width, rHeight = this._element.height,\n          scaleX = 1, scaleY = 1, offsetLeft = 0, offsetTop = 0, cropX = 0, cropY = 0,\n          offset, pWidth = this.width, pHeight = this.height, parsedAttributes = { width: pWidth, height: pHeight };\n      if (pAR && (pAR.alignX !== 'none' || pAR.alignY !== 'none')) {\n        if (pAR.meetOrSlice === 'meet') {\n          scaleX = scaleY = fabric.util.findScaleToFit(this._element, parsedAttributes);\n          offset = (pWidth - rWidth * scaleX) / 2;\n          if (pAR.alignX === 'Min') {\n            offsetLeft = -offset;\n          }\n          if (pAR.alignX === 'Max') {\n            offsetLeft = offset;\n          }\n          offset = (pHeight - rHeight * scaleY) / 2;\n          if (pAR.alignY === 'Min') {\n            offsetTop = -offset;\n          }\n          if (pAR.alignY === 'Max') {\n            offsetTop = offset;\n          }\n        }\n        if (pAR.meetOrSlice === 'slice') {\n          scaleX = scaleY = fabric.util.findScaleToCover(this._element, parsedAttributes);\n          offset = rWidth - pWidth / scaleX;\n          if (pAR.alignX === 'Mid') {\n            cropX = offset / 2;\n          }\n          if (pAR.alignX === 'Max') {\n            cropX = offset;\n          }\n          offset = rHeight - pHeight / scaleY;\n          if (pAR.alignY === 'Mid') {\n            cropY = offset / 2;\n          }\n          if (pAR.alignY === 'Max') {\n            cropY = offset;\n          }\n          rWidth = pWidth / scaleX;\n          rHeight = pHeight / scaleY;\n        }\n      }\n      else {\n        scaleX = pWidth / rWidth;\n        scaleY = pHeight / rHeight;\n      }\n      return {\n        width: rWidth,\n        height: rHeight,\n        scaleX: scaleX,\n        scaleY: scaleY,\n        offsetLeft: offsetLeft,\n        offsetTop: offsetTop,\n        cropX: cropX,\n        cropY: cropY\n      };\n    }\n  });\n\n  /**\n   * Default CSS class name for canvas\n   * @static\n   * @type String\n   * @default\n   */\n  fabric.Image.CSS_CANVAS = 'canvas-img';\n\n  /**\n   * Alias for getSrc\n   * @static\n   */\n  fabric.Image.prototype.getSvgSrc = fabric.Image.prototype.getSrc;\n\n  /**\n   * Creates an instance of fabric.Image from its object representation\n   * @static\n   * @param {Object} object Object to create an instance from\n   * @param {Function} callback Callback to invoke when an image instance is created\n   */\n  fabric.Image.fromObject = function(_object, callback) {\n    var object = fabric.util.object.clone(_object);\n    fabric.util.loadImage(object.src, function(img, error) {\n      if (error) {\n        callback && callback(null, error);\n        return;\n      }\n      fabric.Image.prototype._initFilters.call(object, object.filters, function(filters) {\n        object.filters = filters || [];\n        fabric.Image.prototype._initFilters.call(object, [object.resizeFilter], function(resizeFilters) {\n          object.resizeFilter = resizeFilters[0];\n          fabric.util.enlivenObjects([object.clipPath], function(enlivedProps) {\n            object.clipPath = enlivedProps[0];\n            var image = new fabric.Image(img, object);\n            callback(image);\n          });\n        });\n      });\n    }, null, object.crossOrigin);\n  };\n\n  /**\n   * Creates an instance of fabric.Image from an URL string\n   * @static\n   * @param {String} url URL to create an image from\n   * @param {Function} [callback] Callback to invoke when image is created (newly created image is passed as a first argument)\n   * @param {Object} [imgOptions] Options object\n   */\n  fabric.Image.fromURL = function(url, callback, imgOptions) {\n    fabric.util.loadImage(url, function(img) {\n      callback && callback(new fabric.Image(img, imgOptions));\n    }, null, imgOptions && imgOptions.crossOrigin);\n  };\n\n  /* _FROM_SVG_START_ */\n  /**\n   * List of attribute names to account for when parsing SVG element (used by {@link fabric.Image.fromElement})\n   * @static\n   * @see {@link http://www.w3.org/TR/SVG/struct.html#ImageElement}\n   */\n  fabric.Image.ATTRIBUTE_NAMES =\n    fabric.SHARED_ATTRIBUTES.concat('x y width height preserveAspectRatio xlink:href crossOrigin'.split(' '));\n\n  /**\n   * Returns {@link fabric.Image} instance from an SVG element\n   * @static\n   * @param {SVGElement} element Element to parse\n   * @param {Object} [options] Options object\n   * @param {Function} callback Callback to execute when fabric.Image object is created\n   * @return {fabric.Image} Instance of fabric.Image\n   */\n  fabric.Image.fromElement = function(element, callback, options) {\n    var parsedAttributes = fabric.parseAttributes(element, fabric.Image.ATTRIBUTE_NAMES);\n    fabric.Image.fromURL(parsedAttributes['xlink:href'], callback,\n      extend((options ? fabric.util.object.clone(options) : { }), parsedAttributes));\n  };\n  /* _FROM_SVG_END_ */\n\n})(typeof exports !== 'undefined' ? exports : this);\n\n\nfabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prototype */ {\n\n  /**\n   * @private\n   * @return {Number} angle value\n   */\n  _getAngleValueForStraighten: function() {\n    var angle = this.angle % 360;\n    if (angle > 0) {\n      return Math.round((angle - 1) / 90) * 90;\n    }\n    return Math.round(angle / 90) * 90;\n  },\n\n  /**\n   * Straightens an object (rotating it from current angle to one of 0, 90, 180, 270, etc. depending on which is closer)\n   * @return {fabric.Object} thisArg\n   * @chainable\n   */\n  straighten: function() {\n    this.rotate(this._getAngleValueForStraighten());\n    return this;\n  },\n\n  /**\n   * Same as {@link fabric.Object.prototype.straighten} but with animation\n   * @param {Object} callbacks Object with callback functions\n   * @param {Function} [callbacks.onComplete] Invoked on completion\n   * @param {Function} [callbacks.onChange] Invoked on every step of animation\n   * @return {fabric.Object} thisArg\n   * @chainable\n   */\n  fxStraighten: function(callbacks) {\n    callbacks = callbacks || { };\n\n    var empty = function() { },\n        onComplete = callbacks.onComplete || empty,\n        onChange = callbacks.onChange || empty,\n        _this = this;\n\n    fabric.util.animate({\n      startValue: this.get('angle'),\n      endValue: this._getAngleValueForStraighten(),\n      duration: this.FX_DURATION,\n      onChange: function(value) {\n        _this.rotate(value);\n        onChange();\n      },\n      onComplete: function() {\n        _this.setCoords();\n        onComplete();\n      },\n    });\n\n    return this;\n  }\n});\n\nfabric.util.object.extend(fabric.StaticCanvas.prototype, /** @lends fabric.StaticCanvas.prototype */ {\n\n  /**\n   * Straightens object, then rerenders canvas\n   * @param {fabric.Object} object Object to straighten\n   * @return {fabric.Canvas} thisArg\n   * @chainable\n   */\n  straightenObject: function (object) {\n    object.straighten();\n    this.requestRenderAll();\n    return this;\n  },\n\n  /**\n   * Same as {@link fabric.Canvas.prototype.straightenObject}, but animated\n   * @param {fabric.Object} object Object to straighten\n   * @return {fabric.Canvas} thisArg\n   * @chainable\n   */\n  fxStraightenObject: function (object) {\n    object.fxStraighten({\n      onChange: this.requestRenderAllBound\n    });\n    return this;\n  }\n});\n\n\n(function() {\n\n  'use strict';\n\n  /**\n   * Tests if webgl supports certain precision\n   * @param {WebGL} Canvas WebGL context to test on\n   * @param {String} Precision to test can be any of following: 'lowp', 'mediump', 'highp'\n   * @returns {Boolean} Whether the user's browser WebGL supports given precision.\n   */\n  function testPrecision(gl, precision){\n    var fragmentSource = 'precision ' + precision + ' float;\\nvoid main(){}';\n    var fragmentShader = gl.createShader(gl.FRAGMENT_SHADER);\n    gl.shaderSource(fragmentShader, fragmentSource);\n    gl.compileShader(fragmentShader);\n    if (!gl.getShaderParameter(fragmentShader, gl.COMPILE_STATUS)) {\n      return false;\n    }\n    return true;\n  }\n\n  /**\n   * Indicate whether this filtering backend is supported by the user's browser.\n   * @param {Number} tileSize check if the tileSize is supported\n   * @returns {Boolean} Whether the user's browser supports WebGL.\n   */\n  fabric.isWebglSupported = function(tileSize) {\n    if (fabric.isLikelyNode) {\n      return false;\n    }\n    tileSize = tileSize || fabric.WebglFilterBackend.prototype.tileSize;\n    var canvas = document.createElement('canvas');\n    var gl = canvas.getContext('webgl') || canvas.getContext('experimental-webgl');\n    var isSupported = false;\n    // eslint-disable-next-line\n    if (gl) {\n      fabric.maxTextureSize = gl.getParameter(gl.MAX_TEXTURE_SIZE);\n      isSupported = fabric.maxTextureSize >= tileSize;\n      var precisions = ['highp', 'mediump', 'lowp'];\n      for (var i = 0; i < 3; i++){\n        if (testPrecision(gl, precisions[i])){\n          fabric.webGlPrecision = precisions[i];\n          break;\n        };\n      }\n    }\n    this.isSupported = isSupported;\n    return isSupported;\n  };\n\n  fabric.WebglFilterBackend = WebglFilterBackend;\n\n  /**\n   * WebGL filter backend.\n   */\n  function WebglFilterBackend(options) {\n    if (options && options.tileSize) {\n      this.tileSize = options.tileSize;\n    }\n    this.setupGLContext(this.tileSize, this.tileSize);\n    this.captureGPUInfo();\n  };\n\n  WebglFilterBackend.prototype = /** @lends fabric.WebglFilterBackend.prototype */ {\n\n    tileSize: 2048,\n\n    /**\n     * Experimental. This object is a sort of repository of help layers used to avoid\n     * of recreating them during frequent filtering. If you are previewing a filter with\n     * a slider you problably do not want to create help layers every filter step.\n     * in this object there will be appended some canvases, created once, resized sometimes\n     * cleared never. Clearing is left to the developer.\n     **/\n    resources: {\n\n    },\n\n    /**\n     * Setup a WebGL context suitable for filtering, and bind any needed event handlers.\n     */\n    setupGLContext: function(width, height) {\n      this.dispose();\n      this.createWebGLCanvas(width, height);\n      // eslint-disable-next-line\n      this.aPosition = new Float32Array([0, 0, 0, 1, 1, 0, 1, 1]);\n      this.chooseFastestCopyGLTo2DMethod(width, height);\n    },\n\n    /**\n     * Pick a method to copy data from GL context to 2d canvas.  In some browsers using\n     * putImageData is faster than drawImage for that specific operation.\n     */\n    chooseFastestCopyGLTo2DMethod: function(width, height) {\n      var canMeasurePerf = typeof window.performance !== 'undefined', canUseImageData;\n      try {\n        new ImageData(1, 1);\n        canUseImageData = true;\n      }\n      catch (e) {\n        canUseImageData = false;\n      }\n      // eslint-disable-next-line no-undef\n      var canUseArrayBuffer = typeof ArrayBuffer !== 'undefined';\n      // eslint-disable-next-line no-undef\n      var canUseUint8Clamped = typeof Uint8ClampedArray !== 'undefined';\n\n      if (!(canMeasurePerf && canUseImageData && canUseArrayBuffer && canUseUint8Clamped)) {\n        return;\n      }\n\n      var targetCanvas = fabric.util.createCanvasElement();\n      // eslint-disable-next-line no-undef\n      var imageBuffer = new ArrayBuffer(width * height * 4);\n      if (fabric.forceGLPutImageData) {\n        this.imageBuffer = imageBuffer;\n        this.copyGLTo2D = copyGLTo2DPutImageData;\n        return;\n      }\n      var testContext = {\n        imageBuffer: imageBuffer,\n        destinationWidth: width,\n        destinationHeight: height,\n        targetCanvas: targetCanvas\n      };\n      var startTime, drawImageTime, putImageDataTime;\n      targetCanvas.width = width;\n      targetCanvas.height = height;\n\n      startTime = window.performance.now();\n      copyGLTo2DDrawImage.call(testContext, this.gl, testContext);\n      drawImageTime = window.performance.now() - startTime;\n\n      startTime = window.performance.now();\n      copyGLTo2DPutImageData.call(testContext, this.gl, testContext);\n      putImageDataTime = window.performance.now() - startTime;\n\n      if (drawImageTime > putImageDataTime) {\n        this.imageBuffer = imageBuffer;\n        this.copyGLTo2D = copyGLTo2DPutImageData;\n      }\n      else {\n        this.copyGLTo2D = copyGLTo2DDrawImage;\n      }\n    },\n\n    /**\n     * Create a canvas element and associated WebGL context and attaches them as\n     * class properties to the GLFilterBackend class.\n     */\n    createWebGLCanvas: function(width, height) {\n      var canvas = fabric.util.createCanvasElement();\n      canvas.width = width;\n      canvas.height = height;\n      var glOptions = {\n            alpha: true,\n            premultipliedAlpha: false,\n            depth: false,\n            stencil: false,\n            antialias: false\n          },\n          gl = canvas.getContext('webgl', glOptions);\n      if (!gl) {\n        gl = canvas.getContext('experimental-webgl', glOptions);\n      }\n      if (!gl) {\n        return;\n      }\n      gl.clearColor(0, 0, 0, 0);\n      // this canvas can fire webglcontextlost and webglcontextrestored\n      this.canvas = canvas;\n      this.gl = gl;\n    },\n\n    /**\n     * Attempts to apply the requested filters to the source provided, drawing the filtered output\n     * to the provided target canvas.\n     *\n     * @param {Array} filters The filters to apply.\n     * @param {HTMLImageElement|HTMLCanvasElement} source The source to be filtered.\n     * @param {Number} width The width of the source input.\n     * @param {Number} height The height of the source input.\n     * @param {HTMLCanvasElement} targetCanvas The destination for filtered output to be drawn.\n     * @param {String|undefined} cacheKey A key used to cache resources related to the source. If\n     * omitted, caching will be skipped.\n     */\n    applyFilters: function(filters, source, width, height, targetCanvas, cacheKey) {\n      var gl = this.gl;\n      var cachedTexture;\n      if (cacheKey) {\n        cachedTexture = this.getCachedTexture(cacheKey, source);\n      }\n      var pipelineState = {\n        originalWidth: source.width || source.originalWidth,\n        originalHeight: source.height || source.originalHeight,\n        sourceWidth: width,\n        sourceHeight: height,\n        destinationWidth: width,\n        destinationHeight: height,\n        context: gl,\n        sourceTexture: this.createTexture(gl, width, height, !cachedTexture && source),\n        targetTexture: this.createTexture(gl, width, height),\n        originalTexture: cachedTexture ||\n          this.createTexture(gl, width, height, !cachedTexture && source),\n        passes: filters.length,\n        webgl: true,\n        aPosition: this.aPosition,\n        programCache: this.programCache,\n        pass: 0,\n        filterBackend: this,\n        targetCanvas: targetCanvas\n      };\n      var tempFbo = gl.createFramebuffer();\n      gl.bindFramebuffer(gl.FRAMEBUFFER, tempFbo);\n      filters.forEach(function(filter) { filter && filter.applyTo(pipelineState); });\n      resizeCanvasIfNeeded(pipelineState);\n      this.copyGLTo2D(gl, pipelineState);\n      gl.bindTexture(gl.TEXTURE_2D, null);\n      gl.deleteTexture(pipelineState.sourceTexture);\n      gl.deleteTexture(pipelineState.targetTexture);\n      gl.deleteFramebuffer(tempFbo);\n      targetCanvas.getContext('2d').setTransform(1, 0, 0, 1, 0, 0);\n      return pipelineState;\n    },\n\n    /**\n     * Detach event listeners, remove references, and clean up caches.\n     */\n    dispose: function() {\n      if (this.canvas) {\n        this.canvas = null;\n        this.gl = null;\n      }\n      this.clearWebGLCaches();\n    },\n\n    /**\n     * Wipe out WebGL-related caches.\n     */\n    clearWebGLCaches: function() {\n      this.programCache = {};\n      this.textureCache = {};\n    },\n\n    /**\n     * Create a WebGL texture object.\n     *\n     * Accepts specific dimensions to initialize the textuer to or a source image.\n     *\n     * @param {WebGLRenderingContext} gl The GL context to use for creating the texture.\n     * @param {Number} width The width to initialize the texture at.\n     * @param {Number} height The height to initialize the texture.\n     * @param {HTMLImageElement|HTMLCanvasElement} textureImageSource A source for the texture data.\n     * @returns {WebGLTexture}\n     */\n    createTexture: function(gl, width, height, textureImageSource) {\n      var texture = gl.createTexture();\n      gl.bindTexture(gl.TEXTURE_2D, texture);\n      gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);\n      gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);\n      gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);\n      gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);\n      if (textureImageSource) {\n        gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, textureImageSource);\n      }\n      else {\n        gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, width, height, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);\n      }\n      return texture;\n    },\n\n    /**\n     * Can be optionally used to get a texture from the cache array\n     *\n     * If an existing texture is not found, a new texture is created and cached.\n     *\n     * @param {String} uniqueId A cache key to use to find an existing texture.\n     * @param {HTMLImageElement|HTMLCanvasElement} textureImageSource A source to use to create the\n     * texture cache entry if one does not already exist.\n     */\n    getCachedTexture: function(uniqueId, textureImageSource) {\n      if (this.textureCache[uniqueId]) {\n        return this.textureCache[uniqueId];\n      }\n      else {\n        var texture = this.createTexture(\n          this.gl, textureImageSource.width, textureImageSource.height, textureImageSource);\n        this.textureCache[uniqueId] = texture;\n        return texture;\n      }\n    },\n\n    /**\n     * Clear out cached resources related to a source image that has been\n     * filtered previously.\n     *\n     * @param {String} cacheKey The cache key provided when the source image was filtered.\n     */\n    evictCachesForKey: function(cacheKey) {\n      if (this.textureCache[cacheKey]) {\n        this.gl.deleteTexture(this.textureCache[cacheKey]);\n        delete this.textureCache[cacheKey];\n      }\n    },\n\n    copyGLTo2D: copyGLTo2DDrawImage,\n\n    /**\n     * Attempt to extract GPU information strings from a WebGL context.\n     *\n     * Useful information when debugging or blacklisting specific GPUs.\n     *\n     * @returns {Object} A GPU info object with renderer and vendor strings.\n     */\n    captureGPUInfo: function() {\n      if (this.gpuInfo) {\n        return this.gpuInfo;\n      }\n      var gl = this.gl, gpuInfo = { renderer: '', vendor: '' };\n      if (!gl) {\n        return gpuInfo;\n      }\n      var ext = gl.getExtension('WEBGL_debug_renderer_info');\n      if (ext) {\n        var renderer = gl.getParameter(ext.UNMASKED_RENDERER_WEBGL);\n        var vendor = gl.getParameter(ext.UNMASKED_VENDOR_WEBGL);\n        if (renderer) {\n          gpuInfo.renderer = renderer.toLowerCase();\n        }\n        if (vendor) {\n          gpuInfo.vendor = vendor.toLowerCase();\n        }\n      }\n      this.gpuInfo = gpuInfo;\n      return gpuInfo;\n    },\n  };\n})();\n\nfunction resizeCanvasIfNeeded(pipelineState) {\n  var targetCanvas = pipelineState.targetCanvas,\n      width = targetCanvas.width, height = targetCanvas.height,\n      dWidth = pipelineState.destinationWidth,\n      dHeight = pipelineState.destinationHeight;\n\n  if (width !== dWidth || height !== dHeight) {\n    targetCanvas.width = dWidth;\n    targetCanvas.height = dHeight;\n  }\n}\n\n/**\n * Copy an input WebGL canvas on to an output 2D canvas.\n *\n * The WebGL canvas is assumed to be upside down, with the top-left pixel of the\n * desired output image appearing in the bottom-left corner of the WebGL canvas.\n *\n * @param {WebGLRenderingContext} sourceContext The WebGL context to copy from.\n * @param {HTMLCanvasElement} targetCanvas The 2D target canvas to copy on to.\n * @param {Object} pipelineState The 2D target canvas to copy on to.\n */\nfunction copyGLTo2DDrawImage(gl, pipelineState) {\n  var glCanvas = gl.canvas, targetCanvas = pipelineState.targetCanvas,\n      ctx = targetCanvas.getContext('2d');\n  ctx.translate(0, targetCanvas.height); // move it down again\n  ctx.scale(1, -1); // vertical flip\n  // where is my image on the big glcanvas?\n  var sourceY = glCanvas.height - targetCanvas.height;\n  ctx.drawImage(glCanvas, 0, sourceY, targetCanvas.width, targetCanvas.height, 0, 0,\n    targetCanvas.width, targetCanvas.height);\n}\n\n/**\n * Copy an input WebGL canvas on to an output 2D canvas using 2d canvas' putImageData\n * API. Measurably faster than using ctx.drawImage in Firefox (version 54 on OSX Sierra).\n *\n * @param {WebGLRenderingContext} sourceContext The WebGL context to copy from.\n * @param {HTMLCanvasElement} targetCanvas The 2D target canvas to copy on to.\n * @param {Object} pipelineState The 2D target canvas to copy on to.\n */\nfunction copyGLTo2DPutImageData(gl, pipelineState) {\n  var targetCanvas = pipelineState.targetCanvas, ctx = targetCanvas.getContext('2d'),\n      dWidth = pipelineState.destinationWidth,\n      dHeight = pipelineState.destinationHeight,\n      numBytes = dWidth * dHeight * 4;\n\n  // eslint-disable-next-line no-undef\n  var u8 = new Uint8Array(this.imageBuffer, 0, numBytes);\n  // eslint-disable-next-line no-undef\n  var u8Clamped = new Uint8ClampedArray(this.imageBuffer, 0, numBytes);\n\n  gl.readPixels(0, 0, dWidth, dHeight, gl.RGBA, gl.UNSIGNED_BYTE, u8);\n  var imgData = new ImageData(u8Clamped, dWidth, dHeight);\n  ctx.putImageData(imgData, 0, 0);\n}\n\n\n(function() {\n\n  'use strict';\n\n  var noop = function() {};\n\n  fabric.Canvas2dFilterBackend = Canvas2dFilterBackend;\n\n  /**\n   * Canvas 2D filter backend.\n   */\n  function Canvas2dFilterBackend() {};\n\n  Canvas2dFilterBackend.prototype = /** @lends fabric.Canvas2dFilterBackend.prototype */ {\n    evictCachesForKey: noop,\n    dispose: noop,\n    clearWebGLCaches: noop,\n\n    /**\n     * Experimental. This object is a sort of repository of help layers used to avoid\n     * of recreating them during frequent filtering. If you are previewing a filter with\n     * a slider you probably do not want to create help layers every filter step.\n     * in this object there will be appended some canvases, created once, resized sometimes\n     * cleared never. Clearing is left to the developer.\n     **/\n    resources: {\n\n    },\n\n    /**\n     * Apply a set of filters against a source image and draw the filtered output\n     * to the provided destination canvas.\n     *\n     * @param {EnhancedFilter} filters The filter to apply.\n     * @param {HTMLImageElement|HTMLCanvasElement} sourceElement The source to be filtered.\n     * @param {Number} sourceWidth The width of the source input.\n     * @param {Number} sourceHeight The height of the source input.\n     * @param {HTMLCanvasElement} targetCanvas The destination for filtered output to be drawn.\n     */\n    applyFilters: function(filters, sourceElement, sourceWidth, sourceHeight, targetCanvas) {\n      var ctx = targetCanvas.getContext('2d');\n      ctx.drawImage(sourceElement, 0, 0, sourceWidth, sourceHeight);\n      var imageData = ctx.getImageData(0, 0, sourceWidth, sourceHeight);\n      var originalImageData = ctx.getImageData(0, 0, sourceWidth, sourceHeight);\n      var pipelineState = {\n        sourceWidth: sourceWidth,\n        sourceHeight: sourceHeight,\n        imageData: imageData,\n        originalEl: sourceElement,\n        originalImageData: originalImageData,\n        canvasEl: targetCanvas,\n        ctx: ctx,\n        filterBackend: this,\n      };\n      filters.forEach(function(filter) { filter.applyTo(pipelineState); });\n      if (pipelineState.imageData.width !== sourceWidth || pipelineState.imageData.height !== sourceHeight) {\n        targetCanvas.width = pipelineState.imageData.width;\n        targetCanvas.height = pipelineState.imageData.height;\n      }\n      ctx.putImageData(pipelineState.imageData, 0, 0);\n      return pipelineState;\n    },\n\n  };\n})();\n\n\n/**\n * @namespace fabric.Image.filters\n * @memberOf fabric.Image\n * @tutorial {@link http://fabricjs.com/fabric-intro-part-2#image_filters}\n * @see {@link http://fabricjs.com/image-filters|ImageFilters demo}\n */\nfabric.Image = fabric.Image || { };\nfabric.Image.filters = fabric.Image.filters || { };\n\n/**\n * Root filter class from which all filter classes inherit from\n * @class fabric.Image.filters.BaseFilter\n * @memberOf fabric.Image.filters\n */\nfabric.Image.filters.BaseFilter = fabric.util.createClass(/** @lends fabric.Image.filters.BaseFilter.prototype */ {\n\n  /**\n   * Filter type\n   * @param {String} type\n   * @default\n   */\n  type: 'BaseFilter',\n\n  /**\n   * Array of attributes to send with buffers. do not modify\n   * @private\n   */\n\n  vertexSource: 'attribute vec2 aPosition;\\n' +\n    'varying vec2 vTexCoord;\\n' +\n    'void main() {\\n' +\n      'vTexCoord = aPosition;\\n' +\n      'gl_Position = vec4(aPosition * 2.0 - 1.0, 0.0, 1.0);\\n' +\n    '}',\n\n  fragmentSource: 'precision highp float;\\n' +\n    'varying vec2 vTexCoord;\\n' +\n    'uniform sampler2D uTexture;\\n' +\n    'void main() {\\n' +\n      'gl_FragColor = texture2D(uTexture, vTexCoord);\\n' +\n    '}',\n\n  /**\n   * Constructor\n   * @param {Object} [options] Options object\n   */\n  initialize: function(options) {\n    if (options) {\n      this.setOptions(options);\n    }\n  },\n\n  /**\n   * Sets filter's properties from options\n   * @param {Object} [options] Options object\n   */\n  setOptions: function(options) {\n    for (var prop in options) {\n      this[prop] = options[prop];\n    }\n  },\n\n  /**\n   * Compile this filter's shader program.\n   *\n   * @param {WebGLRenderingContext} gl The GL canvas context to use for shader compilation.\n   * @param {String} fragmentSource fragmentShader source for compilation\n   * @param {String} vertexSource vertexShader source for compilation\n   */\n  createProgram: function(gl, fragmentSource, vertexSource) {\n    fragmentSource = fragmentSource || this.fragmentSource;\n    vertexSource = vertexSource || this.vertexSource;\n    if (fabric.webGlPrecision !== 'highp'){\n      fragmentSource = fragmentSource.replace(\n        /precision highp float/g,\n        'precision ' + fabric.webGlPrecision + ' float'\n      );\n    }\n    var vertexShader = gl.createShader(gl.VERTEX_SHADER);\n    gl.shaderSource(vertexShader, vertexSource);\n    gl.compileShader(vertexShader);\n    if (!gl.getShaderParameter(vertexShader, gl.COMPILE_STATUS)) {\n      throw new Error(\n        // eslint-disable-next-line prefer-template\n        'Vertex shader compile error for ' + this.type + ': ' +\n        gl.getShaderInfoLog(vertexShader)\n      );\n    }\n\n    var fragmentShader = gl.createShader(gl.FRAGMENT_SHADER);\n    gl.shaderSource(fragmentShader, fragmentSource);\n    gl.compileShader(fragmentShader);\n    if (!gl.getShaderParameter(fragmentShader, gl.COMPILE_STATUS)) {\n      throw new Error(\n        // eslint-disable-next-line prefer-template\n        'Fragment shader compile error for ' + this.type + ': ' +\n        gl.getShaderInfoLog(fragmentShader)\n      );\n    }\n\n    var program = gl.createProgram();\n    gl.attachShader(program, vertexShader);\n    gl.attachShader(program, fragmentShader);\n    gl.linkProgram(program);\n    if (!gl.getProgramParameter(program, gl.LINK_STATUS)) {\n      throw new Error(\n        // eslint-disable-next-line prefer-template\n        'Shader link error for \"${this.type}\" ' +\n        gl.getProgramInfoLog(program)\n      );\n    }\n\n    var attributeLocations = this.getAttributeLocations(gl, program);\n    var uniformLocations = this.getUniformLocations(gl, program) || { };\n    uniformLocations.uStepW = gl.getUniformLocation(program, 'uStepW');\n    uniformLocations.uStepH = gl.getUniformLocation(program, 'uStepH');\n    return {\n      program: program,\n      attributeLocations: attributeLocations,\n      uniformLocations: uniformLocations\n    };\n  },\n\n  /**\n   * Return a map of attribute names to WebGLAttributeLocation objects.\n   *\n   * @param {WebGLRenderingContext} gl The canvas context used to compile the shader program.\n   * @param {WebGLShaderProgram} program The shader program from which to take attribute locations.\n   * @returns {Object} A map of attribute names to attribute locations.\n   */\n  getAttributeLocations: function(gl, program) {\n    return {\n      aPosition: gl.getAttribLocation(program, 'aPosition'),\n    };\n  },\n\n  /**\n   * Return a map of uniform names to WebGLUniformLocation objects.\n   *\n   * Intended to be overridden by subclasses.\n   *\n   * @param {WebGLRenderingContext} gl The canvas context used to compile the shader program.\n   * @param {WebGLShaderProgram} program The shader program from which to take uniform locations.\n   * @returns {Object} A map of uniform names to uniform locations.\n   */\n  getUniformLocations: function (/* gl, program */) {\n    // in case i do not need any special uniform i need to return an empty object\n    return { };\n  },\n\n  /**\n   * Send attribute data from this filter to its shader program on the GPU.\n   *\n   * @param {WebGLRenderingContext} gl The canvas context used to compile the shader program.\n   * @param {Object} attributeLocations A map of shader attribute names to their locations.\n   */\n  sendAttributeData: function(gl, attributeLocations, aPositionData) {\n    var attributeLocation = attributeLocations.aPosition;\n    var buffer = gl.createBuffer();\n    gl.bindBuffer(gl.ARRAY_BUFFER, buffer);\n    gl.enableVertexAttribArray(attributeLocation);\n    gl.vertexAttribPointer(attributeLocation, 2, gl.FLOAT, false, 0, 0);\n    gl.bufferData(gl.ARRAY_BUFFER, aPositionData, gl.STATIC_DRAW);\n  },\n\n  _setupFrameBuffer: function(options) {\n    var gl = options.context, width, height;\n    if (options.passes > 1) {\n      width = options.destinationWidth;\n      height = options.destinationHeight;\n      if (options.sourceWidth !== width || options.sourceHeight !== height) {\n        gl.deleteTexture(options.targetTexture);\n        options.targetTexture = options.filterBackend.createTexture(gl, width, height);\n      }\n      gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D,\n        options.targetTexture, 0);\n    }\n    else {\n      // draw last filter on canvas and not to framebuffer.\n      gl.bindFramebuffer(gl.FRAMEBUFFER, null);\n      gl.finish();\n    }\n  },\n\n  _swapTextures: function(options) {\n    options.passes--;\n    options.pass++;\n    var temp = options.targetTexture;\n    options.targetTexture = options.sourceTexture;\n    options.sourceTexture = temp;\n  },\n\n  /**\n   * Generic isNeutral implementation for one parameter based filters.\n   * Used only in image applyFilters to discard filters that will not have an effect\n   * on the image\n   * Other filters may need their own verison ( ColorMatrix, HueRotation, gamma, ComposedFilter )\n   * @param {Object} options\n   **/\n  isNeutralState: function(/* options */) {\n    var main = this.mainParameter,\n        _class = fabric.Image.filters[this.type].prototype;\n    if (main) {\n      if (Array.isArray(_class[main])) {\n        for (var i = _class[main].length; i--;) {\n          if (this[main][i] !== _class[main][i]) {\n            return false;\n          }\n        }\n        return true;\n      }\n      else {\n        return _class[main] === this[main];\n      }\n    }\n    else {\n      return false;\n    }\n  },\n\n  /**\n   * Apply this filter to the input image data provided.\n   *\n   * Determines whether to use WebGL or Canvas2D based on the options.webgl flag.\n   *\n   * @param {Object} options\n   * @param {Number} options.passes The number of filters remaining to be executed\n   * @param {Boolean} options.webgl Whether to use webgl to render the filter.\n   * @param {WebGLTexture} options.sourceTexture The texture setup as the source to be filtered.\n   * @param {WebGLTexture} options.targetTexture The texture where filtered output should be drawn.\n   * @param {WebGLRenderingContext} options.context The GL context used for rendering.\n   * @param {Object} options.programCache A map of compiled shader programs, keyed by filter type.\n   */\n  applyTo: function(options) {\n    if (options.webgl) {\n      this._setupFrameBuffer(options);\n      this.applyToWebGL(options);\n      this._swapTextures(options);\n    }\n    else {\n      this.applyTo2d(options);\n    }\n  },\n\n  /**\n   * Retrieves the cached shader.\n   * @param {Object} options\n   * @param {WebGLRenderingContext} options.context The GL context used for rendering.\n   * @param {Object} options.programCache A map of compiled shader programs, keyed by filter type.\n   */\n  retrieveShader: function(options) {\n    if (!options.programCache.hasOwnProperty(this.type)) {\n      options.programCache[this.type] = this.createProgram(options.context);\n    }\n    return options.programCache[this.type];\n  },\n\n  /**\n   * Apply this filter using webgl.\n   *\n   * @param {Object} options\n   * @param {Number} options.passes The number of filters remaining to be executed\n   * @param {Boolean} options.webgl Whether to use webgl to render the filter.\n   * @param {WebGLTexture} options.originalTexture The texture of the original input image.\n   * @param {WebGLTexture} options.sourceTexture The texture setup as the source to be filtered.\n   * @param {WebGLTexture} options.targetTexture The texture where filtered output should be drawn.\n   * @param {WebGLRenderingContext} options.context The GL context used for rendering.\n   * @param {Object} options.programCache A map of compiled shader programs, keyed by filter type.\n   */\n  applyToWebGL: function(options) {\n    var gl = options.context;\n    var shader = this.retrieveShader(options);\n    if (options.pass === 0 && options.originalTexture) {\n      gl.bindTexture(gl.TEXTURE_2D, options.originalTexture);\n    }\n    else {\n      gl.bindTexture(gl.TEXTURE_2D, options.sourceTexture);\n    }\n    gl.useProgram(shader.program);\n    this.sendAttributeData(gl, shader.attributeLocations, options.aPosition);\n\n    gl.uniform1f(shader.uniformLocations.uStepW, 1 / options.sourceWidth);\n    gl.uniform1f(shader.uniformLocations.uStepH, 1 / options.sourceHeight);\n\n    this.sendUniformData(gl, shader.uniformLocations);\n    gl.viewport(0, 0, options.destinationWidth, options.destinationHeight);\n    gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4);\n  },\n\n  bindAdditionalTexture: function(gl, texture, textureUnit) {\n    gl.activeTexture(textureUnit);\n    gl.bindTexture(gl.TEXTURE_2D, texture);\n    // reset active texture to 0 as usual\n    gl.activeTexture(gl.TEXTURE0);\n  },\n\n  unbindAdditionalTexture: function(gl, textureUnit) {\n    gl.activeTexture(textureUnit);\n    gl.bindTexture(gl.TEXTURE_2D, null);\n    gl.activeTexture(gl.TEXTURE0);\n  },\n\n  getMainParameter: function() {\n    return this[this.mainParameter];\n  },\n\n  setMainParameter: function(value) {\n    this[this.mainParameter] = value;\n  },\n\n  /**\n   * Send uniform data from this filter to its shader program on the GPU.\n   *\n   * Intended to be overridden by subclasses.\n   *\n   * @param {WebGLRenderingContext} gl The canvas context used to compile the shader program.\n   * @param {Object} uniformLocations A map of shader uniform names to their locations.\n   */\n  sendUniformData: function(/* gl, uniformLocations */) {\n    // Intentionally left blank.  Override me in subclasses.\n  },\n\n  /**\n   * If needed by a 2d filter, this functions can create an helper canvas to be used\n   * remember that options.targetCanvas is available for use till end of chain.\n   */\n  createHelpLayer: function(options) {\n    if (!options.helpLayer) {\n      var helpLayer = document.createElement('canvas');\n      helpLayer.width = options.sourceWidth;\n      helpLayer.height = options.sourceHeight;\n      options.helpLayer = helpLayer;\n    }\n  },\n\n  /**\n   * Returns object representation of an instance\n   * @return {Object} Object representation of an instance\n   */\n  toObject: function() {\n    var object = { type: this.type }, mainP = this.mainParameter;\n    if (mainP) {\n      object[mainP] = this[mainP];\n    }\n    return object;\n  },\n\n  /**\n   * Returns a JSON representation of an instance\n   * @return {Object} JSON\n   */\n  toJSON: function() {\n    // delegate, not alias\n    return this.toObject();\n  }\n});\n\nfabric.Image.filters.BaseFilter.fromObject = function(object, callback) {\n  var filter = new fabric.Image.filters[object.type](object);\n  callback && callback(filter);\n  return filter;\n};\n\n\n(function(global) {\n\n  'use strict';\n\n  var fabric  = global.fabric || (global.fabric = { }),\n      filters = fabric.Image.filters,\n      createClass = fabric.util.createClass;\n\n  /**\n   * Color Matrix filter class\n   * @class fabric.Image.filters.ColorMatrix\n   * @memberOf fabric.Image.filters\n   * @extends fabric.Image.filters.BaseFilter\n   * @see {@link fabric.Image.filters.ColorMatrix#initialize} for constructor definition\n   * @see {@link http://fabricjs.com/image-filters|ImageFilters demo}\n   * @see {@Link http://www.webwasp.co.uk/tutorials/219/Color_Matrix_Filter.php}\n   * @see {@Link http://phoboslab.org/log/2013/11/fast-image-filters-with-webgl}\n   * @example <caption>Kodachrome filter</caption>\n   * var filter = new fabric.Image.filters.ColorMatrix({\n   *  matrix: [\n       1.1285582396593525, -0.3967382283601348, -0.03992559172921793, 0, 63.72958762196502,\n       -0.16404339962244616, 1.0835251566291304, -0.05498805115633132, 0, 24.732407896706203,\n       -0.16786010706155763, -0.5603416277695248, 1.6014850761964943, 0, 35.62982807460946,\n       0, 0, 0, 1, 0\n      ]\n   * });\n   * object.filters.push(filter);\n   * object.applyFilters();\n   */\n  filters.ColorMatrix = createClass(filters.BaseFilter, /** @lends fabric.Image.filters.ColorMatrix.prototype */ {\n\n    /**\n     * Filter type\n     * @param {String} type\n     * @default\n     */\n    type: 'ColorMatrix',\n\n    fragmentSource: 'precision highp float;\\n' +\n      'uniform sampler2D uTexture;\\n' +\n      'varying vec2 vTexCoord;\\n' +\n      'uniform mat4 uColorMatrix;\\n' +\n      'uniform vec4 uConstants;\\n' +\n      'void main() {\\n' +\n        'vec4 color = texture2D(uTexture, vTexCoord);\\n' +\n        'color *= uColorMatrix;\\n' +\n        'color += uConstants;\\n' +\n        'gl_FragColor = color;\\n' +\n      '}',\n\n    /**\n     * Colormatrix for pixels.\n     * array of 20 floats. Numbers in positions 4, 9, 14, 19 loose meaning\n     * outside the -1, 1 range.\n     * 0.0039215686 is the part of 1 that get translated to 1 in 2d\n     * @param {Array} matrix array of 20 numbers.\n     * @default\n     */\n    matrix: [\n      1, 0, 0, 0, 0,\n      0, 1, 0, 0, 0,\n      0, 0, 1, 0, 0,\n      0, 0, 0, 1, 0\n    ],\n\n    mainParameter: 'matrix',\n\n    /**\n     * Lock the colormatrix on the color part, skipping alpha, manly for non webgl scenario\n     * to save some calculation\n     */\n    colorsOnly: true,\n\n    /**\n     * Constructor\n     * @param {Object} [options] Options object\n     */\n    initialize: function(options) {\n      this.callSuper('initialize', options);\n      // create a new array instead mutating the prototype with push\n      this.matrix = this.matrix.slice(0);\n    },\n\n    /**\n     * Apply the ColorMatrix operation to a Uint8Array representing the pixels of an image.\n     *\n     * @param {Object} options\n     * @param {ImageData} options.imageData The Uint8Array to be filtered.\n     */\n    applyTo2d: function(options) {\n      var imageData = options.imageData,\n          data = imageData.data,\n          iLen = data.length,\n          m = this.matrix,\n          r, g, b, a, i, colorsOnly = this.colorsOnly;\n\n      for (i = 0; i < iLen; i += 4) {\n        r = data[i];\n        g = data[i + 1];\n        b = data[i + 2];\n        if (colorsOnly) {\n          data[i] = r * m[0] + g * m[1] + b * m[2] + m[4] * 255;\n          data[i + 1] = r * m[5] + g * m[6] + b * m[7] + m[9] * 255;\n          data[i + 2] = r * m[10] + g * m[11] + b * m[12] + m[14] * 255;\n        }\n        else {\n          a = data[i + 3];\n          data[i] = r * m[0] + g * m[1] + b * m[2] + a * m[3] + m[4] * 255;\n          data[i + 1] = r * m[5] + g * m[6] + b * m[7] + a * m[8] + m[9] * 255;\n          data[i + 2] = r * m[10] + g * m[11] + b * m[12] + a * m[13] + m[14] * 255;\n          data[i + 3] = r * m[15] + g * m[16] + b * m[17] + a * m[18] + m[19] * 255;\n        }\n      }\n    },\n\n    /**\n     * Return WebGL uniform locations for this filter's shader.\n     *\n     * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader.\n     * @param {WebGLShaderProgram} program This filter's compiled shader program.\n     */\n    getUniformLocations: function(gl, program) {\n      return {\n        uColorMatrix: gl.getUniformLocation(program, 'uColorMatrix'),\n        uConstants: gl.getUniformLocation(program, 'uConstants'),\n      };\n    },\n\n    /**\n     * Send data from this filter to its shader program's uniforms.\n     *\n     * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader.\n     * @param {Object} uniformLocations A map of string uniform names to WebGLUniformLocation objects\n     */\n    sendUniformData: function(gl, uniformLocations) {\n      var m = this.matrix,\n          matrix = [\n            m[0], m[1], m[2], m[3],\n            m[5], m[6], m[7], m[8],\n            m[10], m[11], m[12], m[13],\n            m[15], m[16], m[17], m[18]\n          ],\n          constants = [m[4], m[9], m[14], m[19]];\n      gl.uniformMatrix4fv(uniformLocations.uColorMatrix, false, matrix);\n      gl.uniform4fv(uniformLocations.uConstants, constants);\n    },\n  });\n\n  /**\n   * Returns filter instance from an object representation\n   * @static\n   * @param {Object} object Object to create an instance from\n   * @param {function} [callback] function to invoke after filter creation\n   * @return {fabric.Image.filters.ColorMatrix} Instance of fabric.Image.filters.ColorMatrix\n   */\n  fabric.Image.filters.ColorMatrix.fromObject = fabric.Image.filters.BaseFilter.fromObject;\n})(typeof exports !== 'undefined' ? exports : this);\n\n\n(function(global) {\n\n  'use strict';\n\n  var fabric  = global.fabric || (global.fabric = { }),\n      filters = fabric.Image.filters,\n      createClass = fabric.util.createClass;\n\n  /**\n   * Brightness filter class\n   * @class fabric.Image.filters.Brightness\n   * @memberOf fabric.Image.filters\n   * @extends fabric.Image.filters.BaseFilter\n   * @see {@link fabric.Image.filters.Brightness#initialize} for constructor definition\n   * @see {@link http://fabricjs.com/image-filters|ImageFilters demo}\n   * @example\n   * var filter = new fabric.Image.filters.Brightness({\n   *   brightness: 0.05\n   * });\n   * object.filters.push(filter);\n   * object.applyFilters();\n   */\n  filters.Brightness = createClass(filters.BaseFilter, /** @lends fabric.Image.filters.Brightness.prototype */ {\n\n    /**\n     * Filter type\n     * @param {String} type\n     * @default\n     */\n    type: 'Brightness',\n\n    /**\n     * Fragment source for the brightness program\n     */\n    fragmentSource: 'precision highp float;\\n' +\n      'uniform sampler2D uTexture;\\n' +\n      'uniform float uBrightness;\\n' +\n      'varying vec2 vTexCoord;\\n' +\n      'void main() {\\n' +\n        'vec4 color = texture2D(uTexture, vTexCoord);\\n' +\n        'color.rgb += uBrightness;\\n' +\n        'gl_FragColor = color;\\n' +\n      '}',\n\n    /**\n     * Brightness value, from -1 to 1.\n     * translated to -255 to 255 for 2d\n     * 0.0039215686 is the part of 1 that get translated to 1 in 2d\n     * @param {Number} brightness\n     * @default\n     */\n    brightness: 0,\n\n    /**\n     * Describe the property that is the filter parameter\n     * @param {String} m\n     * @default\n     */\n    mainParameter: 'brightness',\n\n    /**\n    * Apply the Brightness operation to a Uint8ClampedArray representing the pixels of an image.\n    *\n    * @param {Object} options\n    * @param {ImageData} options.imageData The Uint8ClampedArray to be filtered.\n    */\n    applyTo2d: function(options) {\n      if (this.brightness === 0) {\n        return;\n      }\n      var imageData = options.imageData,\n          data = imageData.data, i, len = data.length,\n          brightness = Math.round(this.brightness * 255);\n      for (i = 0; i < len; i += 4) {\n        data[i] = data[i] + brightness;\n        data[i + 1] = data[i + 1] + brightness;\n        data[i + 2] = data[i + 2] + brightness;\n      }\n    },\n\n    /**\n     * Return WebGL uniform locations for this filter's shader.\n     *\n     * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader.\n     * @param {WebGLShaderProgram} program This filter's compiled shader program.\n     */\n    getUniformLocations: function(gl, program) {\n      return {\n        uBrightness: gl.getUniformLocation(program, 'uBrightness'),\n      };\n    },\n\n    /**\n     * Send data from this filter to its shader program's uniforms.\n     *\n     * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader.\n     * @param {Object} uniformLocations A map of string uniform names to WebGLUniformLocation objects\n     */\n    sendUniformData: function(gl, uniformLocations) {\n      gl.uniform1f(uniformLocations.uBrightness, this.brightness);\n    },\n  });\n\n  /**\n   * Returns filter instance from an object representation\n   * @static\n   * @param {Object} object Object to create an instance from\n   * @param {function} [callback] to be invoked after filter creation\n   * @return {fabric.Image.filters.Brightness} Instance of fabric.Image.filters.Brightness\n   */\n  fabric.Image.filters.Brightness.fromObject = fabric.Image.filters.BaseFilter.fromObject;\n\n})(typeof exports !== 'undefined' ? exports : this);\n\n\n(function(global) {\n\n  'use strict';\n\n  var fabric  = global.fabric || (global.fabric = { }),\n      extend = fabric.util.object.extend,\n      filters = fabric.Image.filters,\n      createClass = fabric.util.createClass;\n\n  /**\n   * Adapted from <a href=\"http://www.html5rocks.com/en/tutorials/canvas/imagefilters/\">html5rocks article</a>\n   * @class fabric.Image.filters.Convolute\n   * @memberOf fabric.Image.filters\n   * @extends fabric.Image.filters.BaseFilter\n   * @see {@link fabric.Image.filters.Convolute#initialize} for constructor definition\n   * @see {@link http://fabricjs.com/image-filters|ImageFilters demo}\n   * @example <caption>Sharpen filter</caption>\n   * var filter = new fabric.Image.filters.Convolute({\n   *   matrix: [ 0, -1,  0,\n   *            -1,  5, -1,\n   *             0, -1,  0 ]\n   * });\n   * object.filters.push(filter);\n   * object.applyFilters();\n   * canvas.renderAll();\n   * @example <caption>Blur filter</caption>\n   * var filter = new fabric.Image.filters.Convolute({\n   *   matrix: [ 1/9, 1/9, 1/9,\n   *             1/9, 1/9, 1/9,\n   *             1/9, 1/9, 1/9 ]\n   * });\n   * object.filters.push(filter);\n   * object.applyFilters();\n   * canvas.renderAll();\n   * @example <caption>Emboss filter</caption>\n   * var filter = new fabric.Image.filters.Convolute({\n   *   matrix: [ 1,   1,  1,\n   *             1, 0.7, -1,\n   *            -1,  -1, -1 ]\n   * });\n   * object.filters.push(filter);\n   * object.applyFilters();\n   * canvas.renderAll();\n   * @example <caption>Emboss filter with opaqueness</caption>\n   * var filter = new fabric.Image.filters.Convolute({\n   *   opaque: true,\n   *   matrix: [ 1,   1,  1,\n   *             1, 0.7, -1,\n   *            -1,  -1, -1 ]\n   * });\n   * object.filters.push(filter);\n   * object.applyFilters();\n   * canvas.renderAll();\n   */\n  filters.Convolute = createClass(filters.BaseFilter, /** @lends fabric.Image.filters.Convolute.prototype */ {\n\n    /**\n     * Filter type\n     * @param {String} type\n     * @default\n     */\n    type: 'Convolute',\n\n    /*\n     * Opaque value (true/false)\n     */\n    opaque: false,\n\n    /*\n     * matrix for the filter, max 9x9\n     */\n    matrix: [0, 0, 0, 0, 1, 0, 0, 0, 0],\n\n    /**\n     * Fragment source for the brightness program\n     */\n    fragmentSource: {\n      Convolute_3_1: 'precision highp float;\\n' +\n        'uniform sampler2D uTexture;\\n' +\n        'uniform float uMatrix[9];\\n' +\n        'uniform float uStepW;\\n' +\n        'uniform float uStepH;\\n' +\n        'varying vec2 vTexCoord;\\n' +\n        'void main() {\\n' +\n          'vec4 color = vec4(0, 0, 0, 0);\\n' +\n          'for (float h = 0.0; h < 3.0; h+=1.0) {\\n' +\n            'for (float w = 0.0; w < 3.0; w+=1.0) {\\n' +\n              'vec2 matrixPos = vec2(uStepW * (w - 1), uStepH * (h - 1));\\n' +\n              'color += texture2D(uTexture, vTexCoord + matrixPos) * uMatrix[int(h * 3.0 + w)];\\n' +\n            '}\\n' +\n          '}\\n' +\n          'gl_FragColor = color;\\n' +\n        '}',\n      Convolute_3_0: 'precision highp float;\\n' +\n        'uniform sampler2D uTexture;\\n' +\n        'uniform float uMatrix[9];\\n' +\n        'uniform float uStepW;\\n' +\n        'uniform float uStepH;\\n' +\n        'varying vec2 vTexCoord;\\n' +\n        'void main() {\\n' +\n          'vec4 color = vec4(0, 0, 0, 1);\\n' +\n          'for (float h = 0.0; h < 3.0; h+=1.0) {\\n' +\n            'for (float w = 0.0; w < 3.0; w+=1.0) {\\n' +\n              'vec2 matrixPos = vec2(uStepW * (w - 1.0), uStepH * (h - 1.0));\\n' +\n              'color.rgb += texture2D(uTexture, vTexCoord + matrixPos).rgb * uMatrix[int(h * 3.0 + w)];\\n' +\n            '}\\n' +\n          '}\\n' +\n          'float alpha = texture2D(uTexture, vTexCoord).a;\\n' +\n          'gl_FragColor = color;\\n' +\n          'gl_FragColor.a = alpha;\\n' +\n        '}',\n      Convolute_5_1: 'precision highp float;\\n' +\n        'uniform sampler2D uTexture;\\n' +\n        'uniform float uMatrix[25];\\n' +\n        'uniform float uStepW;\\n' +\n        'uniform float uStepH;\\n' +\n        'varying vec2 vTexCoord;\\n' +\n        'void main() {\\n' +\n          'vec4 color = vec4(0, 0, 0, 0);\\n' +\n          'for (float h = 0.0; h < 5.0; h+=1.0) {\\n' +\n            'for (float w = 0.0; w < 5.0; w+=1.0) {\\n' +\n              'vec2 matrixPos = vec2(uStepW * (w - 2.0), uStepH * (h - 2.0));\\n' +\n              'color += texture2D(uTexture, vTexCoord + matrixPos) * uMatrix[int(h * 5.0 + w)];\\n' +\n            '}\\n' +\n          '}\\n' +\n          'gl_FragColor = color;\\n' +\n        '}',\n      Convolute_5_0: 'precision highp float;\\n' +\n        'uniform sampler2D uTexture;\\n' +\n        'uniform float uMatrix[25];\\n' +\n        'uniform float uStepW;\\n' +\n        'uniform float uStepH;\\n' +\n        'varying vec2 vTexCoord;\\n' +\n        'void main() {\\n' +\n          'vec4 color = vec4(0, 0, 0, 1);\\n' +\n          'for (float h = 0.0; h < 5.0; h+=1.0) {\\n' +\n            'for (float w = 0.0; w < 5.0; w+=1.0) {\\n' +\n              'vec2 matrixPos = vec2(uStepW * (w - 2.0), uStepH * (h - 2.0));\\n' +\n              'color.rgb += texture2D(uTexture, vTexCoord + matrixPos).rgb * uMatrix[int(h * 5.0 + w)];\\n' +\n            '}\\n' +\n          '}\\n' +\n          'float alpha = texture2D(uTexture, vTexCoord).a;\\n' +\n          'gl_FragColor = color;\\n' +\n          'gl_FragColor.a = alpha;\\n' +\n        '}',\n      Convolute_7_1: 'precision highp float;\\n' +\n        'uniform sampler2D uTexture;\\n' +\n        'uniform float uMatrix[49];\\n' +\n        'uniform float uStepW;\\n' +\n        'uniform float uStepH;\\n' +\n        'varying vec2 vTexCoord;\\n' +\n        'void main() {\\n' +\n          'vec4 color = vec4(0, 0, 0, 0);\\n' +\n          'for (float h = 0.0; h < 7.0; h+=1.0) {\\n' +\n            'for (float w = 0.0; w < 7.0; w+=1.0) {\\n' +\n              'vec2 matrixPos = vec2(uStepW * (w - 3.0), uStepH * (h - 3.0));\\n' +\n              'color += texture2D(uTexture, vTexCoord + matrixPos) * uMatrix[int(h * 7.0 + w)];\\n' +\n            '}\\n' +\n          '}\\n' +\n          'gl_FragColor = color;\\n' +\n        '}',\n      Convolute_7_0: 'precision highp float;\\n' +\n        'uniform sampler2D uTexture;\\n' +\n        'uniform float uMatrix[49];\\n' +\n        'uniform float uStepW;\\n' +\n        'uniform float uStepH;\\n' +\n        'varying vec2 vTexCoord;\\n' +\n        'void main() {\\n' +\n          'vec4 color = vec4(0, 0, 0, 1);\\n' +\n          'for (float h = 0.0; h < 7.0; h+=1.0) {\\n' +\n            'for (float w = 0.0; w < 7.0; w+=1.0) {\\n' +\n              'vec2 matrixPos = vec2(uStepW * (w - 3.0), uStepH * (h - 3.0));\\n' +\n              'color.rgb += texture2D(uTexture, vTexCoord + matrixPos).rgb * uMatrix[int(h * 7.0 + w)];\\n' +\n            '}\\n' +\n          '}\\n' +\n          'float alpha = texture2D(uTexture, vTexCoord).a;\\n' +\n          'gl_FragColor = color;\\n' +\n          'gl_FragColor.a = alpha;\\n' +\n        '}',\n      Convolute_9_1: 'precision highp float;\\n' +\n        'uniform sampler2D uTexture;\\n' +\n        'uniform float uMatrix[81];\\n' +\n        'uniform float uStepW;\\n' +\n        'uniform float uStepH;\\n' +\n        'varying vec2 vTexCoord;\\n' +\n        'void main() {\\n' +\n          'vec4 color = vec4(0, 0, 0, 0);\\n' +\n          'for (float h = 0.0; h < 9.0; h+=1.0) {\\n' +\n            'for (float w = 0.0; w < 9.0; w+=1.0) {\\n' +\n              'vec2 matrixPos = vec2(uStepW * (w - 4.0), uStepH * (h - 4.0));\\n' +\n              'color += texture2D(uTexture, vTexCoord + matrixPos) * uMatrix[int(h * 9.0 + w)];\\n' +\n            '}\\n' +\n          '}\\n' +\n          'gl_FragColor = color;\\n' +\n        '}',\n      Convolute_9_0: 'precision highp float;\\n' +\n        'uniform sampler2D uTexture;\\n' +\n        'uniform float uMatrix[81];\\n' +\n        'uniform float uStepW;\\n' +\n        'uniform float uStepH;\\n' +\n        'varying vec2 vTexCoord;\\n' +\n        'void main() {\\n' +\n          'vec4 color = vec4(0, 0, 0, 1);\\n' +\n          'for (float h = 0.0; h < 9.0; h+=1.0) {\\n' +\n            'for (float w = 0.0; w < 9.0; w+=1.0) {\\n' +\n              'vec2 matrixPos = vec2(uStepW * (w - 4.0), uStepH * (h - 4.0));\\n' +\n              'color.rgb += texture2D(uTexture, vTexCoord + matrixPos).rgb * uMatrix[int(h * 9.0 + w)];\\n' +\n            '}\\n' +\n          '}\\n' +\n          'float alpha = texture2D(uTexture, vTexCoord).a;\\n' +\n          'gl_FragColor = color;\\n' +\n          'gl_FragColor.a = alpha;\\n' +\n        '}',\n    },\n\n    /**\n     * Constructor\n     * @memberOf fabric.Image.filters.Convolute.prototype\n     * @param {Object} [options] Options object\n     * @param {Boolean} [options.opaque=false] Opaque value (true/false)\n     * @param {Array} [options.matrix] Filter matrix\n     */\n\n\n    /**\n    * Retrieves the cached shader.\n    * @param {Object} options\n    * @param {WebGLRenderingContext} options.context The GL context used for rendering.\n    * @param {Object} options.programCache A map of compiled shader programs, keyed by filter type.\n    */\n    retrieveShader: function(options) {\n      var size = Math.sqrt(this.matrix.length);\n      var cacheKey = this.type + '_' + size + '_' + (this.opaque ? 1 : 0);\n      var shaderSource = this.fragmentSource[cacheKey];\n      if (!options.programCache.hasOwnProperty(cacheKey)) {\n        options.programCache[cacheKey] = this.createProgram(options.context, shaderSource);\n      }\n      return options.programCache[cacheKey];\n    },\n\n    /**\n     * Apply the Brightness operation to a Uint8ClampedArray representing the pixels of an image.\n     *\n     * @param {Object} options\n     * @param {ImageData} options.imageData The Uint8ClampedArray to be filtered.\n     */\n    applyTo2d: function(options) {\n      var imageData = options.imageData,\n          data = imageData.data,\n          weights = this.matrix,\n          side = Math.round(Math.sqrt(weights.length)),\n          halfSide = Math.floor(side / 2),\n          sw = imageData.width,\n          sh = imageData.height,\n          output = options.ctx.createImageData(sw, sh),\n          dst = output.data,\n          // go through the destination image pixels\n          alphaFac = this.opaque ? 1 : 0,\n          r, g, b, a, dstOff,\n          scx, scy, srcOff, wt,\n          x, y, cx, cy;\n\n      for (y = 0; y < sh; y++) {\n        for (x = 0; x < sw; x++) {\n          dstOff = (y * sw + x) * 4;\n          // calculate the weighed sum of the source image pixels that\n          // fall under the convolution matrix\n          r = 0; g = 0; b = 0; a = 0;\n\n          for (cy = 0; cy < side; cy++) {\n            for (cx = 0; cx < side; cx++) {\n              scy = y + cy - halfSide;\n              scx = x + cx - halfSide;\n\n              // eslint-disable-next-line max-depth\n              if (scy < 0 || scy > sh || scx < 0 || scx > sw) {\n                continue;\n              }\n\n              srcOff = (scy * sw + scx) * 4;\n              wt = weights[cy * side + cx];\n\n              r += data[srcOff] * wt;\n              g += data[srcOff + 1] * wt;\n              b += data[srcOff + 2] * wt;\n              // eslint-disable-next-line max-depth\n              if (!alphaFac) {\n                a += data[srcOff + 3] * wt;\n              }\n            }\n          }\n          dst[dstOff] = r;\n          dst[dstOff + 1] = g;\n          dst[dstOff + 2] = b;\n          if (!alphaFac) {\n            dst[dstOff + 3] = a;\n          }\n          else {\n            dst[dstOff + 3] = data[dstOff + 3];\n          }\n        }\n      }\n      options.imageData = output;\n    },\n\n    /**\n     * Return WebGL uniform locations for this filter's shader.\n     *\n     * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader.\n     * @param {WebGLShaderProgram} program This filter's compiled shader program.\n     */\n    getUniformLocations: function(gl, program) {\n      return {\n        uMatrix: gl.getUniformLocation(program, 'uMatrix'),\n        uOpaque: gl.getUniformLocation(program, 'uOpaque'),\n        uHalfSize: gl.getUniformLocation(program, 'uHalfSize'),\n        uSize: gl.getUniformLocation(program, 'uSize'),\n      };\n    },\n\n    /**\n     * Send data from this filter to its shader program's uniforms.\n     *\n     * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader.\n     * @param {Object} uniformLocations A map of string uniform names to WebGLUniformLocation objects\n     */\n    sendUniformData: function(gl, uniformLocations) {\n      gl.uniform1fv(uniformLocations.uMatrix, this.matrix);\n    },\n\n    /**\n     * Returns object representation of an instance\n     * @return {Object} Object representation of an instance\n     */\n    toObject: function() {\n      return extend(this.callSuper('toObject'), {\n        opaque: this.opaque,\n        matrix: this.matrix\n      });\n    }\n  });\n\n  /**\n   * Returns filter instance from an object representation\n   * @static\n   * @param {Object} object Object to create an instance from\n   * @param {function} [callback] to be invoked after filter creation\n   * @return {fabric.Image.filters.Convolute} Instance of fabric.Image.filters.Convolute\n   */\n  fabric.Image.filters.Convolute.fromObject = fabric.Image.filters.BaseFilter.fromObject;\n\n})(typeof exports !== 'undefined' ? exports : this);\n\n\n(function(global) {\n\n  'use strict';\n\n  var fabric  = global.fabric || (global.fabric = { }),\n      filters = fabric.Image.filters,\n      createClass = fabric.util.createClass;\n\n  /**\n   * Grayscale image filter class\n   * @class fabric.Image.filters.Grayscale\n   * @memberOf fabric.Image.filters\n   * @extends fabric.Image.filters.BaseFilter\n   * @see {@link http://fabricjs.com/image-filters|ImageFilters demo}\n   * @example\n   * var filter = new fabric.Image.filters.Grayscale();\n   * object.filters.push(filter);\n   * object.applyFilters();\n   */\n  filters.Grayscale = createClass(filters.BaseFilter, /** @lends fabric.Image.filters.Grayscale.prototype */ {\n\n    /**\n     * Filter type\n     * @param {String} type\n     * @default\n     */\n    type: 'Grayscale',\n\n    fragmentSource: {\n      average: 'precision highp float;\\n' +\n        'uniform sampler2D uTexture;\\n' +\n        'varying vec2 vTexCoord;\\n' +\n        'void main() {\\n' +\n          'vec4 color = texture2D(uTexture, vTexCoord);\\n' +\n          'float average = (color.r + color.b + color.g) / 3.0;\\n' +\n          'gl_FragColor = vec4(average, average, average, color.a);\\n' +\n        '}',\n      lightness: 'precision highp float;\\n' +\n        'uniform sampler2D uTexture;\\n' +\n        'uniform int uMode;\\n' +\n        'varying vec2 vTexCoord;\\n' +\n        'void main() {\\n' +\n          'vec4 col = texture2D(uTexture, vTexCoord);\\n' +\n          'float average = (max(max(col.r, col.g),col.b) + min(min(col.r, col.g),col.b)) / 2.0;\\n' +\n          'gl_FragColor = vec4(average, average, average, col.a);\\n' +\n        '}',\n      luminosity: 'precision highp float;\\n' +\n        'uniform sampler2D uTexture;\\n' +\n        'uniform int uMode;\\n' +\n        'varying vec2 vTexCoord;\\n' +\n        'void main() {\\n' +\n          'vec4 col = texture2D(uTexture, vTexCoord);\\n' +\n          'float average = 0.21 * col.r + 0.72 * col.g + 0.07 * col.b;\\n' +\n          'gl_FragColor = vec4(average, average, average, col.a);\\n' +\n        '}',\n    },\n\n\n    /**\n     * Grayscale mode, between 'average', 'lightness', 'luminosity'\n     * @param {String} type\n     * @default\n     */\n    mode: 'average',\n\n    mainParameter: 'mode',\n\n    /**\n     * Apply the Grayscale operation to a Uint8Array representing the pixels of an image.\n     *\n     * @param {Object} options\n     * @param {ImageData} options.imageData The Uint8Array to be filtered.\n     */\n    applyTo2d: function(options) {\n      var imageData = options.imageData,\n          data = imageData.data, i,\n          len = data.length, value,\n          mode = this.mode;\n      for (i = 0; i < len; i += 4) {\n        if (mode === 'average') {\n          value = (data[i] + data[i + 1] + data[i + 2]) / 3;\n        }\n        else if (mode === 'lightness') {\n          value = (Math.min(data[i], data[i + 1], data[i + 2]) +\n            Math.max(data[i], data[i + 1], data[i + 2])) / 2;\n        }\n        else if (mode === 'luminosity') {\n          value = 0.21 * data[i] + 0.72 * data[i + 1] + 0.07 * data[i + 2];\n        }\n        data[i] = value;\n        data[i + 1] = value;\n        data[i + 2] = value;\n      }\n    },\n\n    /**\n     * Retrieves the cached shader.\n     * @param {Object} options\n     * @param {WebGLRenderingContext} options.context The GL context used for rendering.\n     * @param {Object} options.programCache A map of compiled shader programs, keyed by filter type.\n     */\n    retrieveShader: function(options) {\n      var cacheKey = this.type + '_' + this.mode;\n      if (!options.programCache.hasOwnProperty(cacheKey)) {\n        var shaderSource = this.fragmentSource[this.mode];\n        options.programCache[cacheKey] = this.createProgram(options.context, shaderSource);\n      }\n      return options.programCache[cacheKey];\n    },\n\n    /**\n     * Return WebGL uniform locations for this filter's shader.\n     *\n     * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader.\n     * @param {WebGLShaderProgram} program This filter's compiled shader program.\n     */\n    getUniformLocations: function(gl, program) {\n      return {\n        uMode: gl.getUniformLocation(program, 'uMode'),\n      };\n    },\n\n    /**\n     * Send data from this filter to its shader program's uniforms.\n     *\n     * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader.\n     * @param {Object} uniformLocations A map of string uniform names to WebGLUniformLocation objects\n     */\n    sendUniformData: function(gl, uniformLocations) {\n      // default average mode.\n      var mode = 1;\n      gl.uniform1i(uniformLocations.uMode, mode);\n    },\n\n    /**\n     * Grayscale filter isNeutralState implementation\n     * The filter is never neutral\n     * on the image\n     **/\n    isNeutralState: function() {\n      return false;\n    },\n  });\n\n  /**\n   * Returns filter instance from an object representation\n   * @static\n   * @param {Object} object Object to create an instance from\n   * @param {function} [callback] to be invoked after filter creation\n   * @return {fabric.Image.filters.Grayscale} Instance of fabric.Image.filters.Grayscale\n   */\n  fabric.Image.filters.Grayscale.fromObject = fabric.Image.filters.BaseFilter.fromObject;\n\n})(typeof exports !== 'undefined' ? exports : this);\n\n\n(function(global) {\n\n  'use strict';\n\n  var fabric  = global.fabric || (global.fabric = { }),\n      filters = fabric.Image.filters,\n      createClass = fabric.util.createClass;\n\n  /**\n   * Invert filter class\n   * @class fabric.Image.filters.Invert\n   * @memberOf fabric.Image.filters\n   * @extends fabric.Image.filters.BaseFilter\n   * @see {@link http://fabricjs.com/image-filters|ImageFilters demo}\n   * @example\n   * var filter = new fabric.Image.filters.Invert();\n   * object.filters.push(filter);\n   * object.applyFilters(canvas.renderAll.bind(canvas));\n   */\n  filters.Invert = createClass(filters.BaseFilter, /** @lends fabric.Image.filters.Invert.prototype */ {\n\n    /**\n     * Filter type\n     * @param {String} type\n     * @default\n     */\n    type: 'Invert',\n\n    fragmentSource: 'precision highp float;\\n' +\n      'uniform sampler2D uTexture;\\n' +\n      'uniform int uInvert;\\n' +\n      'varying vec2 vTexCoord;\\n' +\n      'void main() {\\n' +\n        'vec4 color = texture2D(uTexture, vTexCoord);\\n' +\n        'if (uInvert == 1) {\\n' +\n          'gl_FragColor = vec4(1.0 - color.r,1.0 -color.g,1.0 -color.b,color.a);\\n' +\n        '} else {\\n' +\n          'gl_FragColor = color;\\n' +\n        '}\\n' +\n      '}',\n\n    /**\n     * Filter invert. if false, does nothing\n     * @param {Boolean} invert\n     * @default\n     */\n    invert: true,\n\n    mainParameter: 'invert',\n\n    /**\n     * Apply the Invert operation to a Uint8Array representing the pixels of an image.\n     *\n     * @param {Object} options\n     * @param {ImageData} options.imageData The Uint8Array to be filtered.\n     */\n    applyTo2d: function(options) {\n      var imageData = options.imageData,\n          data = imageData.data, i,\n          len = data.length;\n      for (i = 0; i < len; i += 4) {\n        data[i] = 255 - data[i];\n        data[i + 1] = 255 - data[i + 1];\n        data[i + 2] = 255 - data[i + 2];\n      }\n    },\n\n    /**\n     * Invert filter isNeutralState implementation\n     * Used only in image applyFilters to discard filters that will not have an effect\n     * on the image\n     * @param {Object} options\n     **/\n    isNeutralState: function() {\n      return !this.invert;\n    },\n\n    /**\n     * Return WebGL uniform locations for this filter's shader.\n     *\n     * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader.\n     * @param {WebGLShaderProgram} program This filter's compiled shader program.\n     */\n    getUniformLocations: function(gl, program) {\n      return {\n        uInvert: gl.getUniformLocation(program, 'uInvert'),\n      };\n    },\n\n    /**\n     * Send data from this filter to its shader program's uniforms.\n     *\n     * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader.\n     * @param {Object} uniformLocations A map of string uniform names to WebGLUniformLocation objects\n     */\n    sendUniformData: function(gl, uniformLocations) {\n      gl.uniform1i(uniformLocations.uInvert, this.invert);\n    },\n  });\n\n  /**\n   * Returns filter instance from an object representation\n   * @static\n   * @param {Object} object Object to create an instance from\n   * @param {function} [callback] to be invoked after filter creation\n   * @return {fabric.Image.filters.Invert} Instance of fabric.Image.filters.Invert\n   */\n  fabric.Image.filters.Invert.fromObject = fabric.Image.filters.BaseFilter.fromObject;\n\n\n})(typeof exports !== 'undefined' ? exports : this);\n\n\n(function(global) {\n\n  'use strict';\n\n  var fabric  = global.fabric || (global.fabric = { }),\n      extend = fabric.util.object.extend,\n      filters = fabric.Image.filters,\n      createClass = fabric.util.createClass;\n\n  /**\n   * Noise filter class\n   * @class fabric.Image.filters.Noise\n   * @memberOf fabric.Image.filters\n   * @extends fabric.Image.filters.BaseFilter\n   * @see {@link fabric.Image.filters.Noise#initialize} for constructor definition\n   * @see {@link http://fabricjs.com/image-filters|ImageFilters demo}\n   * @example\n   * var filter = new fabric.Image.filters.Noise({\n   *   noise: 700\n   * });\n   * object.filters.push(filter);\n   * object.applyFilters();\n   * canvas.renderAll();\n   */\n  filters.Noise = createClass(filters.BaseFilter, /** @lends fabric.Image.filters.Noise.prototype */ {\n\n    /**\n     * Filter type\n     * @param {String} type\n     * @default\n     */\n    type: 'Noise',\n\n    /**\n     * Fragment source for the noise program\n     */\n    fragmentSource: 'precision highp float;\\n' +\n      'uniform sampler2D uTexture;\\n' +\n      'uniform float uStepH;\\n' +\n      'uniform float uNoise;\\n' +\n      'uniform float uSeed;\\n' +\n      'varying vec2 vTexCoord;\\n' +\n      'float rand(vec2 co, float seed, float vScale) {\\n' +\n        'return fract(sin(dot(co.xy * vScale ,vec2(12.9898 , 78.233))) * 43758.5453 * (seed + 0.01) / 2.0);\\n' +\n      '}\\n' +\n      'void main() {\\n' +\n        'vec4 color = texture2D(uTexture, vTexCoord);\\n' +\n        'color.rgb += (0.5 - rand(vTexCoord, uSeed, 0.1 / uStepH)) * uNoise;\\n' +\n        'gl_FragColor = color;\\n' +\n      '}',\n\n    /**\n     * Describe the property that is the filter parameter\n     * @param {String} m\n     * @default\n     */\n    mainParameter: 'noise',\n\n    /**\n     * Noise value, from\n     * @param {Number} noise\n     * @default\n     */\n    noise: 0,\n\n    /**\n     * Apply the Brightness operation to a Uint8ClampedArray representing the pixels of an image.\n     *\n     * @param {Object} options\n     * @param {ImageData} options.imageData The Uint8ClampedArray to be filtered.\n     */\n    applyTo2d: function(options) {\n      if (this.noise === 0) {\n        return;\n      }\n      var imageData = options.imageData,\n          data = imageData.data, i, len = data.length,\n          noise = this.noise, rand;\n\n      for (i = 0, len = data.length; i < len; i += 4) {\n\n        rand = (0.5 - Math.random()) * noise;\n\n        data[i] += rand;\n        data[i + 1] += rand;\n        data[i + 2] += rand;\n      }\n    },\n\n    /**\n     * Return WebGL uniform locations for this filter's shader.\n     *\n     * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader.\n     * @param {WebGLShaderProgram} program This filter's compiled shader program.\n     */\n    getUniformLocations: function(gl, program) {\n      return {\n        uNoise: gl.getUniformLocation(program, 'uNoise'),\n        uSeed: gl.getUniformLocation(program, 'uSeed'),\n      };\n    },\n\n    /**\n     * Send data from this filter to its shader program's uniforms.\n     *\n     * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader.\n     * @param {Object} uniformLocations A map of string uniform names to WebGLUniformLocation objects\n     */\n    sendUniformData: function(gl, uniformLocations) {\n      gl.uniform1f(uniformLocations.uNoise, this.noise / 255);\n      gl.uniform1f(uniformLocations.uSeed, Math.random());\n    },\n\n    /**\n     * Returns object representation of an instance\n     * @return {Object} Object representation of an instance\n     */\n    toObject: function() {\n      return extend(this.callSuper('toObject'), {\n        noise: this.noise\n      });\n    }\n  });\n\n  /**\n   * Returns filter instance from an object representation\n   * @static\n   * @param {Object} object Object to create an instance from\n   * @param {Function} [callback] to be invoked after filter creation\n   * @return {fabric.Image.filters.Noise} Instance of fabric.Image.filters.Noise\n   */\n  fabric.Image.filters.Noise.fromObject = fabric.Image.filters.BaseFilter.fromObject;\n\n})(typeof exports !== 'undefined' ? exports : this);\n\n\n(function(global) {\n\n  'use strict';\n\n  var fabric  = global.fabric || (global.fabric = { }),\n      filters = fabric.Image.filters,\n      createClass = fabric.util.createClass;\n\n  /**\n   * Pixelate filter class\n   * @class fabric.Image.filters.Pixelate\n   * @memberOf fabric.Image.filters\n   * @extends fabric.Image.filters.BaseFilter\n   * @see {@link fabric.Image.filters.Pixelate#initialize} for constructor definition\n   * @see {@link http://fabricjs.com/image-filters|ImageFilters demo}\n   * @example\n   * var filter = new fabric.Image.filters.Pixelate({\n   *   blocksize: 8\n   * });\n   * object.filters.push(filter);\n   * object.applyFilters();\n   */\n  filters.Pixelate = createClass(filters.BaseFilter, /** @lends fabric.Image.filters.Pixelate.prototype */ {\n\n    /**\n     * Filter type\n     * @param {String} type\n     * @default\n     */\n    type: 'Pixelate',\n\n    blocksize: 4,\n\n    mainParameter: 'blocksize',\n\n    /**\n     * Fragment source for the Pixelate program\n     */\n    fragmentSource: 'precision highp float;\\n' +\n      'uniform sampler2D uTexture;\\n' +\n      'uniform float uBlocksize;\\n' +\n      'uniform float uStepW;\\n' +\n      'uniform float uStepH;\\n' +\n      'varying vec2 vTexCoord;\\n' +\n      'void main() {\\n' +\n        'float blockW = uBlocksize * uStepW;\\n' +\n        'float blockH = uBlocksize * uStepW;\\n' +\n        'int posX = int(vTexCoord.x / blockW);\\n' +\n        'int posY = int(vTexCoord.y / blockH);\\n' +\n        'float fposX = float(posX);\\n' +\n        'float fposY = float(posY);\\n' +\n        'vec2 squareCoords = vec2(fposX * blockW, fposY * blockH);\\n' +\n        'vec4 color = texture2D(uTexture, squareCoords);\\n' +\n        'gl_FragColor = color;\\n' +\n      '}',\n\n    /**\n     * Apply the Pixelate operation to a Uint8ClampedArray representing the pixels of an image.\n     *\n     * @param {Object} options\n     * @param {ImageData} options.imageData The Uint8ClampedArray to be filtered.\n     */\n    applyTo2d: function(options) {\n      var imageData = options.imageData,\n          data = imageData.data,\n          iLen = imageData.height,\n          jLen = imageData.width,\n          index, i, j, r, g, b, a,\n          _i, _j, _iLen, _jLen;\n\n      for (i = 0; i < iLen; i += this.blocksize) {\n        for (j = 0; j < jLen; j += this.blocksize) {\n\n          index = (i * 4) * jLen + (j * 4);\n\n          r = data[index];\n          g = data[index + 1];\n          b = data[index + 2];\n          a = data[index + 3];\n\n          _iLen = Math.min(i + this.blocksize, iLen);\n          _jLen = Math.min(j + this.blocksize, jLen);\n          for (_i = i; _i < _iLen; _i++) {\n            for (_j = j; _j < _jLen; _j++) {\n              index = (_i * 4) * jLen + (_j * 4);\n              data[index] = r;\n              data[index + 1] = g;\n              data[index + 2] = b;\n              data[index + 3] = a;\n            }\n          }\n        }\n      }\n    },\n\n    /**\n     * Indicate when the filter is not gonna apply changes to the image\n     **/\n    isNeutralState: function() {\n      return this.blocksize === 1;\n    },\n\n    /**\n     * Return WebGL uniform locations for this filter's shader.\n     *\n     * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader.\n     * @param {WebGLShaderProgram} program This filter's compiled shader program.\n     */\n    getUniformLocations: function(gl, program) {\n      return {\n        uBlocksize: gl.getUniformLocation(program, 'uBlocksize'),\n        uStepW: gl.getUniformLocation(program, 'uStepW'),\n        uStepH: gl.getUniformLocation(program, 'uStepH'),\n      };\n    },\n\n    /**\n     * Send data from this filter to its shader program's uniforms.\n     *\n     * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader.\n     * @param {Object} uniformLocations A map of string uniform names to WebGLUniformLocation objects\n     */\n    sendUniformData: function(gl, uniformLocations) {\n      gl.uniform1f(uniformLocations.uBlocksize, this.blocksize);\n    },\n  });\n\n  /**\n   * Returns filter instance from an object representation\n   * @static\n   * @param {Object} object Object to create an instance from\n   * @param {Function} [callback] to be invoked after filter creation\n   * @return {fabric.Image.filters.Pixelate} Instance of fabric.Image.filters.Pixelate\n   */\n  fabric.Image.filters.Pixelate.fromObject = fabric.Image.filters.BaseFilter.fromObject;\n\n})(typeof exports !== 'undefined' ? exports : this);\n\n\n(function(global) {\n\n  'use strict';\n\n  var fabric  = global.fabric || (global.fabric = { }),\n      extend = fabric.util.object.extend,\n      filters = fabric.Image.filters,\n      createClass = fabric.util.createClass;\n\n  /**\n   * Remove white filter class\n   * @class fabric.Image.filters.RemoveColor\n   * @memberOf fabric.Image.filters\n   * @extends fabric.Image.filters.BaseFilter\n   * @see {@link fabric.Image.filters.RemoveColor#initialize} for constructor definition\n   * @see {@link http://fabricjs.com/image-filters|ImageFilters demo}\n   * @example\n   * var filter = new fabric.Image.filters.RemoveColor({\n   *   threshold: 0.2,\n   * });\n   * object.filters.push(filter);\n   * object.applyFilters();\n   * canvas.renderAll();\n   */\n  filters.RemoveColor = createClass(filters.BaseFilter, /** @lends fabric.Image.filters.RemoveColor.prototype */ {\n\n    /**\n     * Filter type\n     * @param {String} type\n     * @default\n     */\n    type: 'RemoveColor',\n\n    /**\n     * Color to remove, in any format understood by fabric.Color.\n     * @param {String} type\n     * @default\n     */\n    color: '#FFFFFF',\n\n    /**\n     * Fragment source for the brightness program\n     */\n    fragmentSource: 'precision highp float;\\n' +\n      'uniform sampler2D uTexture;\\n' +\n      'uniform vec4 uLow;\\n' +\n      'uniform vec4 uHigh;\\n' +\n      'varying vec2 vTexCoord;\\n' +\n      'void main() {\\n' +\n        'gl_FragColor = texture2D(uTexture, vTexCoord);\\n' +\n        'if(all(greaterThan(gl_FragColor.rgb,uLow.rgb)) && all(greaterThan(uHigh.rgb,gl_FragColor.rgb))) {\\n' +\n          'gl_FragColor.a = 0.0;\\n' +\n        '}\\n' +\n      '}',\n\n    /**\n     * distance to actual color, as value up or down from each r,g,b\n     * between 0 and 1\n     **/\n    distance: 0.02,\n\n    /**\n     * For color to remove inside distance, use alpha channel for a smoother deletion\n     * NOT IMPLEMENTED YET\n     **/\n    useAlpha: false,\n\n    /**\n     * Constructor\n     * @memberOf fabric.Image.filters.RemoveWhite.prototype\n     * @param {Object} [options] Options object\n     * @param {Number} [options.color=#RRGGBB] Threshold value\n     * @param {Number} [options.distance=10] Distance value\n     */\n\n    /**\n     * Applies filter to canvas element\n     * @param {Object} canvasEl Canvas element to apply filter to\n     */\n    applyTo2d: function(options) {\n      var imageData = options.imageData,\n          data = imageData.data, i,\n          distance = this.distance * 255,\n          r, g, b,\n          source = new fabric.Color(this.color).getSource(),\n          lowC = [\n            source[0] - distance,\n            source[1] - distance,\n            source[2] - distance,\n          ],\n          highC = [\n            source[0] + distance,\n            source[1] + distance,\n            source[2] + distance,\n          ];\n\n\n      for (i = 0; i < data.length; i += 4) {\n        r = data[i];\n        g = data[i + 1];\n        b = data[i + 2];\n\n        if (r > lowC[0] &&\n            g > lowC[1] &&\n            b > lowC[2] &&\n            r < highC[0] &&\n            g < highC[1] &&\n            b < highC[2]) {\n          data[i + 3] = 0;\n        }\n      }\n    },\n\n    /**\n     * Return WebGL uniform locations for this filter's shader.\n     *\n     * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader.\n     * @param {WebGLShaderProgram} program This filter's compiled shader program.\n     */\n    getUniformLocations: function(gl, program) {\n      return {\n        uLow: gl.getUniformLocation(program, 'uLow'),\n        uHigh: gl.getUniformLocation(program, 'uHigh'),\n      };\n    },\n\n    /**\n     * Send data from this filter to its shader program's uniforms.\n     *\n     * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader.\n     * @param {Object} uniformLocations A map of string uniform names to WebGLUniformLocation objects\n     */\n    sendUniformData: function(gl, uniformLocations) {\n      var source = new fabric.Color(this.color).getSource(),\n          distance = parseFloat(this.distance),\n          lowC = [\n            0 + source[0] / 255 - distance,\n            0 + source[1] / 255 - distance,\n            0 + source[2] / 255 - distance,\n            1\n          ],\n          highC = [\n            source[0] / 255 + distance,\n            source[1] / 255 + distance,\n            source[2] / 255 + distance,\n            1\n          ];\n      gl.uniform4fv(uniformLocations.uLow, lowC);\n      gl.uniform4fv(uniformLocations.uHigh, highC);\n    },\n\n    /**\n     * Returns object representation of an instance\n     * @return {Object} Object representation of an instance\n     */\n    toObject: function() {\n      return extend(this.callSuper('toObject'), {\n        color: this.color,\n        distance: this.distance\n      });\n    }\n  });\n\n  /**\n   * Returns filter instance from an object representation\n   * @static\n   * @param {Object} object Object to create an instance from\n   * @param {Function} [callback] to be invoked after filter creation\n   * @return {fabric.Image.filters.RemoveColor} Instance of fabric.Image.filters.RemoveWhite\n   */\n  fabric.Image.filters.RemoveColor.fromObject = fabric.Image.filters.BaseFilter.fromObject;\n\n})(typeof exports !== 'undefined' ? exports : this);\n\n\n(function(global) {\n\n  'use strict';\n\n  var fabric  = global.fabric || (global.fabric = { }),\n      filters = fabric.Image.filters,\n      createClass = fabric.util.createClass;\n\n  var matrices = {\n    Brownie: [\n      0.59970,0.34553,-0.27082,0,0.186,\n      -0.03770,0.86095,0.15059,0,-0.1449,\n      0.24113,-0.07441,0.44972,0,-0.02965,\n      0,0,0,1,0\n    ],\n    Vintage: [\n      0.62793,0.32021,-0.03965,0,0.03784,\n      0.02578,0.64411,0.03259,0,0.02926,\n      0.04660,-0.08512,0.52416,0,0.02023,\n      0,0,0,1,0\n    ],\n    Kodachrome: [\n      1.12855,-0.39673,-0.03992,0,0.24991,\n      -0.16404,1.08352,-0.05498,0,0.09698,\n      -0.16786,-0.56034,1.60148,0,0.13972,\n      0,0,0,1,0\n    ],\n    Technicolor: [\n      1.91252,-0.85453,-0.09155,0,0.04624,\n      -0.30878,1.76589,-0.10601,0,-0.27589,\n      -0.23110,-0.75018,1.84759,0,0.12137,\n      0,0,0,1,0\n    ],\n    Polaroid: [\n      1.438,-0.062,-0.062,0,0,\n      -0.122,1.378,-0.122,0,0,\n      -0.016,-0.016,1.483,0,0,\n      0,0,0,1,0\n    ],\n    Sepia: [\n      0.393, 0.769, 0.189, 0, 0,\n      0.349, 0.686, 0.168, 0, 0,\n      0.272, 0.534, 0.131, 0, 0,\n      0, 0, 0, 1, 0\n    ],\n    BlackWhite: [\n      1.5, 1.5, 1.5, 0, -1,\n      1.5, 1.5, 1.5, 0, -1,\n      1.5, 1.5, 1.5, 0, -1,\n      0, 0, 0, 1, 0,\n    ]\n  };\n\n  for (var key in matrices) {\n    filters[key] = createClass(filters.ColorMatrix, /** @lends fabric.Image.filters.Sepia.prototype */ {\n\n      /**\n       * Filter type\n       * @param {String} type\n       * @default\n       */\n      type: key,\n\n      /**\n       * Colormatrix for the effect\n       * array of 20 floats. Numbers in positions 4, 9, 14, 19 loose meaning\n       * outside the -1, 1 range.\n       * @param {Array} matrix array of 20 numbers.\n       * @default\n       */\n      matrix: matrices[key],\n\n      /**\n       * Lock the matrix export for this kind of static, parameter less filters.\n       */\n      mainParameter: false,\n      /**\n       * Lock the colormatrix on the color part, skipping alpha\n       */\n      colorsOnly: true,\n\n    });\n    fabric.Image.filters[key].fromObject = fabric.Image.filters.BaseFilter.fromObject;\n  }\n})(typeof exports !== 'undefined' ? exports : this);\n\n\n(function(global) {\n  'use strict';\n\n  var fabric = global.fabric,\n      filters = fabric.Image.filters,\n      createClass = fabric.util.createClass;\n\n  /**\n   * Color Blend filter class\n   * @class fabric.Image.filter.BlendColor\n   * @memberOf fabric.Image.filters\n   * @extends fabric.Image.filters.BaseFilter\n   * @example\n   * var filter = new fabric.Image.filters.BlendColor({\n   *  color: '#000',\n   *  mode: 'multiply'\n   * });\n   *\n   * var filter = new fabric.Image.filters.BlendImage({\n   *  image: fabricImageObject,\n   *  mode: 'multiply',\n   *  alpha: 0.5\n   * });\n   * object.filters.push(filter);\n   * object.applyFilters();\n   * canvas.renderAll();\n   */\n\n  filters.BlendColor = createClass(filters.BaseFilter, /** @lends fabric.Image.filters.Blend.prototype */ {\n    type: 'BlendColor',\n\n    /**\n     * Color to make the blend operation with. default to a reddish color since black or white\n     * gives always strong result.\n     **/\n    color: '#F95C63',\n\n    /**\n     * Blend mode for the filter: one of multiply, add, diff, screen, subtract,\n     * darken, lighten, overlay, exclusion, tint.\n     **/\n    mode: 'multiply',\n\n    /**\n     * alpha value. represent the strength of the blend color operation.\n     **/\n    alpha: 1,\n\n    /**\n     * Fragment source for the Multiply program\n     */\n    fragmentSource: {\n      multiply: 'gl_FragColor.rgb *= uColor.rgb;\\n',\n      screen: 'gl_FragColor.rgb = 1.0 - (1.0 - gl_FragColor.rgb) * (1.0 - uColor.rgb);\\n',\n      add: 'gl_FragColor.rgb += uColor.rgb;\\n',\n      diff: 'gl_FragColor.rgb = abs(gl_FragColor.rgb - uColor.rgb);\\n',\n      subtract: 'gl_FragColor.rgb -= uColor.rgb;\\n',\n      lighten: 'gl_FragColor.rgb = max(gl_FragColor.rgb, uColor.rgb);\\n',\n      darken: 'gl_FragColor.rgb = min(gl_FragColor.rgb, uColor.rgb);\\n',\n      exclusion: 'gl_FragColor.rgb += uColor.rgb - 2.0 * (uColor.rgb * gl_FragColor.rgb);\\n',\n      overlay: 'if (uColor.r < 0.5) {\\n' +\n          'gl_FragColor.r *= 2.0 * uColor.r;\\n' +\n        '} else {\\n' +\n          'gl_FragColor.r = 1.0 - 2.0 * (1.0 - gl_FragColor.r) * (1.0 - uColor.r);\\n' +\n        '}\\n' +\n        'if (uColor.g < 0.5) {\\n' +\n          'gl_FragColor.g *= 2.0 * uColor.g;\\n' +\n        '} else {\\n' +\n          'gl_FragColor.g = 1.0 - 2.0 * (1.0 - gl_FragColor.g) * (1.0 - uColor.g);\\n' +\n        '}\\n' +\n        'if (uColor.b < 0.5) {\\n' +\n          'gl_FragColor.b *= 2.0 * uColor.b;\\n' +\n        '} else {\\n' +\n          'gl_FragColor.b = 1.0 - 2.0 * (1.0 - gl_FragColor.b) * (1.0 - uColor.b);\\n' +\n        '}\\n',\n      tint: 'gl_FragColor.rgb *= (1.0 - uColor.a);\\n' +\n        'gl_FragColor.rgb += uColor.rgb;\\n',\n    },\n\n    /**\n     * build the fragment source for the filters, joining the common part with\n     * the specific one.\n     * @param {String} mode the mode of the filter, a key of this.fragmentSource\n     * @return {String} the source to be compiled\n     * @private\n     */\n    buildSource: function(mode) {\n      return 'precision highp float;\\n' +\n        'uniform sampler2D uTexture;\\n' +\n        'uniform vec4 uColor;\\n' +\n        'varying vec2 vTexCoord;\\n' +\n        'void main() {\\n' +\n          'vec4 color = texture2D(uTexture, vTexCoord);\\n' +\n          'gl_FragColor = color;\\n' +\n          'if (color.a > 0.0) {\\n' +\n            this.fragmentSource[mode] +\n          '}\\n' +\n        '}';\n    },\n\n    /**\n     * Retrieves the cached shader.\n     * @param {Object} options\n     * @param {WebGLRenderingContext} options.context The GL context used for rendering.\n     * @param {Object} options.programCache A map of compiled shader programs, keyed by filter type.\n     */\n    retrieveShader: function(options) {\n      var cacheKey = this.type + '_' + this.mode, shaderSource;\n      if (!options.programCache.hasOwnProperty(cacheKey)) {\n        shaderSource = this.buildSource(this.mode);\n        options.programCache[cacheKey] = this.createProgram(options.context, shaderSource);\n      }\n      return options.programCache[cacheKey];\n    },\n\n    /**\n     * Apply the Blend operation to a Uint8ClampedArray representing the pixels of an image.\n     *\n     * @param {Object} options\n     * @param {ImageData} options.imageData The Uint8ClampedArray to be filtered.\n     */\n    applyTo2d: function(options) {\n      var imageData = options.imageData,\n          data = imageData.data, iLen = data.length,\n          tr, tg, tb,\n          r, g, b,\n          source, alpha1 = 1 - this.alpha;\n\n      source = new fabric.Color(this.color).getSource();\n      tr = source[0] * this.alpha;\n      tg = source[1] * this.alpha;\n      tb = source[2] * this.alpha;\n\n      for (var i = 0; i < iLen; i += 4) {\n\n        r = data[i];\n        g = data[i + 1];\n        b = data[i + 2];\n\n        switch (this.mode) {\n          case 'multiply':\n            data[i] = r * tr / 255;\n            data[i + 1] = g * tg / 255;\n            data[i + 2] = b * tb / 255;\n            break;\n          case 'screen':\n            data[i] = 255 - (255 - r) * (255 - tr) / 255;\n            data[i + 1] = 255 - (255 - g) * (255 - tg) / 255;\n            data[i + 2] = 255 - (255 - b) * (255 - tb) / 255;\n            break;\n          case 'add':\n            data[i] = r + tr;\n            data[i + 1] = g + tg;\n            data[i + 2] = b + tb;\n            break;\n          case 'diff':\n          case 'difference':\n            data[i] = Math.abs(r - tr);\n            data[i + 1] = Math.abs(g - tg);\n            data[i + 2] = Math.abs(b - tb);\n            break;\n          case 'subtract':\n            data[i] = r - tr;\n            data[i + 1] = g - tg;\n            data[i + 2] = b - tb;\n            break;\n          case 'darken':\n            data[i] = Math.min(r, tr);\n            data[i + 1] = Math.min(g, tg);\n            data[i + 2] = Math.min(b, tb);\n            break;\n          case 'lighten':\n            data[i] = Math.max(r, tr);\n            data[i + 1] = Math.max(g, tg);\n            data[i + 2] = Math.max(b, tb);\n            break;\n          case 'overlay':\n            data[i] = tr < 128 ? (2 * r * tr / 255) : (255 - 2 * (255 - r) * (255 - tr) / 255);\n            data[i + 1] = tg < 128 ? (2 * g * tg / 255) : (255 - 2 * (255 - g) * (255 - tg) / 255);\n            data[i + 2] = tb < 128 ? (2 * b * tb / 255) : (255 - 2 * (255 - b) * (255 - tb) / 255);\n            break;\n          case 'exclusion':\n            data[i] = tr + r - ((2 * tr * r) / 255);\n            data[i + 1] = tg + g - ((2 * tg * g) / 255);\n            data[i + 2] = tb + b - ((2 * tb * b) / 255);\n            break;\n          case 'tint':\n            data[i] = tr + r * alpha1;\n            data[i + 1] = tg + g * alpha1;\n            data[i + 2] = tb + b * alpha1;\n        }\n      }\n    },\n\n    /**\n     * Return WebGL uniform locations for this filter's shader.\n     *\n     * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader.\n     * @param {WebGLShaderProgram} program This filter's compiled shader program.\n     */\n    getUniformLocations: function(gl, program) {\n      return {\n        uColor: gl.getUniformLocation(program, 'uColor'),\n      };\n    },\n\n    /**\n     * Send data from this filter to its shader program's uniforms.\n     *\n     * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader.\n     * @param {Object} uniformLocations A map of string uniform names to WebGLUniformLocation objects\n     */\n    sendUniformData: function(gl, uniformLocations) {\n      var source = new fabric.Color(this.color).getSource();\n      source[0] = this.alpha * source[0] / 255;\n      source[1] = this.alpha * source[1] / 255;\n      source[2] = this.alpha * source[2] / 255;\n      source[3] = this.alpha;\n      gl.uniform4fv(uniformLocations.uColor, source);\n    },\n\n    /**\n     * Returns object representation of an instance\n     * @return {Object} Object representation of an instance\n     */\n    toObject: function() {\n      return {\n        type: this.type,\n        color: this.color,\n        mode: this.mode,\n        alpha: this.alpha\n      };\n    }\n  });\n\n  /**\n   * Returns filter instance from an object representation\n   * @static\n   * @param {Object} object Object to create an instance from\n   * @param {function} [callback] to be invoked after filter creation\n   * @return {fabric.Image.filters.BlendColor} Instance of fabric.Image.filters.BlendColor\n   */\n  fabric.Image.filters.BlendColor.fromObject = fabric.Image.filters.BaseFilter.fromObject;\n\n})(typeof exports !== 'undefined' ? exports : this);\n\n\n(function(global) {\n  'use strict';\n\n  var fabric = global.fabric,\n      filters = fabric.Image.filters,\n      createClass = fabric.util.createClass;\n\n  /**\n   * Image Blend filter class\n   * @class fabric.Image.filter.BlendImage\n   * @memberOf fabric.Image.filters\n   * @extends fabric.Image.filters.BaseFilter\n   * @example\n   * var filter = new fabric.Image.filters.BlendColor({\n   *  color: '#000',\n   *  mode: 'multiply'\n   * });\n   *\n   * var filter = new fabric.Image.filters.BlendImage({\n   *  image: fabricImageObject,\n   *  mode: 'multiply',\n   *  alpha: 0.5\n   * });\n   * object.filters.push(filter);\n   * object.applyFilters();\n   * canvas.renderAll();\n   */\n\n  filters.BlendImage = createClass(filters.BaseFilter, /** @lends fabric.Image.filters.BlendImage.prototype */ {\n    type: 'BlendImage',\n\n    /**\n     * Color to make the blend operation with. default to a reddish color since black or white\n     * gives always strong result.\n     **/\n    image: null,\n\n    /**\n     * Blend mode for the filter: one of multiply, add, diff, screen, subtract,\n     * darken, lighten, overlay, exclusion, tint.\n     **/\n    mode: 'multiply',\n\n    /**\n     * alpha value. represent the strength of the blend image operation.\n     * not implemented.\n     **/\n    alpha: 1,\n\n    vertexSource: 'attribute vec2 aPosition;\\n' +\n      'varying vec2 vTexCoord;\\n' +\n      'varying vec2 vTexCoord2;\\n' +\n      'uniform mat3 uTransformMatrix;\\n' +\n      'void main() {\\n' +\n        'vTexCoord = aPosition;\\n' +\n        'vTexCoord2 = (uTransformMatrix * vec3(aPosition, 1.0)).xy;\\n' +\n        'gl_Position = vec4(aPosition * 2.0 - 1.0, 0.0, 1.0);\\n' +\n      '}',\n\n    /**\n     * Fragment source for the Multiply program\n     */\n    fragmentSource: {\n      multiply: 'precision highp float;\\n' +\n        'uniform sampler2D uTexture;\\n' +\n        'uniform sampler2D uImage;\\n' +\n        'uniform vec4 uColor;\\n' +\n        'varying vec2 vTexCoord;\\n' +\n        'varying vec2 vTexCoord2;\\n' +\n        'void main() {\\n' +\n          'vec4 color = texture2D(uTexture, vTexCoord);\\n' +\n          'vec4 color2 = texture2D(uImage, vTexCoord2);\\n' +\n          'color.rgba *= color2.rgba;\\n' +\n          'gl_FragColor = color;\\n' +\n        '}',\n      mask: 'precision highp float;\\n' +\n        'uniform sampler2D uTexture;\\n' +\n        'uniform sampler2D uImage;\\n' +\n        'uniform vec4 uColor;\\n' +\n        'varying vec2 vTexCoord;\\n' +\n        'varying vec2 vTexCoord2;\\n' +\n        'void main() {\\n' +\n          'vec4 color = texture2D(uTexture, vTexCoord);\\n' +\n          'vec4 color2 = texture2D(uImage, vTexCoord2);\\n' +\n          'color.a = color2.a;\\n' +\n          'gl_FragColor = color;\\n' +\n        '}',\n    },\n\n    /**\n     * Retrieves the cached shader.\n     * @param {Object} options\n     * @param {WebGLRenderingContext} options.context The GL context used for rendering.\n     * @param {Object} options.programCache A map of compiled shader programs, keyed by filter type.\n     */\n    retrieveShader: function(options) {\n      var cacheKey = this.type + '_' + this.mode;\n      var shaderSource = this.fragmentSource[this.mode];\n      if (!options.programCache.hasOwnProperty(cacheKey)) {\n        options.programCache[cacheKey] = this.createProgram(options.context, shaderSource);\n      }\n      return options.programCache[cacheKey];\n    },\n\n    applyToWebGL: function(options) {\n      // load texture to blend.\n      var gl = options.context,\n          texture = this.createTexture(options.filterBackend, this.image);\n      this.bindAdditionalTexture(gl, texture, gl.TEXTURE1);\n      this.callSuper('applyToWebGL', options);\n      this.unbindAdditionalTexture(gl, gl.TEXTURE1);\n    },\n\n    createTexture: function(backend, image) {\n      return backend.getCachedTexture(image.cacheKey, image._element);\n    },\n\n    /**\n     * Calculate a transformMatrix to adapt the image to blend over\n     * @param {Object} options\n     * @param {WebGLRenderingContext} options.context The GL context used for rendering.\n     * @param {Object} options.programCache A map of compiled shader programs, keyed by filter type.\n     */\n    calculateMatrix: function() {\n      var image = this.image,\n          width = image._element.width,\n          height = image._element.height;\n      return [\n        1 / image.scaleX, 0, 0,\n        0, 1 / image.scaleY, 0,\n        -image.left / width, -image.top / height, 1\n      ];\n    },\n\n    /**\n     * Apply the Blend operation to a Uint8ClampedArray representing the pixels of an image.\n     *\n     * @param {Object} options\n     * @param {ImageData} options.imageData The Uint8ClampedArray to be filtered.\n     */\n    applyTo2d: function(options) {\n      var imageData = options.imageData,\n          resources = options.filterBackend.resources,\n          data = imageData.data, iLen = data.length,\n          width = imageData.width,\n          height = imageData.height,\n          tr, tg, tb, ta,\n          r, g, b, a,\n          canvas1, context, image = this.image, blendData;\n\n      if (!resources.blendImage) {\n        resources.blendImage = fabric.util.createCanvasElement();\n      }\n      canvas1 = resources.blendImage;\n      context = canvas1.getContext('2d');\n      if (canvas1.width !== width || canvas1.height !== height) {\n        canvas1.width = width;\n        canvas1.height = height;\n      }\n      else {\n        context.clearRect(0, 0, width, height);\n      }\n      context.setTransform(image.scaleX, 0, 0, image.scaleY, image.left, image.top);\n      context.drawImage(image._element, 0, 0, width, height);\n      blendData = context.getImageData(0, 0, width, height).data;\n      for (var i = 0; i < iLen; i += 4) {\n\n        r = data[i];\n        g = data[i + 1];\n        b = data[i + 2];\n        a = data[i + 3];\n\n        tr = blendData[i];\n        tg = blendData[i + 1];\n        tb = blendData[i + 2];\n        ta = blendData[i + 3];\n\n        switch (this.mode) {\n          case 'multiply':\n            data[i] = r * tr / 255;\n            data[i + 1] = g * tg / 255;\n            data[i + 2] = b * tb / 255;\n            data[i + 3] = a * ta / 255;\n            break;\n          case 'mask':\n            data[i + 3] = ta;\n            break;\n        }\n      }\n    },\n\n    /**\n     * Return WebGL uniform locations for this filter's shader.\n     *\n     * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader.\n     * @param {WebGLShaderProgram} program This filter's compiled shader program.\n     */\n    getUniformLocations: function(gl, program) {\n      return {\n        uTransformMatrix: gl.getUniformLocation(program, 'uTransformMatrix'),\n        uImage: gl.getUniformLocation(program, 'uImage'),\n      };\n    },\n\n    /**\n     * Send data from this filter to its shader program's uniforms.\n     *\n     * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader.\n     * @param {Object} uniformLocations A map of string uniform names to WebGLUniformLocation objects\n     */\n    sendUniformData: function(gl, uniformLocations) {\n      var matrix = this.calculateMatrix();\n      gl.uniform1i(uniformLocations.uImage, 1); // texture unit 1.\n      gl.uniformMatrix3fv(uniformLocations.uTransformMatrix, false, matrix);\n    },\n\n    /**\n     * Returns object representation of an instance\n     * @return {Object} Object representation of an instance\n     */\n    toObject: function() {\n      return {\n        type: this.type,\n        image: this.image && this.image.toObject(),\n        mode: this.mode,\n        alpha: this.alpha\n      };\n    }\n  });\n\n  /**\n   * Returns filter instance from an object representation\n   * @static\n   * @param {Object} object Object to create an instance from\n   * @param {function} callback to be invoked after filter creation\n   * @return {fabric.Image.filters.BlendImage} Instance of fabric.Image.filters.BlendImage\n   */\n  fabric.Image.filters.BlendImage.fromObject = function(object, callback) {\n    fabric.Image.fromObject(object.image, function(image) {\n      var options = fabric.util.object.clone(object);\n      options.image = image;\n      callback(new fabric.Image.filters.BlendImage(options));\n    });\n  };\n\n})(typeof exports !== 'undefined' ? exports : this);\n\n\n(function(global) {\n\n  'use strict';\n\n  var fabric  = global.fabric || (global.fabric = { }), pow = Math.pow, floor = Math.floor,\n      sqrt = Math.sqrt, abs = Math.abs, round = Math.round, sin = Math.sin,\n      ceil = Math.ceil,\n      filters = fabric.Image.filters,\n      createClass = fabric.util.createClass;\n\n  /**\n   * Resize image filter class\n   * @class fabric.Image.filters.Resize\n   * @memberOf fabric.Image.filters\n   * @extends fabric.Image.filters.BaseFilter\n   * @see {@link http://fabricjs.com/image-filters|ImageFilters demo}\n   * @example\n   * var filter = new fabric.Image.filters.Resize();\n   * object.filters.push(filter);\n   * object.applyFilters(canvas.renderAll.bind(canvas));\n   */\n  filters.Resize = createClass(filters.BaseFilter, /** @lends fabric.Image.filters.Resize.prototype */ {\n\n    /**\n     * Filter type\n     * @param {String} type\n     * @default\n     */\n    type: 'Resize',\n\n    /**\n     * Resize type\n     * for webgl resizeType is just lanczos, for canvas2d can be:\n     * bilinear, hermite, sliceHack, lanczos.\n     * @param {String} resizeType\n     * @default\n     */\n    resizeType: 'hermite',\n\n    /**\n     * Scale factor for resizing, x axis\n     * @param {Number} scaleX\n     * @default\n     */\n    scaleX: 1,\n\n    /**\n     * Scale factor for resizing, y axis\n     * @param {Number} scaleY\n     * @default\n     */\n    scaleY: 1,\n\n    /**\n     * LanczosLobes parameter for lanczos filter, valid for resizeType lanczos\n     * @param {Number} lanczosLobes\n     * @default\n     */\n    lanczosLobes: 3,\n\n\n    /**\n     * Return WebGL uniform locations for this filter's shader.\n     *\n     * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader.\n     * @param {WebGLShaderProgram} program This filter's compiled shader program.\n     */\n    getUniformLocations: function(gl, program) {\n      return {\n        uDelta: gl.getUniformLocation(program, 'uDelta'),\n        uTaps: gl.getUniformLocation(program, 'uTaps'),\n      };\n    },\n\n    /**\n     * Send data from this filter to its shader program's uniforms.\n     *\n     * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader.\n     * @param {Object} uniformLocations A map of string uniform names to WebGLUniformLocation objects\n     */\n    sendUniformData: function(gl, uniformLocations) {\n      gl.uniform2fv(uniformLocations.uDelta, this.horizontal ? [1 / this.width, 0] : [0, 1 / this.height]);\n      gl.uniform1fv(uniformLocations.uTaps, this.taps);\n    },\n\n    /**\n     * Retrieves the cached shader.\n     * @param {Object} options\n     * @param {WebGLRenderingContext} options.context The GL context used for rendering.\n     * @param {Object} options.programCache A map of compiled shader programs, keyed by filter type.\n     */\n    retrieveShader: function(options) {\n      var filterWindow = this.getFilterWindow(), cacheKey = this.type + '_' + filterWindow;\n      if (!options.programCache.hasOwnProperty(cacheKey)) {\n        var fragmentShader = this.generateShader(filterWindow);\n        options.programCache[cacheKey] = this.createProgram(options.context, fragmentShader);\n      }\n      return options.programCache[cacheKey];\n    },\n\n    getFilterWindow: function() {\n      var scale = this.tempScale;\n      return Math.ceil(this.lanczosLobes / scale);\n    },\n\n    getTaps: function() {\n      var lobeFunction = this.lanczosCreate(this.lanczosLobes), scale = this.tempScale,\n          filterWindow = this.getFilterWindow(), taps = new Array(filterWindow);\n      for (var i = 1; i <= filterWindow; i++) {\n        taps[i - 1] = lobeFunction(i * scale);\n      }\n      return taps;\n    },\n\n    /**\n     * Generate vertex and shader sources from the necessary steps numbers\n     * @param {Number} filterWindow\n     */\n    generateShader: function(filterWindow) {\n      var offsets = new Array(filterWindow),\n          fragmentShader = this.fragmentSourceTOP, filterWindow;\n\n      for (var i = 1; i <= filterWindow; i++) {\n        offsets[i - 1] = i + '.0 * uDelta';\n      }\n\n      fragmentShader += 'uniform float uTaps[' + filterWindow + '];\\n';\n      fragmentShader += 'void main() {\\n';\n      fragmentShader += '  vec4 color = texture2D(uTexture, vTexCoord);\\n';\n      fragmentShader += '  float sum = 1.0;\\n';\n\n      offsets.forEach(function(offset, i) {\n        fragmentShader += '  color += texture2D(uTexture, vTexCoord + ' + offset + ') * uTaps[' + i + '];\\n';\n        fragmentShader += '  color += texture2D(uTexture, vTexCoord - ' + offset + ') * uTaps[' + i + '];\\n';\n        fragmentShader += '  sum += 2.0 * uTaps[' + i + '];\\n';\n      });\n      fragmentShader += '  gl_FragColor = color / sum;\\n';\n      fragmentShader += '}';\n      return fragmentShader;\n    },\n\n    fragmentSourceTOP: 'precision highp float;\\n' +\n      'uniform sampler2D uTexture;\\n' +\n      'uniform vec2 uDelta;\\n' +\n      'varying vec2 vTexCoord;\\n',\n\n    /**\n     * Apply the resize filter to the image\n     * Determines whether to use WebGL or Canvas2D based on the options.webgl flag.\n     *\n     * @param {Object} options\n     * @param {Number} options.passes The number of filters remaining to be executed\n     * @param {Boolean} options.webgl Whether to use webgl to render the filter.\n     * @param {WebGLTexture} options.sourceTexture The texture setup as the source to be filtered.\n     * @param {WebGLTexture} options.targetTexture The texture where filtered output should be drawn.\n     * @param {WebGLRenderingContext} options.context The GL context used for rendering.\n     * @param {Object} options.programCache A map of compiled shader programs, keyed by filter type.\n     */\n    applyTo: function(options) {\n      if (options.webgl) {\n        options.passes++;\n        this.width = options.sourceWidth;\n        this.horizontal = true;\n        this.dW = Math.round(this.width * this.scaleX);\n        this.dH = options.sourceHeight;\n        this.tempScale = this.dW / this.width;\n        this.taps = this.getTaps();\n        options.destinationWidth = this.dW;\n        this._setupFrameBuffer(options);\n        this.applyToWebGL(options);\n        this._swapTextures(options);\n        options.sourceWidth = options.destinationWidth;\n\n        this.height = options.sourceHeight;\n        this.horizontal = false;\n        this.dH = Math.round(this.height * this.scaleY);\n        this.tempScale = this.dH / this.height;\n        this.taps = this.getTaps();\n        options.destinationHeight = this.dH;\n        this._setupFrameBuffer(options);\n        this.applyToWebGL(options);\n        this._swapTextures(options);\n        options.sourceHeight = options.destinationHeight;\n      }\n      else {\n        this.applyTo2d(options);\n      }\n    },\n\n    isNeutralState: function() {\n      return this.scaleX === 1 && this.scaleY === 1;\n    },\n\n    lanczosCreate: function(lobes) {\n      return function(x) {\n        if (x >= lobes || x <= -lobes) {\n          return 0.0;\n        }\n        if (x < 1.19209290E-07 && x > -1.19209290E-07) {\n          return 1.0;\n        }\n        x *= Math.PI;\n        var xx = x / lobes;\n        return (sin(x) / x) * sin(xx) / xx;\n      };\n    },\n\n    /**\n     * Applies filter to canvas element\n     * @memberOf fabric.Image.filters.Resize.prototype\n     * @param {Object} canvasEl Canvas element to apply filter to\n     * @param {Number} scaleX\n     * @param {Number} scaleY\n     */\n    applyTo2d: function(options) {\n      var imageData = options.imageData,\n          scaleX = this.scaleX,\n          scaleY = this.scaleY;\n\n      this.rcpScaleX = 1 / scaleX;\n      this.rcpScaleY = 1 / scaleY;\n\n      var oW = imageData.width, oH = imageData.height,\n          dW = round(oW * scaleX), dH = round(oH * scaleY),\n          newData;\n\n      if (this.resizeType === 'sliceHack') {\n        newData = this.sliceByTwo(options, oW, oH, dW, dH);\n      }\n      else if (this.resizeType === 'hermite') {\n        newData = this.hermiteFastResize(options, oW, oH, dW, dH);\n      }\n      else if (this.resizeType === 'bilinear') {\n        newData = this.bilinearFiltering(options, oW, oH, dW, dH);\n      }\n      else if (this.resizeType === 'lanczos') {\n        newData = this.lanczosResize(options, oW, oH, dW, dH);\n      }\n      options.imageData = newData;\n    },\n\n    /**\n     * Filter sliceByTwo\n     * @param {Object} canvasEl Canvas element to apply filter to\n     * @param {Number} oW Original Width\n     * @param {Number} oH Original Height\n     * @param {Number} dW Destination Width\n     * @param {Number} dH Destination Height\n     * @returns {ImageData}\n     */\n    sliceByTwo: function(options, oW, oH, dW, dH) {\n      var imageData = options.imageData,\n          mult = 0.5, doneW = false, doneH = false, stepW = oW * mult,\n          stepH = oH * mult, resources = fabric.filterBackend.resources,\n          tmpCanvas, ctx, sX = 0, sY = 0, dX = oW, dY = 0;\n      if (!resources.sliceByTwo) {\n        resources.sliceByTwo = document.createElement('canvas');\n      }\n      tmpCanvas = resources.sliceByTwo;\n      if (tmpCanvas.width < oW * 1.5 || tmpCanvas.height < oH) {\n        tmpCanvas.width = oW * 1.5;\n        tmpCanvas.height = oH;\n      }\n      ctx = tmpCanvas.getContext('2d');\n      ctx.clearRect(0, 0, oW * 1.5, oH);\n      ctx.putImageData(imageData, 0, 0);\n\n      dW = floor(dW);\n      dH = floor(dH);\n\n      while (!doneW || !doneH) {\n        oW = stepW;\n        oH = stepH;\n        if (dW < floor(stepW * mult)) {\n          stepW = floor(stepW * mult);\n        }\n        else {\n          stepW = dW;\n          doneW = true;\n        }\n        if (dH < floor(stepH * mult)) {\n          stepH = floor(stepH * mult);\n        }\n        else {\n          stepH = dH;\n          doneH = true;\n        }\n        ctx.drawImage(tmpCanvas, sX, sY, oW, oH, dX, dY, stepW, stepH);\n        sX = dX;\n        sY = dY;\n        dY += stepH;\n      }\n      return ctx.getImageData(sX, sY, dW, dH);\n    },\n\n    /**\n     * Filter lanczosResize\n     * @param {Object} canvasEl Canvas element to apply filter to\n     * @param {Number} oW Original Width\n     * @param {Number} oH Original Height\n     * @param {Number} dW Destination Width\n     * @param {Number} dH Destination Height\n     * @returns {ImageData}\n     */\n    lanczosResize: function(options, oW, oH, dW, dH) {\n\n      function process(u) {\n        var v, i, weight, idx, a, red, green,\n            blue, alpha, fX, fY;\n        center.x = (u + 0.5) * ratioX;\n        icenter.x = floor(center.x);\n        for (v = 0; v < dH; v++) {\n          center.y = (v + 0.5) * ratioY;\n          icenter.y = floor(center.y);\n          a = 0; red = 0; green = 0; blue = 0; alpha = 0;\n          for (i = icenter.x - range2X; i <= icenter.x + range2X; i++) {\n            if (i < 0 || i >= oW) {\n              continue;\n            }\n            fX = floor(1000 * abs(i - center.x));\n            if (!cacheLanc[fX]) {\n              cacheLanc[fX] = { };\n            }\n            for (var j = icenter.y - range2Y; j <= icenter.y + range2Y; j++) {\n              if (j < 0 || j >= oH) {\n                continue;\n              }\n              fY = floor(1000 * abs(j - center.y));\n              if (!cacheLanc[fX][fY]) {\n                cacheLanc[fX][fY] = lanczos(sqrt(pow(fX * rcpRatioX, 2) + pow(fY * rcpRatioY, 2)) / 1000);\n              }\n              weight = cacheLanc[fX][fY];\n              if (weight > 0) {\n                idx = (j * oW + i) * 4;\n                a += weight;\n                red += weight * srcData[idx];\n                green += weight * srcData[idx + 1];\n                blue += weight * srcData[idx + 2];\n                alpha += weight * srcData[idx + 3];\n              }\n            }\n          }\n          idx = (v * dW + u) * 4;\n          destData[idx] = red / a;\n          destData[idx + 1] = green / a;\n          destData[idx + 2] = blue / a;\n          destData[idx + 3] = alpha / a;\n        }\n\n        if (++u < dW) {\n          return process(u);\n        }\n        else {\n          return destImg;\n        }\n      }\n\n      var srcData = options.imageData.data,\n          destImg = options.ctx.createImageData(dW, dH),\n          destData = destImg.data,\n          lanczos = this.lanczosCreate(this.lanczosLobes),\n          ratioX = this.rcpScaleX, ratioY = this.rcpScaleY,\n          rcpRatioX = 2 / this.rcpScaleX, rcpRatioY = 2 / this.rcpScaleY,\n          range2X = ceil(ratioX * this.lanczosLobes / 2),\n          range2Y = ceil(ratioY * this.lanczosLobes / 2),\n          cacheLanc = { }, center = { }, icenter = { };\n\n      return process(0);\n    },\n\n    /**\n     * bilinearFiltering\n     * @param {Object} canvasEl Canvas element to apply filter to\n     * @param {Number} oW Original Width\n     * @param {Number} oH Original Height\n     * @param {Number} dW Destination Width\n     * @param {Number} dH Destination Height\n     * @returns {ImageData}\n     */\n    bilinearFiltering: function(options, oW, oH, dW, dH) {\n      var a, b, c, d, x, y, i, j, xDiff, yDiff, chnl,\n          color, offset = 0, origPix, ratioX = this.rcpScaleX,\n          ratioY = this.rcpScaleY,\n          w4 = 4 * (oW - 1), img = options.imageData,\n          pixels = img.data, destImage = options.ctx.createImageData(dW, dH),\n          destPixels = destImage.data;\n      for (i = 0; i < dH; i++) {\n        for (j = 0; j < dW; j++) {\n          x = floor(ratioX * j);\n          y = floor(ratioY * i);\n          xDiff = ratioX * j - x;\n          yDiff = ratioY * i - y;\n          origPix = 4 * (y * oW + x);\n\n          for (chnl = 0; chnl < 4; chnl++) {\n            a = pixels[origPix + chnl];\n            b = pixels[origPix + 4 + chnl];\n            c = pixels[origPix + w4 + chnl];\n            d = pixels[origPix + w4 + 4 + chnl];\n            color = a * (1 - xDiff) * (1 - yDiff) + b * xDiff * (1 - yDiff) +\n                    c * yDiff * (1 - xDiff) + d * xDiff * yDiff;\n            destPixels[offset++] = color;\n          }\n        }\n      }\n      return destImage;\n    },\n\n    /**\n     * hermiteFastResize\n     * @param {Object} canvasEl Canvas element to apply filter to\n     * @param {Number} oW Original Width\n     * @param {Number} oH Original Height\n     * @param {Number} dW Destination Width\n     * @param {Number} dH Destination Height\n     * @returns {ImageData}\n     */\n    hermiteFastResize: function(options, oW, oH, dW, dH) {\n      var ratioW = this.rcpScaleX, ratioH = this.rcpScaleY,\n          ratioWHalf = ceil(ratioW / 2),\n          ratioHHalf = ceil(ratioH / 2),\n          img = options.imageData, data = img.data,\n          img2 = options.ctx.createImageData(dW, dH), data2 = img2.data;\n      for (var j = 0; j < dH; j++) {\n        for (var i = 0; i < dW; i++) {\n          var x2 = (i + j * dW) * 4, weight = 0, weights = 0, weightsAlpha = 0,\n              gxR = 0, gxG = 0, gxB = 0, gxA = 0, centerY = (j + 0.5) * ratioH;\n          for (var yy = floor(j * ratioH); yy < (j + 1) * ratioH; yy++) {\n            var dy = abs(centerY - (yy + 0.5)) / ratioHHalf,\n                centerX = (i + 0.5) * ratioW, w0 = dy * dy;\n            for (var xx = floor(i * ratioW); xx < (i + 1) * ratioW; xx++) {\n              var dx = abs(centerX - (xx + 0.5)) / ratioWHalf,\n                  w = sqrt(w0 + dx * dx);\n              /* eslint-disable max-depth */\n              if (w > 1 && w < -1) {\n                continue;\n              }\n              //hermite filter\n              weight = 2 * w * w * w - 3 * w * w + 1;\n              if (weight > 0) {\n                dx = 4 * (xx + yy * oW);\n                //alpha\n                gxA += weight * data[dx + 3];\n                weightsAlpha += weight;\n                //colors\n                if (data[dx + 3] < 255) {\n                  weight = weight * data[dx + 3] / 250;\n                }\n                gxR += weight * data[dx];\n                gxG += weight * data[dx + 1];\n                gxB += weight * data[dx + 2];\n                weights += weight;\n              }\n              /* eslint-enable max-depth */\n            }\n          }\n          data2[x2] = gxR / weights;\n          data2[x2 + 1] = gxG / weights;\n          data2[x2 + 2] = gxB / weights;\n          data2[x2 + 3] = gxA / weightsAlpha;\n        }\n      }\n      return img2;\n    },\n\n    /**\n     * Returns object representation of an instance\n     * @return {Object} Object representation of an instance\n     */\n    toObject: function() {\n      return {\n        type: this.type,\n        scaleX: this.scaleX,\n        scaleY: this.scaleY,\n        resizeType: this.resizeType,\n        lanczosLobes: this.lanczosLobes\n      };\n    }\n  });\n\n  /**\n   * Returns filter instance from an object representation\n   * @static\n   * @param {Object} object Object to create an instance from\n   * @param {Function} [callback] to be invoked after filter creation\n   * @return {fabric.Image.filters.Resize} Instance of fabric.Image.filters.Resize\n   */\n  fabric.Image.filters.Resize.fromObject = fabric.Image.filters.BaseFilter.fromObject;\n\n})(typeof exports !== 'undefined' ? exports : this);\n\n\n(function(global) {\n\n  'use strict';\n\n  var fabric  = global.fabric || (global.fabric = { }),\n      filters = fabric.Image.filters,\n      createClass = fabric.util.createClass;\n\n  /**\n   * Contrast filter class\n   * @class fabric.Image.filters.Contrast\n   * @memberOf fabric.Image.filters\n   * @extends fabric.Image.filters.BaseFilter\n   * @see {@link fabric.Image.filters.Contrast#initialize} for constructor definition\n   * @see {@link http://fabricjs.com/image-filters|ImageFilters demo}\n   * @example\n   * var filter = new fabric.Image.filters.Contrast({\n   *   contrast: 40\n   * });\n   * object.filters.push(filter);\n   * object.applyFilters();\n   */\n  filters.Contrast = createClass(filters.BaseFilter, /** @lends fabric.Image.filters.Contrast.prototype */ {\n\n    /**\n     * Filter type\n     * @param {String} type\n     * @default\n     */\n    type: 'Contrast',\n\n    fragmentSource: 'precision highp float;\\n' +\n      'uniform sampler2D uTexture;\\n' +\n      'uniform float uContrast;\\n' +\n      'varying vec2 vTexCoord;\\n' +\n      'void main() {\\n' +\n        'vec4 color = texture2D(uTexture, vTexCoord);\\n' +\n        'float contrastF = 1.015 * (uContrast + 1.0) / (1.0 * (1.015 - uContrast));\\n' +\n        'color.rgb = contrastF * (color.rgb - 0.5) + 0.5;\\n' +\n        'gl_FragColor = color;\\n' +\n      '}',\n\n    contrast: 0,\n\n    mainParameter: 'contrast',\n\n    /**\n     * Constructor\n     * @memberOf fabric.Image.filters.Contrast.prototype\n     * @param {Object} [options] Options object\n     * @param {Number} [options.contrast=0] Value to contrast the image up (-1...1)\n     */\n\n    /**\n      * Apply the Contrast operation to a Uint8Array representing the pixels of an image.\n      *\n      * @param {Object} options\n      * @param {ImageData} options.imageData The Uint8Array to be filtered.\n      */\n    applyTo2d: function(options) {\n      if (this.contrast === 0) {\n        return;\n      }\n      var imageData = options.imageData, i, len,\n          data = imageData.data, len = data.length,\n          contrast = Math.floor(this.contrast * 255),\n          contrastF = 259 * (contrast + 255) / (255 * (259 - contrast));\n\n      for (i = 0; i < len; i += 4) {\n        data[i] = contrastF * (data[i] - 128) + 128;\n        data[i + 1] = contrastF * (data[i + 1] - 128) + 128;\n        data[i + 2] = contrastF * (data[i + 2] - 128) + 128;\n      }\n    },\n\n    /**\n     * Return WebGL uniform locations for this filter's shader.\n     *\n     * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader.\n     * @param {WebGLShaderProgram} program This filter's compiled shader program.\n     */\n    getUniformLocations: function(gl, program) {\n      return {\n        uContrast: gl.getUniformLocation(program, 'uContrast'),\n      };\n    },\n\n    /**\n     * Send data from this filter to its shader program's uniforms.\n     *\n     * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader.\n     * @param {Object} uniformLocations A map of string uniform names to WebGLUniformLocation objects\n     */\n    sendUniformData: function(gl, uniformLocations) {\n      gl.uniform1f(uniformLocations.uContrast, this.contrast);\n    },\n  });\n\n  /**\n   * Returns filter instance from an object representation\n   * @static\n   * @param {Object} object Object to create an instance from\n   * @param {function} [callback] to be invoked after filter creation\n   * @return {fabric.Image.filters.Contrast} Instance of fabric.Image.filters.Contrast\n   */\n  fabric.Image.filters.Contrast.fromObject = fabric.Image.filters.BaseFilter.fromObject;\n\n})(typeof exports !== 'undefined' ? exports : this);\n\n\n(function(global) {\n\n  'use strict';\n\n  var fabric  = global.fabric || (global.fabric = { }),\n      filters = fabric.Image.filters,\n      createClass = fabric.util.createClass;\n\n  /**\n   * Saturate filter class\n   * @class fabric.Image.filters.Saturation\n   * @memberOf fabric.Image.filters\n   * @extends fabric.Image.filters.BaseFilter\n   * @see {@link fabric.Image.filters.Saturation#initialize} for constructor definition\n   * @see {@link http://fabricjs.com/image-filters|ImageFilters demo}\n   * @example\n   * var filter = new fabric.Image.filters.Saturation({\n   *   saturation: 100\n   * });\n   * object.filters.push(filter);\n   * object.applyFilters();\n   */\n  filters.Saturation = createClass(filters.BaseFilter, /** @lends fabric.Image.filters.Saturation.prototype */ {\n\n    /**\n     * Filter type\n     * @param {String} type\n     * @default\n     */\n    type: 'Saturation',\n\n    fragmentSource: 'precision highp float;\\n' +\n      'uniform sampler2D uTexture;\\n' +\n      'uniform float uSaturation;\\n' +\n      'varying vec2 vTexCoord;\\n' +\n      'void main() {\\n' +\n        'vec4 color = texture2D(uTexture, vTexCoord);\\n' +\n        'float rgMax = max(color.r, color.g);\\n' +\n        'float rgbMax = max(rgMax, color.b);\\n' +\n        'color.r += rgbMax != color.r ? (rgbMax - color.r) * uSaturation : 0.00;\\n' +\n        'color.g += rgbMax != color.g ? (rgbMax - color.g) * uSaturation : 0.00;\\n' +\n        'color.b += rgbMax != color.b ? (rgbMax - color.b) * uSaturation : 0.00;\\n' +\n        'gl_FragColor = color;\\n' +\n      '}',\n\n    saturation: 0,\n\n    mainParameter: 'saturation',\n\n    /**\n     * Constructor\n     * @memberOf fabric.Image.filters.Saturate.prototype\n     * @param {Object} [options] Options object\n     * @param {Number} [options.saturate=0] Value to saturate the image (-1...1)\n     */\n\n    /**\n     * Apply the Saturation operation to a Uint8ClampedArray representing the pixels of an image.\n     *\n     * @param {Object} options\n     * @param {ImageData} options.imageData The Uint8ClampedArray to be filtered.\n     */\n    applyTo2d: function(options) {\n      if (this.saturation === 0) {\n        return;\n      }\n      var imageData = options.imageData,\n          data = imageData.data, len = data.length,\n          adjust = -this.saturation, i, max;\n\n      for (i = 0; i < len; i += 4) {\n        max = Math.max(data[i], data[i + 1], data[i + 2]);\n        data[i] += max !== data[i] ? (max - data[i]) * adjust : 0;\n        data[i + 1] += max !== data[i + 1] ? (max - data[i + 1]) * adjust : 0;\n        data[i + 2] += max !== data[i + 2] ? (max - data[i + 2]) * adjust : 0;\n      }\n    },\n\n    /**\n     * Return WebGL uniform locations for this filter's shader.\n     *\n     * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader.\n     * @param {WebGLShaderProgram} program This filter's compiled shader program.\n     */\n    getUniformLocations: function(gl, program) {\n      return {\n        uSaturation: gl.getUniformLocation(program, 'uSaturation'),\n      };\n    },\n\n    /**\n     * Send data from this filter to its shader program's uniforms.\n     *\n     * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader.\n     * @param {Object} uniformLocations A map of string uniform names to WebGLUniformLocation objects\n     */\n    sendUniformData: function(gl, uniformLocations) {\n      gl.uniform1f(uniformLocations.uSaturation, -this.saturation);\n    },\n  });\n\n  /**\n   * Returns filter instance from an object representation\n   * @static\n   * @param {Object} object Object to create an instance from\n   * @param {Function} [callback] to be invoked after filter creation\n   * @return {fabric.Image.filters.Saturation} Instance of fabric.Image.filters.Saturate\n   */\n  fabric.Image.filters.Saturation.fromObject = fabric.Image.filters.BaseFilter.fromObject;\n\n})(typeof exports !== 'undefined' ? exports : this);\n\n\n(function(global) {\n\n  'use strict';\n\n  var fabric  = global.fabric || (global.fabric = { }),\n      filters = fabric.Image.filters,\n      createClass = fabric.util.createClass;\n\n  /**\n   * Blur filter class\n   * @class fabric.Image.filters.Blur\n   * @memberOf fabric.Image.filters\n   * @extends fabric.Image.filters.BaseFilter\n   * @see {@link fabric.Image.filters.Blur#initialize} for constructor definition\n   * @see {@link http://fabricjs.com/image-filters|ImageFilters demo}\n   * @example\n   * var filter = new fabric.Image.filters.Blur({\n   *   blur: 0.5\n   * });\n   * object.filters.push(filter);\n   * object.applyFilters();\n   * canvas.renderAll();\n   */\n  filters.Blur = createClass(filters.BaseFilter, /** @lends fabric.Image.filters.Blur.prototype */ {\n\n    type: 'Blur',\n\n    /*\n'gl_FragColor = vec4(0.0);',\n'gl_FragColor += texture2D(texture, vTexCoord + -7 * uDelta)*0.0044299121055113265;',\n'gl_FragColor += texture2D(texture, vTexCoord + -6 * uDelta)*0.00895781211794;',\n'gl_FragColor += texture2D(texture, vTexCoord + -5 * uDelta)*0.0215963866053;',\n'gl_FragColor += texture2D(texture, vTexCoord + -4 * uDelta)*0.0443683338718;',\n'gl_FragColor += texture2D(texture, vTexCoord + -3 * uDelta)*0.0776744219933;',\n'gl_FragColor += texture2D(texture, vTexCoord + -2 * uDelta)*0.115876621105;',\n'gl_FragColor += texture2D(texture, vTexCoord + -1 * uDelta)*0.147308056121;',\n'gl_FragColor += texture2D(texture, vTexCoord              )*0.159576912161;',\n'gl_FragColor += texture2D(texture, vTexCoord + 1 * uDelta)*0.147308056121;',\n'gl_FragColor += texture2D(texture, vTexCoord + 2 * uDelta)*0.115876621105;',\n'gl_FragColor += texture2D(texture, vTexCoord + 3 * uDelta)*0.0776744219933;',\n'gl_FragColor += texture2D(texture, vTexCoord + 4 * uDelta)*0.0443683338718;',\n'gl_FragColor += texture2D(texture, vTexCoord + 5 * uDelta)*0.0215963866053;',\n'gl_FragColor += texture2D(texture, vTexCoord + 6 * uDelta)*0.00895781211794;',\n'gl_FragColor += texture2D(texture, vTexCoord + 7 * uDelta)*0.0044299121055113265;',\n*/\n\n    /* eslint-disable max-len */\n    fragmentSource: 'precision highp float;\\n' +\n      'uniform sampler2D uTexture;\\n' +\n      'uniform vec2 uDelta;\\n' +\n      'varying vec2 vTexCoord;\\n' +\n      'const float nSamples = 15.0;\\n' +\n      'vec3 v3offset = vec3(12.9898, 78.233, 151.7182);\\n' +\n      'float random(vec3 scale) {\\n' +\n        /* use the fragment position for a different seed per-pixel */\n        'return fract(sin(dot(gl_FragCoord.xyz, scale)) * 43758.5453);\\n' +\n      '}\\n' +\n      'void main() {\\n' +\n        'vec4 color = vec4(0.0);\\n' +\n        'float total = 0.0;\\n' +\n        'float offset = random(v3offset);\\n' +\n        'for (float t = -nSamples; t <= nSamples; t++) {\\n' +\n          'float percent = (t + offset - 0.5) / nSamples;\\n' +\n          'float weight = 1.0 - abs(percent);\\n' +\n          'color += texture2D(uTexture, vTexCoord + uDelta * percent) * weight;\\n' +\n          'total += weight;\\n' +\n        '}\\n' +\n        'gl_FragColor = color / total;\\n' +\n      '}',\n    /* eslint-enable max-len */\n\n    /**\n     * blur value, in percentage of image dimensions.\n     * specific to keep the image blur constant at different resolutions\n     * range bewteen 0 and 1.\n     */\n    blur: 0,\n\n    mainParameter: 'blur',\n\n    applyTo: function(options) {\n      if (options.webgl) {\n        // this aspectRatio is used to give the same blur to vertical and horizontal\n        this.aspectRatio = options.sourceWidth / options.sourceHeight;\n        options.passes++;\n        this._setupFrameBuffer(options);\n        this.horizontal = true;\n        this.applyToWebGL(options);\n        this._swapTextures(options);\n        this._setupFrameBuffer(options);\n        this.horizontal = false;\n        this.applyToWebGL(options);\n        this._swapTextures(options);\n      }\n      else {\n        this.applyTo2d(options);\n      }\n    },\n\n    applyTo2d: function(options) {\n      // paint canvasEl with current image data.\n      //options.ctx.putImageData(options.imageData, 0, 0);\n      options.imageData = this.simpleBlur(options);\n    },\n\n    simpleBlur: function(options) {\n      var resources = options.filterBackend.resources, canvas1, canvas2,\n          width = options.imageData.width,\n          height = options.imageData.height;\n\n      if (!resources.blurLayer1) {\n        resources.blurLayer1 = fabric.util.createCanvasElement();\n        resources.blurLayer2 = fabric.util.createCanvasElement();\n      }\n      canvas1 = resources.blurLayer1;\n      canvas2 = resources.blurLayer2;\n      if (canvas1.width !== width || canvas1.height !== height) {\n        canvas2.width = canvas1.width = width;\n        canvas2.height = canvas1.height = height;\n      }\n      var ctx1 = canvas1.getContext('2d'),\n          ctx2 = canvas2.getContext('2d'),\n          nSamples = 15,\n          random, percent, j, i,\n          blur = this.blur * 0.06 * 0.5;\n\n      // load first canvas\n      ctx1.putImageData(options.imageData, 0, 0);\n      ctx2.clearRect(0, 0, width, height);\n\n      for (i = -nSamples; i <= nSamples; i++) {\n        random = (Math.random() - 0.5) / 4;\n        percent = i / nSamples;\n        j = blur * percent * width + random;\n        ctx2.globalAlpha = 1 - Math.abs(percent);\n        ctx2.drawImage(canvas1, j, random);\n        ctx1.drawImage(canvas2, 0, 0);\n        ctx2.globalAlpha = 1;\n        ctx2.clearRect(0, 0, canvas2.width, canvas2.height);\n      }\n      for (i = -nSamples; i <= nSamples; i++) {\n        random = (Math.random() - 0.5) / 4;\n        percent = i / nSamples;\n        j = blur * percent * height + random;\n        ctx2.globalAlpha = 1 - Math.abs(percent);\n        ctx2.drawImage(canvas1, random, j);\n        ctx1.drawImage(canvas2, 0, 0);\n        ctx2.globalAlpha = 1;\n        ctx2.clearRect(0, 0, canvas2.width, canvas2.height);\n      }\n      options.ctx.drawImage(canvas1, 0, 0);\n      var newImageData = options.ctx.getImageData(0, 0, canvas1.width, canvas1.height);\n      ctx1.globalAlpha = 1;\n      ctx1.clearRect(0, 0, canvas1.width, canvas1.height);\n      return newImageData;\n    },\n\n    /**\n     * Return WebGL uniform locations for this filter's shader.\n     *\n     * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader.\n     * @param {WebGLShaderProgram} program This filter's compiled shader program.\n     */\n    getUniformLocations: function(gl, program) {\n      return {\n        delta: gl.getUniformLocation(program, 'uDelta'),\n      };\n    },\n\n    /**\n     * Send data from this filter to its shader program's uniforms.\n     *\n     * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader.\n     * @param {Object} uniformLocations A map of string uniform names to WebGLUniformLocation objects\n     */\n    sendUniformData: function(gl, uniformLocations) {\n      var delta = this.chooseRightDelta();\n      gl.uniform2fv(uniformLocations.delta, delta);\n    },\n\n    /**\n     * choose right value of image percentage to blur with\n     * @returns {Array} a numeric array with delta values\n     */\n    chooseRightDelta: function() {\n      var blurScale = 1, delta = [0, 0], blur;\n      if (this.horizontal) {\n        if (this.aspectRatio > 1) {\n          // image is wide, i want to shrink radius horizontal\n          blurScale = 1 / this.aspectRatio;\n        }\n      }\n      else {\n        if (this.aspectRatio < 1) {\n          // image is tall, i want to shrink radius vertical\n          blurScale = this.aspectRatio;\n        }\n      }\n      blur = blurScale * this.blur * 0.12;\n      if (this.horizontal) {\n        delta[0] = blur;\n      }\n      else {\n        delta[1] = blur;\n      }\n      return delta;\n    },\n  });\n\n  /**\n   * Deserialize a JSON definition of a BlurFilter into a concrete instance.\n   */\n  filters.Blur.fromObject = fabric.Image.filters.BaseFilter.fromObject;\n\n})(typeof exports !== 'undefined' ? exports : this);\n\n\n(function(global) {\n\n  'use strict';\n\n  var fabric  = global.fabric || (global.fabric = { }),\n      filters = fabric.Image.filters,\n      createClass = fabric.util.createClass;\n\n  /**\n   * Gamma filter class\n   * @class fabric.Image.filters.Gamma\n   * @memberOf fabric.Image.filters\n   * @extends fabric.Image.filters.BaseFilter\n   * @see {@link fabric.Image.filters.Gamma#initialize} for constructor definition\n   * @see {@link http://fabricjs.com/image-filters|ImageFilters demo}\n   * @example\n   * var filter = new fabric.Image.filters.Gamma({\n   *   brightness: 200\n   * });\n   * object.filters.push(filter);\n   * object.applyFilters();\n   */\n  filters.Gamma = createClass(filters.BaseFilter, /** @lends fabric.Image.filters.Gamma.prototype */ {\n\n    /**\n     * Filter type\n     * @param {String} type\n     * @default\n     */\n    type: 'Gamma',\n\n    fragmentSource: 'precision highp float;\\n' +\n      'uniform sampler2D uTexture;\\n' +\n      'uniform vec3 uGamma;\\n' +\n      'varying vec2 vTexCoord;\\n' +\n      'void main() {\\n' +\n        'vec4 color = texture2D(uTexture, vTexCoord);\\n' +\n        'vec3 correction = (1.0 / uGamma);\\n' +\n        'color.r = pow(color.r, correction.r);\\n' +\n        'color.g = pow(color.g, correction.g);\\n' +\n        'color.b = pow(color.b, correction.b);\\n' +\n        'gl_FragColor = color;\\n' +\n        'gl_FragColor.rgb *= color.a;\\n' +\n      '}',\n\n    /**\n     * Gamma array value, from 0.01 to 2.2.\n     * @param {Array} gamma\n     * @default\n     */\n    gamma: [1, 1, 1],\n\n    /**\n     * Describe the property that is the filter parameter\n     * @param {String} m\n     * @default\n     */\n    mainParameter: 'gamma',\n\n    /**\n     * Constructor\n     * @param {Object} [options] Options object\n     */\n    initialize: function(options) {\n      this.gamma = [1, 1, 1];\n      filters.BaseFilter.prototype.initialize.call(this, options);\n    },\n\n    /**\n     * Apply the Gamma operation to a Uint8Array representing the pixels of an image.\n     *\n     * @param {Object} options\n     * @param {ImageData} options.imageData The Uint8Array to be filtered.\n     */\n    applyTo2d: function(options) {\n      var imageData = options.imageData, data = imageData.data,\n          gamma = this.gamma, len = data.length,\n          rInv = 1 / gamma[0], gInv = 1 / gamma[1],\n          bInv = 1 / gamma[2], i;\n\n      if (!this.rVals) {\n        // eslint-disable-next-line\n        this.rVals = new Uint8Array(256);\n        // eslint-disable-next-line\n        this.gVals = new Uint8Array(256);\n        // eslint-disable-next-line\n        this.bVals = new Uint8Array(256);\n      }\n\n      // This is an optimization - pre-compute a look-up table for each color channel\n      // instead of performing these pow calls for each pixel in the image.\n      for (i = 0, len = 256; i < len; i++) {\n        this.rVals[i] = Math.pow(i / 255, rInv) * 255;\n        this.gVals[i] = Math.pow(i / 255, gInv) * 255;\n        this.bVals[i] = Math.pow(i / 255, bInv) * 255;\n      }\n      for (i = 0, len = data.length; i < len; i += 4) {\n        data[i] = this.rVals[data[i]];\n        data[i + 1] = this.gVals[data[i + 1]];\n        data[i + 2] = this.bVals[data[i + 2]];\n      }\n    },\n\n    /**\n     * Return WebGL uniform locations for this filter's shader.\n     *\n     * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader.\n     * @param {WebGLShaderProgram} program This filter's compiled shader program.\n     */\n    getUniformLocations: function(gl, program) {\n      return {\n        uGamma: gl.getUniformLocation(program, 'uGamma'),\n      };\n    },\n\n    /**\n     * Send data from this filter to its shader program's uniforms.\n     *\n     * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader.\n     * @param {Object} uniformLocations A map of string uniform names to WebGLUniformLocation objects\n     */\n    sendUniformData: function(gl, uniformLocations) {\n      gl.uniform3fv(uniformLocations.uGamma, this.gamma);\n    },\n  });\n\n  /**\n   * Returns filter instance from an object representation\n   * @static\n   * @param {Object} object Object to create an instance from\n   * @param {function} [callback] to be invoked after filter creation\n   * @return {fabric.Image.filters.Gamma} Instance of fabric.Image.filters.Gamma\n   */\n  fabric.Image.filters.Gamma.fromObject = fabric.Image.filters.BaseFilter.fromObject;\n\n})(typeof exports !== 'undefined' ? exports : this);\n\n\n(function(global) {\n\n  'use strict';\n\n  var fabric  = global.fabric || (global.fabric = { }),\n      filters = fabric.Image.filters,\n      createClass = fabric.util.createClass;\n\n  /**\n   * A container class that knows how to apply a sequence of filters to an input image.\n   */\n  filters.Composed = createClass(filters.BaseFilter, /** @lends fabric.Image.filters.Composed.prototype */ {\n\n    type: 'Composed',\n\n    /**\n     * A non sparse array of filters to apply\n     */\n    subFilters: [],\n\n    /**\n     * Constructor\n     * @param {Object} [options] Options object\n     */\n    initialize: function(options) {\n      this.callSuper('initialize', options);\n      // create a new array instead mutating the prototype with push\n      this.subFilters = this.subFilters.slice(0);\n    },\n\n    /**\n     * Apply this container's filters to the input image provided.\n     *\n     * @param {Object} options\n     * @param {Number} options.passes The number of filters remaining to be applied.\n     */\n    applyTo: function(options) {\n      options.passes += this.subFilters.length - 1;\n      this.subFilters.forEach(function(filter) {\n        filter.applyTo(options);\n      });\n    },\n\n    /**\n     * Serialize this filter into JSON.\n     *\n     * @returns {Object} A JSON representation of this filter.\n     */\n    toObject: function() {\n      return fabric.util.object.extend(this.callSuper('toObject'), {\n        subFilters: this.subFilters.map(function(filter) { return filter.toObject(); }),\n      });\n    },\n\n    isNeutralState: function() {\n      return !this.subFilters.some(function(filter) { return !filter.isNeutralState(); });\n    }\n  });\n\n  /**\n   * Deserialize a JSON definition of a ComposedFilter into a concrete instance.\n   */\n  fabric.Image.filters.Composed.fromObject = function(object, callback) {\n    var filters = object.subFilters || [],\n        subFilters = filters.map(function(filter) {\n          return new fabric.Image.filters[filter.type](filter);\n        }),\n        instance = new fabric.Image.filters.Composed({ subFilters: subFilters });\n    callback && callback(instance);\n    return instance;\n  };\n})(typeof exports !== 'undefined' ? exports : this);\n\n\n(function(global) {\n\n  'use strict';\n\n  var fabric  = global.fabric || (global.fabric = { }),\n      filters = fabric.Image.filters,\n      createClass = fabric.util.createClass;\n\n  /**\n   * HueRotation filter class\n   * @class fabric.Image.filters.HueRotation\n   * @memberOf fabric.Image.filters\n   * @extends fabric.Image.filters.BaseFilter\n   * @see {@link fabric.Image.filters.HueRotation#initialize} for constructor definition\n   * @see {@link http://fabricjs.com/image-filters|ImageFilters demo}\n   * @example\n   * var filter = new fabric.Image.filters.HueRotation({\n   *   rotation: -0.5\n   * });\n   * object.filters.push(filter);\n   * object.applyFilters();\n   */\n  filters.HueRotation = createClass(filters.ColorMatrix, /** @lends fabric.Image.filters.HueRotation.prototype */ {\n\n    /**\n     * Filter type\n     * @param {String} type\n     * @default\n     */\n    type: 'HueRotation',\n\n    /**\n     * HueRotation value, from -1 to 1.\n     * the unit is radians\n     * @param {Number} myParameter\n     * @default\n     */\n    rotation: 0,\n\n    /**\n     * Describe the property that is the filter parameter\n     * @param {String} m\n     * @default\n     */\n    mainParameter: 'rotation',\n\n    calculateMatrix: function() {\n      var rad = this.rotation * Math.PI, cos = fabric.util.cos(rad), sin = fabric.util.sin(rad),\n          aThird = 1 / 3, aThirdSqtSin = Math.sqrt(aThird) * sin, OneMinusCos = 1 - cos;\n      this.matrix = [\n        1, 0, 0, 0, 0,\n        0, 1, 0, 0, 0,\n        0, 0, 1, 0, 0,\n        0, 0, 0, 1, 0\n      ];\n      this.matrix[0] = cos + OneMinusCos / 3;\n      this.matrix[1] = aThird * OneMinusCos - aThirdSqtSin;\n      this.matrix[2] = aThird * OneMinusCos + aThirdSqtSin;\n      this.matrix[5] = aThird * OneMinusCos + aThirdSqtSin;\n      this.matrix[6] = cos + aThird * OneMinusCos;\n      this.matrix[7] = aThird * OneMinusCos - aThirdSqtSin;\n      this.matrix[10] = aThird * OneMinusCos - aThirdSqtSin;\n      this.matrix[11] = aThird * OneMinusCos + aThirdSqtSin;\n      this.matrix[12] = cos + aThird * OneMinusCos;\n    },\n\n    /**\n     * HueRotation isNeutralState implementation\n     * Used only in image applyFilters to discard filters that will not have an effect\n     * on the image\n     * @param {Object} options\n     **/\n    isNeutralState: function(options) {\n      this.calculateMatrix();\n      return filters.BaseFilter.prototype.isNeutralState.call(this, options);\n    },\n\n    /**\n     * Apply this filter to the input image data provided.\n     *\n     * Determines whether to use WebGL or Canvas2D based on the options.webgl flag.\n     *\n     * @param {Object} options\n     * @param {Number} options.passes The number of filters remaining to be executed\n     * @param {Boolean} options.webgl Whether to use webgl to render the filter.\n     * @param {WebGLTexture} options.sourceTexture The texture setup as the source to be filtered.\n     * @param {WebGLTexture} options.targetTexture The texture where filtered output should be drawn.\n     * @param {WebGLRenderingContext} options.context The GL context used for rendering.\n     * @param {Object} options.programCache A map of compiled shader programs, keyed by filter type.\n     */\n    applyTo: function(options) {\n      this.calculateMatrix();\n      filters.BaseFilter.prototype.applyTo.call(this, options);\n    },\n\n  });\n\n  /**\n   * Returns filter instance from an object representation\n   * @static\n   * @param {Object} object Object to create an instance from\n   * @param {function} [callback] to be invoked after filter creation\n   * @return {fabric.Image.filters.HueRotation} Instance of fabric.Image.filters.HueRotation\n   */\n  fabric.Image.filters.HueRotation.fromObject = fabric.Image.filters.BaseFilter.fromObject;\n\n})(typeof exports !== 'undefined' ? exports : this);\n\n\n(function(global) {\n\n  'use strict';\n\n  var fabric = global.fabric || (global.fabric = { }),\n      clone = fabric.util.object.clone;\n\n  if (fabric.Text) {\n    fabric.warn('fabric.Text is already defined');\n    return;\n  }\n\n  /**\n   * Text class\n   * @class fabric.Text\n   * @extends fabric.Object\n   * @return {fabric.Text} thisArg\n   * @tutorial {@link http://fabricjs.com/fabric-intro-part-2#text}\n   * @see {@link fabric.Text#initialize} for constructor definition\n   */\n  fabric.Text = fabric.util.createClass(fabric.Object, /** @lends fabric.Text.prototype */ {\n\n    /**\n     * Properties which when set cause object to change dimensions\n     * @type Array\n     * @private\n     */\n    _dimensionAffectingProps: [\n      'fontSize',\n      'fontWeight',\n      'fontFamily',\n      'fontStyle',\n      'lineHeight',\n      'text',\n      'charSpacing',\n      'textAlign',\n      'styles',\n    ],\n\n    /**\n     * @private\n     */\n    _reNewline: /\\r?\\n/,\n\n    /**\n     * Use this regular expression to filter for whitespaces that is not a new line.\n     * Mostly used when text is 'justify' aligned.\n     * @private\n     */\n    _reSpacesAndTabs: /[ \\t\\r]/g,\n\n    /**\n     * Use this regular expression to filter for whitespace that is not a new line.\n     * Mostly used when text is 'justify' aligned.\n     * @private\n     */\n    _reSpaceAndTab: /[ \\t\\r]/,\n\n    /**\n     * Use this regular expression to filter consecutive groups of non spaces.\n     * Mostly used when text is 'justify' aligned.\n     * @private\n     */\n    _reWords: /\\S+/g,\n\n    /**\n     * Type of an object\n     * @type String\n     * @default\n     */\n    type:                 'text',\n\n    /**\n     * Font size (in pixels)\n     * @type Number\n     * @default\n     */\n    fontSize:             40,\n\n    /**\n     * Font weight (e.g. bold, normal, 400, 600, 800)\n     * @type {(Number|String)}\n     * @default\n     */\n    fontWeight:           'normal',\n\n    /**\n     * Font family\n     * @type String\n     * @default\n     */\n    fontFamily:           'Times New Roman',\n\n    /**\n     * Text decoration underline.\n     * @type Boolean\n     * @default\n     */\n    underline:       false,\n\n    /**\n     * Text decoration overline.\n     * @type Boolean\n     * @default\n     */\n    overline:       false,\n\n    /**\n     * Text decoration linethrough.\n     * @type Boolean\n     * @default\n     */\n    linethrough:       false,\n\n    /**\n     * Text alignment. Possible values: \"left\", \"center\", \"right\", \"justify\",\n     * \"justify-left\", \"justify-center\" or \"justify-right\".\n     * @type String\n     * @default\n     */\n    textAlign:            'left',\n\n    /**\n     * Font style . Possible values: \"\", \"normal\", \"italic\" or \"oblique\".\n     * @type String\n     * @default\n     */\n    fontStyle:            'normal',\n\n    /**\n     * Line height\n     * @type Number\n     * @default\n     */\n    lineHeight:           1.16,\n\n    /**\n     * Superscript schema object (minimum overlap)\n     * @type {Object}\n     * @default\n     */\n    superscript: {\n      size:      0.60, // fontSize factor\n      baseline: -0.35  // baseline-shift factor (upwards)\n    },\n\n    /**\n     * Subscript schema object (minimum overlap)\n     * @type {Object}\n     * @default\n     */\n    subscript: {\n      size:      0.60, // fontSize factor\n      baseline:  0.11  // baseline-shift factor (downwards)\n    },\n\n    /**\n     * Background color of text lines\n     * @type String\n     * @default\n     */\n    textBackgroundColor:  '',\n\n    /**\n     * List of properties to consider when checking if\n     * state of an object is changed ({@link fabric.Object#hasStateChanged})\n     * as well as for history (undo/redo) purposes\n     * @type Array\n     */\n    stateProperties: fabric.Object.prototype.stateProperties.concat('fontFamily',\n      'fontWeight',\n      'fontSize',\n      'text',\n      'underline',\n      'overline',\n      'linethrough',\n      'textAlign',\n      'fontStyle',\n      'lineHeight',\n      'textBackgroundColor',\n      'charSpacing',\n      'styles'),\n\n    /**\n     * List of properties to consider when checking if cache needs refresh\n     * @type Array\n     */\n    cacheProperties: fabric.Object.prototype.cacheProperties.concat('fontFamily',\n      'fontWeight',\n      'fontSize',\n      'text',\n      'underline',\n      'overline',\n      'linethrough',\n      'textAlign',\n      'fontStyle',\n      'lineHeight',\n      'textBackgroundColor',\n      'charSpacing',\n      'styles'),\n\n    /**\n     * When defined, an object is rendered via stroke and this property specifies its color.\n     * <b>Backwards incompatibility note:</b> This property was named \"strokeStyle\" until v1.1.6\n     * @type String\n     * @default\n     */\n    stroke:               null,\n\n    /**\n     * Shadow object representing shadow of this shape.\n     * <b>Backwards incompatibility note:</b> This property was named \"textShadow\" (String) until v1.2.11\n     * @type fabric.Shadow\n     * @default\n     */\n    shadow:               null,\n\n    /**\n     * @private\n     */\n    _fontSizeFraction: 0.222,\n\n    /**\n     * @private\n     */\n    offsets: {\n      underline: 0.10,\n      linethrough: -0.315,\n      overline: -0.88\n    },\n\n    /**\n     * Text Line proportion to font Size (in pixels)\n     * @type Number\n     * @default\n     */\n    _fontSizeMult:             1.13,\n\n    /**\n     * additional space between characters\n     * expressed in thousands of em unit\n     * @type Number\n     * @default\n     */\n    charSpacing:             0,\n\n    /**\n     * Object containing character styles - top-level properties -> line numbers,\n     * 2nd-level properties - charater numbers\n     * @type Object\n     * @default\n     */\n    styles: null,\n\n    /**\n     * Reference to a context to measure text char or couple of chars\n     * the cacheContext of the canvas will be used or a freshly created one if the object is not on canvas\n     * once created it will be referenced on fabric._measuringContext to avoide creating a canvas for every\n     * text object created.\n     * @type {CanvasRenderingContext2D}\n     * @default\n     */\n    _measuringContext: null,\n\n    /**\n     * Baseline shift, stlyes only, keep at 0 for the main text object\n     * @type {Number}\n     * @default\n     */\n    deltaY: 0,\n\n    /**\n     * Array of properties that define a style unit (of 'styles').\n     * @type {Array}\n     * @default\n     */\n    _styleProperties: [\n      'stroke',\n      'strokeWidth',\n      'fill',\n      'fontFamily',\n      'fontSize',\n      'fontWeight',\n      'fontStyle',\n      'underline',\n      'overline',\n      'linethrough',\n      'deltaY',\n      'textBackgroundColor',\n    ],\n\n    /**\n     * contains characters bounding boxes\n     */\n    __charBounds: [],\n\n    /**\n     * use this size when measuring text. To avoid IE11 rounding errors\n     * @type {Number}\n     * @default\n     * @readonly\n     * @private\n     */\n    CACHE_FONT_SIZE: 400,\n\n    /**\n     * contains the min text width to avoid getting 0\n     * @type {Number}\n     * @default\n     */\n    MIN_TEXT_WIDTH: 2,\n\n    /**\n     * Constructor\n     * @param {String} text Text string\n     * @param {Object} [options] Options object\n     * @return {fabric.Text} thisArg\n     */\n    initialize: function(text, options) {\n      this.styles = options ? (options.styles || { }) : { };\n      this.text = text;\n      this.__skipDimension = true;\n      this.callSuper('initialize', options);\n      this.__skipDimension = false;\n      this.initDimensions();\n      this.setCoords();\n      this.setupState({ propertySet: '_dimensionAffectingProps' });\n    },\n\n    /**\n     * Return a contex for measurement of text string.\n     * if created it gets stored for reuse\n     * @param {String} text Text string\n     * @param {Object} [options] Options object\n     * @return {fabric.Text} thisArg\n     */\n    getMeasuringContext: function() {\n      // if we did not return we have to measure something.\n      if (!fabric._measuringContext) {\n        fabric._measuringContext = this.canvas && this.canvas.contextCache ||\n          fabric.util.createCanvasElement().getContext('2d');\n      }\n      return fabric._measuringContext;\n    },\n\n    /**\n     * @private\n     * Divides text into lines of text and lines of graphemes.\n     */\n    _splitText: function() {\n      var newLines = this._splitTextIntoLines(this.text);\n      this.textLines = newLines.lines;\n      this._textLines = newLines.graphemeLines;\n      this._unwrappedTextLines = newLines._unwrappedLines;\n      this._text = newLines.graphemeText;\n      return newLines;\n    },\n\n    /**\n     * Initialize or update text dimensions.\n     * Updates this.width and this.height with the proper values.\n     * Does not return dimensions.\n     */\n    initDimensions: function() {\n      if (this.__skipDimension) {\n        return;\n      }\n      this._splitText();\n      this._clearCache();\n      this.width = this.calcTextWidth() || this.cursorWidth || this.MIN_TEXT_WIDTH;\n      if (this.textAlign.indexOf('justify') !== -1) {\n        // once text is measured we need to make space fatter to make justified text.\n        this.enlargeSpaces();\n      }\n      this.height = this.calcTextHeight();\n      this.saveState({ propertySet: '_dimensionAffectingProps' });\n    },\n\n    /**\n     * Enlarge space boxes and shift the others\n     */\n    enlargeSpaces: function() {\n      var diffSpace, currentLineWidth, numberOfSpaces, accumulatedSpace, line, charBound, spaces;\n      for (var i = 0, len = this._textLines.length; i < len; i++) {\n        if (this.textAlign !== 'justify' && (i === len - 1 || this.isEndOfWrapping(i))) {\n          continue;\n        }\n        accumulatedSpace = 0;\n        line = this._textLines[i];\n        currentLineWidth = this.getLineWidth(i);\n        if (currentLineWidth < this.width && (spaces = this.textLines[i].match(this._reSpacesAndTabs))) {\n          numberOfSpaces = spaces.length;\n          diffSpace = (this.width - currentLineWidth) / numberOfSpaces;\n          for (var j = 0, jlen = line.length; j <= jlen; j++) {\n            charBound = this.__charBounds[i][j];\n            if (this._reSpaceAndTab.test(line[j])) {\n              charBound.width += diffSpace;\n              charBound.kernedWidth += diffSpace;\n              charBound.left += accumulatedSpace;\n              accumulatedSpace += diffSpace;\n            }\n            else {\n              charBound.left += accumulatedSpace;\n            }\n          }\n        }\n      }\n    },\n\n    /**\n     * Detect if the text line is ended with an hard break\n     * text and itext do not have wrapping, return false\n     * @return {Boolean}\n     */\n    isEndOfWrapping: function(lineIndex) {\n      return lineIndex === this._textLines.length - 1;\n    },\n\n    /**\n     * Detect if a line has a linebreak and so we need to account for it when moving\n     * and counting style.\n     * It return always for text and Itext.\n     * @return Number\n     */\n    missingNewlineOffset: function() {\n      return 1;\n    },\n\n    /**\n     * Returns string representation of an instance\n     * @return {String} String representation of text object\n     */\n    toString: function() {\n      return '#<fabric.Text (' + this.complexity() +\n        '): { \"text\": \"' + this.text + '\", \"fontFamily\": \"' + this.fontFamily + '\" }>';\n    },\n\n    /**\n     * Return the dimension and the zoom level needed to create a cache canvas\n     * big enough to host the object to be cached.\n     * @private\n     * @param {Object} dim.x width of object to be cached\n     * @param {Object} dim.y height of object to be cached\n     * @return {Object}.width width of canvas\n     * @return {Object}.height height of canvas\n     * @return {Object}.zoomX zoomX zoom value to unscale the canvas before drawing cache\n     * @return {Object}.zoomY zoomY zoom value to unscale the canvas before drawing cache\n     */\n    _getCacheCanvasDimensions: function() {\n      var dims = this.callSuper('_getCacheCanvasDimensions');\n      var fontSize = this.fontSize;\n      dims.width += fontSize * dims.zoomX;\n      dims.height += fontSize * dims.zoomY;\n      return dims;\n    },\n\n    /**\n     * @private\n     * @param {CanvasRenderingContext2D} ctx Context to render on\n     */\n    _render: function(ctx) {\n      this._setTextStyles(ctx);\n      this._renderTextLinesBackground(ctx);\n      this._renderTextDecoration(ctx, 'underline');\n      this._renderText(ctx);\n      this._renderTextDecoration(ctx, 'overline');\n      this._renderTextDecoration(ctx, 'linethrough');\n    },\n\n    /**\n     * @private\n     * @param {CanvasRenderingContext2D} ctx Context to render on\n     */\n    _renderText: function(ctx) {\n      if (this.paintFirst === 'stroke') {\n        this._renderTextStroke(ctx);\n        this._renderTextFill(ctx);\n      }\n      else {\n        this._renderTextFill(ctx);\n        this._renderTextStroke(ctx);\n      }\n    },\n\n    /**\n     * Set the font parameter of the context with the object properties or with charStyle\n     * @private\n     * @param {CanvasRenderingContext2D} ctx Context to render on\n     * @param {Object} [charStyle] object with font style properties\n     * @param {String} [charStyle.fontFamily] Font Family\n     * @param {Number} [charStyle.fontSize] Font size in pixels. ( without px suffix )\n     * @param {String} [charStyle.fontWeight] Font weight\n     * @param {String} [charStyle.fontStyle] Font style (italic|normal)\n     */\n    _setTextStyles: function(ctx, charStyle, forMeasuring) {\n      ctx.textBaseline = 'alphabetic';\n      ctx.font = this._getFontDeclaration(charStyle, forMeasuring);\n    },\n\n    /**\n     * calculate and return the text Width measuring each line.\n     * @private\n     * @param {CanvasRenderingContext2D} ctx Context to render on\n     * @return {Number} Maximum width of fabric.Text object\n     */\n    calcTextWidth: function() {\n      var maxWidth = this.getLineWidth(0);\n\n      for (var i = 1, len = this._textLines.length; i < len; i++) {\n        var currentLineWidth = this.getLineWidth(i);\n        if (currentLineWidth > maxWidth) {\n          maxWidth = currentLineWidth;\n        }\n      }\n      return maxWidth;\n    },\n\n    /**\n     * @private\n     * @param {String} method Method name (\"fillText\" or \"strokeText\")\n     * @param {CanvasRenderingContext2D} ctx Context to render on\n     * @param {String} line Text to render\n     * @param {Number} left Left position of text\n     * @param {Number} top Top position of text\n     * @param {Number} lineIndex Index of a line in a text\n     */\n    _renderTextLine: function(method, ctx, line, left, top, lineIndex) {\n      this._renderChars(method, ctx, line, left, top, lineIndex);\n    },\n\n    /**\n     * Renders the text background for lines, taking care of style\n     * @private\n     * @param {CanvasRenderingContext2D} ctx Context to render on\n     */\n    _renderTextLinesBackground: function(ctx) {\n      if (!this.textBackgroundColor && !this.styleHas('textBackgroundColor')) {\n        return;\n      }\n      var lineTopOffset = 0, heightOfLine,\n          lineLeftOffset, originalFill = ctx.fillStyle,\n          line, lastColor,\n          leftOffset = this._getLeftOffset(),\n          topOffset = this._getTopOffset(),\n          boxStart = 0, boxWidth = 0, charBox, currentColor;\n\n      for (var i = 0, len = this._textLines.length; i < len; i++) {\n        heightOfLine = this.getHeightOfLine(i);\n        if (!this.textBackgroundColor && !this.styleHas('textBackgroundColor', i)) {\n          lineTopOffset += heightOfLine;\n          continue;\n        }\n        line = this._textLines[i];\n        lineLeftOffset = this._getLineLeftOffset(i);\n        boxWidth = 0;\n        boxStart = 0;\n        lastColor = this.getValueOfPropertyAt(i, 0, 'textBackgroundColor');\n        for (var j = 0, jlen = line.length; j < jlen; j++) {\n          charBox = this.__charBounds[i][j];\n          currentColor = this.getValueOfPropertyAt(i, j, 'textBackgroundColor');\n          if (currentColor !== lastColor) {\n            ctx.fillStyle = lastColor;\n            lastColor && ctx.fillRect(\n              leftOffset + lineLeftOffset + boxStart,\n              topOffset + lineTopOffset,\n              boxWidth,\n              heightOfLine / this.lineHeight\n            );\n            boxStart = charBox.left;\n            boxWidth = charBox.width;\n            lastColor = currentColor;\n          }\n          else {\n            boxWidth += charBox.kernedWidth;\n          }\n        }\n        if (currentColor) {\n          ctx.fillStyle = currentColor;\n          ctx.fillRect(\n            leftOffset + lineLeftOffset + boxStart,\n            topOffset + lineTopOffset,\n            boxWidth,\n            heightOfLine / this.lineHeight\n          );\n        }\n        lineTopOffset += heightOfLine;\n      }\n      ctx.fillStyle = originalFill;\n      // if there is text background color no\n      // other shadows should be casted\n      this._removeShadow(ctx);\n    },\n\n    /**\n     * @private\n     * @param {Object} decl style declaration for cache\n     * @param {String} decl.fontFamily fontFamily\n     * @param {String} decl.fontStyle fontStyle\n     * @param {String} decl.fontWeight fontWeight\n     * @return {Object} reference to cache\n     */\n    getFontCache: function(decl) {\n      var fontFamily = decl.fontFamily.toLowerCase();\n      if (!fabric.charWidthsCache[fontFamily]) {\n        fabric.charWidthsCache[fontFamily] = { };\n      }\n      var cache = fabric.charWidthsCache[fontFamily],\n          cacheProp = decl.fontStyle.toLowerCase() + '_' + (decl.fontWeight + '').toLowerCase();\n      if (!cache[cacheProp]) {\n        cache[cacheProp] = { };\n      }\n      return cache[cacheProp];\n    },\n\n    /**\n     * apply all the character style to canvas for rendering\n     * @private\n     * @param {String} _char\n     * @param {Number} lineIndex\n     * @param {Number} charIndex\n     * @param {Object} [decl]\n     */\n    _applyCharStyles: function(method, ctx, lineIndex, charIndex, styleDeclaration) {\n\n      this._setFillStyles(ctx, styleDeclaration);\n      this._setStrokeStyles(ctx, styleDeclaration);\n\n      ctx.font = this._getFontDeclaration(styleDeclaration);\n    },\n\n    /**\n     * measure and return the width of a single character.\n     * possibly overridden to accommodate different measure logic or\n     * to hook some external lib for character measurement\n     * @private\n     * @param {String} _char, char to be measured\n     * @param {Object} charStyle style of char to be measured\n     * @param {String} [previousChar] previous char\n     * @param {Object} [prevCharStyle] style of previous char\n     */\n    _measureChar: function(_char, charStyle, previousChar, prevCharStyle) {\n      // first i try to return from cache\n      var fontCache = this.getFontCache(charStyle), fontDeclaration = this._getFontDeclaration(charStyle),\n          previousFontDeclaration = this._getFontDeclaration(prevCharStyle), couple = previousChar + _char,\n          stylesAreEqual = fontDeclaration === previousFontDeclaration, width, coupleWidth, previousWidth,\n          fontMultiplier = charStyle.fontSize / this.CACHE_FONT_SIZE, kernedWidth;\n\n      if (previousChar && fontCache[previousChar] !== undefined) {\n        previousWidth = fontCache[previousChar];\n      }\n      if (fontCache[_char] !== undefined) {\n        kernedWidth = width = fontCache[_char];\n      }\n      if (stylesAreEqual && fontCache[couple] !== undefined) {\n        coupleWidth = fontCache[couple];\n        kernedWidth = coupleWidth - previousWidth;\n      }\n      if (width === undefined || previousWidth === undefined || coupleWidth === undefined) {\n        var ctx = this.getMeasuringContext();\n        // send a TRUE to specify measuring font size CACHE_FONT_SIZE\n        this._setTextStyles(ctx, charStyle, true);\n      }\n      if (width === undefined) {\n        kernedWidth = width = ctx.measureText(_char).width;\n        fontCache[_char] = width;\n      }\n      if (previousWidth === undefined && stylesAreEqual && previousChar) {\n        previousWidth = ctx.measureText(previousChar).width;\n        fontCache[previousChar] = previousWidth;\n      }\n      if (stylesAreEqual && coupleWidth === undefined) {\n        // we can measure the kerning couple and subtract the width of the previous character\n        coupleWidth = ctx.measureText(couple).width;\n        fontCache[couple] = coupleWidth;\n        kernedWidth = coupleWidth - previousWidth;\n      }\n      return { width: width * fontMultiplier, kernedWidth: kernedWidth * fontMultiplier };\n    },\n\n    /**\n     * Computes height of character at given position\n     * @param {Number} line the line index number\n     * @param {Number} _char the character index number\n     * @return {Number} fontSize of the character\n     */\n    getHeightOfChar: function(line, _char) {\n      return this.getValueOfPropertyAt(line, _char, 'fontSize');\n    },\n\n    /**\n     * measure a text line measuring all characters.\n     * @param {Number} lineIndex line number\n     * @return {Number} Line width\n     */\n    measureLine: function(lineIndex) {\n      var lineInfo = this._measureLine(lineIndex);\n      if (this.charSpacing !== 0) {\n        lineInfo.width -= this._getWidthOfCharSpacing();\n      }\n      if (lineInfo.width < 0) {\n        lineInfo.width = 0;\n      }\n      return lineInfo;\n    },\n\n    /**\n     * measure every grapheme of a line, populating __charBounds\n     * @param {Number} lineIndex\n     * @return {Object} object.width total width of characters\n     * @return {Object} object.widthOfSpaces length of chars that match this._reSpacesAndTabs\n     */\n    _measureLine: function(lineIndex) {\n      var width = 0, i, grapheme, line = this._textLines[lineIndex], prevGrapheme,\n          graphemeInfo, numOfSpaces = 0, lineBounds = new Array(line.length);\n\n      this.__charBounds[lineIndex] = lineBounds;\n      for (i = 0; i < line.length; i++) {\n        grapheme = line[i];\n        graphemeInfo = this._getGraphemeBox(grapheme, lineIndex, i, prevGrapheme);\n        lineBounds[i] = graphemeInfo;\n        width += graphemeInfo.kernedWidth;\n        prevGrapheme = grapheme;\n      }\n      // this latest bound box represent the last character of the line\n      // to simplify cursor handling in interactive mode.\n      lineBounds[i] = {\n        left: graphemeInfo ? graphemeInfo.left + graphemeInfo.width : 0,\n        width: 0,\n        kernedWidth: 0,\n        height: this.fontSize\n      };\n      return { width: width, numOfSpaces: numOfSpaces };\n    },\n\n    /**\n     * Measure and return the info of a single grapheme.\n     * needs the the info of previous graphemes already filled\n     * @private\n     * @param {String} grapheme to be measured\n     * @param {Number} lineIndex index of the line where the char is\n     * @param {Number} charIndex position in the line\n     * @param {String} [prevGrapheme] character preceding the one to be measured\n     */\n    _getGraphemeBox: function(grapheme, lineIndex, charIndex, prevGrapheme, skipLeft) {\n      var style = this.getCompleteStyleDeclaration(lineIndex, charIndex),\n          prevStyle = prevGrapheme ? this.getCompleteStyleDeclaration(lineIndex, charIndex - 1) : { },\n          info = this._measureChar(grapheme, style, prevGrapheme, prevStyle),\n          kernedWidth = info.kernedWidth,\n          width = info.width, charSpacing;\n\n      if (this.charSpacing !== 0) {\n        charSpacing = this._getWidthOfCharSpacing();\n        width += charSpacing;\n        kernedWidth += charSpacing;\n      }\n\n      var box = {\n        width: width,\n        left: 0,\n        height: style.fontSize,\n        kernedWidth: kernedWidth,\n        deltaY: style.deltaY,\n      };\n      if (charIndex > 0 && !skipLeft) {\n        var previousBox = this.__charBounds[lineIndex][charIndex - 1];\n        box.left = previousBox.left + previousBox.width + info.kernedWidth - info.width;\n      }\n      return box;\n    },\n\n    /**\n     * Calculate height of line at 'lineIndex'\n     * @param {Number} lineIndex index of line to calculate\n     * @return {Number}\n     */\n    getHeightOfLine: function(lineIndex) {\n      if (this.__lineHeights[lineIndex]) {\n        return this.__lineHeights[lineIndex];\n      }\n\n      var line = this._textLines[lineIndex],\n          // char 0 is measured before the line cycle because it nneds to char\n          // emptylines\n          maxHeight = this.getHeightOfChar(lineIndex, 0);\n      for (var i = 1, len = line.length; i < len; i++) {\n        maxHeight = Math.max(this.getHeightOfChar(lineIndex, i), maxHeight);\n      }\n\n      return this.__lineHeights[lineIndex] = maxHeight * this.lineHeight * this._fontSizeMult;\n    },\n\n    /**\n     * Calculate text box height\n     */\n    calcTextHeight: function() {\n      var lineHeight, height = 0;\n      for (var i = 0, len = this._textLines.length; i < len; i++) {\n        lineHeight = this.getHeightOfLine(i);\n        height += (i === len - 1 ? lineHeight / this.lineHeight : lineHeight);\n      }\n      return height;\n    },\n\n    /**\n     * @private\n     * @return {Number} Left offset\n     */\n    _getLeftOffset: function() {\n      return -this.width / 2;\n    },\n\n    /**\n     * @private\n     * @return {Number} Top offset\n     */\n    _getTopOffset: function() {\n      return -this.height / 2;\n    },\n\n    /**\n     * @private\n     * @param {CanvasRenderingContext2D} ctx Context to render on\n     * @param {String} method Method name (\"fillText\" or \"strokeText\")\n     */\n    _renderTextCommon: function(ctx, method) {\n      ctx.save();\n      var lineHeights = 0, left = this._getLeftOffset(), top = this._getTopOffset(),\n          offsets = this._applyPatternGradientTransform(ctx, method === 'fillText' ? this.fill : this.stroke);\n      for (var i = 0, len = this._textLines.length; i < len; i++) {\n        var heightOfLine = this.getHeightOfLine(i),\n            maxHeight = heightOfLine / this.lineHeight,\n            leftOffset = this._getLineLeftOffset(i);\n        this._renderTextLine(\n          method,\n          ctx,\n          this._textLines[i],\n          left + leftOffset - offsets.offsetX,\n          top + lineHeights + maxHeight - offsets.offsetY,\n          i\n        );\n        lineHeights += heightOfLine;\n      }\n      ctx.restore();\n    },\n\n    /**\n     * @private\n     * @param {CanvasRenderingContext2D} ctx Context to render on\n     */\n    _renderTextFill: function(ctx) {\n      if (!this.fill && !this.styleHas('fill')) {\n        return;\n      }\n\n      this._renderTextCommon(ctx, 'fillText');\n    },\n\n    /**\n     * @private\n     * @param {CanvasRenderingContext2D} ctx Context to render on\n     */\n    _renderTextStroke: function(ctx) {\n      if ((!this.stroke || this.strokeWidth === 0) && this.isEmptyStyles()) {\n        return;\n      }\n\n      if (this.shadow && !this.shadow.affectStroke) {\n        this._removeShadow(ctx);\n      }\n\n      ctx.save();\n      this._setLineDash(ctx, this.strokeDashArray);\n      ctx.beginPath();\n      this._renderTextCommon(ctx, 'strokeText');\n      ctx.closePath();\n      ctx.restore();\n    },\n\n    /**\n     * @private\n     * @param {String} method\n     * @param {CanvasRenderingContext2D} ctx Context to render on\n     * @param {String} line Content of the line\n     * @param {Number} left\n     * @param {Number} top\n     * @param {Number} lineIndex\n     * @param {Number} charOffset\n     */\n    _renderChars: function(method, ctx, line, left, top, lineIndex) {\n      // set proper line offset\n      var lineHeight = this.getHeightOfLine(lineIndex),\n          isJustify = this.textAlign.indexOf('justify') !== -1,\n          actualStyle,\n          nextStyle,\n          charsToRender = '',\n          charBox,\n          boxWidth = 0,\n          timeToRender,\n          shortCut = !isJustify && this.charSpacing === 0 && this.isEmptyStyles(lineIndex);\n\n      ctx.save();\n      top -= lineHeight * this._fontSizeFraction / this.lineHeight;\n      if (shortCut) {\n        // render all the line in one pass without checking\n        this._renderChar(method, ctx, lineIndex, 0, this.textLines[lineIndex], left, top, lineHeight);\n        ctx.restore();\n        return;\n      }\n      for (var i = 0, len = line.length - 1; i <= len; i++) {\n        timeToRender = i === len || this.charSpacing;\n        charsToRender += line[i];\n        charBox = this.__charBounds[lineIndex][i];\n        if (boxWidth === 0) {\n          left += charBox.kernedWidth - charBox.width;\n          boxWidth += charBox.width;\n        }\n        else {\n          boxWidth += charBox.kernedWidth;\n        }\n        if (isJustify && !timeToRender) {\n          if (this._reSpaceAndTab.test(line[i])) {\n            timeToRender = true;\n          }\n        }\n        if (!timeToRender) {\n          // if we have charSpacing, we render char by char\n          actualStyle = actualStyle || this.getCompleteStyleDeclaration(lineIndex, i);\n          nextStyle = this.getCompleteStyleDeclaration(lineIndex, i + 1);\n          timeToRender = this._hasStyleChanged(actualStyle, nextStyle);\n        }\n        if (timeToRender) {\n          this._renderChar(method, ctx, lineIndex, i, charsToRender, left, top, lineHeight);\n          charsToRender = '';\n          actualStyle = nextStyle;\n          left += boxWidth;\n          boxWidth = 0;\n        }\n      }\n      ctx.restore();\n    },\n\n    /**\n     * @private\n     * @param {String} method\n     * @param {CanvasRenderingContext2D} ctx Context to render on\n     * @param {Number} lineIndex\n     * @param {Number} charIndex\n     * @param {String} _char\n     * @param {Number} left Left coordinate\n     * @param {Number} top Top coordinate\n     * @param {Number} lineHeight Height of the line\n     */\n    _renderChar: function(method, ctx, lineIndex, charIndex, _char, left, top) {\n      var decl = this._getStyleDeclaration(lineIndex, charIndex),\n          fullDecl = this.getCompleteStyleDeclaration(lineIndex, charIndex),\n          shouldFill = method === 'fillText' && fullDecl.fill,\n          shouldStroke = method === 'strokeText' && fullDecl.stroke && fullDecl.strokeWidth;\n\n      if (!shouldStroke && !shouldFill) {\n        return;\n      }\n      decl && ctx.save();\n\n      this._applyCharStyles(method, ctx, lineIndex, charIndex, fullDecl);\n\n      if (decl && decl.textBackgroundColor) {\n        this._removeShadow(ctx);\n      }\n      if (decl && decl.deltaY) {\n        top += decl.deltaY;\n      }\n\n      shouldFill && ctx.fillText(_char, left, top);\n      shouldStroke && ctx.strokeText(_char, left, top);\n      decl && ctx.restore();\n    },\n\n    /**\n     * Turns the character into a 'superior figure' (i.e. 'superscript')\n     * @param {Number} start selection start\n     * @param {Number} end selection end\n     * @returns {fabric.Text} thisArg\n     * @chainable\n     */\n    setSuperscript: function(start, end) {\n      return this._setScript(start, end, this.superscript);\n    },\n\n    /**\n     * Turns the character into an 'inferior figure' (i.e. 'subscript')\n     * @param {Number} start selection start\n     * @param {Number} end selection end\n     * @returns {fabric.Text} thisArg\n     * @chainable\n     */\n    setSubscript: function(start, end) {\n      return this._setScript(start, end, this.subscript);\n    },\n\n    /**\n     * Applies 'schema' at given position\n     * @private\n     * @param {Number} start selection start\n     * @param {Number} end selection end\n     * @param {Number} schema\n     * @returns {fabric.Text} thisArg\n     * @chainable\n     */\n    _setScript: function(start, end, schema) {\n      var loc = this.get2DCursorLocation(start, true),\n          fontSize = this.getValueOfPropertyAt(loc.lineIndex, loc.charIndex, 'fontSize'),\n          dy = this.getValueOfPropertyAt(loc.lineIndex, loc.charIndex, 'deltaY'),\n          style = { fontSize: fontSize * schema.size, deltaY: dy + fontSize * schema.baseline };\n      this.setSelectionStyles(style, start, end);\n      return this;\n    },\n\n    /**\n     * @private\n     * @param {Object} prevStyle\n     * @param {Object} thisStyle\n     */\n    _hasStyleChanged: function(prevStyle, thisStyle) {\n      return prevStyle.fill !== thisStyle.fill ||\n              prevStyle.stroke !== thisStyle.stroke ||\n              prevStyle.strokeWidth !== thisStyle.strokeWidth ||\n              prevStyle.fontSize !== thisStyle.fontSize ||\n              prevStyle.fontFamily !== thisStyle.fontFamily ||\n              prevStyle.fontWeight !== thisStyle.fontWeight ||\n              prevStyle.fontStyle !== thisStyle.fontStyle ||\n              prevStyle.deltaY !== thisStyle.deltaY;\n    },\n\n    /**\n     * @private\n     * @param {Object} prevStyle\n     * @param {Object} thisStyle\n     */\n    _hasStyleChangedForSvg: function(prevStyle, thisStyle) {\n      return this._hasStyleChanged(prevStyle, thisStyle) ||\n        prevStyle.overline !== thisStyle.overline ||\n        prevStyle.underline !== thisStyle.underline ||\n        prevStyle.linethrough !== thisStyle.linethrough;\n    },\n\n    /**\n     * @private\n     * @param {Number} lineIndex index text line\n     * @return {Number} Line left offset\n     */\n    _getLineLeftOffset: function(lineIndex) {\n      var lineWidth = this.getLineWidth(lineIndex);\n      if (this.textAlign === 'center') {\n        return (this.width - lineWidth) / 2;\n      }\n      if (this.textAlign === 'right') {\n        return this.width - lineWidth;\n      }\n      if (this.textAlign === 'justify-center' && this.isEndOfWrapping(lineIndex)) {\n        return (this.width - lineWidth) / 2;\n      }\n      if (this.textAlign === 'justify-right' && this.isEndOfWrapping(lineIndex)) {\n        return this.width - lineWidth;\n      }\n      return 0;\n    },\n\n    /**\n     * @private\n     */\n    _clearCache: function() {\n      this.__lineWidths = [];\n      this.__lineHeights = [];\n      this.__charBounds = [];\n    },\n\n    /**\n     * @private\n     */\n    _shouldClearDimensionCache: function() {\n      var shouldClear = this._forceClearCache;\n      shouldClear || (shouldClear = this.hasStateChanged('_dimensionAffectingProps'));\n      if (shouldClear) {\n        this.dirty = true;\n        this._forceClearCache = false;\n      }\n      return shouldClear;\n    },\n\n    /**\n     * Measure a single line given its index. Used to calculate the initial\n     * text bounding box. The values are calculated and stored in __lineWidths cache.\n     * @private\n     * @param {Number} lineIndex line number\n     * @return {Number} Line width\n     */\n    getLineWidth: function(lineIndex) {\n      if (this.__lineWidths[lineIndex]) {\n        return this.__lineWidths[lineIndex];\n      }\n\n      var width, line = this._textLines[lineIndex], lineInfo;\n\n      if (line === '') {\n        width = 0;\n      }\n      else {\n        lineInfo = this.measureLine(lineIndex);\n        width = lineInfo.width;\n      }\n      this.__lineWidths[lineIndex] = width;\n      return width;\n    },\n\n    _getWidthOfCharSpacing: function() {\n      if (this.charSpacing !== 0) {\n        return this.fontSize * this.charSpacing / 1000;\n      }\n      return 0;\n    },\n\n    /**\n     * Retrieves the value of property at given character position\n     * @param {Number} lineIndex the line number\n     * @param {Number} charIndex the charater number\n     * @param {String} property the property name\n     * @returns the value of 'property'\n     */\n    getValueOfPropertyAt: function(lineIndex, charIndex, property) {\n      var charStyle = this._getStyleDeclaration(lineIndex, charIndex);\n      if (charStyle && typeof charStyle[property] !== 'undefined') {\n        return charStyle[property];\n      }\n      return this[property];\n    },\n\n    /**\n     * @private\n     * @param {CanvasRenderingContext2D} ctx Context to render on\n     */\n    _renderTextDecoration: function(ctx, type) {\n      if (!this[type] && !this.styleHas(type)) {\n        return;\n      }\n      var heightOfLine, size, _size,\n          lineLeftOffset, dy, _dy,\n          line, lastDecoration,\n          leftOffset = this._getLeftOffset(),\n          topOffset = this._getTopOffset(), top,\n          boxStart, boxWidth, charBox, currentDecoration,\n          maxHeight, currentFill, lastFill,\n          charSpacing = this._getWidthOfCharSpacing();\n\n      for (var i = 0, len = this._textLines.length; i < len; i++) {\n        heightOfLine = this.getHeightOfLine(i);\n        if (!this[type] && !this.styleHas(type, i)) {\n          topOffset += heightOfLine;\n          continue;\n        }\n        line = this._textLines[i];\n        maxHeight = heightOfLine / this.lineHeight;\n        lineLeftOffset = this._getLineLeftOffset(i);\n        boxStart = 0;\n        boxWidth = 0;\n        lastDecoration = this.getValueOfPropertyAt(i, 0, type);\n        lastFill = this.getValueOfPropertyAt(i, 0, 'fill');\n        top = topOffset + maxHeight * (1 - this._fontSizeFraction);\n        size = this.getHeightOfChar(i, 0);\n        dy = this.getValueOfPropertyAt(i, 0, 'deltaY');\n        for (var j = 0, jlen = line.length; j < jlen; j++) {\n          charBox = this.__charBounds[i][j];\n          currentDecoration = this.getValueOfPropertyAt(i, j, type);\n          currentFill = this.getValueOfPropertyAt(i, j, 'fill');\n          _size = this.getHeightOfChar(i, j);\n          _dy = this.getValueOfPropertyAt(i, j, 'deltaY');\n          if ((currentDecoration !== lastDecoration || currentFill !== lastFill || _size !== size || _dy !== dy) &&\n              boxWidth > 0) {\n            ctx.fillStyle = lastFill;\n            lastDecoration && lastFill && ctx.fillRect(\n              leftOffset + lineLeftOffset + boxStart,\n              top + this.offsets[type] * size + dy,\n              boxWidth,\n              this.fontSize / 15\n            );\n            boxStart = charBox.left;\n            boxWidth = charBox.width;\n            lastDecoration = currentDecoration;\n            lastFill = currentFill;\n            size = _size;\n            dy = _dy;\n          }\n          else {\n            boxWidth += charBox.kernedWidth;\n          }\n        }\n        ctx.fillStyle = currentFill;\n        currentDecoration && currentFill && ctx.fillRect(\n          leftOffset + lineLeftOffset + boxStart,\n          top + this.offsets[type] * size + dy,\n          boxWidth - charSpacing,\n          this.fontSize / 15\n        );\n        topOffset += heightOfLine;\n      }\n      // if there is text background color no\n      // other shadows should be casted\n      this._removeShadow(ctx);\n    },\n\n    /**\n     * return font declaration string for canvas context\n     * @param {Object} [styleObject] object\n     * @returns {String} font declaration formatted for canvas context.\n     */\n    _getFontDeclaration: function(styleObject, forMeasuring) {\n      var style = styleObject || this, family = this.fontFamily,\n          fontIsGeneric = fabric.Text.genericFonts.indexOf(family.toLowerCase()) > -1;\n      var fontFamily = family === undefined ||\n      family.indexOf('\\'') > -1 || family.indexOf(',') > -1 ||\n      family.indexOf('\"') > -1 || fontIsGeneric\n        ? style.fontFamily : '\"' + style.fontFamily + '\"';\n      return [\n        // node-canvas needs \"weight style\", while browsers need \"style weight\"\n        // verify if this can be fixed in JSDOM\n        (fabric.isLikelyNode ? style.fontWeight : style.fontStyle),\n        (fabric.isLikelyNode ? style.fontStyle : style.fontWeight),\n        forMeasuring ? this.CACHE_FONT_SIZE + 'px' : style.fontSize + 'px',\n        fontFamily\n      ].join(' ');\n    },\n\n    /**\n     * Renders text instance on a specified context\n     * @param {CanvasRenderingContext2D} ctx Context to render on\n     */\n    render: function(ctx) {\n      // do not render if object is not visible\n      if (!this.visible) {\n        return;\n      }\n      if (this.canvas && this.canvas.skipOffscreen && !this.group && !this.isOnScreen()) {\n        return;\n      }\n      if (this._shouldClearDimensionCache()) {\n        this.initDimensions();\n      }\n      this.callSuper('render', ctx);\n    },\n\n    /**\n     * Returns the text as an array of lines.\n     * @param {String} text text to split\n     * @returns {Array} Lines in the text\n     */\n    _splitTextIntoLines: function(text) {\n      var lines = text.split(this._reNewline),\n          newLines = new Array(lines.length),\n          newLine = ['\\n'],\n          newText = [];\n      for (var i = 0; i < lines.length; i++) {\n        newLines[i] = fabric.util.string.graphemeSplit(lines[i]);\n        newText = newText.concat(newLines[i], newLine);\n      }\n      newText.pop();\n      return { _unwrappedLines: newLines, lines: lines, graphemeText: newText, graphemeLines: newLines };\n    },\n\n    /**\n     * Returns object representation of an instance\n     * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output\n     * @return {Object} Object representation of an instance\n     */\n    toObject: function(propertiesToInclude) {\n      var additionalProperties = [\n        'text',\n        'fontSize',\n        'fontWeight',\n        'fontFamily',\n        'fontStyle',\n        'lineHeight',\n        'underline',\n        'overline',\n        'linethrough',\n        'textAlign',\n        'textBackgroundColor',\n        'charSpacing',\n      ].concat(propertiesToInclude);\n      var obj = this.callSuper('toObject', additionalProperties);\n      obj.styles = clone(this.styles, true);\n      return obj;\n    },\n\n    /**\n     * 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()`.\n     * @param {String|Object} key Property name or object (if object, iterate over the object properties)\n     * @param {Object|Function} value Property value (if function, the value is passed into it and its return value is used as a new one)\n     * @return {fabric.Object} thisArg\n     * @chainable\n     */\n    set: function(key, value) {\n      this.callSuper('set', key, value);\n      var needsDims = false;\n      if (typeof key === 'object') {\n        for (var _key in key) {\n          needsDims = needsDims || this._dimensionAffectingProps.indexOf(_key) !== -1;\n        }\n      }\n      else {\n        needsDims = this._dimensionAffectingProps.indexOf(key) !== -1;\n      }\n      if (needsDims) {\n        this.initDimensions();\n        this.setCoords();\n      }\n      return this;\n    },\n\n    /**\n     * Returns complexity of an instance\n     * @return {Number} complexity\n     */\n    complexity: function() {\n      return 1;\n    }\n  });\n\n  /* _FROM_SVG_START_ */\n  /**\n   * List of attribute names to account for when parsing SVG element (used by {@link fabric.Text.fromElement})\n   * @static\n   * @memberOf fabric.Text\n   * @see: http://www.w3.org/TR/SVG/text.html#TextElement\n   */\n  fabric.Text.ATTRIBUTE_NAMES = fabric.SHARED_ATTRIBUTES.concat(\n    'x y dx dy font-family font-style font-weight font-size letter-spacing text-decoration text-anchor'.split(' '));\n\n  /**\n   * Default SVG font size\n   * @static\n   * @memberOf fabric.Text\n   */\n  fabric.Text.DEFAULT_SVG_FONT_SIZE = 16;\n\n  /**\n   * Returns fabric.Text instance from an SVG element (<b>not yet implemented</b>)\n   * @static\n   * @memberOf fabric.Text\n   * @param {SVGElement} element Element to parse\n   * @param {Function} callback callback function invoked after parsing\n   * @param {Object} [options] Options object\n   */\n  fabric.Text.fromElement = function(element, callback, options) {\n    if (!element) {\n      return callback(null);\n    }\n\n    var parsedAttributes = fabric.parseAttributes(element, fabric.Text.ATTRIBUTE_NAMES),\n        parsedAnchor = parsedAttributes.textAnchor || 'left';\n    options = fabric.util.object.extend((options ? clone(options) : { }), parsedAttributes);\n\n    options.top = options.top || 0;\n    options.left = options.left || 0;\n    if (parsedAttributes.textDecoration) {\n      var textDecoration = parsedAttributes.textDecoration;\n      if (textDecoration.indexOf('underline') !== -1) {\n        options.underline = true;\n      }\n      if (textDecoration.indexOf('overline') !== -1) {\n        options.overline = true;\n      }\n      if (textDecoration.indexOf('line-through') !== -1) {\n        options.linethrough = true;\n      }\n      delete options.textDecoration;\n    }\n    if ('dx' in parsedAttributes) {\n      options.left += parsedAttributes.dx;\n    }\n    if ('dy' in parsedAttributes) {\n      options.top += parsedAttributes.dy;\n    }\n    if (!('fontSize' in options)) {\n      options.fontSize = fabric.Text.DEFAULT_SVG_FONT_SIZE;\n    }\n\n    var textContent = '';\n\n    // The XML is not properly parsed in IE9 so a workaround to get\n    // textContent is through firstChild.data. Another workaround would be\n    // to convert XML loaded from a file to be converted using DOMParser (same way loadSVGFromString() does)\n    if (!('textContent' in element)) {\n      if ('firstChild' in element && element.firstChild !== null) {\n        if ('data' in element.firstChild && element.firstChild.data !== null) {\n          textContent = element.firstChild.data;\n        }\n      }\n    }\n    else {\n      textContent = element.textContent;\n    }\n\n    textContent = textContent.replace(/^\\s+|\\s+$|\\n+/g, '').replace(/\\s+/g, ' ');\n    var originalStrokeWidth = options.strokeWidth;\n    options.strokeWidth = 0;\n\n    var text = new fabric.Text(textContent, options),\n        textHeightScaleFactor = text.getScaledHeight() / text.height,\n        lineHeightDiff = (text.height + text.strokeWidth) * text.lineHeight - text.height,\n        scaledDiff = lineHeightDiff * textHeightScaleFactor,\n        textHeight = text.getScaledHeight() + scaledDiff,\n        offX = 0;\n    /*\n      Adjust positioning:\n        x/y attributes in SVG correspond to the bottom-left corner of text bounding box\n        fabric output by default at top, left.\n    */\n    if (parsedAnchor === 'center') {\n      offX = text.getScaledWidth() / 2;\n    }\n    if (parsedAnchor === 'right') {\n      offX = text.getScaledWidth();\n    }\n    text.set({\n      left: text.left - offX,\n      top: text.top - (textHeight - text.fontSize * (0.07 + text._fontSizeFraction)) / text.lineHeight,\n      strokeWidth: typeof originalStrokeWidth !== 'undefined' ? originalStrokeWidth : 1,\n    });\n    callback(text);\n  };\n  /* _FROM_SVG_END_ */\n\n  /**\n   * Returns fabric.Text instance from an object representation\n   * @static\n   * @memberOf fabric.Text\n   * @param {Object} object Object to create an instance from\n   * @param {Function} [callback] Callback to invoke when an fabric.Text instance is created\n   */\n  fabric.Text.fromObject = function(object, callback) {\n    return fabric.Object._fromObject('Text', object, callback, 'text');\n  };\n\n  fabric.Text.genericFonts = ['sans-serif', 'serif', 'cursive', 'fantasy', 'monospace'];\n\n  fabric.util.createAccessors && fabric.util.createAccessors(fabric.Text);\n\n})(typeof exports !== 'undefined' ? exports : this);\n\n\n(function() {\n  fabric.util.object.extend(fabric.Text.prototype, /** @lends fabric.Text.prototype */ {\n    /**\n     * Returns true if object has no styling or no styling in a line\n     * @param {Number} lineIndex , lineIndex is on wrapped lines.\n     * @return {Boolean}\n     */\n    isEmptyStyles: function(lineIndex) {\n      if (!this.styles) {\n        return true;\n      }\n      if (typeof lineIndex !== 'undefined' && !this.styles[lineIndex]) {\n        return true;\n      }\n      var obj = typeof lineIndex === 'undefined' ? this.styles : { line: this.styles[lineIndex] };\n      for (var p1 in obj) {\n        for (var p2 in obj[p1]) {\n          // eslint-disable-next-line no-unused-vars\n          for (var p3 in obj[p1][p2]) {\n            return false;\n          }\n        }\n      }\n      return true;\n    },\n\n    /**\n     * Returns true if object has a style property or has it ina specified line\n     * This function is used to detect if a text will use a particular property or not.\n     * @param {String} property to check for\n     * @param {Number} lineIndex to check the style on\n     * @return {Boolean}\n     */\n    styleHas: function(property, lineIndex) {\n      if (!this.styles || !property || property === '') {\n        return false;\n      }\n      if (typeof lineIndex !== 'undefined' && !this.styles[lineIndex]) {\n        return false;\n      }\n      var obj = typeof lineIndex === 'undefined' ? this.styles : { 0: this.styles[lineIndex] };\n      // eslint-disable-next-line\n      for (var p1 in obj) {\n        // eslint-disable-next-line\n        for (var p2 in obj[p1]) {\n          if (typeof obj[p1][p2][property] !== 'undefined') {\n            return true;\n          }\n        }\n      }\n      return false;\n    },\n\n    /**\n     * Check if characters in a text have a value for a property\n     * whose value matches the textbox's value for that property.  If so,\n     * the character-level property is deleted.  If the character\n     * has no other properties, then it is also deleted.  Finally,\n     * if the line containing that character has no other characters\n     * then it also is deleted.\n     *\n     * @param {string} property The property to compare between characters and text.\n     */\n    cleanStyle: function(property) {\n      if (!this.styles || !property || property === '') {\n        return false;\n      }\n      var obj = this.styles, stylesCount = 0, letterCount, stylePropertyValue,\n          allStyleObjectPropertiesMatch = true, graphemeCount = 0, styleObject;\n      // eslint-disable-next-line\n      for (var p1 in obj) {\n        letterCount = 0;\n        // eslint-disable-next-line\n        for (var p2 in obj[p1]) {\n          var styleObject = obj[p1][p2],\n              stylePropertyHasBeenSet = styleObject.hasOwnProperty(property);\n\n          stylesCount++;\n\n          if (stylePropertyHasBeenSet) {\n            if (!stylePropertyValue) {\n              stylePropertyValue = styleObject[property];\n            }\n            else if (styleObject[property] !== stylePropertyValue) {\n              allStyleObjectPropertiesMatch = false;\n            }\n\n            if (styleObject[property] === this[property]) {\n              delete styleObject[property];\n            }\n          }\n          else {\n            allStyleObjectPropertiesMatch = false;\n          }\n\n          if (Object.keys(styleObject).length !== 0) {\n            letterCount++;\n          }\n          else {\n            delete obj[p1][p2];\n          }\n        }\n\n        if (letterCount === 0) {\n          delete obj[p1];\n        }\n      }\n      // if every grapheme has the same style set then\n      // delete those styles and set it on the parent\n      for (var i = 0; i < this._textLines.length; i++) {\n        graphemeCount += this._textLines[i].length;\n      }\n      if (allStyleObjectPropertiesMatch && stylesCount === graphemeCount) {\n        this[property] = stylePropertyValue;\n        this.removeStyle(property);\n      }\n    },\n\n    /**\n     * Remove a style property or properties from all individual character styles\n     * in a text object.  Deletes the character style object if it contains no other style\n     * props.  Deletes a line style object if it contains no other character styles.\n     *\n     * @param {String} props The property to remove from character styles.\n     */\n    removeStyle: function(property) {\n      if (!this.styles || !property || property === '') {\n        return;\n      }\n      var obj = this.styles, line, lineNum, charNum;\n      for (lineNum in obj) {\n        line = obj[lineNum];\n        for (charNum in line) {\n          delete line[charNum][property];\n          if (Object.keys(line[charNum]).length === 0) {\n            delete line[charNum];\n          }\n        }\n        if (Object.keys(line).length === 0) {\n          delete obj[lineNum];\n        }\n      }\n    },\n\n    /**\n     * @private\n     */\n    _extendStyles: function(index, styles) {\n      var loc = this.get2DCursorLocation(index);\n\n      if (!this._getLineStyle(loc.lineIndex)) {\n        this._setLineStyle(loc.lineIndex);\n      }\n\n      if (!this._getStyleDeclaration(loc.lineIndex, loc.charIndex)) {\n        this._setStyleDeclaration(loc.lineIndex, loc.charIndex, {});\n      }\n\n      fabric.util.object.extend(this._getStyleDeclaration(loc.lineIndex, loc.charIndex), styles);\n    },\n\n    /**\n     * Returns 2d representation (lineIndex and charIndex) of cursor (or selection start)\n     * @param {Number} [selectionStart] Optional index. When not given, current selectionStart is used.\n     * @param {Boolean} [skipWrapping] consider the location for unwrapped lines. usefull to manage styles.\n     */\n    get2DCursorLocation: function(selectionStart, skipWrapping) {\n      if (typeof selectionStart === 'undefined') {\n        selectionStart = this.selectionStart;\n      }\n      var lines = skipWrapping ? this._unwrappedTextLines : this._textLines,\n          len = lines.length;\n      for (var i = 0; i < len; i++) {\n        if (selectionStart <= lines[i].length) {\n          return {\n            lineIndex: i,\n            charIndex: selectionStart\n          };\n        }\n        selectionStart -= lines[i].length + this.missingNewlineOffset(i);\n      }\n      return {\n        lineIndex: i - 1,\n        charIndex: lines[i - 1].length < selectionStart ? lines[i - 1].length : selectionStart\n      };\n    },\n\n    /**\n     * Gets style of a current selection/cursor (at the start position)\n     * if startIndex or endIndex are not provided, slectionStart or selectionEnd will be used.\n     * @param {Number} [startIndex] Start index to get styles at\n     * @param {Number} [endIndex] End index to get styles at, if not specified selectionEnd or startIndex + 1\n     * @param {Boolean} [complete] get full style or not\n     * @return {Array} styles an array with one, zero or more Style objects\n     */\n    getSelectionStyles: function(startIndex, endIndex, complete) {\n      if (typeof startIndex === 'undefined') {\n        startIndex = this.selectionStart || 0;\n      }\n      if (typeof endIndex === 'undefined') {\n        endIndex = this.selectionEnd || startIndex;\n      }\n      var styles = [];\n      for (var i = startIndex; i < endIndex; i++) {\n        styles.push(this.getStyleAtPosition(i, complete));\n      }\n      return styles;\n    },\n\n    /**\n     * Gets style of a current selection/cursor position\n     * @param {Number} position  to get styles at\n     * @param {Boolean} [complete] full style if true\n     * @return {Object} style Style object at a specified index\n     * @private\n     */\n    getStyleAtPosition: function(position, complete) {\n      var loc = this.get2DCursorLocation(position),\n          style = complete ? this.getCompleteStyleDeclaration(loc.lineIndex, loc.charIndex) :\n            this._getStyleDeclaration(loc.lineIndex, loc.charIndex);\n      return style || {};\n    },\n\n    /**\n     * Sets style of a current selection, if no selection exist, do not set anything.\n     * @param {Object} [styles] Styles object\n     * @param {Number} [startIndex] Start index to get styles at\n     * @param {Number} [endIndex] End index to get styles at, if not specified selectionEnd or startIndex + 1\n     * @return {fabric.IText} thisArg\n     * @chainable\n     */\n    setSelectionStyles: function(styles, startIndex, endIndex) {\n      if (typeof startIndex === 'undefined') {\n        startIndex = this.selectionStart || 0;\n      }\n      if (typeof endIndex === 'undefined') {\n        endIndex = this.selectionEnd || startIndex;\n      }\n      for (var i = startIndex; i < endIndex; i++) {\n        this._extendStyles(i, styles);\n      }\n      /* not included in _extendStyles to avoid clearing cache more than once */\n      this._forceClearCache = true;\n      return this;\n    },\n\n    /**\n     * get the reference, not a clone, of the style object for a given character\n     * @param {Number} lineIndex\n     * @param {Number} charIndex\n     * @return {Object} style object\n     */\n    _getStyleDeclaration: function(lineIndex, charIndex) {\n      var lineStyle = this.styles && this.styles[lineIndex];\n      if (!lineStyle) {\n        return null;\n      }\n      return lineStyle[charIndex];\n    },\n\n    /**\n     * return a new object that contains all the style property for a character\n     * the object returned is newly created\n     * @param {Number} lineIndex of the line where the character is\n     * @param {Number} charIndex position of the character on the line\n     * @return {Object} style object\n     */\n    getCompleteStyleDeclaration: function(lineIndex, charIndex) {\n      var style = this._getStyleDeclaration(lineIndex, charIndex) || { },\n          styleObject = { }, prop;\n      for (var i = 0; i < this._styleProperties.length; i++) {\n        prop = this._styleProperties[i];\n        styleObject[prop] = typeof style[prop] === 'undefined' ? this[prop] : style[prop];\n      }\n      return styleObject;\n    },\n\n    /**\n     * @param {Number} lineIndex\n     * @param {Number} charIndex\n     * @param {Object} style\n     * @private\n     */\n    _setStyleDeclaration: function(lineIndex, charIndex, style) {\n      this.styles[lineIndex][charIndex] = style;\n    },\n\n    /**\n     *\n     * @param {Number} lineIndex\n     * @param {Number} charIndex\n     * @private\n     */\n    _deleteStyleDeclaration: function(lineIndex, charIndex) {\n      delete this.styles[lineIndex][charIndex];\n    },\n\n    /**\n     * @param {Number} lineIndex\n     * @return {Boolean} if the line exists or not\n     * @private\n     */\n    _getLineStyle: function(lineIndex) {\n      return !!this.styles[lineIndex];\n    },\n\n    /**\n     * Set the line style to an empty object so that is initialized\n     * @param {Number} lineIndex\n     * @private\n     */\n    _setLineStyle: function(lineIndex) {\n      this.styles[lineIndex] = {};\n    },\n\n    /**\n     * @param {Number} lineIndex\n     * @private\n     */\n    _deleteLineStyle: function(lineIndex) {\n      delete this.styles[lineIndex];\n    }\n  });\n})();\n\n\n(function() {\n\n  function parseDecoration(object) {\n    if (object.textDecoration) {\n      object.textDecoration.indexOf('underline') > -1 && (object.underline = true);\n      object.textDecoration.indexOf('line-through') > -1 && (object.linethrough = true);\n      object.textDecoration.indexOf('overline') > -1 && (object.overline = true);\n      delete object.textDecoration;\n    }\n  }\n\n  /**\n   * IText class (introduced in <b>v1.4</b>) Events are also fired with \"text:\"\n   * prefix when observing canvas.\n   * @class fabric.IText\n   * @extends fabric.Text\n   * @mixes fabric.Observable\n   *\n   * @fires changed\n   * @fires selection:changed\n   * @fires editing:entered\n   * @fires editing:exited\n   *\n   * @return {fabric.IText} thisArg\n   * @see {@link fabric.IText#initialize} for constructor definition\n   *\n   * <p>Supported key combinations:</p>\n   * <pre>\n   *   Move cursor:                    left, right, up, down\n   *   Select character:               shift + left, shift + right\n   *   Select text vertically:         shift + up, shift + down\n   *   Move cursor by word:            alt + left, alt + right\n   *   Select words:                   shift + alt + left, shift + alt + right\n   *   Move cursor to line start/end:  cmd + left, cmd + right or home, end\n   *   Select till start/end of line:  cmd + shift + left, cmd + shift + right or shift + home, shift + end\n   *   Jump to start/end of text:      cmd + up, cmd + down\n   *   Select till start/end of text:  cmd + shift + up, cmd + shift + down or shift + pgUp, shift + pgDown\n   *   Delete character:               backspace\n   *   Delete word:                    alt + backspace\n   *   Delete line:                    cmd + backspace\n   *   Forward delete:                 delete\n   *   Copy text:                      ctrl/cmd + c\n   *   Paste text:                     ctrl/cmd + v\n   *   Cut text:                       ctrl/cmd + x\n   *   Select entire text:             ctrl/cmd + a\n   *   Quit editing                    tab or esc\n   * </pre>\n   *\n   * <p>Supported mouse/touch combination</p>\n   * <pre>\n   *   Position cursor:                click/touch\n   *   Create selection:               click/touch & drag\n   *   Create selection:               click & shift + click\n   *   Select word:                    double click\n   *   Select line:                    triple click\n   * </pre>\n   */\n  fabric.IText = fabric.util.createClass(fabric.Text, fabric.Observable, /** @lends fabric.IText.prototype */ {\n\n    /**\n     * Type of an object\n     * @type String\n     * @default\n     */\n    type: 'i-text',\n\n    /**\n     * Index where text selection starts (or where cursor is when there is no selection)\n     * @type Number\n     * @default\n     */\n    selectionStart: 0,\n\n    /**\n     * Index where text selection ends\n     * @type Number\n     * @default\n     */\n    selectionEnd: 0,\n\n    /**\n     * Color of text selection\n     * @type String\n     * @default\n     */\n    selectionColor: 'rgba(17,119,255,0.3)',\n\n    /**\n     * Indicates whether text is in editing mode\n     * @type Boolean\n     * @default\n     */\n    isEditing: false,\n\n    /**\n     * Indicates whether a text can be edited\n     * @type Boolean\n     * @default\n     */\n    editable: true,\n\n    /**\n     * Border color of text object while it's in editing mode\n     * @type String\n     * @default\n     */\n    editingBorderColor: 'rgba(102,153,255,0.25)',\n\n    /**\n     * Width of cursor (in px)\n     * @type Number\n     * @default\n     */\n    cursorWidth: 2,\n\n    /**\n     * Color of default cursor (when not overwritten by character style)\n     * @type String\n     * @default\n     */\n    cursorColor: '#333',\n\n    /**\n     * Delay between cursor blink (in ms)\n     * @type Number\n     * @default\n     */\n    cursorDelay: 1000,\n\n    /**\n     * Duration of cursor fadein (in ms)\n     * @type Number\n     * @default\n     */\n    cursorDuration: 600,\n\n    /**\n     * Indicates whether internal text char widths can be cached\n     * @type Boolean\n     * @default\n     */\n    caching: true,\n\n    /**\n     * @private\n     */\n    _reSpace: /\\s|\\n/,\n\n    /**\n     * @private\n     */\n    _currentCursorOpacity: 0,\n\n    /**\n     * @private\n     */\n    _selectionDirection: null,\n\n    /**\n     * @private\n     */\n    _abortCursorAnimation: false,\n\n    /**\n     * @private\n     */\n    __widthOfSpace: [],\n\n    /**\n     * Helps determining when the text is in composition, so that the cursor\n     * rendering is altered.\n     */\n    inCompositionMode: false,\n\n    /**\n     * Constructor\n     * @param {String} text Text string\n     * @param {Object} [options] Options object\n     * @return {fabric.IText} thisArg\n     */\n    initialize: function(text, options) {\n      this.callSuper('initialize', text, options);\n      this.initBehavior();\n    },\n\n    /**\n     * Sets selection start (left boundary of a selection)\n     * @param {Number} index Index to set selection start to\n     */\n    setSelectionStart: function(index) {\n      index = Math.max(index, 0);\n      this._updateAndFire('selectionStart', index);\n    },\n\n    /**\n     * Sets selection end (right boundary of a selection)\n     * @param {Number} index Index to set selection end to\n     */\n    setSelectionEnd: function(index) {\n      index = Math.min(index, this.text.length);\n      this._updateAndFire('selectionEnd', index);\n    },\n\n    /**\n     * @private\n     * @param {String} property 'selectionStart' or 'selectionEnd'\n     * @param {Number} index new position of property\n     */\n    _updateAndFire: function(property, index) {\n      if (this[property] !== index) {\n        this._fireSelectionChanged();\n        this[property] = index;\n      }\n      this._updateTextarea();\n    },\n\n    /**\n     * Fires the even of selection changed\n     * @private\n     */\n    _fireSelectionChanged: function() {\n      this.fire('selection:changed');\n      this.canvas && this.canvas.fire('text:selection:changed', { target: this });\n    },\n\n    /**\n     * Initialize text dimensions. Render all text on given context\n     * or on a offscreen canvas to get the text width with measureText.\n     * Updates this.width and this.height with the proper values.\n     * Does not return dimensions.\n     * @private\n     */\n    initDimensions: function() {\n      this.isEditing && this.initDelayedCursor();\n      this.clearContextTop();\n      this.callSuper('initDimensions');\n    },\n\n    /**\n     * @private\n     * @param {CanvasRenderingContext2D} ctx Context to render on\n     */\n    render: function(ctx) {\n      this.clearContextTop();\n      this.callSuper('render', ctx);\n      // clear the cursorOffsetCache, so we ensure to calculate once per renderCursor\n      // the correct position but not at every cursor animation.\n      this.cursorOffsetCache = { };\n      this.renderCursorOrSelection();\n    },\n\n    /**\n     * @private\n     * @param {CanvasRenderingContext2D} ctx Context to render on\n     */\n    _render: function(ctx) {\n      this.callSuper('_render', ctx);\n    },\n\n    /**\n     * Prepare and clean the contextTop\n     */\n    clearContextTop: function(skipRestore) {\n      if (!this.isEditing || !this.canvas || !this.canvas.contextTop) {\n        return;\n      }\n      var ctx = this.canvas.contextTop, v = this.canvas.viewportTransform;\n      ctx.save();\n      ctx.transform(v[0], v[1], v[2], v[3], v[4], v[5]);\n      this.transform(ctx);\n      this.transformMatrix && ctx.transform.apply(ctx, this.transformMatrix);\n      this._clearTextArea(ctx);\n      skipRestore || ctx.restore();\n    },\n\n    /**\n     * Renders cursor or selection (depending on what exists)\n     * it does on the contextTop. If contextTop is not available, do nothing.\n     */\n    renderCursorOrSelection: function() {\n      if (!this.isEditing || !this.canvas || !this.canvas.contextTop) {\n        return;\n      }\n      var boundaries = this._getCursorBoundaries(),\n          ctx = this.canvas.contextTop;\n      this.clearContextTop(true);\n      if (this.selectionStart === this.selectionEnd) {\n        this.renderCursor(boundaries, ctx);\n      }\n      else {\n        this.renderSelection(boundaries, ctx);\n      }\n      ctx.restore();\n    },\n\n    _clearTextArea: function(ctx) {\n      // we add 4 pixel, to be sure to do not leave any pixel out\n      var width = this.width + 4, height = this.height + 4;\n      ctx.clearRect(-width / 2, -height / 2, width, height);\n    },\n\n    /**\n     * Returns cursor boundaries (left, top, leftOffset, topOffset)\n     * @private\n     * @param {Array} chars Array of characters\n     * @param {String} typeOfBoundaries\n     */\n    _getCursorBoundaries: function(position) {\n\n      // left/top are left/top of entire text box\n      // leftOffset/topOffset are offset from that left/top point of a text box\n\n      if (typeof position === 'undefined') {\n        position = this.selectionStart;\n      }\n\n      var left = this._getLeftOffset(),\n          top = this._getTopOffset(),\n          offsets = this._getCursorBoundariesOffsets(position);\n\n      return {\n        left: left,\n        top: top,\n        leftOffset: offsets.left,\n        topOffset: offsets.top\n      };\n    },\n\n    /**\n     * @private\n     */\n    _getCursorBoundariesOffsets: function(position) {\n      if (this.cursorOffsetCache && 'top' in this.cursorOffsetCache) {\n        return this.cursorOffsetCache;\n      }\n      var lineLeftOffset,\n          lineIndex,\n          charIndex,\n          topOffset = 0,\n          leftOffset = 0,\n          boundaries,\n          cursorPosition = this.get2DCursorLocation(position);\n      charIndex = cursorPosition.charIndex;\n      lineIndex = cursorPosition.lineIndex;\n      for (var i = 0; i < lineIndex; i++) {\n        topOffset += this.getHeightOfLine(i);\n      }\n      lineLeftOffset = this._getLineLeftOffset(lineIndex);\n      var bound = this.__charBounds[lineIndex][charIndex];\n      bound && (leftOffset = bound.left);\n      if (this.charSpacing !== 0 && charIndex === this._textLines[lineIndex].length) {\n        leftOffset -= this._getWidthOfCharSpacing();\n      }\n      boundaries = {\n        top: topOffset,\n        left: lineLeftOffset + (leftOffset > 0 ? leftOffset : 0),\n      };\n      this.cursorOffsetCache = boundaries;\n      return this.cursorOffsetCache;\n    },\n\n    /**\n     * Renders cursor\n     * @param {Object} boundaries\n     * @param {CanvasRenderingContext2D} ctx transformed context to draw on\n     */\n    renderCursor: function(boundaries, ctx) {\n      var cursorLocation = this.get2DCursorLocation(),\n          lineIndex = cursorLocation.lineIndex,\n          charIndex = cursorLocation.charIndex > 0 ? cursorLocation.charIndex - 1 : 0,\n          charHeight = this.getValueOfPropertyAt(lineIndex, charIndex, 'fontSize'),\n          multiplier = this.scaleX * this.canvas.getZoom(),\n          cursorWidth = this.cursorWidth / multiplier,\n          topOffset = boundaries.topOffset,\n          dy = this.getValueOfPropertyAt(lineIndex, charIndex, 'deltaY');\n\n      topOffset += (1 - this._fontSizeFraction) * this.getHeightOfLine(lineIndex) / this.lineHeight\n        - charHeight * (1 - this._fontSizeFraction);\n\n      if (this.inCompositionMode) {\n        this.renderSelection(boundaries, ctx);\n      }\n\n      ctx.fillStyle = this.getValueOfPropertyAt(lineIndex, charIndex, 'fill');\n      ctx.globalAlpha = this.__isMousedown ? 1 : this._currentCursorOpacity;\n      ctx.fillRect(\n        boundaries.left + boundaries.leftOffset - cursorWidth / 2,\n        topOffset + boundaries.top + dy,\n        cursorWidth,\n        charHeight);\n    },\n\n    /**\n     * Renders text selection\n     * @param {Object} boundaries Object with left/top/leftOffset/topOffset\n     * @param {CanvasRenderingContext2D} ctx transformed context to draw on\n     */\n    renderSelection: function(boundaries, ctx) {\n\n      var selectionStart = this.inCompositionMode ? this.hiddenTextarea.selectionStart : this.selectionStart,\n          selectionEnd = this.inCompositionMode ? this.hiddenTextarea.selectionEnd : this.selectionEnd,\n          isJustify = this.textAlign.indexOf('justify') !== -1,\n          start = this.get2DCursorLocation(selectionStart),\n          end = this.get2DCursorLocation(selectionEnd),\n          startLine = start.lineIndex,\n          endLine = end.lineIndex,\n          startChar = start.charIndex < 0 ? 0 : start.charIndex,\n          endChar = end.charIndex < 0 ? 0 : end.charIndex;\n\n      for (var i = startLine; i <= endLine; i++) {\n        var lineOffset = this._getLineLeftOffset(i) || 0,\n            lineHeight = this.getHeightOfLine(i),\n            realLineHeight = 0, boxStart = 0, boxEnd = 0;\n\n        if (i === startLine) {\n          boxStart = this.__charBounds[startLine][startChar].left;\n        }\n        if (i >= startLine && i < endLine) {\n          boxEnd = isJustify && !this.isEndOfWrapping(i) ? this.width : this.getLineWidth(i) || 5; // WTF is this 5?\n        }\n        else if (i === endLine) {\n          if (endChar === 0) {\n            boxEnd = this.__charBounds[endLine][endChar].left;\n          }\n          else {\n            var charSpacing = this._getWidthOfCharSpacing();\n            boxEnd = this.__charBounds[endLine][endChar - 1].left\n              + this.__charBounds[endLine][endChar - 1].width - charSpacing;\n          }\n        }\n        realLineHeight = lineHeight;\n        if (this.lineHeight < 1 || (i === endLine && this.lineHeight > 1)) {\n          lineHeight /= this.lineHeight;\n        }\n        if (this.inCompositionMode) {\n          ctx.fillStyle = this.compositionColor || 'black';\n          ctx.fillRect(\n            boundaries.left + lineOffset + boxStart,\n            boundaries.top + boundaries.topOffset + lineHeight,\n            boxEnd - boxStart,\n            1);\n        }\n        else {\n          ctx.fillStyle = this.selectionColor;\n          ctx.fillRect(\n            boundaries.left + lineOffset + boxStart,\n            boundaries.top + boundaries.topOffset,\n            boxEnd - boxStart,\n            lineHeight);\n        }\n\n\n        boundaries.topOffset += realLineHeight;\n      }\n    },\n\n    /**\n     * High level function to know the height of the cursor.\n     * the currentChar is the one that precedes the cursor\n     * Returns fontSize of char at the current cursor\n     * @return {Number} Character font size\n     */\n    getCurrentCharFontSize: function() {\n      var cp = this._getCurrentCharIndex();\n      return this.getValueOfPropertyAt(cp.l, cp.c, 'fontSize');\n    },\n\n    /**\n     * High level function to know the color of the cursor.\n     * the currentChar is the one that precedes the cursor\n     * Returns color (fill) of char at the current cursor\n     * @return {String} Character color (fill)\n     */\n    getCurrentCharColor: function() {\n      var cp = this._getCurrentCharIndex();\n      return this.getValueOfPropertyAt(cp.l, cp.c, 'fill');\n    },\n\n    /**\n     * Returns the cursor position for the getCurrent.. functions\n     * @private\n     */\n    _getCurrentCharIndex: function() {\n      var cursorPosition = this.get2DCursorLocation(this.selectionStart, true),\n          charIndex = cursorPosition.charIndex > 0 ? cursorPosition.charIndex - 1 : 0;\n      return { l: cursorPosition.lineIndex, c: charIndex };\n    }\n  });\n\n  /**\n   * Returns fabric.IText instance from an object representation\n   * @static\n   * @memberOf fabric.IText\n   * @param {Object} object Object to create an instance from\n   * @param {function} [callback] invoked with new instance as argument\n   */\n  fabric.IText.fromObject = function(object, callback) {\n    parseDecoration(object);\n    if (object.styles) {\n      for (var i in object.styles) {\n        for (var j in object.styles[i]) {\n          parseDecoration(object.styles[i][j]);\n        }\n      }\n    }\n    fabric.Object._fromObject('IText', object, callback, 'text');\n  };\n})();\n\n\n(function() {\n\n  var clone = fabric.util.object.clone;\n\n  fabric.util.object.extend(fabric.IText.prototype, /** @lends fabric.IText.prototype */ {\n\n    /**\n     * Initializes all the interactive behavior of IText\n     */\n    initBehavior: function() {\n      this.initAddedHandler();\n      this.initRemovedHandler();\n      this.initCursorSelectionHandlers();\n      this.initDoubleClickSimulation();\n      this.mouseMoveHandler = this.mouseMoveHandler.bind(this);\n    },\n\n    onDeselect: function() {\n      this.isEditing && this.exitEditing();\n      this.selected = false;\n    },\n\n    /**\n     * Initializes \"added\" event handler\n     */\n    initAddedHandler: function() {\n      var _this = this;\n      this.on('added', function() {\n        var canvas = _this.canvas;\n        if (canvas) {\n          if (!canvas._hasITextHandlers) {\n            canvas._hasITextHandlers = true;\n            _this._initCanvasHandlers(canvas);\n          }\n          canvas._iTextInstances = canvas._iTextInstances || [];\n          canvas._iTextInstances.push(_this);\n        }\n      });\n    },\n\n    initRemovedHandler: function() {\n      var _this = this;\n      this.on('removed', function() {\n        var canvas = _this.canvas;\n        if (canvas) {\n          canvas._iTextInstances = canvas._iTextInstances || [];\n          fabric.util.removeFromArray(canvas._iTextInstances, _this);\n          if (canvas._iTextInstances.length === 0) {\n            canvas._hasITextHandlers = false;\n            _this._removeCanvasHandlers(canvas);\n          }\n        }\n      });\n    },\n\n    /**\n     * register canvas event to manage exiting on other instances\n     * @private\n     */\n    _initCanvasHandlers: function(canvas) {\n      canvas._mouseUpITextHandler = function() {\n        if (canvas._iTextInstances) {\n          canvas._iTextInstances.forEach(function(obj) {\n            obj.__isMousedown = false;\n          });\n        }\n      };\n      canvas.on('mouse:up', canvas._mouseUpITextHandler);\n    },\n\n    /**\n     * remove canvas event to manage exiting on other instances\n     * @private\n     */\n    _removeCanvasHandlers: function(canvas) {\n      canvas.off('mouse:up', canvas._mouseUpITextHandler);\n    },\n\n    /**\n     * @private\n     */\n    _tick: function() {\n      this._currentTickState = this._animateCursor(this, 1, this.cursorDuration, '_onTickComplete');\n    },\n\n    /**\n     * @private\n     */\n    _animateCursor: function(obj, targetOpacity, duration, completeMethod) {\n\n      var tickState;\n\n      tickState = {\n        isAborted: false,\n        abort: function() {\n          this.isAborted = true;\n        },\n      };\n\n      obj.animate('_currentCursorOpacity', targetOpacity, {\n        duration: duration,\n        onComplete: function() {\n          if (!tickState.isAborted) {\n            obj[completeMethod]();\n          }\n        },\n        onChange: function() {\n          // we do not want to animate a selection, only cursor\n          if (obj.canvas && obj.selectionStart === obj.selectionEnd) {\n            obj.renderCursorOrSelection();\n          }\n        },\n        abort: function() {\n          return tickState.isAborted;\n        }\n      });\n      return tickState;\n    },\n\n    /**\n     * @private\n     */\n    _onTickComplete: function() {\n\n      var _this = this;\n\n      if (this._cursorTimeout1) {\n        clearTimeout(this._cursorTimeout1);\n      }\n      this._cursorTimeout1 = setTimeout(function() {\n        _this._currentTickCompleteState = _this._animateCursor(_this, 0, this.cursorDuration / 2, '_tick');\n      }, 100);\n    },\n\n    /**\n     * Initializes delayed cursor\n     */\n    initDelayedCursor: function(restart) {\n      var _this = this,\n          delay = restart ? 0 : this.cursorDelay;\n\n      this.abortCursorAnimation();\n      this._currentCursorOpacity = 1;\n      this._cursorTimeout2 = setTimeout(function() {\n        _this._tick();\n      }, delay);\n    },\n\n    /**\n     * Aborts cursor animation and clears all timeouts\n     */\n    abortCursorAnimation: function() {\n      var shouldClear = this._currentTickState || this._currentTickCompleteState,\n          canvas = this.canvas;\n      this._currentTickState && this._currentTickState.abort();\n      this._currentTickCompleteState && this._currentTickCompleteState.abort();\n\n      clearTimeout(this._cursorTimeout1);\n      clearTimeout(this._cursorTimeout2);\n\n      this._currentCursorOpacity = 0;\n      // to clear just itext area we need to transform the context\n      // it may not be worth it\n      if (shouldClear && canvas) {\n        canvas.clearContext(canvas.contextTop || canvas.contextContainer);\n      }\n\n    },\n\n    /**\n     * Selects entire text\n     * @return {fabric.IText} thisArg\n     * @chainable\n     */\n    selectAll: function() {\n      this.selectionStart = 0;\n      this.selectionEnd = this._text.length;\n      this._fireSelectionChanged();\n      this._updateTextarea();\n      return this;\n    },\n\n    /**\n     * Returns selected text\n     * @return {String}\n     */\n    getSelectedText: function() {\n      return this._text.slice(this.selectionStart, this.selectionEnd).join('');\n    },\n\n    /**\n     * Find new selection index representing start of current word according to current selection index\n     * @param {Number} startFrom Current selection index\n     * @return {Number} New selection index\n     */\n    findWordBoundaryLeft: function(startFrom) {\n      var offset = 0, index = startFrom - 1;\n\n      // remove space before cursor first\n      if (this._reSpace.test(this._text[index])) {\n        while (this._reSpace.test(this._text[index])) {\n          offset++;\n          index--;\n        }\n      }\n      while (/\\S/.test(this._text[index]) && index > -1) {\n        offset++;\n        index--;\n      }\n\n      return startFrom - offset;\n    },\n\n    /**\n     * Find new selection index representing end of current word according to current selection index\n     * @param {Number} startFrom Current selection index\n     * @return {Number} New selection index\n     */\n    findWordBoundaryRight: function(startFrom) {\n      var offset = 0, index = startFrom;\n\n      // remove space after cursor first\n      if (this._reSpace.test(this._text[index])) {\n        while (this._reSpace.test(this._text[index])) {\n          offset++;\n          index++;\n        }\n      }\n      while (/\\S/.test(this._text[index]) && index < this._text.length) {\n        offset++;\n        index++;\n      }\n\n      return startFrom + offset;\n    },\n\n    /**\n     * Find new selection index representing start of current line according to current selection index\n     * @param {Number} startFrom Current selection index\n     * @return {Number} New selection index\n     */\n    findLineBoundaryLeft: function(startFrom) {\n      var offset = 0, index = startFrom - 1;\n\n      while (!/\\n/.test(this._text[index]) && index > -1) {\n        offset++;\n        index--;\n      }\n\n      return startFrom - offset;\n    },\n\n    /**\n     * Find new selection index representing end of current line according to current selection index\n     * @param {Number} startFrom Current selection index\n     * @return {Number} New selection index\n     */\n    findLineBoundaryRight: function(startFrom) {\n      var offset = 0, index = startFrom;\n\n      while (!/\\n/.test(this._text[index]) && index < this._text.length) {\n        offset++;\n        index++;\n      }\n\n      return startFrom + offset;\n    },\n\n    /**\n     * Finds index corresponding to beginning or end of a word\n     * @param {Number} selectionStart Index of a character\n     * @param {Number} direction 1 or -1\n     * @return {Number} Index of the beginning or end of a word\n     */\n    searchWordBoundary: function(selectionStart, direction) {\n      var index     = this._reSpace.test(this._text[selectionStart]) ? selectionStart - 1 : selectionStart,\n          _char     = this._text[index],\n          reNonWord = /[ \\n\\.,;!\\?\\-]/;\n\n      while (!reNonWord.test(_char) && index > 0 && index < this._text.length) {\n        index += direction;\n        _char = this._text[index];\n      }\n      if (reNonWord.test(_char) && _char !== '\\n') {\n        index += direction === 1 ? 0 : 1;\n      }\n      return index;\n    },\n\n    /**\n     * Selects a word based on the index\n     * @param {Number} selectionStart Index of a character\n     */\n    selectWord: function(selectionStart) {\n      selectionStart = selectionStart || this.selectionStart;\n      var newSelectionStart = this.searchWordBoundary(selectionStart, -1), /* search backwards */\n          newSelectionEnd = this.searchWordBoundary(selectionStart, 1); /* search forward */\n\n      this.selectionStart = newSelectionStart;\n      this.selectionEnd = newSelectionEnd;\n      this._fireSelectionChanged();\n      this._updateTextarea();\n      this.renderCursorOrSelection();\n    },\n\n    /**\n     * Selects a line based on the index\n     * @param {Number} selectionStart Index of a character\n     * @return {fabric.IText} thisArg\n     * @chainable\n     */\n    selectLine: function(selectionStart) {\n      selectionStart = selectionStart || this.selectionStart;\n      var newSelectionStart = this.findLineBoundaryLeft(selectionStart),\n          newSelectionEnd = this.findLineBoundaryRight(selectionStart);\n\n      this.selectionStart = newSelectionStart;\n      this.selectionEnd = newSelectionEnd;\n      this._fireSelectionChanged();\n      this._updateTextarea();\n      return this;\n    },\n\n    /**\n     * Enters editing state\n     * @return {fabric.IText} thisArg\n     * @chainable\n     */\n    enterEditing: function(e) {\n      if (this.isEditing || !this.editable) {\n        return;\n      }\n\n      if (this.canvas) {\n        this.canvas.calcOffset();\n        this.exitEditingOnOthers(this.canvas);\n      }\n\n      this.isEditing = true;\n\n      this.initHiddenTextarea(e);\n      this.hiddenTextarea.focus();\n      this.hiddenTextarea.value = this.text;\n      this._updateTextarea();\n      this._saveEditingProps();\n      this._setEditingProps();\n      this._textBeforeEdit = this.text;\n\n      this._tick();\n      this.fire('editing:entered');\n      this._fireSelectionChanged();\n      if (!this.canvas) {\n        return this;\n      }\n      this.canvas.fire('text:editing:entered', { target: this });\n      this.initMouseMoveHandler();\n      this.canvas.requestRenderAll();\n      return this;\n    },\n\n    exitEditingOnOthers: function(canvas) {\n      if (canvas._iTextInstances) {\n        canvas._iTextInstances.forEach(function(obj) {\n          obj.selected = false;\n          if (obj.isEditing) {\n            obj.exitEditing();\n          }\n        });\n      }\n    },\n\n    /**\n     * Initializes \"mousemove\" event handler\n     */\n    initMouseMoveHandler: function() {\n      this.canvas.on('mouse:move', this.mouseMoveHandler);\n    },\n\n    /**\n     * @private\n     */\n    mouseMoveHandler: function(options) {\n      if (!this.__isMousedown || !this.isEditing) {\n        return;\n      }\n\n      var newSelectionStart = this.getSelectionStartFromPointer(options.e),\n          currentStart = this.selectionStart,\n          currentEnd = this.selectionEnd;\n      if (\n        (newSelectionStart !== this.__selectionStartOnMouseDown || currentStart === currentEnd)\n        &&\n        (currentStart === newSelectionStart || currentEnd === newSelectionStart)\n      ) {\n        return;\n      }\n      if (newSelectionStart > this.__selectionStartOnMouseDown) {\n        this.selectionStart = this.__selectionStartOnMouseDown;\n        this.selectionEnd = newSelectionStart;\n      }\n      else {\n        this.selectionStart = newSelectionStart;\n        this.selectionEnd = this.__selectionStartOnMouseDown;\n      }\n      if (this.selectionStart !== currentStart || this.selectionEnd !== currentEnd) {\n        this.restartCursorIfNeeded();\n        this._fireSelectionChanged();\n        this._updateTextarea();\n        this.renderCursorOrSelection();\n      }\n    },\n\n    /**\n     * @private\n     */\n    _setEditingProps: function() {\n      this.hoverCursor = 'text';\n\n      if (this.canvas) {\n        this.canvas.defaultCursor = this.canvas.moveCursor = 'text';\n      }\n\n      this.borderColor = this.editingBorderColor;\n      this.hasControls = this.selectable = false;\n      this.lockMovementX = this.lockMovementY = true;\n    },\n\n    /**\n     * convert from textarea to grapheme indexes\n     */\n    fromStringToGraphemeSelection: function(start, end, text) {\n      var smallerTextStart = text.slice(0, start),\n          graphemeStart = fabric.util.string.graphemeSplit(smallerTextStart).length;\n      if (start === end) {\n        return { selectionStart: graphemeStart, selectionEnd: graphemeStart };\n      }\n      var smallerTextEnd = text.slice(start, end),\n          graphemeEnd = fabric.util.string.graphemeSplit(smallerTextEnd).length;\n      return { selectionStart: graphemeStart, selectionEnd: graphemeStart + graphemeEnd };\n    },\n\n    /**\n     * convert from fabric to textarea values\n     */\n    fromGraphemeToStringSelection: function(start, end, _text) {\n      var smallerTextStart = _text.slice(0, start),\n          graphemeStart = smallerTextStart.join('').length;\n      if (start === end) {\n        return { selectionStart: graphemeStart, selectionEnd: graphemeStart };\n      }\n      var smallerTextEnd = _text.slice(start, end),\n          graphemeEnd = smallerTextEnd.join('').length;\n      return { selectionStart: graphemeStart, selectionEnd: graphemeStart + graphemeEnd };\n    },\n\n    /**\n     * @private\n     */\n    _updateTextarea: function() {\n      this.cursorOffsetCache = { };\n      if (!this.hiddenTextarea) {\n        return;\n      }\n      if (!this.inCompositionMode) {\n        var newSelection = this.fromGraphemeToStringSelection(this.selectionStart, this.selectionEnd, this._text);\n        this.hiddenTextarea.selectionStart = newSelection.selectionStart;\n        this.hiddenTextarea.selectionEnd = newSelection.selectionEnd;\n      }\n      this.updateTextareaPosition();\n    },\n\n    /**\n     * @private\n     */\n    updateFromTextArea: function() {\n      if (!this.hiddenTextarea) {\n        return;\n      }\n      this.cursorOffsetCache = { };\n      this.text = this.hiddenTextarea.value;\n      if (this._shouldClearDimensionCache()) {\n        this.initDimensions();\n        this.setCoords();\n      }\n      var newSelection = this.fromStringToGraphemeSelection(\n        this.hiddenTextarea.selectionStart, this.hiddenTextarea.selectionEnd, this.hiddenTextarea.value);\n      this.selectionEnd = this.selectionStart = newSelection.selectionEnd;\n      if (!this.inCompositionMode) {\n        this.selectionStart = newSelection.selectionStart;\n      }\n      this.updateTextareaPosition();\n    },\n\n    /**\n     * @private\n     */\n    updateTextareaPosition: function() {\n      if (this.selectionStart === this.selectionEnd) {\n        var style = this._calcTextareaPosition();\n        this.hiddenTextarea.style.left = style.left;\n        this.hiddenTextarea.style.top = style.top;\n      }\n    },\n\n    /**\n     * @private\n     * @return {Object} style contains style for hiddenTextarea\n     */\n    _calcTextareaPosition: function() {\n      if (!this.canvas) {\n        return { x: 1, y: 1 };\n      }\n      var desiredPosition = this.inCompositionMode ? this.compositionStart : this.selectionStart,\n          boundaries = this._getCursorBoundaries(desiredPosition),\n          cursorLocation = this.get2DCursorLocation(desiredPosition),\n          lineIndex = cursorLocation.lineIndex,\n          charIndex = cursorLocation.charIndex,\n          charHeight = this.getValueOfPropertyAt(lineIndex, charIndex, 'fontSize') * this.lineHeight,\n          leftOffset = boundaries.leftOffset,\n          m = this.calcTransformMatrix(),\n          p = {\n            x: boundaries.left + leftOffset,\n            y: boundaries.top + boundaries.topOffset + charHeight\n          },\n          upperCanvas = this.canvas.upperCanvasEl,\n          upperCanvasWidth = upperCanvas.width,\n          upperCanvasHeight = upperCanvas.height,\n          maxWidth = upperCanvasWidth - charHeight,\n          maxHeight = upperCanvasHeight - charHeight,\n          scaleX = upperCanvas.clientWidth / upperCanvasWidth,\n          scaleY = upperCanvas.clientHeight / upperCanvasHeight;\n\n      p = fabric.util.transformPoint(p, m);\n      p = fabric.util.transformPoint(p, this.canvas.viewportTransform);\n      p.x *= scaleX;\n      p.y *= scaleY;\n      if (p.x < 0) {\n        p.x = 0;\n      }\n      if (p.x > maxWidth) {\n        p.x = maxWidth;\n      }\n      if (p.y < 0) {\n        p.y = 0;\n      }\n      if (p.y > maxHeight) {\n        p.y = maxHeight;\n      }\n\n      // add canvas offset on document\n      p.x += this.canvas._offset.left;\n      p.y += this.canvas._offset.top;\n\n      return { left: p.x + 'px', top: p.y + 'px', fontSize: charHeight + 'px', charHeight: charHeight };\n    },\n\n    /**\n     * @private\n     */\n    _saveEditingProps: function() {\n      this._savedProps = {\n        hasControls: this.hasControls,\n        borderColor: this.borderColor,\n        lockMovementX: this.lockMovementX,\n        lockMovementY: this.lockMovementY,\n        hoverCursor: this.hoverCursor,\n        selectable: this.selectable,\n        defaultCursor: this.canvas && this.canvas.defaultCursor,\n        moveCursor: this.canvas && this.canvas.moveCursor\n      };\n    },\n\n    /**\n     * @private\n     */\n    _restoreEditingProps: function() {\n      if (!this._savedProps) {\n        return;\n      }\n\n      this.hoverCursor = this._savedProps.hoverCursor;\n      this.hasControls = this._savedProps.hasControls;\n      this.borderColor = this._savedProps.borderColor;\n      this.selectable = this._savedProps.selectable;\n      this.lockMovementX = this._savedProps.lockMovementX;\n      this.lockMovementY = this._savedProps.lockMovementY;\n\n      if (this.canvas) {\n        this.canvas.defaultCursor = this._savedProps.defaultCursor;\n        this.canvas.moveCursor = this._savedProps.moveCursor;\n      }\n    },\n\n    /**\n     * Exits from editing state\n     * @return {fabric.IText} thisArg\n     * @chainable\n     */\n    exitEditing: function() {\n      var isTextChanged = (this._textBeforeEdit !== this.text);\n      this.selected = false;\n      this.isEditing = false;\n\n      this.selectionEnd = this.selectionStart;\n\n      if (this.hiddenTextarea) {\n        this.hiddenTextarea.blur && this.hiddenTextarea.blur();\n        this.canvas && this.hiddenTextarea.parentNode.removeChild(this.hiddenTextarea);\n        this.hiddenTextarea = null;\n      }\n\n      this.abortCursorAnimation();\n      this._restoreEditingProps();\n      this._currentCursorOpacity = 0;\n      if (this._shouldClearDimensionCache()) {\n        this.initDimensions();\n        this.setCoords();\n      }\n      this.fire('editing:exited');\n      isTextChanged && this.fire('modified');\n      if (this.canvas) {\n        this.canvas.off('mouse:move', this.mouseMoveHandler);\n        this.canvas.fire('text:editing:exited', { target: this });\n        isTextChanged && this.canvas.fire('object:modified', { target: this });\n      }\n      return this;\n    },\n\n    /**\n     * @private\n     */\n    _removeExtraneousStyles: function() {\n      for (var prop in this.styles) {\n        if (!this._textLines[prop]) {\n          delete this.styles[prop];\n        }\n      }\n    },\n\n    /**\n     * remove and reflow a style block from start to end.\n     * @param {Number} start linear start position for removal (included in removal)\n     * @param {Number} end linear end position for removal ( excluded from removal )\n     */\n    removeStyleFromTo: function(start, end) {\n      var cursorStart = this.get2DCursorLocation(start, true),\n          cursorEnd = this.get2DCursorLocation(end, true),\n          lineStart = cursorStart.lineIndex,\n          charStart = cursorStart.charIndex,\n          lineEnd = cursorEnd.lineIndex,\n          charEnd = cursorEnd.charIndex,\n          i, styleObj;\n      if (lineStart !== lineEnd) {\n        // step1 remove the trailing of lineStart\n        if (this.styles[lineStart]) {\n          for (i = charStart; i < this._unwrappedTextLines[lineStart].length; i++) {\n            delete this.styles[lineStart][i];\n          }\n        }\n        // step2 move the trailing of lineEnd to lineStart if needed\n        if (this.styles[lineEnd]) {\n          for (i = charEnd; i < this._unwrappedTextLines[lineEnd].length; i++) {\n            styleObj = this.styles[lineEnd][i];\n            if (styleObj) {\n              this.styles[lineStart] || (this.styles[lineStart] = { });\n              this.styles[lineStart][charStart + i - charEnd] = styleObj;\n            }\n          }\n        }\n        // step3 detects lines will be completely removed.\n        for (i = lineStart + 1; i <= lineEnd; i++) {\n          delete this.styles[i];\n        }\n        // step4 shift remaining lines.\n        this.shiftLineStyles(lineEnd, lineStart - lineEnd);\n      }\n      else {\n        // remove and shift left on the same line\n        if (this.styles[lineStart]) {\n          styleObj = this.styles[lineStart];\n          var diff = charEnd - charStart, numericChar, _char;\n          for (i = charStart; i < charEnd; i++) {\n            delete styleObj[i];\n          }\n          for (_char in this.styles[lineStart]) {\n            numericChar = parseInt(_char, 10);\n            if (numericChar >= charEnd) {\n              styleObj[numericChar - diff] = styleObj[_char];\n              delete styleObj[_char];\n            }\n          }\n        }\n      }\n    },\n\n    /**\n     * Shifts line styles up or down\n     * @param {Number} lineIndex Index of a line\n     * @param {Number} offset Can any number?\n     */\n    shiftLineStyles: function(lineIndex, offset) {\n      // shift all line styles by offset upward or downward\n      // do not clone deep. we need new array, not new style objects\n      var clonedStyles = clone(this.styles);\n      for (var line in this.styles) {\n        var numericLine = parseInt(line, 10);\n        if (numericLine > lineIndex) {\n          this.styles[numericLine + offset] = clonedStyles[numericLine];\n          if (!clonedStyles[numericLine - offset]) {\n            delete this.styles[numericLine];\n          }\n        }\n      }\n    },\n\n    restartCursorIfNeeded: function() {\n      if (!this._currentTickState || this._currentTickState.isAborted\n        || !this._currentTickCompleteState || this._currentTickCompleteState.isAborted\n      ) {\n        this.initDelayedCursor();\n      }\n    },\n\n    /**\n     * Inserts new style object\n     * @param {Number} lineIndex Index of a line\n     * @param {Number} charIndex Index of a char\n     * @param {Number} qty number of lines to add\n     * @param {Array} copiedStyle Array of objects styles\n     */\n    insertNewlineStyleObject: function(lineIndex, charIndex, qty, copiedStyle) {\n      var currentCharStyle,\n          newLineStyles = {},\n          somethingAdded = false;\n\n      qty || (qty = 1);\n      this.shiftLineStyles(lineIndex, qty);\n      if (this.styles[lineIndex]) {\n        currentCharStyle = this.styles[lineIndex][charIndex === 0 ? charIndex : charIndex - 1];\n      }\n\n      // we clone styles of all chars\n      // after cursor onto the current line\n      for (var index in this.styles[lineIndex]) {\n        var numIndex = parseInt(index, 10);\n        if (numIndex >= charIndex) {\n          somethingAdded = true;\n          newLineStyles[numIndex - charIndex] = this.styles[lineIndex][index];\n          // remove lines from the previous line since they're on a new line now\n          delete this.styles[lineIndex][index];\n        }\n      }\n      if (somethingAdded) {\n        this.styles[lineIndex + qty] = newLineStyles;\n      }\n      else {\n        delete this.styles[lineIndex + qty];\n      }\n      // for the other lines\n      // we clone current char style onto the next (otherwise empty) line\n      while (qty > 1) {\n        qty--;\n        if (copiedStyle && copiedStyle[qty]) {\n          this.styles[lineIndex + qty] = { 0: clone(copiedStyle[qty]) };\n        }\n        else if (currentCharStyle) {\n          this.styles[lineIndex + qty] = { 0: clone(currentCharStyle) };\n        }\n        else {\n          delete this.styles[lineIndex + qty];\n        }\n      }\n      this._forceClearCache = true;\n    },\n\n    /**\n     * Inserts style object for a given line/char index\n     * @param {Number} lineIndex Index of a line\n     * @param {Number} charIndex Index of a char\n     * @param {Number} quantity number Style object to insert, if given\n     * @param {Array} copiedStyle array of style objects\n     */\n    insertCharStyleObject: function(lineIndex, charIndex, quantity, copiedStyle) {\n      if (!this.styles) {\n        this.styles = {};\n      }\n      var currentLineStyles       = this.styles[lineIndex],\n          currentLineStylesCloned = currentLineStyles ? clone(currentLineStyles) : {};\n\n      quantity || (quantity = 1);\n      // shift all char styles by quantity forward\n      // 0,1,2,3 -> (charIndex=2) -> 0,1,3,4 -> (insert 2) -> 0,1,2,3,4\n      for (var index in currentLineStylesCloned) {\n        var numericIndex = parseInt(index, 10);\n        if (numericIndex >= charIndex) {\n          currentLineStyles[numericIndex + quantity] = currentLineStylesCloned[numericIndex];\n          // only delete the style if there was nothing moved there\n          if (!currentLineStylesCloned[numericIndex - quantity]) {\n            delete currentLineStyles[numericIndex];\n          }\n        }\n      }\n      this._forceClearCache = true;\n      if (copiedStyle) {\n        while (quantity--) {\n          if (!Object.keys(copiedStyle[quantity]).length) {\n            continue;\n          }\n          if (!this.styles[lineIndex]) {\n            this.styles[lineIndex] = {};\n          }\n          this.styles[lineIndex][charIndex + quantity] = clone(copiedStyle[quantity]);\n        }\n        return;\n      }\n      if (!currentLineStyles) {\n        return;\n      }\n      var newStyle = currentLineStyles[charIndex ? charIndex - 1 : 1];\n      while (newStyle && quantity--) {\n        this.styles[lineIndex][charIndex + quantity] = clone(newStyle);\n      }\n    },\n\n    /**\n     * Inserts style object(s)\n     * @param {Array} insertedText Characters at the location where style is inserted\n     * @param {Number} start cursor index for inserting style\n     * @param {Array} [copiedStyle] array of style objects to insert.\n     */\n    insertNewStyleBlock: function(insertedText, start, copiedStyle) {\n      var cursorLoc = this.get2DCursorLocation(start, true),\n          addedLines = [0], linesLength = 0;\n      for (var i = 0; i < insertedText.length; i++) {\n        if (insertedText[i] === '\\n') {\n          linesLength++;\n          addedLines[linesLength] = 0;\n        }\n        else {\n          addedLines[linesLength]++;\n        }\n      }\n      if (addedLines[0] > 0) {\n        this.insertCharStyleObject(cursorLoc.lineIndex, cursorLoc.charIndex, addedLines[0], copiedStyle);\n        copiedStyle = copiedStyle && copiedStyle.slice(addedLines[0] + 1);\n      }\n      linesLength && this.insertNewlineStyleObject(\n        cursorLoc.lineIndex, cursorLoc.charIndex + addedLines[0], linesLength);\n      for (var i = 1; i < linesLength; i++) {\n        if (addedLines[i] > 0) {\n          this.insertCharStyleObject(cursorLoc.lineIndex + i, 0, addedLines[i], copiedStyle);\n        }\n        else if (copiedStyle) {\n          this.styles[cursorLoc.lineIndex + i][0] = copiedStyle[0];\n        }\n        copiedStyle = copiedStyle && copiedStyle.slice(addedLines[i] + 1);\n      }\n      // we use i outside the loop to get it like linesLength\n      if (addedLines[i] > 0) {\n        this.insertCharStyleObject(cursorLoc.lineIndex + i, 0, addedLines[i], copiedStyle);\n      }\n    },\n\n    /**\n     * Set the selectionStart and selectionEnd according to the new position of cursor\n     * mimic the key - mouse navigation when shift is pressed.\n     */\n    setSelectionStartEndWithShift: function(start, end, newSelection) {\n      if (newSelection <= start) {\n        if (end === start) {\n          this._selectionDirection = 'left';\n        }\n        else if (this._selectionDirection === 'right') {\n          this._selectionDirection = 'left';\n          this.selectionEnd = start;\n        }\n        this.selectionStart = newSelection;\n      }\n      else if (newSelection > start && newSelection < end) {\n        if (this._selectionDirection === 'right') {\n          this.selectionEnd = newSelection;\n        }\n        else {\n          this.selectionStart = newSelection;\n        }\n      }\n      else {\n        // newSelection is > selection start and end\n        if (end === start) {\n          this._selectionDirection = 'right';\n        }\n        else if (this._selectionDirection === 'left') {\n          this._selectionDirection = 'right';\n          this.selectionStart = end;\n        }\n        this.selectionEnd = newSelection;\n      }\n    },\n\n    setSelectionInBoundaries: function() {\n      var length = this.text.length;\n      if (this.selectionStart > length) {\n        this.selectionStart = length;\n      }\n      else if (this.selectionStart < 0) {\n        this.selectionStart = 0;\n      }\n      if (this.selectionEnd > length) {\n        this.selectionEnd = length;\n      }\n      else if (this.selectionEnd < 0) {\n        this.selectionEnd = 0;\n      }\n    }\n  });\n})();\n\n\nfabric.util.object.extend(fabric.IText.prototype, /** @lends fabric.IText.prototype */ {\n  /**\n   * Initializes \"dbclick\" event handler\n   */\n  initDoubleClickSimulation: function() {\n\n    // for double click\n    this.__lastClickTime = +new Date();\n\n    // for triple click\n    this.__lastLastClickTime = +new Date();\n\n    this.__lastPointer = { };\n\n    this.on('mousedown', this.onMouseDown);\n  },\n\n  /**\n   * Default event handler to simulate triple click\n   * @private\n   */\n  onMouseDown: function(options) {\n    if (!this.canvas) {\n      return;\n    }\n    this.__newClickTime = +new Date();\n    var newPointer = options.pointer;\n    if (this.isTripleClick(newPointer)) {\n      this.fire('tripleclick', options);\n      this._stopEvent(options.e);\n    }\n    this.__lastLastClickTime = this.__lastClickTime;\n    this.__lastClickTime = this.__newClickTime;\n    this.__lastPointer = newPointer;\n    this.__lastIsEditing = this.isEditing;\n    this.__lastSelected = this.selected;\n  },\n\n  isTripleClick: function(newPointer) {\n    return this.__newClickTime - this.__lastClickTime < 500 &&\n        this.__lastClickTime - this.__lastLastClickTime < 500 &&\n        this.__lastPointer.x === newPointer.x &&\n        this.__lastPointer.y === newPointer.y;\n  },\n\n  /**\n   * @private\n   */\n  _stopEvent: function(e) {\n    e.preventDefault && e.preventDefault();\n    e.stopPropagation && e.stopPropagation();\n  },\n\n  /**\n   * Initializes event handlers related to cursor or selection\n   */\n  initCursorSelectionHandlers: function() {\n    this.initMousedownHandler();\n    this.initMouseupHandler();\n    this.initClicks();\n  },\n\n  /**\n   * Initializes double and triple click event handlers\n   */\n  initClicks: function() {\n    this.on('mousedblclick', function(options) {\n      this.selectWord(this.getSelectionStartFromPointer(options.e));\n    });\n    this.on('tripleclick', function(options) {\n      this.selectLine(this.getSelectionStartFromPointer(options.e));\n    });\n  },\n\n  /**\n   * Default event handler for the basic functionalities needed on _mouseDown\n   * can be overridden to do something different.\n   * Scope of this implementation is: find the click position, set selectionStart\n   * find selectionEnd, initialize the drawing of either cursor or selection area\n   */\n  _mouseDownHandler: function(options) {\n    if (!this.canvas || !this.editable || (options.e.button && options.e.button !== 1)) {\n      return;\n    }\n\n    this.__isMousedown = true;\n\n    if (this.selected) {\n      this.setCursorByClick(options.e);\n    }\n\n    if (this.isEditing) {\n      this.__selectionStartOnMouseDown = this.selectionStart;\n      if (this.selectionStart === this.selectionEnd) {\n        this.abortCursorAnimation();\n      }\n      this.renderCursorOrSelection();\n    }\n  },\n\n  /**\n   * Default event handler for the basic functionalities needed on mousedown:before\n   * can be overridden to do something different.\n   * Scope of this implementation is: verify the object is already selected when mousing down\n   */\n  _mouseDownHandlerBefore: function(options) {\n    if (!this.canvas || !this.editable || (options.e.button && options.e.button !== 1)) {\n      return;\n    }\n    if (this === this.canvas._activeObject) {\n      this.selected = true;\n    }\n  },\n\n  /**\n   * Initializes \"mousedown\" event handler\n   */\n  initMousedownHandler: function() {\n    this.on('mousedown', this._mouseDownHandler);\n    this.on('mousedown:before', this._mouseDownHandlerBefore);\n  },\n\n  /**\n   * Initializes \"mouseup\" event handler\n   */\n  initMouseupHandler: function() {\n    this.on('mouseup', this.mouseUpHandler);\n  },\n\n  /**\n   * standard hander for mouse up, overridable\n   * @private\n   */\n  mouseUpHandler: function(options) {\n    this.__isMousedown = false;\n    if (!this.editable || this.group ||\n      (options.transform && options.transform.actionPerformed) ||\n      (options.e.button && options.e.button !== 1)) {\n      return;\n    }\n\n    if (this.canvas) {\n      var currentActive = this.canvas._activeObject;\n      if (currentActive && currentActive !== this) {\n        // avoid running this logic when there is an active object\n        // this because is possible with shift click and fast clicks,\n        // to rapidly deselect and reselect this object and trigger an enterEdit\n        return;\n      }\n    }\n\n    if (this.__lastSelected && !this.__corner) {\n      this.selected = false;\n      this.__lastSelected = false;\n      this.enterEditing(options.e);\n      if (this.selectionStart === this.selectionEnd) {\n        this.initDelayedCursor(true);\n      }\n      else {\n        this.renderCursorOrSelection();\n      }\n    }\n    else {\n      this.selected = true;\n    }\n  },\n\n  /**\n   * Changes cursor location in a text depending on passed pointer (x/y) object\n   * @param {Event} e Event object\n   */\n  setCursorByClick: function(e) {\n    var newSelection = this.getSelectionStartFromPointer(e),\n        start = this.selectionStart, end = this.selectionEnd;\n    if (e.shiftKey) {\n      this.setSelectionStartEndWithShift(start, end, newSelection);\n    }\n    else {\n      this.selectionStart = newSelection;\n      this.selectionEnd = newSelection;\n    }\n    if (this.isEditing) {\n      this._fireSelectionChanged();\n      this._updateTextarea();\n    }\n  },\n\n  /**\n   * Returns index of a character corresponding to where an object was clicked\n   * @param {Event} e Event object\n   * @return {Number} Index of a character\n   */\n  getSelectionStartFromPointer: function(e) {\n    var mouseOffset = this.getLocalPointer(e),\n        prevWidth = 0,\n        width = 0,\n        height = 0,\n        charIndex = 0,\n        lineIndex = 0,\n        lineLeftOffset,\n        line;\n\n    for (var i = 0, len = this._textLines.length; i < len; i++) {\n      if (height <= mouseOffset.y) {\n        height += this.getHeightOfLine(i) * this.scaleY;\n        lineIndex = i;\n        if (i > 0) {\n          charIndex += this._textLines[i - 1].length + this.missingNewlineOffset(i - 1);\n        }\n      }\n      else {\n        break;\n      }\n    }\n    lineLeftOffset = this._getLineLeftOffset(lineIndex);\n    width = lineLeftOffset * this.scaleX;\n    line = this._textLines[lineIndex];\n    for (var j = 0, jlen = line.length; j < jlen; j++) {\n      prevWidth = width;\n      // i removed something about flipX here, check.\n      width += this.__charBounds[lineIndex][j].kernedWidth * this.scaleX;\n      if (width <= mouseOffset.x) {\n        charIndex++;\n      }\n      else {\n        break;\n      }\n    }\n    return this._getNewSelectionStartFromOffset(mouseOffset, prevWidth, width, charIndex, jlen);\n  },\n\n  /**\n   * @private\n   */\n  _getNewSelectionStartFromOffset: function(mouseOffset, prevWidth, width, index, jlen) {\n    // we need Math.abs because when width is after the last char, the offset is given as 1, while is 0\n    var distanceBtwLastCharAndCursor = mouseOffset.x - prevWidth,\n        distanceBtwNextCharAndCursor = width - mouseOffset.x,\n        offset = distanceBtwNextCharAndCursor > distanceBtwLastCharAndCursor ||\n          distanceBtwNextCharAndCursor < 0 ? 0 : 1,\n        newSelectionStart = index + offset;\n    // if object is horizontally flipped, mirror cursor location from the end\n    if (this.flipX) {\n      newSelectionStart = jlen - newSelectionStart;\n    }\n\n    if (newSelectionStart > this._text.length) {\n      newSelectionStart = this._text.length;\n    }\n\n    return newSelectionStart;\n  }\n});\n\n\nfabric.util.object.extend(fabric.IText.prototype, /** @lends fabric.IText.prototype */ {\n\n  /**\n   * Initializes hidden textarea (needed to bring up keyboard in iOS)\n   */\n  initHiddenTextarea: function() {\n    this.hiddenTextarea = fabric.document.createElement('textarea');\n    this.hiddenTextarea.setAttribute('autocapitalize', 'off');\n    this.hiddenTextarea.setAttribute('autocorrect', 'off');\n    this.hiddenTextarea.setAttribute('autocomplete', 'off');\n    this.hiddenTextarea.setAttribute('spellcheck', 'false');\n    this.hiddenTextarea.setAttribute('data-fabric-hiddentextarea', '');\n    this.hiddenTextarea.setAttribute('wrap', 'off');\n    var style = this._calcTextareaPosition();\n    // line-height: 1px; was removed from the style to fix this:\n    // https://bugs.chromium.org/p/chromium/issues/detail?id=870966\n    this.hiddenTextarea.style.cssText = 'position: absolute; top: ' + style.top +\n    '; left: ' + style.left + '; z-index: -999; opacity: 0; width: 1px; height: 1px; font-size: 1px;' +\n    ' paddingï½°top: ' + style.fontSize + ';';\n    fabric.document.body.appendChild(this.hiddenTextarea);\n\n    fabric.util.addListener(this.hiddenTextarea, 'keydown', this.onKeyDown.bind(this));\n    fabric.util.addListener(this.hiddenTextarea, 'keyup', this.onKeyUp.bind(this));\n    fabric.util.addListener(this.hiddenTextarea, 'input', this.onInput.bind(this));\n    fabric.util.addListener(this.hiddenTextarea, 'copy', this.copy.bind(this));\n    fabric.util.addListener(this.hiddenTextarea, 'cut', this.copy.bind(this));\n    fabric.util.addListener(this.hiddenTextarea, 'paste', this.paste.bind(this));\n    fabric.util.addListener(this.hiddenTextarea, 'compositionstart', this.onCompositionStart.bind(this));\n    fabric.util.addListener(this.hiddenTextarea, 'compositionupdate', this.onCompositionUpdate.bind(this));\n    fabric.util.addListener(this.hiddenTextarea, 'compositionend', this.onCompositionEnd.bind(this));\n\n    if (!this._clickHandlerInitialized && this.canvas) {\n      fabric.util.addListener(this.canvas.upperCanvasEl, 'click', this.onClick.bind(this));\n      this._clickHandlerInitialized = true;\n    }\n  },\n\n  /**\n   * For functionalities on keyDown\n   * Map a special key to a function of the instance/prototype\n   * If you need different behaviour for ESC or TAB or arrows, you have to change\n   * this map setting the name of a function that you build on the fabric.Itext or\n   * your prototype.\n   * the map change will affect all Instances unless you need for only some text Instances\n   * in that case you have to clone this object and assign your Instance.\n   * this.keysMap = fabric.util.object.clone(this.keysMap);\n   * The function must be in fabric.Itext.prototype.myFunction And will receive event as args[0]\n   */\n  keysMap: {\n    9:  'exitEditing',\n    27: 'exitEditing',\n    33: 'moveCursorUp',\n    34: 'moveCursorDown',\n    35: 'moveCursorRight',\n    36: 'moveCursorLeft',\n    37: 'moveCursorLeft',\n    38: 'moveCursorUp',\n    39: 'moveCursorRight',\n    40: 'moveCursorDown',\n  },\n\n  /**\n   * For functionalities on keyUp + ctrl || cmd\n   */\n  ctrlKeysMapUp: {\n    67: 'copy',\n    88: 'cut'\n  },\n\n  /**\n   * For functionalities on keyDown + ctrl || cmd\n   */\n  ctrlKeysMapDown: {\n    65: 'selectAll'\n  },\n\n  onClick: function() {\n    // No need to trigger click event here, focus is enough to have the keyboard appear on Android\n    this.hiddenTextarea && this.hiddenTextarea.focus();\n  },\n\n  /**\n   * Handles keyup event\n   * @param {Event} e Event object\n   */\n  onKeyDown: function(e) {\n    if (!this.isEditing || this.inCompositionMode) {\n      return;\n    }\n    if (e.keyCode in this.keysMap) {\n      this[this.keysMap[e.keyCode]](e);\n    }\n    else if ((e.keyCode in this.ctrlKeysMapDown) && (e.ctrlKey || e.metaKey)) {\n      this[this.ctrlKeysMapDown[e.keyCode]](e);\n    }\n    else {\n      return;\n    }\n    e.stopImmediatePropagation();\n    e.preventDefault();\n    if (e.keyCode >= 33 && e.keyCode <= 40) {\n      // if i press an arrow key just update selection\n      this.clearContextTop();\n      this.renderCursorOrSelection();\n    }\n    else {\n      this.canvas && this.canvas.requestRenderAll();\n    }\n  },\n\n  /**\n   * Handles keyup event\n   * We handle KeyUp because ie11 and edge have difficulties copy/pasting\n   * if a copy/cut event fired, keyup is dismissed\n   * @param {Event} e Event object\n   */\n  onKeyUp: function(e) {\n    if (!this.isEditing || this._copyDone || this.inCompositionMode) {\n      this._copyDone = false;\n      return;\n    }\n    if ((e.keyCode in this.ctrlKeysMapUp) && (e.ctrlKey || e.metaKey)) {\n      this[this.ctrlKeysMapUp[e.keyCode]](e);\n    }\n    else {\n      return;\n    }\n    e.stopImmediatePropagation();\n    e.preventDefault();\n    this.canvas && this.canvas.requestRenderAll();\n  },\n\n  /**\n   * Handles onInput event\n   * @param {Event} e Event object\n   */\n  onInput: function(e) {\n    var fromPaste = this.fromPaste;\n    this.fromPaste = false;\n    e && e.stopPropagation();\n    if (!this.isEditing) {\n      return;\n    }\n    // decisions about style changes.\n    var nextText = this._splitTextIntoLines(this.hiddenTextarea.value).graphemeText,\n        charCount = this._text.length,\n        nextCharCount = nextText.length,\n        removedText, insertedText,\n        charDiff = nextCharCount - charCount;\n    if (this.hiddenTextarea.value === '') {\n      this.styles = { };\n      this.updateFromTextArea();\n      this.fire('changed');\n      if (this.canvas) {\n        this.canvas.fire('text:changed', { target: this });\n        this.canvas.requestRenderAll();\n      }\n      return;\n    }\n\n    var textareaSelection = this.fromStringToGraphemeSelection(\n      this.hiddenTextarea.selectionStart,\n      this.hiddenTextarea.selectionEnd,\n      this.hiddenTextarea.value\n    );\n    var backDelete = this.selectionStart > textareaSelection.selectionStart;\n\n    if (this.selectionStart !== this.selectionEnd) {\n      removedText = this._text.slice(this.selectionStart, this.selectionEnd);\n      charDiff += this.selectionEnd - this.selectionStart;\n    }\n    else if (nextCharCount < charCount) {\n      if (backDelete) {\n        removedText = this._text.slice(this.selectionEnd + charDiff, this.selectionEnd);\n      }\n      else {\n        removedText = this._text.slice(this.selectionStart, this.selectionStart - charDiff);\n      }\n    }\n    insertedText = nextText.slice(textareaSelection.selectionEnd - charDiff, textareaSelection.selectionEnd);\n    if (removedText && removedText.length) {\n      if (this.selectionStart !== this.selectionEnd) {\n        this.removeStyleFromTo(this.selectionStart, this.selectionEnd);\n      }\n      else if (backDelete) {\n        // detect differencies between forwardDelete and backDelete\n        this.removeStyleFromTo(this.selectionEnd - removedText.length, this.selectionEnd);\n      }\n      else {\n        this.removeStyleFromTo(this.selectionEnd, this.selectionEnd + removedText.length);\n      }\n    }\n    if (insertedText.length) {\n      if (fromPaste && insertedText.join('') === fabric.copiedText && !fabric.disableStyleCopyPaste) {\n        this.insertNewStyleBlock(insertedText, this.selectionStart, fabric.copiedTextStyle);\n      }\n      else {\n        this.insertNewStyleBlock(insertedText, this.selectionStart);\n      }\n    }\n    this.updateFromTextArea();\n    this.fire('changed');\n    if (this.canvas) {\n      this.canvas.fire('text:changed', { target: this });\n      this.canvas.requestRenderAll();\n    }\n  },\n  /**\n   * Composition start\n   */\n  onCompositionStart: function() {\n    this.inCompositionMode = true;\n  },\n\n  /**\n   * Composition end\n   */\n  onCompositionEnd: function() {\n    this.inCompositionMode = false;\n  },\n\n  // /**\n  //  * Composition update\n  //  */\n  onCompositionUpdate: function(e) {\n    this.compositionStart = e.target.selectionStart;\n    this.compositionEnd = e.target.selectionEnd;\n    this.updateTextareaPosition();\n  },\n\n  /**\n   * Copies selected text\n   * @param {Event} e Event object\n   */\n  copy: function() {\n    if (this.selectionStart === this.selectionEnd) {\n      //do not cut-copy if no selection\n      return;\n    }\n\n    fabric.copiedText = this.getSelectedText();\n    if (!fabric.disableStyleCopyPaste) {\n      fabric.copiedTextStyle = this.getSelectionStyles(this.selectionStart, this.selectionEnd, true);\n    }\n    else {\n      fabric.copiedTextStyle = null;\n    }\n    this._copyDone = true;\n  },\n\n  /**\n   * Pastes text\n   * @param {Event} e Event object\n   */\n  paste: function() {\n    this.fromPaste = true;\n  },\n\n  /**\n   * @private\n   * @param {Event} e Event object\n   * @return {Object} Clipboard data object\n   */\n  _getClipboardData: function(e) {\n    return (e && e.clipboardData) || fabric.window.clipboardData;\n  },\n\n  /**\n   * Finds the width in pixels before the cursor on the same line\n   * @private\n   * @param {Number} lineIndex\n   * @param {Number} charIndex\n   * @return {Number} widthBeforeCursor width before cursor\n   */\n  _getWidthBeforeCursor: function(lineIndex, charIndex) {\n    var widthBeforeCursor = this._getLineLeftOffset(lineIndex), bound;\n\n    if (charIndex > 0) {\n      bound = this.__charBounds[lineIndex][charIndex - 1];\n      widthBeforeCursor += bound.left + bound.width;\n    }\n    return widthBeforeCursor;\n  },\n\n  /**\n   * Gets start offset of a selection\n   * @param {Event} e Event object\n   * @param {Boolean} isRight\n   * @return {Number}\n   */\n  getDownCursorOffset: function(e, isRight) {\n    var selectionProp = this._getSelectionForOffset(e, isRight),\n        cursorLocation = this.get2DCursorLocation(selectionProp),\n        lineIndex = cursorLocation.lineIndex;\n    // if on last line, down cursor goes to end of line\n    if (lineIndex === this._textLines.length - 1 || e.metaKey || e.keyCode === 34) {\n      // move to the end of a text\n      return this._text.length - selectionProp;\n    }\n    var charIndex = cursorLocation.charIndex,\n        widthBeforeCursor = this._getWidthBeforeCursor(lineIndex, charIndex),\n        indexOnOtherLine = this._getIndexOnLine(lineIndex + 1, widthBeforeCursor),\n        textAfterCursor = this._textLines[lineIndex].slice(charIndex);\n    return textAfterCursor.length + indexOnOtherLine + 1 + this.missingNewlineOffset(lineIndex);\n  },\n\n  /**\n   * private\n   * Helps finding if the offset should be counted from Start or End\n   * @param {Event} e Event object\n   * @param {Boolean} isRight\n   * @return {Number}\n   */\n  _getSelectionForOffset: function(e, isRight) {\n    if (e.shiftKey && this.selectionStart !== this.selectionEnd && isRight) {\n      return this.selectionEnd;\n    }\n    else {\n      return this.selectionStart;\n    }\n  },\n\n  /**\n   * @param {Event} e Event object\n   * @param {Boolean} isRight\n   * @return {Number}\n   */\n  getUpCursorOffset: function(e, isRight) {\n    var selectionProp = this._getSelectionForOffset(e, isRight),\n        cursorLocation = this.get2DCursorLocation(selectionProp),\n        lineIndex = cursorLocation.lineIndex;\n    if (lineIndex === 0 || e.metaKey || e.keyCode === 33) {\n      // if on first line, up cursor goes to start of line\n      return -selectionProp;\n    }\n    var charIndex = cursorLocation.charIndex,\n        widthBeforeCursor = this._getWidthBeforeCursor(lineIndex, charIndex),\n        indexOnOtherLine = this._getIndexOnLine(lineIndex - 1, widthBeforeCursor),\n        textBeforeCursor = this._textLines[lineIndex].slice(0, charIndex),\n        missingNewlineOffset = this.missingNewlineOffset(lineIndex - 1);\n    // return a negative offset\n    return -this._textLines[lineIndex - 1].length\n     + indexOnOtherLine - textBeforeCursor.length + (1 - missingNewlineOffset);\n  },\n\n  /**\n   * for a given width it founds the matching character.\n   * @private\n   */\n  _getIndexOnLine: function(lineIndex, width) {\n\n    var line = this._textLines[lineIndex],\n        lineLeftOffset = this._getLineLeftOffset(lineIndex),\n        widthOfCharsOnLine = lineLeftOffset,\n        indexOnLine = 0, charWidth, foundMatch;\n\n    for (var j = 0, jlen = line.length; j < jlen; j++) {\n      charWidth = this.__charBounds[lineIndex][j].width;\n      widthOfCharsOnLine += charWidth;\n      if (widthOfCharsOnLine > width) {\n        foundMatch = true;\n        var leftEdge = widthOfCharsOnLine - charWidth,\n            rightEdge = widthOfCharsOnLine,\n            offsetFromLeftEdge = Math.abs(leftEdge - width),\n            offsetFromRightEdge = Math.abs(rightEdge - width);\n\n        indexOnLine = offsetFromRightEdge < offsetFromLeftEdge ? j : (j - 1);\n        break;\n      }\n    }\n\n    // reached end\n    if (!foundMatch) {\n      indexOnLine = line.length - 1;\n    }\n\n    return indexOnLine;\n  },\n\n\n  /**\n   * Moves cursor down\n   * @param {Event} e Event object\n   */\n  moveCursorDown: function(e) {\n    if (this.selectionStart >= this._text.length && this.selectionEnd >= this._text.length) {\n      return;\n    }\n    this._moveCursorUpOrDown('Down', e);\n  },\n\n  /**\n   * Moves cursor up\n   * @param {Event} e Event object\n   */\n  moveCursorUp: function(e) {\n    if (this.selectionStart === 0 && this.selectionEnd === 0) {\n      return;\n    }\n    this._moveCursorUpOrDown('Up', e);\n  },\n\n  /**\n   * Moves cursor up or down, fires the events\n   * @param {String} direction 'Up' or 'Down'\n   * @param {Event} e Event object\n   */\n  _moveCursorUpOrDown: function(direction, e) {\n    // getUpCursorOffset\n    // getDownCursorOffset\n    var action = 'get' + direction + 'CursorOffset',\n        offset = this[action](e, this._selectionDirection === 'right');\n    if (e.shiftKey) {\n      this.moveCursorWithShift(offset);\n    }\n    else {\n      this.moveCursorWithoutShift(offset);\n    }\n    if (offset !== 0) {\n      this.setSelectionInBoundaries();\n      this.abortCursorAnimation();\n      this._currentCursorOpacity = 1;\n      this.initDelayedCursor();\n      this._fireSelectionChanged();\n      this._updateTextarea();\n    }\n  },\n\n  /**\n   * Moves cursor with shift\n   * @param {Number} offset\n   */\n  moveCursorWithShift: function(offset) {\n    var newSelection = this._selectionDirection === 'left'\n      ? this.selectionStart + offset\n      : this.selectionEnd + offset;\n    this.setSelectionStartEndWithShift(this.selectionStart, this.selectionEnd, newSelection);\n    return offset !== 0;\n  },\n\n  /**\n   * Moves cursor up without shift\n   * @param {Number} offset\n   */\n  moveCursorWithoutShift: function(offset) {\n    if (offset < 0) {\n      this.selectionStart += offset;\n      this.selectionEnd = this.selectionStart;\n    }\n    else {\n      this.selectionEnd += offset;\n      this.selectionStart = this.selectionEnd;\n    }\n    return offset !== 0;\n  },\n\n  /**\n   * Moves cursor left\n   * @param {Event} e Event object\n   */\n  moveCursorLeft: function(e) {\n    if (this.selectionStart === 0 && this.selectionEnd === 0) {\n      return;\n    }\n    this._moveCursorLeftOrRight('Left', e);\n  },\n\n  /**\n   * @private\n   * @return {Boolean} true if a change happened\n   */\n  _move: function(e, prop, direction) {\n    var newValue;\n    if (e.altKey) {\n      newValue = this['findWordBoundary' + direction](this[prop]);\n    }\n    else if (e.metaKey || e.keyCode === 35 ||  e.keyCode === 36 ) {\n      newValue = this['findLineBoundary' + direction](this[prop]);\n    }\n    else {\n      this[prop] += direction === 'Left' ? -1 : 1;\n      return true;\n    }\n    if (typeof newValue !== undefined && this[prop] !== newValue) {\n      this[prop] = newValue;\n      return true;\n    }\n  },\n\n  /**\n   * @private\n   */\n  _moveLeft: function(e, prop) {\n    return this._move(e, prop, 'Left');\n  },\n\n  /**\n   * @private\n   */\n  _moveRight: function(e, prop) {\n    return this._move(e, prop, 'Right');\n  },\n\n  /**\n   * Moves cursor left without keeping selection\n   * @param {Event} e\n   */\n  moveCursorLeftWithoutShift: function(e) {\n    var change = true;\n    this._selectionDirection = 'left';\n\n    // only move cursor when there is no selection,\n    // otherwise we discard it, and leave cursor on same place\n    if (this.selectionEnd === this.selectionStart && this.selectionStart !== 0) {\n      change = this._moveLeft(e, 'selectionStart');\n\n    }\n    this.selectionEnd = this.selectionStart;\n    return change;\n  },\n\n  /**\n   * Moves cursor left while keeping selection\n   * @param {Event} e\n   */\n  moveCursorLeftWithShift: function(e) {\n    if (this._selectionDirection === 'right' && this.selectionStart !== this.selectionEnd) {\n      return this._moveLeft(e, 'selectionEnd');\n    }\n    else if (this.selectionStart !== 0){\n      this._selectionDirection = 'left';\n      return this._moveLeft(e, 'selectionStart');\n    }\n  },\n\n  /**\n   * Moves cursor right\n   * @param {Event} e Event object\n   */\n  moveCursorRight: function(e) {\n    if (this.selectionStart >= this._text.length && this.selectionEnd >= this._text.length) {\n      return;\n    }\n    this._moveCursorLeftOrRight('Right', e);\n  },\n\n  /**\n   * Moves cursor right or Left, fires event\n   * @param {String} direction 'Left', 'Right'\n   * @param {Event} e Event object\n   */\n  _moveCursorLeftOrRight: function(direction, e) {\n    var actionName = 'moveCursor' + direction + 'With';\n    this._currentCursorOpacity = 1;\n\n    if (e.shiftKey) {\n      actionName += 'Shift';\n    }\n    else {\n      actionName += 'outShift';\n    }\n    if (this[actionName](e)) {\n      this.abortCursorAnimation();\n      this.initDelayedCursor();\n      this._fireSelectionChanged();\n      this._updateTextarea();\n    }\n  },\n\n  /**\n   * Moves cursor right while keeping selection\n   * @param {Event} e\n   */\n  moveCursorRightWithShift: function(e) {\n    if (this._selectionDirection === 'left' && this.selectionStart !== this.selectionEnd) {\n      return this._moveRight(e, 'selectionStart');\n    }\n    else if (this.selectionEnd !== this._text.length) {\n      this._selectionDirection = 'right';\n      return this._moveRight(e, 'selectionEnd');\n    }\n  },\n\n  /**\n   * Moves cursor right without keeping selection\n   * @param {Event} e Event object\n   */\n  moveCursorRightWithoutShift: function(e) {\n    var changed = true;\n    this._selectionDirection = 'right';\n\n    if (this.selectionStart === this.selectionEnd) {\n      changed = this._moveRight(e, 'selectionStart');\n      this.selectionEnd = this.selectionStart;\n    }\n    else {\n      this.selectionStart = this.selectionEnd;\n    }\n    return changed;\n  },\n\n  /**\n   * Removes characters from start/end\n   * start/end ar per grapheme position in _text array.\n   *\n   * @param {Number} start\n   * @param {Number} end default to start + 1\n   */\n  removeChars: function(start, end) {\n    if (typeof end === 'undefined') {\n      end = start + 1;\n    }\n    this.removeStyleFromTo(start, end);\n    this._text.splice(start, end - start);\n    this.text = this._text.join('');\n    this.set('dirty', true);\n    if (this._shouldClearDimensionCache()) {\n      this.initDimensions();\n      this.setCoords();\n    }\n    this._removeExtraneousStyles();\n  },\n\n  /**\n   * insert characters at start position, before start position.\n   * start  equal 1 it means the text get inserted between actual grapheme 0 and 1\n   * if style array is provided, it must be as the same length of text in graphemes\n   * if end is provided and is bigger than start, old text is replaced.\n   * start/end ar per grapheme position in _text array.\n   *\n   * @param {String} text text to insert\n   * @param {Array} style array of style objects\n   * @param {Number} start\n   * @param {Number} end default to start + 1\n   */\n  insertChars: function(text, style, start, end) {\n    if (typeof end === 'undefined') {\n      end = start;\n    }\n    if (end > start) {\n      this.removeStyleFromTo(start, end);\n    }\n    var graphemes = fabric.util.string.graphemeSplit(text);\n    this.insertNewStyleBlock(graphemes, start, style);\n    this._text = [].concat(this._text.slice(0, start), graphemes, this._text.slice(end));\n    this.text = this._text.join('');\n    this.set('dirty', true);\n    if (this._shouldClearDimensionCache()) {\n      this.initDimensions();\n      this.setCoords();\n    }\n    this._removeExtraneousStyles();\n  },\n\n});\n\n\n/* _TO_SVG_START_ */\n(function() {\n  var toFixed = fabric.util.toFixed,\n      multipleSpacesRegex = /  +/g;\n\n  fabric.util.object.extend(fabric.Text.prototype, /** @lends fabric.Text.prototype */ {\n\n    /**\n     * Returns SVG representation of an instance\n     * @param {Function} [reviver] Method for further parsing of svg representation.\n     * @return {String} svg representation of an instance\n     */\n    _toSVG: function() {\n      var offsets = this._getSVGLeftTopOffsets(),\n          textAndBg = this._getSVGTextAndBg(offsets.textTop, offsets.textLeft);\n      return this._wrapSVGTextAndBg(textAndBg);\n    },\n\n    /**\n     * Returns svg representation of an instance\n     * @param {Function} [reviver] Method for further parsing of svg representation.\n     * @return {String} svg representation of an instance\n     */\n    toSVG: function(reviver) {\n      return this._createBaseSVGMarkup(\n        this._toSVG(),\n        { reviver: reviver, noStyle: true, withShadow: true }\n      );\n    },\n\n    /**\n     * @private\n     */\n    _getSVGLeftTopOffsets: function() {\n      return {\n        textLeft: -this.width / 2,\n        textTop: -this.height / 2,\n        lineTop: this.getHeightOfLine(0)\n      };\n    },\n\n    /**\n     * @private\n     */\n    _wrapSVGTextAndBg: function(textAndBg) {\n      var noShadow = true,\n          textDecoration = this.getSvgTextDecoration(this);\n      return [\n        textAndBg.textBgRects.join(''),\n        '\\t\\t<text xml:space=\"preserve\" ',\n        (this.fontFamily ? 'font-family=\"' + this.fontFamily.replace(/\"/g, '\\'') + '\" ' : ''),\n        (this.fontSize ? 'font-size=\"' + this.fontSize + '\" ' : ''),\n        (this.fontStyle ? 'font-style=\"' + this.fontStyle + '\" ' : ''),\n        (this.fontWeight ? 'font-weight=\"' + this.fontWeight + '\" ' : ''),\n        (textDecoration ? 'text-decoration=\"' + textDecoration + '\" ' : ''),\n        'style=\"', this.getSvgStyles(noShadow), '\"', this.addPaintOrder(), ' >',\n        textAndBg.textSpans.join(''),\n        '</text>\\n'\n      ];\n    },\n\n    /**\n     * @private\n     * @param {Number} textTopOffset Text top offset\n     * @param {Number} textLeftOffset Text left offset\n     * @return {Object}\n     */\n    _getSVGTextAndBg: function(textTopOffset, textLeftOffset) {\n      var textSpans = [],\n          textBgRects = [],\n          height = textTopOffset, lineOffset;\n      // bounding-box background\n      this._setSVGBg(textBgRects);\n\n      // text and text-background\n      for (var i = 0, len = this._textLines.length; i < len; i++) {\n        lineOffset = this._getLineLeftOffset(i);\n        if (this.textBackgroundColor || this.styleHas('textBackgroundColor', i)) {\n          this._setSVGTextLineBg(textBgRects, i, textLeftOffset + lineOffset, height);\n        }\n        this._setSVGTextLineText(textSpans, i, textLeftOffset + lineOffset, height);\n        height += this.getHeightOfLine(i);\n      }\n\n      return {\n        textSpans: textSpans,\n        textBgRects: textBgRects\n      };\n    },\n\n    /**\n     * @private\n     */\n    _createTextCharSpan: function(_char, styleDecl, left, top) {\n      var shouldUseWhitespace = _char !== _char.trim() || _char.match(multipleSpacesRegex),\n          styleProps = this.getSvgSpanStyles(styleDecl, shouldUseWhitespace),\n          fillStyles = styleProps ? 'style=\"' + styleProps + '\"' : '',\n          dy = styleDecl.deltaY, dySpan = '',\n          NUM_FRACTION_DIGITS = fabric.Object.NUM_FRACTION_DIGITS;\n      if (dy) {\n        dySpan = ' dy=\"' + toFixed(dy, NUM_FRACTION_DIGITS) + '\" ';\n      }\n      return [\n        '<tspan x=\"', toFixed(left, NUM_FRACTION_DIGITS), '\" y=\"',\n        toFixed(top, NUM_FRACTION_DIGITS), '\" ', dySpan,\n        fillStyles, '>',\n        fabric.util.string.escapeXml(_char),\n        '</tspan>'\n      ].join('');\n    },\n\n    _setSVGTextLineText: function(textSpans, lineIndex, textLeftOffset, textTopOffset) {\n      // set proper line offset\n      var lineHeight = this.getHeightOfLine(lineIndex),\n          isJustify = this.textAlign.indexOf('justify') !== -1,\n          actualStyle,\n          nextStyle,\n          charsToRender = '',\n          charBox, style,\n          boxWidth = 0,\n          line = this._textLines[lineIndex],\n          timeToRender;\n\n      textTopOffset += lineHeight * (1 - this._fontSizeFraction) / this.lineHeight;\n      for (var i = 0, len = line.length - 1; i <= len; i++) {\n        timeToRender = i === len || this.charSpacing;\n        charsToRender += line[i];\n        charBox = this.__charBounds[lineIndex][i];\n        if (boxWidth === 0) {\n          textLeftOffset += charBox.kernedWidth - charBox.width;\n          boxWidth += charBox.width;\n        }\n        else {\n          boxWidth += charBox.kernedWidth;\n        }\n        if (isJustify && !timeToRender) {\n          if (this._reSpaceAndTab.test(line[i])) {\n            timeToRender = true;\n          }\n        }\n        if (!timeToRender) {\n          // if we have charSpacing, we render char by char\n          actualStyle = actualStyle || this.getCompleteStyleDeclaration(lineIndex, i);\n          nextStyle = this.getCompleteStyleDeclaration(lineIndex, i + 1);\n          timeToRender = this._hasStyleChangedForSvg(actualStyle, nextStyle);\n        }\n        if (timeToRender) {\n          style = this._getStyleDeclaration(lineIndex, i) || { };\n          textSpans.push(this._createTextCharSpan(charsToRender, style, textLeftOffset, textTopOffset));\n          charsToRender = '';\n          actualStyle = nextStyle;\n          textLeftOffset += boxWidth;\n          boxWidth = 0;\n        }\n      }\n    },\n\n    _pushTextBgRect: function(textBgRects, color, left, top, width, height) {\n      var NUM_FRACTION_DIGITS = fabric.Object.NUM_FRACTION_DIGITS;\n      textBgRects.push(\n        '\\t\\t<rect ',\n        this._getFillAttributes(color),\n        ' x=\"',\n        toFixed(left, NUM_FRACTION_DIGITS),\n        '\" y=\"',\n        toFixed(top, NUM_FRACTION_DIGITS),\n        '\" width=\"',\n        toFixed(width, NUM_FRACTION_DIGITS),\n        '\" height=\"',\n        toFixed(height, NUM_FRACTION_DIGITS),\n        '\"></rect>\\n');\n    },\n\n    _setSVGTextLineBg: function(textBgRects, i, leftOffset, textTopOffset) {\n      var line = this._textLines[i],\n          heightOfLine = this.getHeightOfLine(i) / this.lineHeight,\n          boxWidth = 0,\n          boxStart = 0,\n          charBox, currentColor,\n          lastColor = this.getValueOfPropertyAt(i, 0, 'textBackgroundColor');\n      for (var j = 0, jlen = line.length; j < jlen; j++) {\n        charBox = this.__charBounds[i][j];\n        currentColor = this.getValueOfPropertyAt(i, j, 'textBackgroundColor');\n        if (currentColor !== lastColor) {\n          lastColor && this._pushTextBgRect(textBgRects, lastColor, leftOffset + boxStart,\n            textTopOffset, boxWidth, heightOfLine);\n          boxStart = charBox.left;\n          boxWidth = charBox.width;\n          lastColor = currentColor;\n        }\n        else {\n          boxWidth += charBox.kernedWidth;\n        }\n      }\n      currentColor && this._pushTextBgRect(textBgRects, currentColor, leftOffset + boxStart,\n        textTopOffset, boxWidth, heightOfLine);\n    },\n\n    /**\n     * Adobe Illustrator (at least CS5) is unable to render rgba()-based fill values\n     * we work around it by \"moving\" alpha channel into opacity attribute and setting fill's alpha to 1\n     *\n     * @private\n     * @param {*} value\n     * @return {String}\n     */\n    _getFillAttributes: function(value) {\n      var fillColor = (value && typeof value === 'string') ? new fabric.Color(value) : '';\n      if (!fillColor || !fillColor.getSource() || fillColor.getAlpha() === 1) {\n        return 'fill=\"' + value + '\"';\n      }\n      return 'opacity=\"' + fillColor.getAlpha() + '\" fill=\"' + fillColor.setAlpha(1).toRgb() + '\"';\n    },\n\n    /**\n     * @private\n     */\n    _getSVGLineTopOffset: function(lineIndex) {\n      var lineTopOffset = 0, lastHeight = 0;\n      for (var j = 0; j < lineIndex; j++) {\n        lineTopOffset += this.getHeightOfLine(j);\n      }\n      lastHeight = this.getHeightOfLine(j);\n      return {\n        lineTop: lineTopOffset,\n        offset: (this._fontSizeMult - this._fontSizeFraction) * lastHeight / (this.lineHeight * this._fontSizeMult)\n      };\n    },\n\n    /**\n     * Returns styles-string for svg-export\n     * @param {Boolean} skipShadow a boolean to skip shadow filter output\n     * @return {String}\n     */\n    getSvgStyles: function(skipShadow) {\n      var svgStyle = fabric.Object.prototype.getSvgStyles.call(this, skipShadow);\n      return svgStyle + ' white-space: pre;';\n    },\n  });\n})();\n/* _TO_SVG_END_ */\n\n\n(function(global) {\n\n  'use strict';\n\n  var fabric = global.fabric || (global.fabric = {});\n\n  /**\n   * Textbox class, based on IText, allows the user to resize the text rectangle\n   * and wraps lines automatically. Textboxes have their Y scaling locked, the\n   * user can only change width. Height is adjusted automatically based on the\n   * wrapping of lines.\n   * @class fabric.Textbox\n   * @extends fabric.IText\n   * @mixes fabric.Observable\n   * @return {fabric.Textbox} thisArg\n   * @see {@link fabric.Textbox#initialize} for constructor definition\n   */\n  fabric.Textbox = fabric.util.createClass(fabric.IText, fabric.Observable, {\n\n    /**\n     * Type of an object\n     * @type String\n     * @default\n     */\n    type: 'textbox',\n\n    /**\n     * Minimum width of textbox, in pixels.\n     * @type Number\n     * @default\n     */\n    minWidth: 20,\n\n    /**\n     * Minimum calculated width of a textbox, in pixels.\n     * fixed to 2 so that an empty textbox cannot go to 0\n     * and is still selectable without text.\n     * @type Number\n     * @default\n     */\n    dynamicMinWidth: 2,\n\n    /**\n     * Cached array of text wrapping.\n     * @type Array\n     */\n    __cachedLines: null,\n\n    /**\n     * Override standard Object class values\n     */\n    lockScalingFlip: true,\n\n    /**\n     * Override standard Object class values\n     * Textbox needs this on false\n     */\n    noScaleCache: false,\n\n    /**\n     * Properties which when set cause object to change dimensions\n     * @type Object\n     * @private\n     */\n    _dimensionAffectingProps: fabric.Text.prototype._dimensionAffectingProps.concat('width'),\n\n    /**\n     * Use this regular expression to split strings in breakable lines\n     * @private\n     */\n    _wordJoiners: /[ \\t\\r]/,\n\n    /**\n     * Use this boolean property in order to split strings that have no white space concept.\n     * this is a cheap way to help with chinese/japaense\n     * @type Boolean\n     * @since 2.6.0\n     */\n    splitByGrapheme: false,\n\n    /**\n     * Unlike superclass's version of this function, Textbox does not update\n     * its width.\n     * @private\n     * @override\n     */\n    initDimensions: function() {\n      if (this.__skipDimension) {\n        return;\n      }\n      this.isEditing && this.initDelayedCursor();\n      this.clearContextTop();\n      this._clearCache();\n      // clear dynamicMinWidth as it will be different after we re-wrap line\n      this.dynamicMinWidth = 0;\n      // wrap lines\n      this._styleMap = this._generateStyleMap(this._splitText());\n      // if after wrapping, the width is smaller than dynamicMinWidth, change the width and re-wrap\n      if (this.dynamicMinWidth > this.width) {\n        this._set('width', this.dynamicMinWidth);\n      }\n      if (this.textAlign.indexOf('justify') !== -1) {\n        // once text is measured we need to make space fatter to make justified text.\n        this.enlargeSpaces();\n      }\n      // clear cache and re-calculate height\n      this.height = this.calcTextHeight();\n      this.saveState({ propertySet: '_dimensionAffectingProps' });\n    },\n\n    /**\n     * Generate an object that translates the style object so that it is\n     * broken up by visual lines (new lines and automatic wrapping).\n     * The original text styles object is broken up by actual lines (new lines only),\n     * which is only sufficient for Text / IText\n     * @private\n     */\n    _generateStyleMap: function(textInfo) {\n      var realLineCount     = 0,\n          realLineCharCount = 0,\n          charCount         = 0,\n          map               = {};\n\n      for (var i = 0; i < textInfo.graphemeLines.length; i++) {\n        if (textInfo.graphemeText[charCount] === '\\n' && i > 0) {\n          realLineCharCount = 0;\n          charCount++;\n          realLineCount++;\n        }\n        else if (!this.splitByGrapheme && this._reSpaceAndTab.test(textInfo.graphemeText[charCount]) && i > 0) {\n          // this case deals with space's that are removed from end of lines when wrapping\n          realLineCharCount++;\n          charCount++;\n        }\n\n        map[i] = { line: realLineCount, offset: realLineCharCount };\n\n        charCount += textInfo.graphemeLines[i].length;\n        realLineCharCount += textInfo.graphemeLines[i].length;\n      }\n\n      return map;\n    },\n\n    /**\n     * Returns true if object has a style property or has it on a specified line\n     * @param {Number} lineIndex\n     * @return {Boolean}\n     */\n    styleHas: function(property, lineIndex) {\n      if (this._styleMap && !this.isWrapping) {\n        var map = this._styleMap[lineIndex];\n        if (map) {\n          lineIndex = map.line;\n        }\n      }\n      return fabric.Text.prototype.styleHas.call(this, property, lineIndex);\n    },\n\n    /**\n     * Returns true if object has no styling or no styling in a line\n     * @param {Number} lineIndex , lineIndex is on wrapped lines.\n     * @return {Boolean}\n     */\n    isEmptyStyles: function(lineIndex) {\n      var offset = 0, nextLineIndex = lineIndex + 1, nextOffset, obj, shouldLimit = false;\n      var map = this._styleMap[lineIndex];\n      var mapNextLine = this._styleMap[lineIndex + 1];\n      if (map) {\n        lineIndex = map.line;\n        offset = map.offset;\n      }\n      if (mapNextLine) {\n        nextLineIndex = mapNextLine.line;\n        shouldLimit = nextLineIndex === lineIndex;\n        nextOffset = mapNextLine.offset;\n      }\n      obj = typeof lineIndex === 'undefined' ? this.styles : { line: this.styles[lineIndex] };\n      for (var p1 in obj) {\n        for (var p2 in obj[p1]) {\n          if (p2 >= offset && (!shouldLimit || p2 < nextOffset)) {\n            // eslint-disable-next-line no-unused-vars\n            for (var p3 in obj[p1][p2]) {\n              return false;\n            }\n          }\n        }\n      }\n      return true;\n    },\n\n    /**\n     * @param {Number} lineIndex\n     * @param {Number} charIndex\n     * @private\n     */\n    _getStyleDeclaration: function(lineIndex, charIndex) {\n      if (this._styleMap && !this.isWrapping) {\n        var map = this._styleMap[lineIndex];\n        if (!map) {\n          return null;\n        }\n        lineIndex = map.line;\n        charIndex = map.offset + charIndex;\n      }\n      return this.callSuper('_getStyleDeclaration', lineIndex, charIndex);\n    },\n\n    /**\n     * @param {Number} lineIndex\n     * @param {Number} charIndex\n     * @param {Object} style\n     * @private\n     */\n    _setStyleDeclaration: function(lineIndex, charIndex, style) {\n      var map = this._styleMap[lineIndex];\n      lineIndex = map.line;\n      charIndex = map.offset + charIndex;\n\n      this.styles[lineIndex][charIndex] = style;\n    },\n\n    /**\n     * @param {Number} lineIndex\n     * @param {Number} charIndex\n     * @private\n     */\n    _deleteStyleDeclaration: function(lineIndex, charIndex) {\n      var map = this._styleMap[lineIndex];\n      lineIndex = map.line;\n      charIndex = map.offset + charIndex;\n      delete this.styles[lineIndex][charIndex];\n    },\n\n    /**\n     * probably broken need a fix\n     * Returns the real style line that correspond to the wrapped lineIndex line\n     * Used just to verify if the line does exist or not.\n     * @param {Number} lineIndex\n     * @returns {Boolean} if the line exists or not\n     * @private\n     */\n    _getLineStyle: function(lineIndex) {\n      var map = this._styleMap[lineIndex];\n      return !!this.styles[map.line];\n    },\n\n    /**\n     * Set the line style to an empty object so that is initialized\n     * @param {Number} lineIndex\n     * @param {Object} style\n     * @private\n     */\n    _setLineStyle: function(lineIndex) {\n      var map = this._styleMap[lineIndex];\n      this.styles[map.line] = {};\n    },\n\n    /**\n     * Wraps text using the 'width' property of Textbox. First this function\n     * splits text on newlines, so we preserve newlines entered by the user.\n     * Then it wraps each line using the width of the Textbox by calling\n     * _wrapLine().\n     * @param {Array} lines The string array of text that is split into lines\n     * @param {Number} desiredWidth width you want to wrap to\n     * @returns {Array} Array of lines\n     */\n    _wrapText: function(lines, desiredWidth) {\n      var wrapped = [], i;\n      this.isWrapping = true;\n      for (i = 0; i < lines.length; i++) {\n        wrapped = wrapped.concat(this._wrapLine(lines[i], i, desiredWidth));\n      }\n      this.isWrapping = false;\n      return wrapped;\n    },\n\n    /**\n     * Helper function to measure a string of text, given its lineIndex and charIndex offset\n     * it gets called when charBounds are not available yet.\n     * @param {CanvasRenderingContext2D} ctx\n     * @param {String} text\n     * @param {number} lineIndex\n     * @param {number} charOffset\n     * @returns {number}\n     * @private\n     */\n    _measureWord: function(word, lineIndex, charOffset) {\n      var width = 0, prevGrapheme, skipLeft = true;\n      charOffset = charOffset || 0;\n      for (var i = 0, len = word.length; i < len; i++) {\n        var box = this._getGraphemeBox(word[i], lineIndex, i + charOffset, prevGrapheme, skipLeft);\n        width += box.kernedWidth;\n        prevGrapheme = word[i];\n      }\n      return width;\n    },\n\n    /**\n     * Wraps a line of text using the width of the Textbox and a context.\n     * @param {Array} line The grapheme array that represent the line\n     * @param {Number} lineIndex\n     * @param {Number} desiredWidth width you want to wrap the line to\n     * @param {Number} reservedSpace space to remove from wrapping for custom functionalities\n     * @returns {Array} Array of line(s) into which the given text is wrapped\n     * to.\n     */\n    _wrapLine: function(_line, lineIndex, desiredWidth, reservedSpace) {\n      var lineWidth = 0,\n          splitByGrapheme = this.splitByGrapheme,\n          graphemeLines = [],\n          line = [],\n          // spaces in different languges?\n          words = splitByGrapheme ? fabric.util.string.graphemeSplit(_line) : _line.split(this._wordJoiners),\n          word = '',\n          offset = 0,\n          infix = splitByGrapheme ? '' : ' ',\n          wordWidth = 0,\n          infixWidth = 0,\n          largestWordWidth = 0,\n          lineJustStarted = true,\n          additionalSpace = splitByGrapheme ? 0 : this._getWidthOfCharSpacing(),\n          reservedSpace = reservedSpace || 0;\n      // fix a difference between split and graphemeSplit\n      if (words.length === 0) {\n        words.push([]);\n      }\n      desiredWidth -= reservedSpace;\n      for (var i = 0; i < words.length; i++) {\n        // if using splitByGrapheme words are already in graphemes.\n        word = splitByGrapheme ? words[i] : fabric.util.string.graphemeSplit(words[i]);\n        wordWidth = this._measureWord(word, lineIndex, offset);\n        offset += word.length;\n\n        lineWidth += infixWidth + wordWidth - additionalSpace;\n\n        if (lineWidth >= desiredWidth && !lineJustStarted) {\n          graphemeLines.push(line);\n          line = [];\n          lineWidth = wordWidth;\n          lineJustStarted = true;\n        }\n        else {\n          lineWidth += additionalSpace;\n        }\n\n        if (!lineJustStarted && !splitByGrapheme) {\n          line.push(infix);\n        }\n        line = line.concat(word);\n\n        infixWidth = this._measureWord([infix], lineIndex, offset);\n        offset++;\n        lineJustStarted = false;\n        // keep track of largest word\n        if (wordWidth > largestWordWidth) {\n          largestWordWidth = wordWidth;\n        }\n      }\n\n      i && graphemeLines.push(line);\n\n      if (largestWordWidth + reservedSpace > this.dynamicMinWidth) {\n        this.dynamicMinWidth = largestWordWidth - additionalSpace + reservedSpace;\n      }\n\n      return graphemeLines;\n    },\n\n    /**\n     * Detect if the text line is ended with an hard break\n     * text and itext do not have wrapping, return false\n     * @param {Number} lineIndex text to split\n     * @return {Boolean}\n     */\n    isEndOfWrapping: function(lineIndex) {\n      if (!this._styleMap[lineIndex + 1]) {\n        // is last line, return true;\n        return true;\n      }\n      if (this._styleMap[lineIndex + 1].line !== this._styleMap[lineIndex].line) {\n        // this is last line before a line break, return true;\n        return true;\n      }\n      return false;\n    },\n\n    /**\n     * Detect if a line has a linebreak and so we need to account for it when moving\n     * and counting style.\n     * @return Number\n     */\n    missingNewlineOffset: function(lineIndex) {\n      if (this.splitByGrapheme) {\n        return this.isEndOfWrapping(lineIndex) ? 1 : 0;\n      }\n      return 1;\n    },\n\n    /**\n    * Gets lines of text to render in the Textbox. This function calculates\n    * text wrapping on the fly every time it is called.\n    * @param {String} text text to split\n    * @returns {Array} Array of lines in the Textbox.\n    * @override\n    */\n    _splitTextIntoLines: function(text) {\n      var newText = fabric.Text.prototype._splitTextIntoLines.call(this, text),\n          graphemeLines = this._wrapText(newText.lines, this.width),\n          lines = new Array(graphemeLines.length);\n      for (var i = 0; i < graphemeLines.length; i++) {\n        lines[i] = graphemeLines[i].join('');\n      }\n      newText.lines = lines;\n      newText.graphemeLines = graphemeLines;\n      return newText;\n    },\n\n    getMinWidth: function() {\n      return Math.max(this.minWidth, this.dynamicMinWidth);\n    },\n\n    _removeExtraneousStyles: function() {\n      var linesToKeep = {};\n      for (var prop in this._styleMap) {\n        if (this._textLines[prop]) {\n          linesToKeep[this._styleMap[prop].line] = 1;\n        }\n      }\n      for (var prop in this.styles) {\n        if (!linesToKeep[prop]) {\n          delete this.styles[prop];\n        }\n      }\n    },\n\n    /**\n     * Returns object representation of an instance\n     * @method toObject\n     * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output\n     * @return {Object} object representation of an instance\n     */\n    toObject: function(propertiesToInclude) {\n      return this.callSuper('toObject', ['minWidth', 'splitByGrapheme'].concat(propertiesToInclude));\n    }\n  });\n\n  /**\n   * Returns fabric.Textbox instance from an object representation\n   * @static\n   * @memberOf fabric.Textbox\n   * @param {Object} object Object to create an instance from\n   * @param {Function} [callback] Callback to invoke when an fabric.Textbox instance is created\n   */\n  fabric.Textbox.fromObject = function(object, callback) {\n    return fabric.Object._fromObject('Textbox', object, callback, 'text');\n  };\n})(typeof exports !== 'undefined' ? exports : this);\n\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ../es2015/.internal/fabric/fabric.js\n// module id = /Im6\n// module chunks = 71c9","exports.read = function (buffer, offset, isLE, mLen, nBytes) {\n  var e, m\n  var eLen = (nBytes * 8) - mLen - 1\n  var eMax = (1 << eLen) - 1\n  var eBias = eMax >> 1\n  var nBits = -7\n  var i = isLE ? (nBytes - 1) : 0\n  var d = isLE ? -1 : 1\n  var s = buffer[offset + i]\n\n  i += d\n\n  e = s & ((1 << (-nBits)) - 1)\n  s >>= (-nBits)\n  nBits += eLen\n  for (; nBits > 0; e = (e * 256) + buffer[offset + i], i += d, nBits -= 8) {}\n\n  m = e & ((1 << (-nBits)) - 1)\n  e >>= (-nBits)\n  nBits += mLen\n  for (; nBits > 0; m = (m * 256) + buffer[offset + i], i += d, nBits -= 8) {}\n\n  if (e === 0) {\n    e = 1 - eBias\n  } else if (e === eMax) {\n    return m ? NaN : ((s ? -1 : 1) * Infinity)\n  } else {\n    m = m + Math.pow(2, mLen)\n    e = e - eBias\n  }\n  return (s ? -1 : 1) * m * Math.pow(2, e - mLen)\n}\n\nexports.write = function (buffer, value, offset, isLE, mLen, nBytes) {\n  var e, m, c\n  var eLen = (nBytes * 8) - mLen - 1\n  var eMax = (1 << eLen) - 1\n  var eBias = eMax >> 1\n  var rt = (mLen === 23 ? Math.pow(2, -24) - Math.pow(2, -77) : 0)\n  var i = isLE ? 0 : (nBytes - 1)\n  var d = isLE ? 1 : -1\n  var s = value < 0 || (value === 0 && 1 / value < 0) ? 1 : 0\n\n  value = Math.abs(value)\n\n  if (isNaN(value) || value === Infinity) {\n    m = isNaN(value) ? 1 : 0\n    e = eMax\n  } else {\n    e = Math.floor(Math.log(value) / Math.LN2)\n    if (value * (c = Math.pow(2, -e)) < 1) {\n      e--\n      c *= 2\n    }\n    if (e + eBias >= 1) {\n      value += rt / c\n    } else {\n      value += rt * Math.pow(2, 1 - eBias)\n    }\n    if (value * c >= 2) {\n      e++\n      c /= 2\n    }\n\n    if (e + eBias >= eMax) {\n      m = 0\n      e = eMax\n    } else if (e + eBias >= 1) {\n      m = ((value * c) - 1) * Math.pow(2, mLen)\n      e = e + eBias\n    } else {\n      m = value * Math.pow(2, eBias - 1) * Math.pow(2, mLen)\n      e = 0\n    }\n  }\n\n  for (; mLen >= 8; buffer[offset + i] = m & 0xff, i += d, m /= 256, mLen -= 8) {}\n\n  e = (e << mLen) | m\n  eLen += mLen\n  for (; eLen > 0; buffer[offset + i] = e & 0xff, i += d, e /= 256, eLen -= 8) {}\n\n  buffer[offset + i - d] |= s * 128\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// c:/Users/Antanas/Dropbox/am/Projects/typescript/amcharts4dev/node_modules/ieee754/index.js\n// module id = 1x5Z\n// module chunks = 71c9 bf3e","var toString = {}.toString;\n\nmodule.exports = Array.isArray || function (arr) {\n  return toString.call(arr) == '[object Array]';\n};\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// c:/Users/Antanas/Dropbox/am/Projects/typescript/amcharts4dev/node_modules/isarray/index.js\n// module id = 6I2M\n// module chunks = 71c9 bf3e","/**\r\n * Icons from:\r\n * https://www.iconfinder.com/iconsets/google-material-design-icons\r\n */\r\n\r\nexport class AnnotationIcons {\r\n\t// UI icons\r\n\tstatic line: string = '<svg viewBox=\"0 0 128 128\" version=\"1\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M1 59h126v10H1z\"/></svg>';\r\n\tstatic arrow: string = '<svg viewBox=\"0 0 48 48\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M44 24l-8-8v6H6v4h30v6z\"/></svg>';\r\n\tstatic blank: string = '<svg viewBox=\"0 0 48 48\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M0 0h48v48H0z\" fill=\"none\"/></svg>';\r\n\tstatic colors: string = '<svg viewBox=\"0 0 48 48\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M24 6a18 18 0 0 0 0 36 3 3 0 0 0 2-5l-1-2c0-2 2-3 3-3h4c6 0 10-4 10-10 0-9-8-16-18-16zM13 24a3 3 0 1 1 0-6 3 3 0 0 1 0 6zm6-8a3 3 0 1 1 0-6 3 3 0 0 1 0 6zm10 0a3 3 0 1 1 0-6 3 3 0 0 1 0 6zm6 8a3 3 0 1 1 0-6 3 3 0 0 1 0 6z\"/></svg>';\r\n\tstatic delete: string = '<svg viewBox=\"0 0 48 48\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M12 38c0 2 2 4 4 4h16c2 0 4-2 4-4V14H12v24zM38 8h-7l-2-2H19l-2 2h-7v4h28V8z\"/></svg>';\r\n\tstatic discard: string = '<svg viewBox=\"0 0 32 32\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M16 0a16 16 0 1 0 0 32 16 16 0 0 0 0-32zm0 30a14 14 0 1 1 0-28 14 14 0 0 1 0 28z\"/><path d=\"M9.27 22.7c.4.4 1.04.4 1.43 0l5.32-5.27 5.28 5.27a1 1 0 0 0 1.43 0c.4-.4.4-1.03 0-1.43L17.46 16l5.24-5.2a1 1 0 0 0 0-1.4c-.4-.4-1.04-.4-1.43 0l-5.23 5.18-5.31-5.3a1 1 0 0 0-1.43 0c-.4.39-.4 1.03 0 1.42l5.3 5.3-5.33 5.3a1 1 0 0 0 0 1.4z\"/></svg>';\r\n\tstatic done: string = '<svg viewBox=\"0 0 32 32\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M30 0H2a2 2 0 0 0-2 2v28c0 1.1.9 2 2 2h28a2 2 0 0 0 2-2V2a2 2 0 0 0-2-2zm0 30H2V2h28v28z\"/><path d=\"M12.3 22.6c.38.39 1.04.4 1.43 0l11-10.9a1 1 0 0 0 0-1.4c-.4-.4-1.04-.4-1.43 0L13.01 20.48l-4.28-4.2c-.4-.39-1.03-.39-1.43 0a1 1 0 0 0 0 1.42l5 4.9z\"/></svg>';\r\n\tstatic draw: string = '<svg viewBox=\"0 0 48 48\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M9.2 13.8c1.4-1.5 2.8-2.7 3.4-2.5 1 .4 0 2.1-.6 3-.5 1-5.7 7.8-5.7 12.7 0 2.6 1 4.7 2.7 6a6 6 0 0 0 5.3.9c2.1-.7 3.9-2.8 6-5.6 2.5-3 5.8-6.8 8.3-6.8 3.2 0 3.2 2 3.5 3.6-7.6 1.3-10.8 7.3-10.8 10.7s2.9 6.2 6.4 6.2c3.3 0 8.6-2.7 9.4-12.2H42v-5h-5c-.2-3.3-2.1-8.4-8-8.4-4.5 0-8.4 3.8-9.9 5.7l-4.5 5.5c-.5.5-1.4 1.6-2.3 1.6-.9 0-1.4-1.6-.7-3.8.7-2.2 2.8-5.7 3.7-7 1.6-2.3 2.6-3.9 2.6-6.6 0-4.4-3.3-5.8-5-5.8-2.7 0-5 2-5.5 2.5-.7.7-1.3 1.3-1.7 1.9l3.5 3.4zM27.8 37c-.7 0-1.5-.5-1.5-1.4 0-1.2 1.4-4.4 5.7-5.6-.6 5.4-2.8 7-4.2 7z\"/></svg>';\r\n\tstatic icon: string = '<svg viewBox=\"0 0 48 48\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M42 38V10c0-2-2-4-4-4H10c-2 0-4 2-4 4v28c0 2 2 4 4 4h28c2 0 4-2 4-4zM17 27l5 6 7-9 9 12H10l7-9z\"/></svg>';\r\n\tstatic more: string = '<svg viewBox=\"0 0 48 48\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M12 20a4 4 0 1 0 0 8 4 4 0 0 0 0-8zm24 0a4 4 0 1 0 0 8 4 4 0 0 0 0-8zm-12 0a4 4 0 1 0 0 8 4 4 0 0 0 0-8z\"/></svg>';\r\n\tstatic pencil: string = '<svg viewBox=\"0 0 48 48\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M6 35v7h8l22-22-8-8L6 35zm35-21v-3l-4-4h-3l-4 3 8 8 3-4z\"/></svg>';\r\n\tstatic ok: string = '<svg viewBox=\"0 0 48 48\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M18 32l-8-8-3 3 11 11 24-24-3-3z\" stroke=\"#fff\"/></svg>';\r\n\tstatic opacity: string = '<svg viewBox=\"0 0 48 48\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M35.32 15.99L24 4.69l-11.32 11.3C9.56 19.11 8 23.27 8 27.27s1.56 8.22 4.68 11.34a15.98 15.98 0 0 0 22.64 0C38.44 35.49 40 31.27 40 27.27s-1.56-8.16-4.68-11.28zM12 28c.02-4 1.24-6.55 3.52-8.81L24 10.53l8.48 8.75C34.76 21.55 35.98 24 36 28H12z\"/></svg>';\r\n\tstatic redo: string = '<svg viewBox=\"0 0 48 48\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M37 21c-4-3-9-5-14-5-9 0-17 6-20 14l5 2a16 16 0 0 1 25-7l-7 7h18V14l-7 7z\"/></svg>';\r\n\tstatic select: string = '<svg version=\"1\" viewBox=\"0 0 24 24\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M7 2l12 11-6 1 3 7-2 1-3-7-4 4V2\"/></svg>';\r\n\tstatic text: string = '<svg viewBox=\"0 0 32 32\" version=\"1\" xmlns=\"http://www.w3.org/2000/svg\"><g><path d=\"M4 6v4h8v18h4V10h8V6zM30 4V2h-6v2h2v24h-2v2h6v-2h-2V4z\"/></g></svg>';\r\n\tstatic textAdd: string = '<svg viewBox=\"0 0 32 32\" version=\"1\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M4 4v24h24V4H4zm22 22H6V6h20v20zM8 22h12v-2H8v2zm16-6H8v2h16v-2zm0-4H8v2h16v-2z\"/></svg>';\r\n\tstatic textWeight: string = '<svg viewBox=\"0 0 32 32\" version=\"1\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M24 10V8s0-6-6-6H8v28h10c6 0 6-6 6-6v-2c0-6-6-6-6-6s6 0 6-6zm-8 14h-2v-4h2s2 0 2 2-2 2-2 2zm0-12h-2V8h2s2 0 2 2-2 2-2 2z\"/></svg>';\r\n\tstatic textSize: string = '<svg viewBox=\"0 0 20 20\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M16 9v8h-2V9h-4V7h10v2h-4zM8 5v12H6V5H0V3h15v2H8z\"/></svg>';\r\n\tstatic tools: string = '<svg viewBox=\"0 0 24 24\" version=\"1\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M0 5v18l1 1h8l1-1V5L5 0 0 5zm8 17H2v-3h6v3zm0-4H2V6h6v12zM3 5l2-2 3 2H3zM21 0h-5l-1 1v2h-2l-1 1v8l1 1 1-1V5h1v18l1 1h5l1-1V1l-1-1zm-1 22h-3V10h3v12zm0-13h-3V8h3v1zm0-2h-3V2h3v5z\"/></svg>';\r\n\tstatic undo: string = '<svg viewBox=\"0 0 48 48\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M25 16c-5 0-10 2-14 5l-7-7v18h18l-7-7c3-3 6-4 10-4 7 0 13 5 15 11l5-2c-3-8-11-14-20-14z\"/></svg>';\r\n\tstatic width: string = '<svg viewBox=\"0 0 48 48\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\"><path d=\"M6 34h36v-4H6v4zm0 6h36v-2H6v2zm0-14h36v-6H6v6zM6 8v8h36V8H6z\"/></svg>';\r\n\r\n\t// Annotation icons\r\n\tstatic heart: string = '<svg viewBox=\"0 0 48 48\" width=\"48\" height=\"48\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M24 43l-3-3C11 31 4 25 4 17 4 11 9 6 15 6c3 0 7 2 9 4 2-2 6-4 9-4 6 0 11 5 11 11 0 8-7 14-17 23l-3 3z\"/></svg>';\r\n\tstatic check: string = '<svg viewBox=\"0 0 29.75 22.87\" width=\"29.75\" height=\"22.87\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M29.05 1.57L28.19.7a2.43 2.43 0 0 0-3.43 0L10.17 15.29 5 10.12a2.43 2.43 0 0 0-3.43 0l-.86.86a2.44 2.44 0 0 0 0 3.43l7.74 7.75c.95.95 2.49.95 3.43 0L29.05 5c.94-.95.94-2.49 0-3.43z\"/></svg>';\r\n\tstatic pin: string = '<svg viewBox=\"0 0 48 48\" width=\"48\" height=\"48\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M24 4c-8 0-14 6-14 14 0 11 14 26 14 26s14-15 14-26c0-8-6-14-14-14zm0 19a5 5 0 1 1 0-10 5 5 0 0 1 0 10z\"/></svg>';\r\n\tstatic like: string = '<svg viewBox=\"0 0 48 48\" width=\"48\" height=\"48\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M2 42h8V18H2v24zm44-22c0-2-2-4-4-4H29l2-9V6l-1-2-2-2-13 13-1 3v20c0 2 2 4 4 4h18l4-2 6-15v-5z\"/></svg>';\r\n\tstatic dislike: string = '<svg viewBox=\"0 0 48 48\" width=\"48\" height=\"48\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M30 6H12L8 8 2 23v5c0 2 2 4 4 4h13l-2 9v1l1 2 2 2 13-13 1-3V10c0-2-2-4-4-4zm8 0v24h8V6h-8z\"/></svg>';\r\n\tstatic tag: string = '<svg viewBox=\"0 0 48 48\" width=\"48\" height=\"48\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M35 12l-3-2H10c-2 0-4 2-4 4v20c0 2 2 4 4 4h22l3-2 9-12-9-12z\"/></svg>';\r\n\tstatic attention: string = '<svg viewBox=\"0 0 48 48\" width=\"48\" height=\"48\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M40 4H8C6 4 4 6 4 8v36l8-8h28c2 0 4-2 4-4V8c0-2-2-4-4-4zM26 22h-4V10h4v12zm0 8h-4v-4h4v4z\"/></svg>';\r\n\tstatic smiley: string = '<svg viewBox=\"0 0 48 48\" width=\"48\" height=\"48\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M31 21a3 3 0 1 0 0-6 3 3 0 0 0 0 6zm-14 0a3 3 0 1 0 0-6 3 3 0 0 0 0 6zm7 14c5 0 10-3 11-8H13c1 5 6 8 11 8zm0-32a20 20 0 1 0 0 40 20 20 0 0 0 0-40zm0 36a16 16 0 1 1 0-32 16 16 0 0 1 0 32z\"/></svg>';\r\n}\n\n\n// WEBPACK FOOTER //\n// ../../../../../src/.internal/plugins/annotation/AnnotationIcons.ts","/**\r\n * Plugin which enables annotation functionality for charts.\r\n */\r\n\r\n/**\r\n * ============================================================================\r\n * IMPORTS\r\n * ============================================================================\r\n * @hidden\r\n */\r\nimport { fabric } from \"../../fabric/fabric.js\";\r\nimport { AnnotationIcons } from \"./AnnotationIcons\";\r\nimport { Plugin } from \"../../core/utils/Plugin\";\r\nimport { IExportCustomOptions } from \"../../core/export/Export\";\r\nimport { ExportMenu, IExportMenuItem } from \"../../core/export/ExportMenu\";\r\nimport { registry } from \"../../core/Registry\";\r\nimport { Color, color } from \"../../core/utils/Color\";\r\nimport { getInteraction } from \"../../core/interaction/Interaction\";\r\nimport { keyboard } from \"../../core/utils/Keyboard\";\r\nimport * as $math from \"../../core/utils/Math\";\r\n\r\n\r\n/**\r\n * ============================================================================\r\n * MAIN CLASS\r\n * ============================================================================\r\n * @hidden\r\n */\r\n\r\n/**\r\n * A plugin which automatically groups [[PercenSeries]] slices that are smaller\r\n * than certain percent into one \"Other\" slice.\r\n *\r\n * By pushing an instance of [[Annnotation]] into `plugin` list of\r\n * any [[Chart]], it automatically applies the functionality.\r\n *\r\n * Example:\r\n *\r\n * ```TypeScript\r\n * let annotation = chart.plugins.push(new am4plugins_annotation.Annotation());\r\n * ```\r\n * ```JavaScript\r\n * let annotation = chart.plugins.push(new am4plugins_annotation.Annotation());\r\n * ```\r\n * ```JSON\r\n * {\r\n *   \"plugins\": [{\r\n *     \"type\": \"Annotation\"\r\n *   }]\r\n * }\r\n * ```\r\n *\r\n * @since 4.5.5\r\n *\r\n * @todo resolve translations\r\n * @todo change mouse cursors based on context/tool\r\n * @todo better line selection on click\r\n * @todo arrow support\r\n * @todo undo/redo\r\n * @todo reposition/resize annotations on chart resize\r\n * @todo make annotations hold on IE (when in not annotation mode)\r\n */\r\nexport class Annotation extends Plugin {\r\n\r\n\t/**\r\n\t * Indicates if Sprite is currently in annotating mode.\r\n\t */\r\n\tprivate _active: boolean = false;\r\n\r\n\t/**\r\n\t * A reference to menu item that holds annotation tools.\r\n\t */\r\n\tprivate _menu: IExportMenuItem;\r\n\r\n\t/**\r\n\t * An ID of an element that represents the currently selected tool indicator.\r\n\t */\r\n\tprivate _indicatorId: string;\r\n\r\n\t/**\r\n\t * Currently selected tool.\r\n\t */\r\n\tprivate _currentTool: string = \"draw\";\r\n\r\n\t/**\r\n\t * Current color in use.\r\n\t */\r\n\tprivate _currentColor: Color = color(\"#c00\");\r\n\r\n\t/**\r\n\t * Currently selected weight/width.\r\n\t */\r\n\tprivate _currentWidth: number = 2;\r\n\r\n\t/**\r\n\t * Currently selected opacity.\r\n\t */\r\n\tprivate _currentOpacity: number = 0.8;\r\n\r\n\t/**\r\n\t * Font size.\r\n\t */\r\n\tprivate _currentFontSize: number = 20;\r\n\r\n\t/**\r\n\t * Font weight.\r\n\t */\r\n\tprivate _currentFontWeight: number = 400;\r\n\r\n\t/**\r\n\t * Color selection.\r\n\t */\r\n\tprivate _colors: Array<Color> = [];\r\n\r\n\t/**\r\n\t * Available line widths.\r\n\t */\r\n\tprivate _widths: Array<number> = [];\r\n\r\n\t/**\r\n\t * Available opacities.\r\n\t */\r\n\tprivate _opacities: Array<number> = [];\r\n\r\n\t/**\r\n\t * Available font sizes.\r\n\t */\r\n\tprivate _fontSizes: Array<number> = [];\r\n\r\n\t/**\r\n\t * Available font weights.\r\n\t */\r\n\tprivate _fontWeights: Array<number> = [];\r\n\r\n\t/**\r\n\t * Menu enabled?\r\n\t */\r\n\tprivate _useMenu: boolean = true;\r\n\r\n\t/**\r\n\t * Did plugin create own menu or reusing existing ExportMenu?\r\n\t */\r\n\tprivate _ownMenu: boolean = true;\r\n\r\n\t/**\r\n\t * A Fabric's Canvas element.\r\n\t *\r\n\t * @see {@link http://fabricjs.com/docs/fabric.Canvas.html}\r\n\t */\r\n\tprivate _fabric: fabric.Canvas;\r\n\r\n\t/**\r\n\t * Reference to `<g>` element that holds annotation objects.\r\n\t */\r\n\tprivate _group: SVGGElement;\r\n\r\n\tprivate _pointerDown: boolean = false;\r\n\tprivate _currentLine: any;\r\n\tprivate _currentArrowhead: any;\r\n\tprivate _data: any;\r\n\tprivate _exportInited: boolean = false;\r\n\r\n\t/**\r\n\t * List of icons to use in annotation\r\n\t */\r\n\tpublic icons: Array<string> = [];\r\n\r\n\t/**\r\n\t * Logs orinal size of the chart so that annotations can be repositioned\r\n\t * relatively when that changes.\r\n\t * @type {number}\r\n\t */\r\n\tprivate _originalBbox: { width: number, height: number };\r\n\r\n\t/**\r\n\t * If set to `true` plugin will try to reposition annotation relatively when\r\n\t * size of the chart chanages.\r\n\t *\r\n\t * This feature is experimental. Use at your own risk.\r\n\t *\r\n\t * @default false\r\n\t * @since 4.7.19\r\n\t * @type {boolean}\r\n\t */\r\n\tpublic autoSize: boolean = false;\r\n\r\n\t/**\r\n\t * Constructor\r\n\t */\r\n\tconstructor() {\r\n\t\t// Nothing to do here\r\n\t\tsuper();\r\n\r\n\t\t// Set default colors\r\n\t\tthis._colors = [\r\n\t\t\tcolor(\"#000\"),\r\n\t\t\tcolor(\"#fff\"),\r\n\t\t\tcolor(\"#c00\"),\r\n\t\t\tcolor(\"#0c0\"),\r\n\t\t\tcolor(\"#00c\")\r\n\t\t];\r\n\r\n\t\t// Set defaults\r\n\t\tthis._widths = [1, 2, 4, 10];\r\n\t\tthis._opacities = [0.2, 0.4, 0.6, 0.8, 1];\r\n\r\n\t\t// Set default font sizes\r\n\t\tthis._fontSizes = [10, 15, 20, 30];\r\n\t\tthis._fontWeights = [200, 300, 400, 800];\r\n\r\n\t\t// Add default icons\r\n\t\tthis.icons = [\r\n\t\t\tAnnotationIcons.pin,\r\n\t\t\tAnnotationIcons.heart,\r\n\t\t\tAnnotationIcons.check,\r\n\t\t\tAnnotationIcons.like,\r\n\t\t\tAnnotationIcons.dislike,\r\n\t\t\tAnnotationIcons.tag,\r\n\t\t\tAnnotationIcons.attention,\r\n\t\t\tAnnotationIcons.smiley\r\n\t\t];\r\n\t}\r\n\r\n\tpublic init() {\r\n\t\tsuper.init();\r\n\t\tthis.initExporting();\r\n\t\tif (this._data) {\r\n\t\t\tthis.loadData();\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Initializes menus for the annotation.\r\n\t *\r\n\t * Will try to use existing [[ExportMenu]] if present.\r\n\t */\r\n\tprotected initExporting(): void {\r\n\t\tconst target = this.target;\r\n\r\n\t\t// Create an export menu if it does not yet exist\r\n\t\tif (this.useMenu) {\r\n\t\t\tif (!target.exporting.menu) {\r\n\t\t\t\ttarget.exporting.menu = new ExportMenu();\r\n\t\t\t\ttarget.exporting.menu.items[0].menu = [];\r\n\t\t\t\tthis._ownMenu = true;\r\n\t\t\t}\r\n\t\t\telse {\r\n\t\t\t\ttarget.exporting.menu.invalidate();\r\n\t\t\t\tthis._ownMenu = false;\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\t// Update indicator when menu is created\r\n\t\ttarget.exporting.events.once(\"menucreated\", this.updateIndicator);\r\n\r\n\t\ttarget.events.on(\"sizechanged\", this.sizeAnnotations, this);\r\n\r\n\t\t// Create DEL key handler\r\n\t\tgetInteraction().body.events.on(\"keyup\", (ev) => {\r\n\t\t\tif (this.active && keyboard.isKey(ev.event, \"del\")) {\r\n\t\t\t\tthis.deleteSelected();\r\n\t\t\t}\r\n\t\t});\r\n\r\n\t\t// Update/show SVG annotation if currently in annotation mode and user\r\n\t\t// triggers export.\r\n\t\ttarget.exporting.events.on(\"exportstarted\", (ev) => {\r\n\t\t\tif (this.active) {\r\n\t\t\t\tthis.updateSVG();\r\n\t\t\t\t(<any>this).fabric.wrapperEl.style.display = \"none\";\r\n\t\t\t\tthis._group.style.display = \"\";\r\n\t\t\t}\r\n\t\t});\r\n\r\n\t\ttarget.exporting.events.on(\"exportfinished\", (ev) => {\r\n\t\t\tif (this.active) {\r\n\t\t\t\tthis._group.style.display = \"none\";\r\n\t\t\t\t(<any>this).fabric.wrapperEl.style.display = \"block\";\r\n\t\t\t}\r\n\t\t});\r\n\r\n\t\t// Generate a unique id for indicator\r\n\t\tthis._indicatorId = registry.getUniqueId();\r\n\r\n\t\tif (this.useMenu) {\r\n\r\n\t\t\t// Add annotation menu\r\n\t\t\ttarget.exporting.menu.items[0].menu.push({\r\n\t\t\t\tlabel: target.language.translateAny(\"Annotate\"),\r\n\t\t\t\ttype: \"custom\",\r\n\t\t\t\toptions: {\r\n\t\t\t\t\tcallback: this.handleClick,\r\n\t\t\t\t\tcallbackTarget: this\r\n\t\t\t\t}\r\n\t\t\t});\r\n\r\n\t\t\t// Color list\r\n\t\t\tlet colors: Array<IExportMenuItem> = [];\r\n\t\t\tfor (let i = 0; i < this.colors.length; i++) {\r\n\t\t\t\tcolors.push({\r\n\t\t\t\t\ttype: \"custom\",\r\n\t\t\t\t\tsvg: AnnotationIcons.ok,\r\n\t\t\t\t\tcolor: this.colors[i],\r\n\t\t\t\t\toptions: {\r\n\t\t\t\t\t\tcallback: () => {\r\n\t\t\t\t\t\t\tthis.setColor(this.colors[i])\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t}\r\n\t\t\t\t});\r\n\t\t\t}\r\n\r\n\t\t\t// Width list\r\n\t\t\tlet widths: Array<IExportMenuItem> = [];\r\n\t\t\tfor (let i = 0; i < this.widths.length; i++) {\r\n\t\t\t\twidths.push({\r\n\t\t\t\t\ttype: \"custom\",\r\n\t\t\t\t\tlabel: this.widths[i] + \"px\",\r\n\t\t\t\t\toptions: {\r\n\t\t\t\t\t\tcallback: () => {\r\n\t\t\t\t\t\t\tthis.setWidth(this.widths[i])\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t}\r\n\t\t\t\t});\r\n\t\t\t}\r\n\r\n\t\t\t// Opacity list\r\n\t\t\tlet opacities: Array<IExportMenuItem> = [];\r\n\t\t\tfor (let i = 0; i < this.opacities.length; i++) {\r\n\t\t\t\topacities.push({\r\n\t\t\t\t\ttype: \"custom\",\r\n\t\t\t\t\tlabel: \"<span style=\\\"opacity: \" + this.opacities[i] + \"\\\">\" + (this.opacities[i] * 100) + \"%</span>\",\r\n\t\t\t\t\toptions: {\r\n\t\t\t\t\t\tcallback: () => {\r\n\t\t\t\t\t\t\tthis.setOpacity(this.opacities[i])\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t}\r\n\t\t\t\t});\r\n\t\t\t}\r\n\r\n\t\t\t// Font sizes\r\n\t\t\tlet fontSizes: Array<IExportMenuItem> = [];\r\n\t\t\tfor (let i = 0; i < this.fontSizes.length; i++) {\r\n\t\t\t\tfontSizes.push({\r\n\t\t\t\t\ttype: \"custom\",\r\n\t\t\t\t\tlabel: \"\" + this.fontSizes[i],\r\n\t\t\t\t\toptions: {\r\n\t\t\t\t\t\tcallback: () => {\r\n\t\t\t\t\t\t\tthis.setFontSize(this.fontSizes[i])\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t}\r\n\t\t\t\t});\r\n\t\t\t}\r\n\r\n\t\t\t// Font weights\r\n\t\t\tlet fontWeights: Array<IExportMenuItem> = [];\r\n\t\t\tfor (let i = 0; i < this.fontWeights.length; i++) {\r\n\t\t\t\tfontWeights.push({\r\n\t\t\t\t\ttype: \"custom\",\r\n\t\t\t\t\tlabel: \"\" + this.fontWeights[i],\r\n\t\t\t\t\toptions: {\r\n\t\t\t\t\t\tcallback: () => {\r\n\t\t\t\t\t\t\tthis.setFontWeight(this.fontWeights[i])\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t}\r\n\t\t\t\t});\r\n\t\t\t}\r\n\r\n\t\t\t// Icons\r\n\t\t\tlet icons: Array<IExportMenuItem> = [];\r\n\t\t\tfor (let i = 0; i < this.icons.length; i++) {\r\n\t\t\t\ticons.push({\r\n\t\t\t\t\ttype: \"custom\",\r\n\t\t\t\t\tsvg: this.icons[i],\r\n\t\t\t\t\toptions: {\r\n\t\t\t\t\t\tcallback: () => {\r\n\t\t\t\t\t\t\tthis.addIcon(this.icons[i])\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t}\r\n\t\t\t\t});\r\n\t\t\t}\r\n\r\n\t\t\t// Construct main menu item\r\n\t\t\tconst id = this._indicatorId;\r\n\t\t\t//let mainitem = this.target.exporting.menu.createSvgElement(0, \"custom\", AnnotationIcons.select).outerHTML;\r\n\t\t\tlet mainitem = \"<svg xmlns=\\\"http://www.w3.org/2000/svg\\\" version=\\\"1\\\" viewBox=\\\"0 0 24 24\\\"></svg>\";\r\n\t\t\tmainitem += \"<span class=\\\"\" + id + \"_color\\\" style=\\\"display: block; background-color: \" + this.currentColor.hex + \"; width: 1.2em; height: 1.2em; margin: 0.2em auto 0.4em auto;\\\"></span>\";\r\n\r\n\t\t\t// Add annotation tools menu\r\n\t\t\tthis._menu = {\r\n\t\t\t\thidden: !this.active,\r\n\t\t\t\t// icon: AnnotationIcons.select,\r\n\t\t\t\tlabel: mainitem,\r\n\t\t\t\tid: this._indicatorId,\r\n\t\t\t\tmenu: [{\r\n\t\t\t\t\ttype: \"custom\",\r\n\t\t\t\t\tsvg: AnnotationIcons.tools,\r\n\t\t\t\t\tlabel: target.language.translateAny(\"Tools\"),\r\n\t\t\t\t\tmenu: [{\r\n\t\t\t\t\t\ttype: \"custom\",\r\n\t\t\t\t\t\tsvg: AnnotationIcons.select,\r\n\t\t\t\t\t\tlabel: target.language.translateAny(\"Select\"),\r\n\t\t\t\t\t\toptions: {\r\n\t\t\t\t\t\t\tcallback: this.select,\r\n\t\t\t\t\t\t\tcallbackTarget: this\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t}, {\r\n\t\t\t\t\t\ttype: \"custom\",\r\n\t\t\t\t\t\tsvg: AnnotationIcons.draw,\r\n\t\t\t\t\t\tlabel: target.language.translateAny(\"Draw\"),\r\n\t\t\t\t\t\toptions: {\r\n\t\t\t\t\t\t\tcallback: this.draw,\r\n\t\t\t\t\t\t\tcallbackTarget: this\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t}, {\r\n\t\t\t\t\t\ttype: \"custom\",\r\n\t\t\t\t\t\tsvg: AnnotationIcons.line,\r\n\t\t\t\t\t\tlabel: target.language.translateAny(\"Line\"),\r\n\t\t\t\t\t\toptions: {\r\n\t\t\t\t\t\t\tcallback: this.line,\r\n\t\t\t\t\t\t\tcallbackTarget: this\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t}, {\r\n\t\t\t\t\t\ttype: \"custom\",\r\n\t\t\t\t\t\tsvg: AnnotationIcons.arrow,\r\n\t\t\t\t\t\tlabel: target.language.translateAny(\"Arrow\"),\r\n\t\t\t\t\t\toptions: {\r\n\t\t\t\t\t\t\tcallback: this.arrow,\r\n\t\t\t\t\t\t\tcallbackTarget: this\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t}, {\r\n\t\t\t\t\t\ttype: \"custom\",\r\n\t\t\t\t\t\tsvg: AnnotationIcons.width,\r\n\t\t\t\t\t\tlabel: target.language.translateAny(\"Weight\"),\r\n\t\t\t\t\t\tmenu: widths\r\n\t\t\t\t\t}, {\r\n\t\t\t\t\t\ttype: \"custom\",\r\n\t\t\t\t\t\tsvg: AnnotationIcons.delete,\r\n\t\t\t\t\t\tlabel: target.language.translateAny(\"Delete\"),\r\n\t\t\t\t\t\toptions: {\r\n\t\t\t\t\t\t\tcallback: this.delete,\r\n\t\t\t\t\t\t\tcallbackTarget: this\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t}]\r\n\t\t\t\t}, {\r\n\t\t\t\t\ttype: \"custom\",\r\n\t\t\t\t\tsvg: AnnotationIcons.text,\r\n\t\t\t\t\tlabel: target.language.translateAny(\"Text\"),\r\n\t\t\t\t\tmenu: [{\r\n\t\t\t\t\t\ttype: \"custom\",\r\n\t\t\t\t\t\tsvg: AnnotationIcons.textAdd,\r\n\t\t\t\t\t\tlabel: target.language.translateAny(\"Add\"),\r\n\t\t\t\t\t\toptions: {\r\n\t\t\t\t\t\t\tcallback: this.addText,\r\n\t\t\t\t\t\t\tcallbackTarget: this\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t}, {\r\n\t\t\t\t\t\ttype: \"custom\",\r\n\t\t\t\t\t\tsvg: AnnotationIcons.textWeight,\r\n\t\t\t\t\t\tlabel: target.language.translateAny(\"Weight\"),\r\n\t\t\t\t\t\tmenu: fontWeights\r\n\t\t\t\t\t}, {\r\n\t\t\t\t\t\ttype: \"custom\",\r\n\t\t\t\t\t\tsvg: AnnotationIcons.textSize,\r\n\t\t\t\t\t\tlabel: target.language.translateAny(\"Size\"),\r\n\t\t\t\t\t\tmenu: fontSizes\r\n\t\t\t\t\t}]\r\n\t\t\t\t}, {\r\n\t\t\t\t\ttype: \"custom\",\r\n\t\t\t\t\tsvg: AnnotationIcons.colors,\r\n\t\t\t\t\tlabel: target.language.translateAny(\"Color\"),\r\n\t\t\t\t\tmenu: colors\r\n\t\t\t\t}, {\r\n\t\t\t\t\ttype: \"custom\",\r\n\t\t\t\t\tsvg: AnnotationIcons.opacity,\r\n\t\t\t\t\tlabel: target.language.translateAny(\"Opacity\"),\r\n\t\t\t\t\tmenu: opacities\r\n\t\t\t\t}, {\r\n\t\t\t\t\ttype: \"custom\",\r\n\t\t\t\t\tsvg: AnnotationIcons.icon,\r\n\t\t\t\t\tlabel: target.language.translateAny(\"Icon\"),\r\n\t\t\t\t\tmenu: icons\r\n\t\t\t\t}, {\r\n\t\t\t\t\ttype: \"custom\",\r\n\t\t\t\t\tsvg: AnnotationIcons.more,\r\n\t\t\t\t\tlabel: target.language.translateAny(\"More\"),\r\n\t\t\t\t\tmenu: [/*{\r\n\t\t\t\t\t\ttype: \"custom\",\r\n\t\t\t\t\t\tsvg: AnnotationIcons.undo,\r\n\t\t\t\t\t\tlabel: target.language.translateAny(\"Undo\"),\r\n\t\t\t\t\t\toptions: {\r\n\t\t\t\t\t\t\tcallback: this.underConstruction,\r\n\t\t\t\t\t\t\tcallbackTarget: this\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t}, {\r\n\t\t\t\t\t\ttype: \"custom\",\r\n\t\t\t\t\t\tsvg: AnnotationIcons.redo,\r\n\t\t\t\t\t\tlabel: target.language.translateAny(\"Redo\"),\r\n\t\t\t\t\t\toptions: {\r\n\t\t\t\t\t\t\tcallback: this.underConstruction,\r\n\t\t\t\t\t\t\tcallbackTarget: this\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t}, */{\r\n\t\t\t\t\t\t\ttype: \"custom\",\r\n\t\t\t\t\t\t\tsvg: AnnotationIcons.done,\r\n\t\t\t\t\t\t\tlabel: target.language.translateAny(\"Done\"),\r\n\t\t\t\t\t\t\toptions: {\r\n\t\t\t\t\t\t\t\tcallback: this.deactivate,\r\n\t\t\t\t\t\t\t\tcallbackTarget: this\r\n\t\t\t\t\t\t\t}\r\n\t\t\t\t\t\t}, {\r\n\t\t\t\t\t\t\ttype: \"custom\",\r\n\t\t\t\t\t\t\tsvg: AnnotationIcons.discard,\r\n\t\t\t\t\t\t\tlabel: target.language.translateAny(\"Discard\"),\r\n\t\t\t\t\t\t\toptions: {\r\n\t\t\t\t\t\t\t\tcallback: this.discard,\r\n\t\t\t\t\t\t\t\tcallbackTarget: this\r\n\t\t\t\t\t\t\t}\r\n\t\t\t\t\t\t}]\r\n\t\t\t\t}]\r\n\t\t\t};\r\n\t\t\ttarget.exporting.menu.items.push(this._menu);\r\n\t\t}\r\n\r\n\t\tthis._exportInited = true;\r\n\r\n\t}\r\n\r\n\t/**\r\n\t * Toggles annotation mode on click of the related menu item.\r\n\t *\r\n\t * @ignore\r\n\t * @param  options  Options\r\n\t */\r\n\tpublic handleClick(options: IExportCustomOptions): void {\r\n\t\tthis.active = !this.active;\r\n\t}\r\n\r\n\t/**\r\n\t * Returns an instance of Fabric's `Canvas`.\r\n\t * @return Canvas\r\n\t */\r\n\tpublic get fabric(): fabric.Canvas {\r\n\t\t// Init canvas if not yet done\r\n\t\tif (!this._fabric) {\r\n\r\n\t\t\t// Creae <canvas> element\r\n\t\t\tlet canvas = document.createElement(\"canvas\");\r\n\t\t\tcanvas.width = this.target.pixelWidth;\r\n\t\t\tcanvas.height = this.target.pixelHeight;\r\n\t\t\tcanvas.style.position = \"absolute\";\r\n\t\t\tcanvas.style.top = \"0\";\r\n\t\t\tcanvas.style.left = \"0\";\r\n\t\t\tthis.target.svgContainer.SVGContainer.appendChild(canvas);\r\n\r\n\t\t\t// Create Fabric representation of the canvas\r\n\t\t\tthis._fabric = new fabric.Canvas(canvas, {\r\n\t\t\t\t//isDrawingMode: true,\r\n\t\t\t\tcontainerClass: \"am4plugins_annotation_canvas_container\"\r\n\t\t\t});\r\n\t\t\t(<any>this).fabric.wrapperEl.style.position = \"absolute\";\r\n\t\t\t(<any>this).fabric.wrapperEl.style.top = \"0\";\r\n\t\t\t(<any>this).fabric.wrapperEl.style.left = \"0\";\r\n\r\n\t\t\t// Set up events for deletion\r\n\t\t\tthis.fabric.on(\"selection:created\", (ev) => {\r\n\t\t\t\tif (this.currentTool == \"delete\") {\r\n\t\t\t\t\tthis.deleteSelected();\r\n\t\t\t\t}\r\n\t\t\t});\r\n\r\n\t\t\t// Set up events for drawing lines/arrows\r\n\t\t\tthis._fabric.on(\"mouse:down\", (ev) => {\r\n\r\n\t\t\t\tif (this.currentTool != \"line\" && this.currentTool != \"arrow\") {\r\n\t\t\t\t\treturn;\r\n\t\t\t\t}\r\n\r\n\t\t\t\t// Line\r\n\t\t\t\tthis._pointerDown = true;\r\n\t\t\t\tlet pointer = this._fabric.getPointer(ev.e);\r\n\t\t\t\tlet points = [pointer.x, pointer.y, pointer.x, pointer.y];\r\n\r\n\t\t\t\tthis._currentLine = new fabric.Line(points, {\r\n\t\t\t\t\tstrokeWidth: this.currentWidth,\r\n\t\t\t\t\tfill: this.currentColor.hex,\r\n\t\t\t\t\tstroke: this.currentColor.hex,\r\n\t\t\t\t\topacity: this.currentOpacity,\r\n\t\t\t\t\toriginX: \"center\",\r\n\t\t\t\t\toriginY: \"center\"\r\n\t\t\t\t});\r\n\t\t\t\tthis._fabric.add(this._currentLine);\r\n\r\n\t\t\t\t// Arrowhead\r\n\t\t\t\tif (this.currentTool == \"arrow\") {\r\n\t\t\t\t\tthis._currentArrowhead = new fabric.Triangle({\r\n\t\t\t\t\t\twidth: 10,\r\n\t\t\t\t\t\theight: 10,\r\n\t\t\t\t\t\tstrokeWidth: this.currentWidth,\r\n\t\t\t\t\t\tfill: this.currentColor.hex,\r\n\t\t\t\t\t\tstroke: this.currentColor.hex,\r\n\t\t\t\t\t\topacity: this.currentOpacity,\r\n\t\t\t\t\t\tleft: pointer.x - 5,\r\n\t\t\t\t\t\ttop: pointer.y - 10,\r\n\t\t\t\t\t\toriginX: \"center\",\r\n\t\t\t\t\t\toriginY: \"center\",\r\n\t\t\t\t\t\tangle: 0\r\n\t\t\t\t\t});\r\n\t\t\t\t\tthis._fabric.add(this._currentArrowhead);\r\n\t\t\t\t}\r\n\r\n\t\t\t});\r\n\r\n\t\t\tthis._fabric.on(\"mouse:move\", (ev) => {\r\n\t\t\t\tif (!this._pointerDown || (this.currentTool != \"line\" && this.currentTool != \"arrow\")) {\r\n\t\t\t\t\treturn;\r\n\t\t\t\t}\r\n\r\n\t\t\t\tlet pointer = this._fabric.getPointer(ev.e);\r\n\t\t\t\tthis._currentLine.set({ x2: pointer.x, y2: pointer.y });\r\n\r\n\t\t\t\t// Move and rotate arrowhead\r\n\t\t\t\tif (this.currentTool == \"arrow\") {\r\n\t\t\t\t\tconst angle = $math.getAngle(\r\n\t\t\t\t\t\t{ x: this._currentLine.x1, y: this._currentLine.y1 },\r\n\t\t\t\t\t\t{ x: this._currentLine.x2, y: this._currentLine.y2 }\r\n\t\t\t\t\t);\r\n\t\t\t\t\tthis._currentArrowhead.set({\r\n\t\t\t\t\t\tleft: pointer.x,\r\n\t\t\t\t\t\ttop: pointer.y,\r\n\t\t\t\t\t\tangle: angle + 90\r\n\t\t\t\t\t});\r\n\t\t\t\t}\r\n\r\n\t\t\t\tthis._fabric.renderAll();\r\n\r\n\t\t\t});\r\n\r\n\t\t\tthis._fabric.on(\"mouse:up\", (ev) => {\r\n\t\t\t\tthis._pointerDown = false;\r\n\t\t\t});\r\n\r\n\t\t\t// Load data if necessary\r\n\t\t\tif (this._data) {\r\n\t\t\t\tthis.loadData();\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\treturn this._fabric;\r\n\t}\r\n\r\n\t/**\r\n\t * A `<g>` that holds SVG representation of the annotations in chart overlay.\r\n\t *\r\n\t * @return  Group element\r\n\t */\r\n\tpublic get group(): SVGGElement {\r\n\t\tif (!this._group) {\r\n\t\t\t//this.group = this.target.svgContainer.container.dom.appendChild(document.createElement(\"g\"));\r\n\t\t\tthis._group = this.target.paper.add(\"g\").node;\r\n\t\t\tthis._group.style.pointerEvents = \"none\";\r\n\t\t\tthis._group.setAttribute(\"clip-path\", this.target.dom.getAttribute(\"clip-path\"));\r\n\t\t\tthis.target.svgContainer.container.dom.appendChild(this._group);\r\n\t\t}\r\n\t\treturn this._group;\r\n\t}\r\n\r\n\t/**\r\n\t * Activates annotation mode.\r\n\t */\r\n\tpublic activate(): void {\r\n\t\tthis.active = true;\r\n\t\tthis.updateTool();\r\n\t\t(<any>this).fabric.wrapperEl.style.display = \"block\";\r\n\t\tthis.group.style.display = \"none\";\r\n\t}\r\n\r\n\t/**\r\n\t * Deactivates annotation mode.\r\n\t */\r\n\tpublic deactivate(): void {\r\n\t\tthis.active = false;\r\n\t\tthis.updateTool();\r\n\t\t(<any>this).fabric.wrapperEl.style.display = \"none\";\r\n\t\tthis.updateSVG();\r\n\t\tthis.group.style.display = \"\";\r\n\t}\r\n\r\n\t/**\r\n\t * Updates SVG overlay to display annotations when in non-annotation mode.\r\n\t *\r\n\t * @todo Set contents properly (not use innerHTML)\r\n\t */\r\n\tprivate updateSVG(): void {\r\n\t\tlet svg = this.fabric.toSVG();\r\n\t\tconst matches = svg.replace(/[\\n\\r]*/g, \"\").match(/<g.*<\\/g>/g);\r\n\t\tif (matches) {\r\n\t\t\tthis.group.innerHTML = matches[0];\r\n\t\t}\r\n\t\telse {\r\n\t\t\tthis.group.innerHTML = \"\";\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Seting to `true` puts the chart in annotation mode.\r\n\t *\r\n\t * Setting to `false` returns chart to regular mode of operation.\r\n\t *\r\n\t * @default false\r\n\t * @param  value  Active?\r\n\t */\r\n\tpublic set active(value: boolean) {\r\n\t\tif (this._active != value) {\r\n\t\t\tthis._active = value;\r\n\t\t\tif (value) {\r\n\t\t\t\tthis.activate();\r\n\t\t\t\tif (this.useMenu) {\r\n\t\t\t\t\tthis.target.exporting.menu.showBranch(this._menu);\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t\telse {\r\n\t\t\t\tthis.deactivate();\r\n\t\t\t\tif (this.useMenu) {\r\n\t\t\t\t\tthis.target.exporting.menu.hideBranch(this._menu);\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t\tthis.updateIndicator();\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * @return Active?\r\n\t */\r\n\tpublic get active(): boolean {\r\n\t\treturn this._active;\r\n\t}\r\n\r\n\t/**\r\n\t * Currently selected color.\r\n\t *\r\n\t * @default #000\r\n\t * @param  value  Color\r\n\t */\r\n\tpublic set currentColor(value: Color) {\r\n\t\tif (this._currentColor != value) {\r\n\t\t\tthis._currentColor = value;\r\n\t\t\tthis.updateIndicator();\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * @return Color\r\n\t */\r\n\tpublic get currentColor(): Color {\r\n\t\treturn this._currentColor;\r\n\t}\r\n\r\n\t/**\r\n\t * List of colors to show in selection.\r\n\t *\r\n\t * @param  value  Colors\r\n\t */\r\n\tpublic set colors(value: Array<Color>) {\r\n\t\tif (this._colors != value) {\r\n\t\t\tthis._colors = value;\r\n\t\t\tthis.updateIndicator();\r\n\t\t\tthis.setColor(this._currentColor);\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * @return Colors\r\n\t */\r\n\tpublic get colors(): Array<Color> {\r\n\t\treturn this._colors;\r\n\t}\r\n\r\n\t/**\r\n\t * Currently selected width.\r\n\t *\r\n\t * @default 1\r\n\t * @param  value  Width\r\n\t */\r\n\tpublic set currentWidth(value: number) {\r\n\t\tif (this._currentWidth != value) {\r\n\t\t\tthis._currentWidth = value;\r\n\t\t\tthis.updateIndicator();\r\n\t\t\tthis.setWidth(this._currentWidth);\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * @return Width\r\n\t */\r\n\tpublic get currentWidth(): number {\r\n\t\treturn this._currentWidth;\r\n\t}\r\n\r\n\t/**\r\n\t * List of widths in pixels for line and free-draw tool.\r\n\t *\r\n\t * @param  value  Widths\r\n\t */\r\n\tpublic set widths(value: Array<number>) {\r\n\t\tif (this._widths != value) {\r\n\t\t\tthis._widths = value;\r\n\t\t\tthis.updateIndicator();\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * @return Widths\r\n\t */\r\n\tpublic get widths(): Array<number> {\r\n\t\treturn this._widths;\r\n\t}\r\n\r\n\t/**\r\n\t * Currently selected opacity.\r\n\t *\r\n\t * @default 1\r\n\t * @param  value  Opacity\r\n\t */\r\n\tpublic set currentOpacity(value: number) {\r\n\t\tif (this._currentOpacity != value) {\r\n\t\t\tthis._currentOpacity = value;\r\n\t\t\tthis.updateIndicator();\r\n\t\t\tthis.setOpacity(this._currentOpacity);\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * @return Opacity\r\n\t */\r\n\tpublic get currentOpacity(): number {\r\n\t\treturn this._currentOpacity;\r\n\t}\r\n\r\n\t/**\r\n\t * List of opacities available for selection.\r\n\t *\r\n\t * @param  value  Opacities\r\n\t */\r\n\tpublic set opacities(value: Array<number>) {\r\n\t\tif (this._opacities != value) {\r\n\t\t\tthis._opacities = value;\r\n\t\t\tthis.updateIndicator();\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * @return Opacities\r\n\t */\r\n\tpublic get opacities(): Array<number> {\r\n\t\treturn this._opacities;\r\n\t}\r\n\r\n\t/**\r\n\t * Currently selected font size.\r\n\t *\r\n\t * @default 10\r\n\t * @param  value  Font size\r\n\t */\r\n\tpublic set currentFontSize(value: number) {\r\n\t\tif (this._currentFontSize != value) {\r\n\t\t\tthis._currentFontSize = value;\r\n\t\t\tthis.updateIndicator();\r\n\t\t\tthis.setFontSize(this._currentFontSize);\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * @return Font size\r\n\t */\r\n\tpublic get currentFontSize(): number {\r\n\t\treturn this._currentFontSize;\r\n\t}\r\n\r\n\t/**\r\n\t * List of available font sizes.\r\n\t *\r\n\t * @param  value  Font sizes\r\n\t */\r\n\tpublic set fontSizes(value: Array<number>) {\r\n\t\tif (this._fontSizes != value) {\r\n\t\t\tthis._fontSizes = value;\r\n\t\t\tthis.updateIndicator();\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * @return Font sizes\r\n\t */\r\n\tpublic get fontSizes(): Array<number> {\r\n\t\treturn this._fontSizes;\r\n\t}\r\n\r\n\t/**\r\n\t * Currently selected font weight.\r\n\t *\r\n\t * @default 400\r\n\t * @param  value  Font weight\r\n\t */\r\n\tpublic set currentFontWeight(value: number) {\r\n\t\tif (this._currentFontWeight != value) {\r\n\t\t\tthis._currentFontWeight = value;\r\n\t\t\tthis.updateIndicator();\r\n\t\t\t//this.setFontWeight(this._currentFontWeight);\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * @return Font weight\r\n\t */\r\n\tpublic get currentFontWeight(): number {\r\n\t\treturn this._currentFontWeight;\r\n\t}\r\n\r\n\t/**\r\n\t * List of available font weights.\r\n\t *\r\n\t * @param  value  Font weights\r\n\t */\r\n\tpublic set fontWeights(value: Array<number>) {\r\n\t\tif (this._fontWeights != value) {\r\n\t\t\tthis._fontWeights = value;\r\n\t\t\tthis.updateIndicator();\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * @return Font weights\r\n\t */\r\n\tpublic get fontWeights(): Array<number> {\r\n\t\treturn this._fontWeights;\r\n\t}\r\n\r\n\t/**\r\n\t * Currently selected tool.\r\n\t *\r\n\t * @default select\r\n\t * @param  value  Tool\r\n\t */\r\n\tpublic set currentTool(value: string) {\r\n\t\tif (this._currentTool != value) {\r\n\t\t\tthis._currentTool = value;\r\n\t\t\tthis.updateTool();\r\n\t\t\tthis.updateIndicator();\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * @return Tool\r\n\t */\r\n\tpublic get currentTool(): string {\r\n\t\treturn this._currentTool;\r\n\t}\r\n\r\n\t/**\r\n\t * Initiates tool.\r\n\t */\r\n\tprivate updateTool(): void {\r\n\t\tswitch (this.currentTool) {\r\n\t\t\tcase \"select\":\r\n\t\t\t\tthis.select();\r\n\t\t\t\tbreak;\r\n\t\t\tcase \"draw\":\r\n\t\t\t\tthis.draw();\r\n\t\t\t\tbreak;\r\n\t\t\tcase \"delete\":\r\n\t\t\t\tthis.delete();\r\n\t\t\t\tbreak;\r\n\t\t\tcase \"line\":\r\n\t\t\t\tthis.line();\r\n\t\t\t\tbreak;\r\n\t\t\tcase \"arrow\":\r\n\t\t\t\tthis.arrow();\r\n\t\t\t\tbreak;\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Updates currently selected tool/color indicator.\r\n\t */\r\n\tprivate updateIndicator(): void {\r\n\t\tif (this.indicator) {\r\n\r\n\t\t\t// Update tool icon\r\n\t\t\tlet container = this.indicator.getElementsByTagName(\"a\")[0];\r\n\t\t\tlet newicon = this.target.exporting.menu.createSvgElement(0, \"custom\", (<any>AnnotationIcons)[this.currentTool]);\r\n\t\t\tlet oldicon = this.indicator.getElementsByTagName(\"svg\")[0];\r\n\t\t\tcontainer.insertBefore(newicon, oldicon);\r\n\t\t\tcontainer.removeChild(oldicon);\r\n\r\n\t\t\t// Update color\r\n\t\t\t(<any>this.indicator.getElementsByClassName(this._indicatorId + \"_color\"))[0].style.backgroundColor = this.currentColor.hex;\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Current tool/color indicator element.\r\n\t *\r\n\t * @return  Indicator\r\n\t */\r\n\tpublic get indicator(): HTMLElement {\r\n\t\treturn document.getElementById(this._indicatorId);\r\n\t}\r\n\r\n\t/**\r\n\t * Sets color.\r\n\t *\r\n\t * @param  value  Color\r\n\t */\r\n\tpublic setColor(value: Color): void {\r\n\t\tthis.currentColor = value;\r\n\r\n\t\tlet brushColor = color(value);\r\n\t\tbrushColor.alpha = this.currentOpacity;\r\n\t\tthis.fabric.freeDrawingBrush.color = brushColor.rgba;\r\n\r\n\t\t// Update selected objects\r\n\t\tlet selected: any = this.fabric.getActiveObjects();\r\n\t\tfor (let i = 0; i < selected.length; i++) {\r\n\t\t\tif (selected[i].isType(\"textbox\") || (selected[i].isType(\"path\") && selected[i].fill)) {\r\n\t\t\t\tselected[i].set(\"fill\", value.hex);\r\n\t\t\t}\r\n\t\t\telse if (selected[i].isType(\"triangle\")) {\r\n\t\t\t\tselected[i].set(\"stroke\", value.hex);\r\n\t\t\t\tselected[i].set(\"fill\", value.hex);\r\n\t\t\t}\r\n\t\t\telse if ((<any>selected[i]).getSrc) {\r\n\t\t\t\tthis.setIconFill(<fabric.Image>selected[i]);\r\n\t\t\t}\r\n\t\t\telse {\r\n\t\t\t\tselected[i].set(\"stroke\", value.hex);\r\n\t\t\t}\r\n\t\t}\r\n\t\tthis.fabric.requestRenderAll();\r\n\t}\r\n\r\n\t/**\r\n\t * Sets line width.\r\n\t *\r\n\t * @param  value  Width\r\n\t */\r\n\tpublic setWidth(value: number): void {\r\n\t\tthis.currentWidth = value;\r\n\t\tthis.fabric.freeDrawingBrush.width = value;\r\n\r\n\t\t// Update selected objects\r\n\t\tlet selected = this.fabric.getActiveObjects();\r\n\t\tfor (let i = 0; i < selected.length; i++) {\r\n\t\t\tselected[i].set(\"strokeWidth\", value);\r\n\t\t}\r\n\t\tthis.fabric.requestRenderAll();\r\n\t}\r\n\r\n\t/**\r\n\t * Sets opacity.\r\n\t *\r\n\t * @param  value  Opacity\r\n\t */\r\n\tpublic setOpacity(value: number): void {\r\n\t\tthis.currentOpacity = value;\r\n\r\n\t\tlet brushColor = color(this.currentColor);\r\n\t\tbrushColor.alpha = this.currentOpacity;\r\n\t\tthis.fabric.freeDrawingBrush.color = brushColor.rgba;\r\n\r\n\t\t// Update selected objects\r\n\t\tlet selected = this.fabric.getActiveObjects();\r\n\t\tfor (let i = 0; i < selected.length; i++) {\r\n\t\t\tif (selected[i].isType(\"path\")) {\r\n\t\t\t\tselected[i].set(\"stroke\", this.currentColor.hex);\r\n\t\t\t}\r\n\t\t\tselected[i].set(\"opacity\", value);\r\n\t\t}\r\n\t\tthis.fabric.requestRenderAll();\r\n\t}\r\n\r\n\t/**\r\n\t * Sets font size.\r\n\t *\r\n\t * @param  value  Font size\r\n\t */\r\n\tpublic setFontSize(value: number): void {\r\n\t\tthis.currentFontSize = value;\r\n\r\n\t\t// Update selected objects\r\n\t\tlet selected = this.fabric.getActiveObjects();\r\n\t\tfor (let i = 0; i < selected.length; i++) {\r\n\t\t\tif ((<any>selected[i]).text) {\r\n\t\t\t\t(<any>selected[i]).set(\"fontSize\", value);\r\n\t\t\t}\r\n\t\t}\r\n\t\tthis.fabric.requestRenderAll();\r\n\t}\r\n\r\n\t/**\r\n\t * Sets font weight.\r\n\t *\r\n\t * @param  value  Font weight\r\n\t */\r\n\tpublic setFontWeight(value: number): void {\r\n\t\tthis.currentFontWeight = value;\r\n\r\n\t\t// Update selected objects\r\n\t\tlet selected = this.fabric.getActiveObjects();\r\n\t\tfor (let i = 0; i < selected.length; i++) {\r\n\t\t\tif ((<any>selected[i]).text) {\r\n\t\t\t\t(<any>selected[i]).set(\"fontWeight\", value);\r\n\t\t\t}\r\n\t\t}\r\n\t\tthis.fabric.requestRenderAll();\r\n\t}\r\n\r\n\t/**\r\n\t * Does nothing.\r\n\t */\r\n\tpublic underConstruction(): void {\r\n\t\talert(\"This feature is not yet implemented\");\r\n\t}\r\n\r\n\t/**\r\n\t * Puts annotator in object selection mode.\r\n\t */\r\n\tpublic select(): void {\r\n\t\tthis.currentTool = \"select\";\r\n\t\tthis.fabric.isDrawingMode = false;\r\n\t\tthis.fabric.selection = true;\r\n\t}\r\n\r\n\t/**\r\n\t * Puts annotator in free-drawing mode.\r\n\t */\r\n\tpublic draw(): void {\r\n\t\tthis.currentTool = \"draw\";\r\n\t\tthis.fabric.isDrawingMode = true;\r\n\t\tthis.fabric.selection = false;\r\n\r\n\t\tlet brushColor = color(this.currentColor);\r\n\t\tbrushColor.alpha = this.currentOpacity;\r\n\t\tthis.fabric.freeDrawingBrush.color = brushColor.rgba;\r\n\t\tthis.fabric.freeDrawingBrush.width = this.currentWidth;\r\n\t}\r\n\r\n\t/**\r\n\t * Puts annotator in line drawing mode.\r\n\t */\r\n\tpublic line(): void {\r\n\t\tthis.currentTool = \"line\";\r\n\t\tthis.fabric.isDrawingMode = false;\r\n\t\tthis.fabric.selection = false;\r\n\t}\r\n\r\n\t/**\r\n\t * Puts annotator in arrow drawing mode.\r\n\t */\r\n\tpublic arrow(): void {\r\n\t\tthis.currentTool = \"arrow\";\r\n\t\tthis.fabric.isDrawingMode = false;\r\n\t\tthis.fabric.selection = false;\r\n\t}\r\n\r\n\t/**\r\n\t * Adds an editable text object to canvas.\r\n\t */\r\n\tpublic addText(): void {\r\n\t\tthis.fabric.isDrawingMode = false;\r\n\t\tthis.fabric.selection = true;\r\n\t\tthis.select();\r\n\t\tlet text = new fabric.Textbox(this.target.language.translateAny(\"Type...\"), {\r\n\t\t\t//left: this.target.pixelWidth / 2,\r\n\t\t\t//top: this.target.pixelHeight / 2,\r\n\t\t\tfontSize: this.currentFontSize,\r\n\t\t\tfontWeight: this.currentFontWeight,\r\n\t\t\tfill: this.currentColor.hex,\r\n\t\t\topacity: this.currentOpacity\r\n\t\t});\r\n\t\tthis.fabric.add(text);\r\n\t\tthis.fabric.centerObject(text);\r\n\t\ttext.enterEditing();\r\n\t\ttext.selectAll();\r\n\t\tthis.fabric.setActiveObject(text);\r\n\t}\r\n\r\n\t/**\r\n\t * Adds an image to canvas.\r\n\t */\r\n\tpublic addIcon(url: string): void {\r\n\t\tthis.fabric.isDrawingMode = false;\r\n\t\tthis.fabric.selection = true;\r\n\t\tthis.select();\r\n\r\n\t\tfabric.loadSVGFromString(url, (res) => {\r\n\t\t\tfor (let i = 0; i < res.length; i++) {\r\n\t\t\t\tthis.fabric.add(res[i]);\r\n\t\t\t\tthis.fabric.centerObject(res[i]);\r\n\t\t\t\tthis.fabric.setActiveObject(res[i]);\r\n\t\t\t\tthis.fabric.setActiveObject(res[i]);\r\n\t\t\t\tres[i].opacity = this.currentOpacity;\r\n\t\t\t\tres[i].fill = this.currentColor.hex;\r\n\t\t\t}\r\n\t\t});\r\n\r\n\t\t// fabric.Image.fromElement(element, (img: any) => {\r\n\t\t// \tconsole.log(img)\r\n\t\t// \tthis.fabric.add(img);\r\n\t\t// \tthis.fabric.centerObject(img);\r\n\t\t// \tthis.fabric.setActiveObject(img);\r\n\t\t// \t// img.fill = this.currentColor.hex;\r\n\t\t// \t//this.fabric.requestRenderAll();\r\n\t\t// \timg.opacity = this.currentOpacity;\r\n\t\t// \tthis.setIconFill(img);\r\n\t\t// });\r\n\t}\r\n\r\n\t/**\r\n\t * Attemps to set a fill to the SVG icon.\r\n\t * @param  img  Fabric image reference\r\n\t */\r\n\tpublic setIconFill(img: fabric.Image): void {\r\n\t\tlet src = img.getSrc();\r\n\t\tlet svg = \"\";\r\n\t\tif (src.match(/;base64\\,/)) {\r\n\t\t\ttry {\r\n\t\t\t\tsvg = atob(src.replace(/^.*;base64\\,/g, \"\"));\r\n\t\t\t\tsvg = svg.replace(/fill=\"[^\"]+\"/, \"\");\r\n\t\t\t\tsvg = svg.replace(/\\/>/g, \" fill=\\\"\" + this.currentColor.hex + \"\\\" \\/>\");\r\n\t\t\t\tsrc = src.replace(/(^.*;base64\\,).*$/, \"$1\") + btoa(svg);\r\n\t\t\t\timg.setSrc(src);\r\n\t\t\t}\r\n\t\t\tcatch (e) {\r\n\t\t\t\treturn;\r\n\t\t\t}\r\n\t\t}\r\n\t\telse if (src.match(/^data:/)) {\r\n\t\t\tsvg = src.replace(/^data:[^,]*\\,/, \"\");\r\n\t\t\tsvg = svg.replace(/fill=\"[^\"]+\"/, \"\");\r\n\t\t\tsvg = svg.replace(/\\/>/g, \" fill=\\\"\" + this.currentColor.hex + \"\\\" \\/>\");\r\n\t\t\tsrc = src.replace(/(^.*;base64\\,).*$/, \"$1\") + svg;\r\n\t\t\timg.setSrc(src);\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Puts annotator in object deletion mode\r\n\t */\r\n\tpublic delete(): void {\r\n\t\tthis.currentTool = \"delete\";\r\n\t\tthis.fabric.isDrawingMode = false;\r\n\t}\r\n\r\n\t/**\r\n\t * Clears all annotations.\r\n\t */\r\n\tpublic clear(): void {\r\n\t\tthis.fabric.clear();\r\n\t}\r\n\r\n\t/**\r\n\t * Clears all annotations and exits annotation mode.\r\n\t */\r\n\tpublic discard(): void {\r\n\t\tthis.fabric.clear();\r\n\t\tthis.updateSVG();\r\n\t\tthis.deactivate();\r\n\t}\r\n\r\n\t/**\r\n\t * Deletes selected objects\r\n\t */\r\n\tpublic deleteSelected(): void {\r\n\t\tlet selected = this.fabric.getActiveObjects();\r\n\t\tfor (let i = 0; i < selected.length; i++) {\r\n\t\t\tthis.fabric.remove(selected[i]);\r\n\t\t}\r\n\t\tthis.fabric.requestRenderAll();\r\n\t}\r\n\r\n\t/**\r\n\t * Set or get annotation data.\r\n\t *\r\n\t * @since 4.5.6\r\n\t * @param  value  Data\r\n\t */\r\n\tpublic set data(value: any) {\r\n\t\tthis._data = value;\r\n\t\tif (this._fabric || this._exportInited) {\r\n\t\t\t// Canvas is ready, update now\r\n\t\t\tthis.loadData();\r\n\t\t}\r\n\t\telse {\r\n\t\t\t// Canvas is not yeat ready, just save data for later\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * @return Data\r\n\t */\r\n\tpublic get data(): any {\r\n\t\tif (this._fabric) {\r\n\t\t\treturn this.fabric.toObject();\r\n\t\t}\r\n\t\telse {\r\n\t\t\treturn this._data;\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * If set to `false` the plugin will not create own menu nor will add its\r\n\t * items to existing Export menu.\r\n\t *\r\n\t * In such case, annotation functionality will be available only via API.\r\n\t *\r\n\t * @since 4.8.0\r\n\t * @default true\r\n\t * @param  value  Use menu?\r\n\t */\r\n\tpublic set useMenu(value: boolean) {\r\n\t\tthis._useMenu = value;\r\n\t\tif (!value && this.target.exporting.menu) {\r\n\t\t\tif (this._ownMenu) {\r\n\t\t\t\tthis.target.exporting.menu.items[0].menu = [];\r\n\t\t\t\tthis.target.exporting.menu.invalidate();\r\n\t\t\t}\r\n\t\t\telse {\r\n\t\t\t\tthis.target.exporting.menu.items[0].menu.pop();\r\n\t\t\t\tthis.target.exporting.menu.invalidate();\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * @return Use menu?\r\n\t */\r\n\tpublic get useMenu(): boolean {\r\n\t\treturn this._useMenu;\r\n\t}\r\n\r\n\t/**\r\n\t * Loads data onto canvas.\r\n\t */\r\n\tprivate loadData(): void {\r\n\t\tthis.fabric.loadFromJSON(this._data, (e: any) => {\r\n\t\t\tthis.updateSVG();\r\n\t\t\tthis._data = undefined;\r\n\t\t});\r\n\t}\r\n\r\n\t/**\r\n\t * Resizes annotation as per trget chart size.\r\n\t */\r\n\tprivate sizeAnnotations(): void {\r\n\t\tif (this.autoSize) {\r\n\t\t\tif (!this._originalBbox) {\r\n\t\t\t\tconst bbox = this.group.getBBox();\r\n\t\t\t\tthis._originalBbox = {\r\n\t\t\t\t\twidth: bbox.width,\r\n\t\t\t\t\theight: bbox.height\r\n\t\t\t\t}\r\n\t\t\t}\r\n\r\n\t\t\t//console.log(bbox.width);\r\n\t\t\tconst w = this.target.pixelWidth;\r\n\t\t\tconst h = this.target.pixelHeight;\r\n\t\t\tconst dx = (w / this._originalBbox.width);\r\n\t\t\tconst dy = (h / this._originalBbox.height);\r\n\t\t\tconst data = this.data;\r\n\r\n\t\t\tfor (let i = 0; i < data.objects.length; i++) {\r\n\t\t\t\tconst item = <any>data.objects[i];\r\n\t\t\t\titem.left *= dx;\r\n\t\t\t\titem.top *= dy;\r\n\t\t\t}\r\n\r\n\t\t\tthis.data = data;\r\n\t\t\tthis._originalBbox = {\r\n\t\t\t\twidth: w,\r\n\t\t\t\theight: h\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\r\n}\r\n\r\n/**\r\n * Register class in system, so that it can be instantiated using its name from\r\n * anywhere.\r\n *\r\n * @ignore\r\n */\r\nregistry.registeredClasses[\"Annotation\"] = Annotation;\r\n\n\n\n// WEBPACK FOOTER //\n// ../../../../../src/.internal/plugins/annotation/Annotation.ts","import * as m from \"../../es2015/plugins/annotation\";\nwindow.am4plugins_annotation = m;\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./plugins/annotation.js\n// module id = null\n// module chunks = ","module.exports = jsdom;\n\n\n//////////////////\n// WEBPACK FOOTER\n// external \"jsdom\"\n// module id = M4QQ\n// module chunks = 71c9","/*!\n * The buffer module from node.js, for the browser.\n *\n * @author   Feross Aboukhadijeh <http://feross.org>\n * @license  MIT\n */\n/* eslint-disable no-proto */\n\n'use strict'\n\nvar base64 = require('base64-js')\nvar ieee754 = require('ieee754')\nvar isArray = require('isarray')\n\nexports.Buffer = Buffer\nexports.SlowBuffer = SlowBuffer\nexports.INSPECT_MAX_BYTES = 50\n\n/**\n * If `Buffer.TYPED_ARRAY_SUPPORT`:\n *   === true    Use Uint8Array implementation (fastest)\n *   === false   Use Object implementation (most compatible, even IE6)\n *\n * Browsers that support typed arrays are IE 10+, Firefox 4+, Chrome 7+, Safari 5.1+,\n * Opera 11.6+, iOS 4.2+.\n *\n * Due to various browser bugs, sometimes the Object implementation will be used even\n * when the browser supports typed arrays.\n *\n * Note:\n *\n *   - Firefox 4-29 lacks support for adding new properties to `Uint8Array` instances,\n *     See: https://bugzilla.mozilla.org/show_bug.cgi?id=695438.\n *\n *   - Chrome 9-10 is missing the `TypedArray.prototype.subarray` function.\n *\n *   - IE10 has a broken `TypedArray.prototype.subarray` function which returns arrays of\n *     incorrect length in some situations.\n\n * We detect these buggy browsers and set `Buffer.TYPED_ARRAY_SUPPORT` to `false` so they\n * get the Object implementation, which is slower but behaves correctly.\n */\nBuffer.TYPED_ARRAY_SUPPORT = global.TYPED_ARRAY_SUPPORT !== undefined\n  ? global.TYPED_ARRAY_SUPPORT\n  : typedArraySupport()\n\n/*\n * Export kMaxLength after typed array support is determined.\n */\nexports.kMaxLength = kMaxLength()\n\nfunction typedArraySupport () {\n  try {\n    var arr = new Uint8Array(1)\n    arr.__proto__ = {__proto__: Uint8Array.prototype, foo: function () { return 42 }}\n    return arr.foo() === 42 && // typed array instances can be augmented\n        typeof arr.subarray === 'function' && // chrome 9-10 lack `subarray`\n        arr.subarray(1, 1).byteLength === 0 // ie10 has broken `subarray`\n  } catch (e) {\n    return false\n  }\n}\n\nfunction kMaxLength () {\n  return Buffer.TYPED_ARRAY_SUPPORT\n    ? 0x7fffffff\n    : 0x3fffffff\n}\n\nfunction createBuffer (that, length) {\n  if (kMaxLength() < length) {\n    throw new RangeError('Invalid typed array length')\n  }\n  if (Buffer.TYPED_ARRAY_SUPPORT) {\n    // Return an augmented `Uint8Array` instance, for best performance\n    that = new Uint8Array(length)\n    that.__proto__ = Buffer.prototype\n  } else {\n    // Fallback: Return an object instance of the Buffer class\n    if (that === null) {\n      that = new Buffer(length)\n    }\n    that.length = length\n  }\n\n  return that\n}\n\n/**\n * The Buffer constructor returns instances of `Uint8Array` that have their\n * prototype changed to `Buffer.prototype`. Furthermore, `Buffer` is a subclass of\n * `Uint8Array`, so the returned instances will have all the node `Buffer` methods\n * and the `Uint8Array` methods. Square bracket notation works as expected -- it\n * returns a single octet.\n *\n * The `Uint8Array` prototype remains unmodified.\n */\n\nfunction Buffer (arg, encodingOrOffset, length) {\n  if (!Buffer.TYPED_ARRAY_SUPPORT && !(this instanceof Buffer)) {\n    return new Buffer(arg, encodingOrOffset, length)\n  }\n\n  // Common case.\n  if (typeof arg === 'number') {\n    if (typeof encodingOrOffset === 'string') {\n      throw new Error(\n        'If encoding is specified then the first argument must be a string'\n      )\n    }\n    return allocUnsafe(this, arg)\n  }\n  return from(this, arg, encodingOrOffset, length)\n}\n\nBuffer.poolSize = 8192 // not used by this implementation\n\n// TODO: Legacy, not needed anymore. Remove in next major version.\nBuffer._augment = function (arr) {\n  arr.__proto__ = Buffer.prototype\n  return arr\n}\n\nfunction from (that, value, encodingOrOffset, length) {\n  if (typeof value === 'number') {\n    throw new TypeError('\"value\" argument must not be a number')\n  }\n\n  if (typeof ArrayBuffer !== 'undefined' && value instanceof ArrayBuffer) {\n    return fromArrayBuffer(that, value, encodingOrOffset, length)\n  }\n\n  if (typeof value === 'string') {\n    return fromString(that, value, encodingOrOffset)\n  }\n\n  return fromObject(that, value)\n}\n\n/**\n * Functionally equivalent to Buffer(arg, encoding) but throws a TypeError\n * if value is a number.\n * Buffer.from(str[, encoding])\n * Buffer.from(array)\n * Buffer.from(buffer)\n * Buffer.from(arrayBuffer[, byteOffset[, length]])\n **/\nBuffer.from = function (value, encodingOrOffset, length) {\n  return from(null, value, encodingOrOffset, length)\n}\n\nif (Buffer.TYPED_ARRAY_SUPPORT) {\n  Buffer.prototype.__proto__ = Uint8Array.prototype\n  Buffer.__proto__ = Uint8Array\n  if (typeof Symbol !== 'undefined' && Symbol.species &&\n      Buffer[Symbol.species] === Buffer) {\n    // Fix subarray() in ES2016. See: https://github.com/feross/buffer/pull/97\n    Object.defineProperty(Buffer, Symbol.species, {\n      value: null,\n      configurable: true\n    })\n  }\n}\n\nfunction assertSize (size) {\n  if (typeof size !== 'number') {\n    throw new TypeError('\"size\" argument must be a number')\n  } else if (size < 0) {\n    throw new RangeError('\"size\" argument must not be negative')\n  }\n}\n\nfunction alloc (that, size, fill, encoding) {\n  assertSize(size)\n  if (size <= 0) {\n    return createBuffer(that, size)\n  }\n  if (fill !== undefined) {\n    // Only pay attention to encoding if it's a string. This\n    // prevents accidentally sending in a number that would\n    // be interpretted as a start offset.\n    return typeof encoding === 'string'\n      ? createBuffer(that, size).fill(fill, encoding)\n      : createBuffer(that, size).fill(fill)\n  }\n  return createBuffer(that, size)\n}\n\n/**\n * Creates a new filled Buffer instance.\n * alloc(size[, fill[, encoding]])\n **/\nBuffer.alloc = function (size, fill, encoding) {\n  return alloc(null, size, fill, encoding)\n}\n\nfunction allocUnsafe (that, size) {\n  assertSize(size)\n  that = createBuffer(that, size < 0 ? 0 : checked(size) | 0)\n  if (!Buffer.TYPED_ARRAY_SUPPORT) {\n    for (var i = 0; i < size; ++i) {\n      that[i] = 0\n    }\n  }\n  return that\n}\n\n/**\n * Equivalent to Buffer(num), by default creates a non-zero-filled Buffer instance.\n * */\nBuffer.allocUnsafe = function (size) {\n  return allocUnsafe(null, size)\n}\n/**\n * Equivalent to SlowBuffer(num), by default creates a non-zero-filled Buffer instance.\n */\nBuffer.allocUnsafeSlow = function (size) {\n  return allocUnsafe(null, size)\n}\n\nfunction fromString (that, string, encoding) {\n  if (typeof encoding !== 'string' || encoding === '') {\n    encoding = 'utf8'\n  }\n\n  if (!Buffer.isEncoding(encoding)) {\n    throw new TypeError('\"encoding\" must be a valid string encoding')\n  }\n\n  var length = byteLength(string, encoding) | 0\n  that = createBuffer(that, length)\n\n  var actual = that.write(string, encoding)\n\n  if (actual !== length) {\n    // Writing a hex string, for example, that contains invalid characters will\n    // cause everything after the first invalid character to be ignored. (e.g.\n    // 'abxxcd' will be treated as 'ab')\n    that = that.slice(0, actual)\n  }\n\n  return that\n}\n\nfunction fromArrayLike (that, array) {\n  var length = array.length < 0 ? 0 : checked(array.length) | 0\n  that = createBuffer(that, length)\n  for (var i = 0; i < length; i += 1) {\n    that[i] = array[i] & 255\n  }\n  return that\n}\n\nfunction fromArrayBuffer (that, array, byteOffset, length) {\n  array.byteLength // this throws if `array` is not a valid ArrayBuffer\n\n  if (byteOffset < 0 || array.byteLength < byteOffset) {\n    throw new RangeError('\\'offset\\' is out of bounds')\n  }\n\n  if (array.byteLength < byteOffset + (length || 0)) {\n    throw new RangeError('\\'length\\' is out of bounds')\n  }\n\n  if (byteOffset === undefined && length === undefined) {\n    array = new Uint8Array(array)\n  } else if (length === undefined) {\n    array = new Uint8Array(array, byteOffset)\n  } else {\n    array = new Uint8Array(array, byteOffset, length)\n  }\n\n  if (Buffer.TYPED_ARRAY_SUPPORT) {\n    // Return an augmented `Uint8Array` instance, for best performance\n    that = array\n    that.__proto__ = Buffer.prototype\n  } else {\n    // Fallback: Return an object instance of the Buffer class\n    that = fromArrayLike(that, array)\n  }\n  return that\n}\n\nfunction fromObject (that, obj) {\n  if (Buffer.isBuffer(obj)) {\n    var len = checked(obj.length) | 0\n    that = createBuffer(that, len)\n\n    if (that.length === 0) {\n      return that\n    }\n\n    obj.copy(that, 0, 0, len)\n    return that\n  }\n\n  if (obj) {\n    if ((typeof ArrayBuffer !== 'undefined' &&\n        obj.buffer instanceof ArrayBuffer) || 'length' in obj) {\n      if (typeof obj.length !== 'number' || isnan(obj.length)) {\n        return createBuffer(that, 0)\n      }\n      return fromArrayLike(that, obj)\n    }\n\n    if (obj.type === 'Buffer' && isArray(obj.data)) {\n      return fromArrayLike(that, obj.data)\n    }\n  }\n\n  throw new TypeError('First argument must be a string, Buffer, ArrayBuffer, Array, or array-like object.')\n}\n\nfunction checked (length) {\n  // Note: cannot use `length < kMaxLength()` here because that fails when\n  // length is NaN (which is otherwise coerced to zero.)\n  if (length >= kMaxLength()) {\n    throw new RangeError('Attempt to allocate Buffer larger than maximum ' +\n                         'size: 0x' + kMaxLength().toString(16) + ' bytes')\n  }\n  return length | 0\n}\n\nfunction SlowBuffer (length) {\n  if (+length != length) { // eslint-disable-line eqeqeq\n    length = 0\n  }\n  return Buffer.alloc(+length)\n}\n\nBuffer.isBuffer = function isBuffer (b) {\n  return !!(b != null && b._isBuffer)\n}\n\nBuffer.compare = function compare (a, b) {\n  if (!Buffer.isBuffer(a) || !Buffer.isBuffer(b)) {\n    throw new TypeError('Arguments must be Buffers')\n  }\n\n  if (a === b) return 0\n\n  var x = a.length\n  var y = b.length\n\n  for (var i = 0, len = Math.min(x, y); i < len; ++i) {\n    if (a[i] !== b[i]) {\n      x = a[i]\n      y = b[i]\n      break\n    }\n  }\n\n  if (x < y) return -1\n  if (y < x) return 1\n  return 0\n}\n\nBuffer.isEncoding = function isEncoding (encoding) {\n  switch (String(encoding).toLowerCase()) {\n    case 'hex':\n    case 'utf8':\n    case 'utf-8':\n    case 'ascii':\n    case 'latin1':\n    case 'binary':\n    case 'base64':\n    case 'ucs2':\n    case 'ucs-2':\n    case 'utf16le':\n    case 'utf-16le':\n      return true\n    default:\n      return false\n  }\n}\n\nBuffer.concat = function concat (list, length) {\n  if (!isArray(list)) {\n    throw new TypeError('\"list\" argument must be an Array of Buffers')\n  }\n\n  if (list.length === 0) {\n    return Buffer.alloc(0)\n  }\n\n  var i\n  if (length === undefined) {\n    length = 0\n    for (i = 0; i < list.length; ++i) {\n      length += list[i].length\n    }\n  }\n\n  var buffer = Buffer.allocUnsafe(length)\n  var pos = 0\n  for (i = 0; i < list.length; ++i) {\n    var buf = list[i]\n    if (!Buffer.isBuffer(buf)) {\n      throw new TypeError('\"list\" argument must be an Array of Buffers')\n    }\n    buf.copy(buffer, pos)\n    pos += buf.length\n  }\n  return buffer\n}\n\nfunction byteLength (string, encoding) {\n  if (Buffer.isBuffer(string)) {\n    return string.length\n  }\n  if (typeof ArrayBuffer !== 'undefined' && typeof ArrayBuffer.isView === 'function' &&\n      (ArrayBuffer.isView(string) || string instanceof ArrayBuffer)) {\n    return string.byteLength\n  }\n  if (typeof string !== 'string') {\n    string = '' + string\n  }\n\n  var len = string.length\n  if (len === 0) return 0\n\n  // Use a for loop to avoid recursion\n  var loweredCase = false\n  for (;;) {\n    switch (encoding) {\n      case 'ascii':\n      case 'latin1':\n      case 'binary':\n        return len\n      case 'utf8':\n      case 'utf-8':\n      case undefined:\n        return utf8ToBytes(string).length\n      case 'ucs2':\n      case 'ucs-2':\n      case 'utf16le':\n      case 'utf-16le':\n        return len * 2\n      case 'hex':\n        return len >>> 1\n      case 'base64':\n        return base64ToBytes(string).length\n      default:\n        if (loweredCase) return utf8ToBytes(string).length // assume utf8\n        encoding = ('' + encoding).toLowerCase()\n        loweredCase = true\n    }\n  }\n}\nBuffer.byteLength = byteLength\n\nfunction slowToString (encoding, start, end) {\n  var loweredCase = false\n\n  // No need to verify that \"this.length <= MAX_UINT32\" since it's a read-only\n  // property of a typed array.\n\n  // This behaves neither like String nor Uint8Array in that we set start/end\n  // to their upper/lower bounds if the value passed is out of range.\n  // undefined is handled specially as per ECMA-262 6th Edition,\n  // Section 13.3.3.7 Runtime Semantics: KeyedBindingInitialization.\n  if (start === undefined || start < 0) {\n    start = 0\n  }\n  // Return early if start > this.length. Done here to prevent potential uint32\n  // coercion fail below.\n  if (start > this.length) {\n    return ''\n  }\n\n  if (end === undefined || end > this.length) {\n    end = this.length\n  }\n\n  if (end <= 0) {\n    return ''\n  }\n\n  // Force coersion to uint32. This will also coerce falsey/NaN values to 0.\n  end >>>= 0\n  start >>>= 0\n\n  if (end <= start) {\n    return ''\n  }\n\n  if (!encoding) encoding = 'utf8'\n\n  while (true) {\n    switch (encoding) {\n      case 'hex':\n        return hexSlice(this, start, end)\n\n      case 'utf8':\n      case 'utf-8':\n        return utf8Slice(this, start, end)\n\n      case 'ascii':\n        return asciiSlice(this, start, end)\n\n      case 'latin1':\n      case 'binary':\n        return latin1Slice(this, start, end)\n\n      case 'base64':\n        return base64Slice(this, start, end)\n\n      case 'ucs2':\n      case 'ucs-2':\n      case 'utf16le':\n      case 'utf-16le':\n        return utf16leSlice(this, start, end)\n\n      default:\n        if (loweredCase) throw new TypeError('Unknown encoding: ' + encoding)\n        encoding = (encoding + '').toLowerCase()\n        loweredCase = true\n    }\n  }\n}\n\n// The property is used by `Buffer.isBuffer` and `is-buffer` (in Safari 5-7) to detect\n// Buffer instances.\nBuffer.prototype._isBuffer = true\n\nfunction swap (b, n, m) {\n  var i = b[n]\n  b[n] = b[m]\n  b[m] = i\n}\n\nBuffer.prototype.swap16 = function swap16 () {\n  var len = this.length\n  if (len % 2 !== 0) {\n    throw new RangeError('Buffer size must be a multiple of 16-bits')\n  }\n  for (var i = 0; i < len; i += 2) {\n    swap(this, i, i + 1)\n  }\n  return this\n}\n\nBuffer.prototype.swap32 = function swap32 () {\n  var len = this.length\n  if (len % 4 !== 0) {\n    throw new RangeError('Buffer size must be a multiple of 32-bits')\n  }\n  for (var i = 0; i < len; i += 4) {\n    swap(this, i, i + 3)\n    swap(this, i + 1, i + 2)\n  }\n  return this\n}\n\nBuffer.prototype.swap64 = function swap64 () {\n  var len = this.length\n  if (len % 8 !== 0) {\n    throw new RangeError('Buffer size must be a multiple of 64-bits')\n  }\n  for (var i = 0; i < len; i += 8) {\n    swap(this, i, i + 7)\n    swap(this, i + 1, i + 6)\n    swap(this, i + 2, i + 5)\n    swap(this, i + 3, i + 4)\n  }\n  return this\n}\n\nBuffer.prototype.toString = function toString () {\n  var length = this.length | 0\n  if (length === 0) return ''\n  if (arguments.length === 0) return utf8Slice(this, 0, length)\n  return slowToString.apply(this, arguments)\n}\n\nBuffer.prototype.equals = function equals (b) {\n  if (!Buffer.isBuffer(b)) throw new TypeError('Argument must be a Buffer')\n  if (this === b) return true\n  return Buffer.compare(this, b) === 0\n}\n\nBuffer.prototype.inspect = function inspect () {\n  var str = ''\n  var max = exports.INSPECT_MAX_BYTES\n  if (this.length > 0) {\n    str = this.toString('hex', 0, max).match(/.{2}/g).join(' ')\n    if (this.length > max) str += ' ... '\n  }\n  return '<Buffer ' + str + '>'\n}\n\nBuffer.prototype.compare = function compare (target, start, end, thisStart, thisEnd) {\n  if (!Buffer.isBuffer(target)) {\n    throw new TypeError('Argument must be a Buffer')\n  }\n\n  if (start === undefined) {\n    start = 0\n  }\n  if (end === undefined) {\n    end = target ? target.length : 0\n  }\n  if (thisStart === undefined) {\n    thisStart = 0\n  }\n  if (thisEnd === undefined) {\n    thisEnd = this.length\n  }\n\n  if (start < 0 || end > target.length || thisStart < 0 || thisEnd > this.length) {\n    throw new RangeError('out of range index')\n  }\n\n  if (thisStart >= thisEnd && start >= end) {\n    return 0\n  }\n  if (thisStart >= thisEnd) {\n    return -1\n  }\n  if (start >= end) {\n    return 1\n  }\n\n  start >>>= 0\n  end >>>= 0\n  thisStart >>>= 0\n  thisEnd >>>= 0\n\n  if (this === target) return 0\n\n  var x = thisEnd - thisStart\n  var y = end - start\n  var len = Math.min(x, y)\n\n  var thisCopy = this.slice(thisStart, thisEnd)\n  var targetCopy = target.slice(start, end)\n\n  for (var i = 0; i < len; ++i) {\n    if (thisCopy[i] !== targetCopy[i]) {\n      x = thisCopy[i]\n      y = targetCopy[i]\n      break\n    }\n  }\n\n  if (x < y) return -1\n  if (y < x) return 1\n  return 0\n}\n\n// Finds either the first index of `val` in `buffer` at offset >= `byteOffset`,\n// OR the last index of `val` in `buffer` at offset <= `byteOffset`.\n//\n// Arguments:\n// - buffer - a Buffer to search\n// - val - a string, Buffer, or number\n// - byteOffset - an index into `buffer`; will be clamped to an int32\n// - encoding - an optional encoding, relevant is val is a string\n// - dir - true for indexOf, false for lastIndexOf\nfunction bidirectionalIndexOf (buffer, val, byteOffset, encoding, dir) {\n  // Empty buffer means no match\n  if (buffer.length === 0) return -1\n\n  // Normalize byteOffset\n  if (typeof byteOffset === 'string') {\n    encoding = byteOffset\n    byteOffset = 0\n  } else if (byteOffset > 0x7fffffff) {\n    byteOffset = 0x7fffffff\n  } else if (byteOffset < -0x80000000) {\n    byteOffset = -0x80000000\n  }\n  byteOffset = +byteOffset  // Coerce to Number.\n  if (isNaN(byteOffset)) {\n    // byteOffset: it it's undefined, null, NaN, \"foo\", etc, search whole buffer\n    byteOffset = dir ? 0 : (buffer.length - 1)\n  }\n\n  // Normalize byteOffset: negative offsets start from the end of the buffer\n  if (byteOffset < 0) byteOffset = buffer.length + byteOffset\n  if (byteOffset >= buffer.length) {\n    if (dir) return -1\n    else byteOffset = buffer.length - 1\n  } else if (byteOffset < 0) {\n    if (dir) byteOffset = 0\n    else return -1\n  }\n\n  // Normalize val\n  if (typeof val === 'string') {\n    val = Buffer.from(val, encoding)\n  }\n\n  // Finally, search either indexOf (if dir is true) or lastIndexOf\n  if (Buffer.isBuffer(val)) {\n    // Special case: looking for empty string/buffer always fails\n    if (val.length === 0) {\n      return -1\n    }\n    return arrayIndexOf(buffer, val, byteOffset, encoding, dir)\n  } else if (typeof val === 'number') {\n    val = val & 0xFF // Search for a byte value [0-255]\n    if (Buffer.TYPED_ARRAY_SUPPORT &&\n        typeof Uint8Array.prototype.indexOf === 'function') {\n      if (dir) {\n        return Uint8Array.prototype.indexOf.call(buffer, val, byteOffset)\n      } else {\n        return Uint8Array.prototype.lastIndexOf.call(buffer, val, byteOffset)\n      }\n    }\n    return arrayIndexOf(buffer, [ val ], byteOffset, encoding, dir)\n  }\n\n  throw new TypeError('val must be string, number or Buffer')\n}\n\nfunction arrayIndexOf (arr, val, byteOffset, encoding, dir) {\n  var indexSize = 1\n  var arrLength = arr.length\n  var valLength = val.length\n\n  if (encoding !== undefined) {\n    encoding = String(encoding).toLowerCase()\n    if (encoding === 'ucs2' || encoding === 'ucs-2' ||\n        encoding === 'utf16le' || encoding === 'utf-16le') {\n      if (arr.length < 2 || val.length < 2) {\n        return -1\n      }\n      indexSize = 2\n      arrLength /= 2\n      valLength /= 2\n      byteOffset /= 2\n    }\n  }\n\n  function read (buf, i) {\n    if (indexSize === 1) {\n      return buf[i]\n    } else {\n      return buf.readUInt16BE(i * indexSize)\n    }\n  }\n\n  var i\n  if (dir) {\n    var foundIndex = -1\n    for (i = byteOffset; i < arrLength; i++) {\n      if (read(arr, i) === read(val, foundIndex === -1 ? 0 : i - foundIndex)) {\n        if (foundIndex === -1) foundIndex = i\n        if (i - foundIndex + 1 === valLength) return foundIndex * indexSize\n      } else {\n        if (foundIndex !== -1) i -= i - foundIndex\n        foundIndex = -1\n      }\n    }\n  } else {\n    if (byteOffset + valLength > arrLength) byteOffset = arrLength - valLength\n    for (i = byteOffset; i >= 0; i--) {\n      var found = true\n      for (var j = 0; j < valLength; j++) {\n        if (read(arr, i + j) !== read(val, j)) {\n          found = false\n          break\n        }\n      }\n      if (found) return i\n    }\n  }\n\n  return -1\n}\n\nBuffer.prototype.includes = function includes (val, byteOffset, encoding) {\n  return this.indexOf(val, byteOffset, encoding) !== -1\n}\n\nBuffer.prototype.indexOf = function indexOf (val, byteOffset, encoding) {\n  return bidirectionalIndexOf(this, val, byteOffset, encoding, true)\n}\n\nBuffer.prototype.lastIndexOf = function lastIndexOf (val, byteOffset, encoding) {\n  return bidirectionalIndexOf(this, val, byteOffset, encoding, false)\n}\n\nfunction hexWrite (buf, string, offset, length) {\n  offset = Number(offset) || 0\n  var remaining = buf.length - offset\n  if (!length) {\n    length = remaining\n  } else {\n    length = Number(length)\n    if (length > remaining) {\n      length = remaining\n    }\n  }\n\n  // must be an even number of digits\n  var strLen = string.length\n  if (strLen % 2 !== 0) throw new TypeError('Invalid hex string')\n\n  if (length > strLen / 2) {\n    length = strLen / 2\n  }\n  for (var i = 0; i < length; ++i) {\n    var parsed = parseInt(string.substr(i * 2, 2), 16)\n    if (isNaN(parsed)) return i\n    buf[offset + i] = parsed\n  }\n  return i\n}\n\nfunction utf8Write (buf, string, offset, length) {\n  return blitBuffer(utf8ToBytes(string, buf.length - offset), buf, offset, length)\n}\n\nfunction asciiWrite (buf, string, offset, length) {\n  return blitBuffer(asciiToBytes(string), buf, offset, length)\n}\n\nfunction latin1Write (buf, string, offset, length) {\n  return asciiWrite(buf, string, offset, length)\n}\n\nfunction base64Write (buf, string, offset, length) {\n  return blitBuffer(base64ToBytes(string), buf, offset, length)\n}\n\nfunction ucs2Write (buf, string, offset, length) {\n  return blitBuffer(utf16leToBytes(string, buf.length - offset), buf, offset, length)\n}\n\nBuffer.prototype.write = function write (string, offset, length, encoding) {\n  // Buffer#write(string)\n  if (offset === undefined) {\n    encoding = 'utf8'\n    length = this.length\n    offset = 0\n  // Buffer#write(string, encoding)\n  } else if (length === undefined && typeof offset === 'string') {\n    encoding = offset\n    length = this.length\n    offset = 0\n  // Buffer#write(string, offset[, length][, encoding])\n  } else if (isFinite(offset)) {\n    offset = offset | 0\n    if (isFinite(length)) {\n      length = length | 0\n      if (encoding === undefined) encoding = 'utf8'\n    } else {\n      encoding = length\n      length = undefined\n    }\n  // legacy write(string, encoding, offset, length) - remove in v0.13\n  } else {\n    throw new Error(\n      'Buffer.write(string, encoding, offset[, length]) is no longer supported'\n    )\n  }\n\n  var remaining = this.length - offset\n  if (length === undefined || length > remaining) length = remaining\n\n  if ((string.length > 0 && (length < 0 || offset < 0)) || offset > this.length) {\n    throw new RangeError('Attempt to write outside buffer bounds')\n  }\n\n  if (!encoding) encoding = 'utf8'\n\n  var loweredCase = false\n  for (;;) {\n    switch (encoding) {\n      case 'hex':\n        return hexWrite(this, string, offset, length)\n\n      case 'utf8':\n      case 'utf-8':\n        return utf8Write(this, string, offset, length)\n\n      case 'ascii':\n        return asciiWrite(this, string, offset, length)\n\n      case 'latin1':\n      case 'binary':\n        return latin1Write(this, string, offset, length)\n\n      case 'base64':\n        // Warning: maxLength not taken into account in base64Write\n        return base64Write(this, string, offset, length)\n\n      case 'ucs2':\n      case 'ucs-2':\n      case 'utf16le':\n      case 'utf-16le':\n        return ucs2Write(this, string, offset, length)\n\n      default:\n        if (loweredCase) throw new TypeError('Unknown encoding: ' + encoding)\n        encoding = ('' + encoding).toLowerCase()\n        loweredCase = true\n    }\n  }\n}\n\nBuffer.prototype.toJSON = function toJSON () {\n  return {\n    type: 'Buffer',\n    data: Array.prototype.slice.call(this._arr || this, 0)\n  }\n}\n\nfunction base64Slice (buf, start, end) {\n  if (start === 0 && end === buf.length) {\n    return base64.fromByteArray(buf)\n  } else {\n    return base64.fromByteArray(buf.slice(start, end))\n  }\n}\n\nfunction utf8Slice (buf, start, end) {\n  end = Math.min(buf.length, end)\n  var res = []\n\n  var i = start\n  while (i < end) {\n    var firstByte = buf[i]\n    var codePoint = null\n    var bytesPerSequence = (firstByte > 0xEF) ? 4\n      : (firstByte > 0xDF) ? 3\n      : (firstByte > 0xBF) ? 2\n      : 1\n\n    if (i + bytesPerSequence <= end) {\n      var secondByte, thirdByte, fourthByte, tempCodePoint\n\n      switch (bytesPerSequence) {\n        case 1:\n          if (firstByte < 0x80) {\n            codePoint = firstByte\n          }\n          break\n        case 2:\n          secondByte = buf[i + 1]\n          if ((secondByte & 0xC0) === 0x80) {\n            tempCodePoint = (firstByte & 0x1F) << 0x6 | (secondByte & 0x3F)\n            if (tempCodePoint > 0x7F) {\n              codePoint = tempCodePoint\n            }\n          }\n          break\n        case 3:\n          secondByte = buf[i + 1]\n          thirdByte = buf[i + 2]\n          if ((secondByte & 0xC0) === 0x80 && (thirdByte & 0xC0) === 0x80) {\n            tempCodePoint = (firstByte & 0xF) << 0xC | (secondByte & 0x3F) << 0x6 | (thirdByte & 0x3F)\n            if (tempCodePoint > 0x7FF && (tempCodePoint < 0xD800 || tempCodePoint > 0xDFFF)) {\n              codePoint = tempCodePoint\n            }\n          }\n          break\n        case 4:\n          secondByte = buf[i + 1]\n          thirdByte = buf[i + 2]\n          fourthByte = buf[i + 3]\n          if ((secondByte & 0xC0) === 0x80 && (thirdByte & 0xC0) === 0x80 && (fourthByte & 0xC0) === 0x80) {\n            tempCodePoint = (firstByte & 0xF) << 0x12 | (secondByte & 0x3F) << 0xC | (thirdByte & 0x3F) << 0x6 | (fourthByte & 0x3F)\n            if (tempCodePoint > 0xFFFF && tempCodePoint < 0x110000) {\n              codePoint = tempCodePoint\n            }\n          }\n      }\n    }\n\n    if (codePoint === null) {\n      // we did not generate a valid codePoint so insert a\n      // replacement char (U+FFFD) and advance only 1 byte\n      codePoint = 0xFFFD\n      bytesPerSequence = 1\n    } else if (codePoint > 0xFFFF) {\n      // encode to utf16 (surrogate pair dance)\n      codePoint -= 0x10000\n      res.push(codePoint >>> 10 & 0x3FF | 0xD800)\n      codePoint = 0xDC00 | codePoint & 0x3FF\n    }\n\n    res.push(codePoint)\n    i += bytesPerSequence\n  }\n\n  return decodeCodePointsArray(res)\n}\n\n// Based on http://stackoverflow.com/a/22747272/680742, the browser with\n// the lowest limit is Chrome, with 0x10000 args.\n// We go 1 magnitude less, for safety\nvar MAX_ARGUMENTS_LENGTH = 0x1000\n\nfunction decodeCodePointsArray (codePoints) {\n  var len = codePoints.length\n  if (len <= MAX_ARGUMENTS_LENGTH) {\n    return String.fromCharCode.apply(String, codePoints) // avoid extra slice()\n  }\n\n  // Decode in chunks to avoid \"call stack size exceeded\".\n  var res = ''\n  var i = 0\n  while (i < len) {\n    res += String.fromCharCode.apply(\n      String,\n      codePoints.slice(i, i += MAX_ARGUMENTS_LENGTH)\n    )\n  }\n  return res\n}\n\nfunction asciiSlice (buf, start, end) {\n  var ret = ''\n  end = Math.min(buf.length, end)\n\n  for (var i = start; i < end; ++i) {\n    ret += String.fromCharCode(buf[i] & 0x7F)\n  }\n  return ret\n}\n\nfunction latin1Slice (buf, start, end) {\n  var ret = ''\n  end = Math.min(buf.length, end)\n\n  for (var i = start; i < end; ++i) {\n    ret += String.fromCharCode(buf[i])\n  }\n  return ret\n}\n\nfunction hexSlice (buf, start, end) {\n  var len = buf.length\n\n  if (!start || start < 0) start = 0\n  if (!end || end < 0 || end > len) end = len\n\n  var out = ''\n  for (var i = start; i < end; ++i) {\n    out += toHex(buf[i])\n  }\n  return out\n}\n\nfunction utf16leSlice (buf, start, end) {\n  var bytes = buf.slice(start, end)\n  var res = ''\n  for (var i = 0; i < bytes.length; i += 2) {\n    res += String.fromCharCode(bytes[i] + bytes[i + 1] * 256)\n  }\n  return res\n}\n\nBuffer.prototype.slice = function slice (start, end) {\n  var len = this.length\n  start = ~~start\n  end = end === undefined ? len : ~~end\n\n  if (start < 0) {\n    start += len\n    if (start < 0) start = 0\n  } else if (start > len) {\n    start = len\n  }\n\n  if (end < 0) {\n    end += len\n    if (end < 0) end = 0\n  } else if (end > len) {\n    end = len\n  }\n\n  if (end < start) end = start\n\n  var newBuf\n  if (Buffer.TYPED_ARRAY_SUPPORT) {\n    newBuf = this.subarray(start, end)\n    newBuf.__proto__ = Buffer.prototype\n  } else {\n    var sliceLen = end - start\n    newBuf = new Buffer(sliceLen, undefined)\n    for (var i = 0; i < sliceLen; ++i) {\n      newBuf[i] = this[i + start]\n    }\n  }\n\n  return newBuf\n}\n\n/*\n * Need to make sure that buffer isn't trying to write out of bounds.\n */\nfunction checkOffset (offset, ext, length) {\n  if ((offset % 1) !== 0 || offset < 0) throw new RangeError('offset is not uint')\n  if (offset + ext > length) throw new RangeError('Trying to access beyond buffer length')\n}\n\nBuffer.prototype.readUIntLE = function readUIntLE (offset, byteLength, noAssert) {\n  offset = offset | 0\n  byteLength = byteLength | 0\n  if (!noAssert) checkOffset(offset, byteLength, this.length)\n\n  var val = this[offset]\n  var mul = 1\n  var i = 0\n  while (++i < byteLength && (mul *= 0x100)) {\n    val += this[offset + i] * mul\n  }\n\n  return val\n}\n\nBuffer.prototype.readUIntBE = function readUIntBE (offset, byteLength, noAssert) {\n  offset = offset | 0\n  byteLength = byteLength | 0\n  if (!noAssert) {\n    checkOffset(offset, byteLength, this.length)\n  }\n\n  var val = this[offset + --byteLength]\n  var mul = 1\n  while (byteLength > 0 && (mul *= 0x100)) {\n    val += this[offset + --byteLength] * mul\n  }\n\n  return val\n}\n\nBuffer.prototype.readUInt8 = function readUInt8 (offset, noAssert) {\n  if (!noAssert) checkOffset(offset, 1, this.length)\n  return this[offset]\n}\n\nBuffer.prototype.readUInt16LE = function readUInt16LE (offset, noAssert) {\n  if (!noAssert) checkOffset(offset, 2, this.length)\n  return this[offset] | (this[offset + 1] << 8)\n}\n\nBuffer.prototype.readUInt16BE = function readUInt16BE (offset, noAssert) {\n  if (!noAssert) checkOffset(offset, 2, this.length)\n  return (this[offset] << 8) | this[offset + 1]\n}\n\nBuffer.prototype.readUInt32LE = function readUInt32LE (offset, noAssert) {\n  if (!noAssert) checkOffset(offset, 4, this.length)\n\n  return ((this[offset]) |\n      (this[offset + 1] << 8) |\n      (this[offset + 2] << 16)) +\n      (this[offset + 3] * 0x1000000)\n}\n\nBuffer.prototype.readUInt32BE = function readUInt32BE (offset, noAssert) {\n  if (!noAssert) checkOffset(offset, 4, this.length)\n\n  return (this[offset] * 0x1000000) +\n    ((this[offset + 1] << 16) |\n    (this[offset + 2] << 8) |\n    this[offset + 3])\n}\n\nBuffer.prototype.readIntLE = function readIntLE (offset, byteLength, noAssert) {\n  offset = offset | 0\n  byteLength = byteLength | 0\n  if (!noAssert) checkOffset(offset, byteLength, this.length)\n\n  var val = this[offset]\n  var mul = 1\n  var i = 0\n  while (++i < byteLength && (mul *= 0x100)) {\n    val += this[offset + i] * mul\n  }\n  mul *= 0x80\n\n  if (val >= mul) val -= Math.pow(2, 8 * byteLength)\n\n  return val\n}\n\nBuffer.prototype.readIntBE = function readIntBE (offset, byteLength, noAssert) {\n  offset = offset | 0\n  byteLength = byteLength | 0\n  if (!noAssert) checkOffset(offset, byteLength, this.length)\n\n  var i = byteLength\n  var mul = 1\n  var val = this[offset + --i]\n  while (i > 0 && (mul *= 0x100)) {\n    val += this[offset + --i] * mul\n  }\n  mul *= 0x80\n\n  if (val >= mul) val -= Math.pow(2, 8 * byteLength)\n\n  return val\n}\n\nBuffer.prototype.readInt8 = function readInt8 (offset, noAssert) {\n  if (!noAssert) checkOffset(offset, 1, this.length)\n  if (!(this[offset] & 0x80)) return (this[offset])\n  return ((0xff - this[offset] + 1) * -1)\n}\n\nBuffer.prototype.readInt16LE = function readInt16LE (offset, noAssert) {\n  if (!noAssert) checkOffset(offset, 2, this.length)\n  var val = this[offset] | (this[offset + 1] << 8)\n  return (val & 0x8000) ? val | 0xFFFF0000 : val\n}\n\nBuffer.prototype.readInt16BE = function readInt16BE (offset, noAssert) {\n  if (!noAssert) checkOffset(offset, 2, this.length)\n  var val = this[offset + 1] | (this[offset] << 8)\n  return (val & 0x8000) ? val | 0xFFFF0000 : val\n}\n\nBuffer.prototype.readInt32LE = function readInt32LE (offset, noAssert) {\n  if (!noAssert) checkOffset(offset, 4, this.length)\n\n  return (this[offset]) |\n    (this[offset + 1] << 8) |\n    (this[offset + 2] << 16) |\n    (this[offset + 3] << 24)\n}\n\nBuffer.prototype.readInt32BE = function readInt32BE (offset, noAssert) {\n  if (!noAssert) checkOffset(offset, 4, this.length)\n\n  return (this[offset] << 24) |\n    (this[offset + 1] << 16) |\n    (this[offset + 2] << 8) |\n    (this[offset + 3])\n}\n\nBuffer.prototype.readFloatLE = function readFloatLE (offset, noAssert) {\n  if (!noAssert) checkOffset(offset, 4, this.length)\n  return ieee754.read(this, offset, true, 23, 4)\n}\n\nBuffer.prototype.readFloatBE = function readFloatBE (offset, noAssert) {\n  if (!noAssert) checkOffset(offset, 4, this.length)\n  return ieee754.read(this, offset, false, 23, 4)\n}\n\nBuffer.prototype.readDoubleLE = function readDoubleLE (offset, noAssert) {\n  if (!noAssert) checkOffset(offset, 8, this.length)\n  return ieee754.read(this, offset, true, 52, 8)\n}\n\nBuffer.prototype.readDoubleBE = function readDoubleBE (offset, noAssert) {\n  if (!noAssert) checkOffset(offset, 8, this.length)\n  return ieee754.read(this, offset, false, 52, 8)\n}\n\nfunction checkInt (buf, value, offset, ext, max, min) {\n  if (!Buffer.isBuffer(buf)) throw new TypeError('\"buffer\" argument must be a Buffer instance')\n  if (value > max || value < min) throw new RangeError('\"value\" argument is out of bounds')\n  if (offset + ext > buf.length) throw new RangeError('Index out of range')\n}\n\nBuffer.prototype.writeUIntLE = function writeUIntLE (value, offset, byteLength, noAssert) {\n  value = +value\n  offset = offset | 0\n  byteLength = byteLength | 0\n  if (!noAssert) {\n    var maxBytes = Math.pow(2, 8 * byteLength) - 1\n    checkInt(this, value, offset, byteLength, maxBytes, 0)\n  }\n\n  var mul = 1\n  var i = 0\n  this[offset] = value & 0xFF\n  while (++i < byteLength && (mul *= 0x100)) {\n    this[offset + i] = (value / mul) & 0xFF\n  }\n\n  return offset + byteLength\n}\n\nBuffer.prototype.writeUIntBE = function writeUIntBE (value, offset, byteLength, noAssert) {\n  value = +value\n  offset = offset | 0\n  byteLength = byteLength | 0\n  if (!noAssert) {\n    var maxBytes = Math.pow(2, 8 * byteLength) - 1\n    checkInt(this, value, offset, byteLength, maxBytes, 0)\n  }\n\n  var i = byteLength - 1\n  var mul = 1\n  this[offset + i] = value & 0xFF\n  while (--i >= 0 && (mul *= 0x100)) {\n    this[offset + i] = (value / mul) & 0xFF\n  }\n\n  return offset + byteLength\n}\n\nBuffer.prototype.writeUInt8 = function writeUInt8 (value, offset, noAssert) {\n  value = +value\n  offset = offset | 0\n  if (!noAssert) checkInt(this, value, offset, 1, 0xff, 0)\n  if (!Buffer.TYPED_ARRAY_SUPPORT) value = Math.floor(value)\n  this[offset] = (value & 0xff)\n  return offset + 1\n}\n\nfunction objectWriteUInt16 (buf, value, offset, littleEndian) {\n  if (value < 0) value = 0xffff + value + 1\n  for (var i = 0, j = Math.min(buf.length - offset, 2); i < j; ++i) {\n    buf[offset + i] = (value & (0xff << (8 * (littleEndian ? i : 1 - i)))) >>>\n      (littleEndian ? i : 1 - i) * 8\n  }\n}\n\nBuffer.prototype.writeUInt16LE = function writeUInt16LE (value, offset, noAssert) {\n  value = +value\n  offset = offset | 0\n  if (!noAssert) checkInt(this, value, offset, 2, 0xffff, 0)\n  if (Buffer.TYPED_ARRAY_SUPPORT) {\n    this[offset] = (value & 0xff)\n    this[offset + 1] = (value >>> 8)\n  } else {\n    objectWriteUInt16(this, value, offset, true)\n  }\n  return offset + 2\n}\n\nBuffer.prototype.writeUInt16BE = function writeUInt16BE (value, offset, noAssert) {\n  value = +value\n  offset = offset | 0\n  if (!noAssert) checkInt(this, value, offset, 2, 0xffff, 0)\n  if (Buffer.TYPED_ARRAY_SUPPORT) {\n    this[offset] = (value >>> 8)\n    this[offset + 1] = (value & 0xff)\n  } else {\n    objectWriteUInt16(this, value, offset, false)\n  }\n  return offset + 2\n}\n\nfunction objectWriteUInt32 (buf, value, offset, littleEndian) {\n  if (value < 0) value = 0xffffffff + value + 1\n  for (var i = 0, j = Math.min(buf.length - offset, 4); i < j; ++i) {\n    buf[offset + i] = (value >>> (littleEndian ? i : 3 - i) * 8) & 0xff\n  }\n}\n\nBuffer.prototype.writeUInt32LE = function writeUInt32LE (value, offset, noAssert) {\n  value = +value\n  offset = offset | 0\n  if (!noAssert) checkInt(this, value, offset, 4, 0xffffffff, 0)\n  if (Buffer.TYPED_ARRAY_SUPPORT) {\n    this[offset + 3] = (value >>> 24)\n    this[offset + 2] = (value >>> 16)\n    this[offset + 1] = (value >>> 8)\n    this[offset] = (value & 0xff)\n  } else {\n    objectWriteUInt32(this, value, offset, true)\n  }\n  return offset + 4\n}\n\nBuffer.prototype.writeUInt32BE = function writeUInt32BE (value, offset, noAssert) {\n  value = +value\n  offset = offset | 0\n  if (!noAssert) checkInt(this, value, offset, 4, 0xffffffff, 0)\n  if (Buffer.TYPED_ARRAY_SUPPORT) {\n    this[offset] = (value >>> 24)\n    this[offset + 1] = (value >>> 16)\n    this[offset + 2] = (value >>> 8)\n    this[offset + 3] = (value & 0xff)\n  } else {\n    objectWriteUInt32(this, value, offset, false)\n  }\n  return offset + 4\n}\n\nBuffer.prototype.writeIntLE = function writeIntLE (value, offset, byteLength, noAssert) {\n  value = +value\n  offset = offset | 0\n  if (!noAssert) {\n    var limit = Math.pow(2, 8 * byteLength - 1)\n\n    checkInt(this, value, offset, byteLength, limit - 1, -limit)\n  }\n\n  var i = 0\n  var mul = 1\n  var sub = 0\n  this[offset] = value & 0xFF\n  while (++i < byteLength && (mul *= 0x100)) {\n    if (value < 0 && sub === 0 && this[offset + i - 1] !== 0) {\n      sub = 1\n    }\n    this[offset + i] = ((value / mul) >> 0) - sub & 0xFF\n  }\n\n  return offset + byteLength\n}\n\nBuffer.prototype.writeIntBE = function writeIntBE (value, offset, byteLength, noAssert) {\n  value = +value\n  offset = offset | 0\n  if (!noAssert) {\n    var limit = Math.pow(2, 8 * byteLength - 1)\n\n    checkInt(this, value, offset, byteLength, limit - 1, -limit)\n  }\n\n  var i = byteLength - 1\n  var mul = 1\n  var sub = 0\n  this[offset + i] = value & 0xFF\n  while (--i >= 0 && (mul *= 0x100)) {\n    if (value < 0 && sub === 0 && this[offset + i + 1] !== 0) {\n      sub = 1\n    }\n    this[offset + i] = ((value / mul) >> 0) - sub & 0xFF\n  }\n\n  return offset + byteLength\n}\n\nBuffer.prototype.writeInt8 = function writeInt8 (value, offset, noAssert) {\n  value = +value\n  offset = offset | 0\n  if (!noAssert) checkInt(this, value, offset, 1, 0x7f, -0x80)\n  if (!Buffer.TYPED_ARRAY_SUPPORT) value = Math.floor(value)\n  if (value < 0) value = 0xff + value + 1\n  this[offset] = (value & 0xff)\n  return offset + 1\n}\n\nBuffer.prototype.writeInt16LE = function writeInt16LE (value, offset, noAssert) {\n  value = +value\n  offset = offset | 0\n  if (!noAssert) checkInt(this, value, offset, 2, 0x7fff, -0x8000)\n  if (Buffer.TYPED_ARRAY_SUPPORT) {\n    this[offset] = (value & 0xff)\n    this[offset + 1] = (value >>> 8)\n  } else {\n    objectWriteUInt16(this, value, offset, true)\n  }\n  return offset + 2\n}\n\nBuffer.prototype.writeInt16BE = function writeInt16BE (value, offset, noAssert) {\n  value = +value\n  offset = offset | 0\n  if (!noAssert) checkInt(this, value, offset, 2, 0x7fff, -0x8000)\n  if (Buffer.TYPED_ARRAY_SUPPORT) {\n    this[offset] = (value >>> 8)\n    this[offset + 1] = (value & 0xff)\n  } else {\n    objectWriteUInt16(this, value, offset, false)\n  }\n  return offset + 2\n}\n\nBuffer.prototype.writeInt32LE = function writeInt32LE (value, offset, noAssert) {\n  value = +value\n  offset = offset | 0\n  if (!noAssert) checkInt(this, value, offset, 4, 0x7fffffff, -0x80000000)\n  if (Buffer.TYPED_ARRAY_SUPPORT) {\n    this[offset] = (value & 0xff)\n    this[offset + 1] = (value >>> 8)\n    this[offset + 2] = (value >>> 16)\n    this[offset + 3] = (value >>> 24)\n  } else {\n    objectWriteUInt32(this, value, offset, true)\n  }\n  return offset + 4\n}\n\nBuffer.prototype.writeInt32BE = function writeInt32BE (value, offset, noAssert) {\n  value = +value\n  offset = offset | 0\n  if (!noAssert) checkInt(this, value, offset, 4, 0x7fffffff, -0x80000000)\n  if (value < 0) value = 0xffffffff + value + 1\n  if (Buffer.TYPED_ARRAY_SUPPORT) {\n    this[offset] = (value >>> 24)\n    this[offset + 1] = (value >>> 16)\n    this[offset + 2] = (value >>> 8)\n    this[offset + 3] = (value & 0xff)\n  } else {\n    objectWriteUInt32(this, value, offset, false)\n  }\n  return offset + 4\n}\n\nfunction checkIEEE754 (buf, value, offset, ext, max, min) {\n  if (offset + ext > buf.length) throw new RangeError('Index out of range')\n  if (offset < 0) throw new RangeError('Index out of range')\n}\n\nfunction writeFloat (buf, value, offset, littleEndian, noAssert) {\n  if (!noAssert) {\n    checkIEEE754(buf, value, offset, 4, 3.4028234663852886e+38, -3.4028234663852886e+38)\n  }\n  ieee754.write(buf, value, offset, littleEndian, 23, 4)\n  return offset + 4\n}\n\nBuffer.prototype.writeFloatLE = function writeFloatLE (value, offset, noAssert) {\n  return writeFloat(this, value, offset, true, noAssert)\n}\n\nBuffer.prototype.writeFloatBE = function writeFloatBE (value, offset, noAssert) {\n  return writeFloat(this, value, offset, false, noAssert)\n}\n\nfunction writeDouble (buf, value, offset, littleEndian, noAssert) {\n  if (!noAssert) {\n    checkIEEE754(buf, value, offset, 8, 1.7976931348623157E+308, -1.7976931348623157E+308)\n  }\n  ieee754.write(buf, value, offset, littleEndian, 52, 8)\n  return offset + 8\n}\n\nBuffer.prototype.writeDoubleLE = function writeDoubleLE (value, offset, noAssert) {\n  return writeDouble(this, value, offset, true, noAssert)\n}\n\nBuffer.prototype.writeDoubleBE = function writeDoubleBE (value, offset, noAssert) {\n  return writeDouble(this, value, offset, false, noAssert)\n}\n\n// copy(targetBuffer, targetStart=0, sourceStart=0, sourceEnd=buffer.length)\nBuffer.prototype.copy = function copy (target, targetStart, start, end) {\n  if (!start) start = 0\n  if (!end && end !== 0) end = this.length\n  if (targetStart >= target.length) targetStart = target.length\n  if (!targetStart) targetStart = 0\n  if (end > 0 && end < start) end = start\n\n  // Copy 0 bytes; we're done\n  if (end === start) return 0\n  if (target.length === 0 || this.length === 0) return 0\n\n  // Fatal error conditions\n  if (targetStart < 0) {\n    throw new RangeError('targetStart out of bounds')\n  }\n  if (start < 0 || start >= this.length) throw new RangeError('sourceStart out of bounds')\n  if (end < 0) throw new RangeError('sourceEnd out of bounds')\n\n  // Are we oob?\n  if (end > this.length) end = this.length\n  if (target.length - targetStart < end - start) {\n    end = target.length - targetStart + start\n  }\n\n  var len = end - start\n  var i\n\n  if (this === target && start < targetStart && targetStart < end) {\n    // descending copy from end\n    for (i = len - 1; i >= 0; --i) {\n      target[i + targetStart] = this[i + start]\n    }\n  } else if (len < 1000 || !Buffer.TYPED_ARRAY_SUPPORT) {\n    // ascending copy from start\n    for (i = 0; i < len; ++i) {\n      target[i + targetStart] = this[i + start]\n    }\n  } else {\n    Uint8Array.prototype.set.call(\n      target,\n      this.subarray(start, start + len),\n      targetStart\n    )\n  }\n\n  return len\n}\n\n// Usage:\n//    buffer.fill(number[, offset[, end]])\n//    buffer.fill(buffer[, offset[, end]])\n//    buffer.fill(string[, offset[, end]][, encoding])\nBuffer.prototype.fill = function fill (val, start, end, encoding) {\n  // Handle string cases:\n  if (typeof val === 'string') {\n    if (typeof start === 'string') {\n      encoding = start\n      start = 0\n      end = this.length\n    } else if (typeof end === 'string') {\n      encoding = end\n      end = this.length\n    }\n    if (val.length === 1) {\n      var code = val.charCodeAt(0)\n      if (code < 256) {\n        val = code\n      }\n    }\n    if (encoding !== undefined && typeof encoding !== 'string') {\n      throw new TypeError('encoding must be a string')\n    }\n    if (typeof encoding === 'string' && !Buffer.isEncoding(encoding)) {\n      throw new TypeError('Unknown encoding: ' + encoding)\n    }\n  } else if (typeof val === 'number') {\n    val = val & 255\n  }\n\n  // Invalid ranges are not set to a default, so can range check early.\n  if (start < 0 || this.length < start || this.length < end) {\n    throw new RangeError('Out of range index')\n  }\n\n  if (end <= start) {\n    return this\n  }\n\n  start = start >>> 0\n  end = end === undefined ? this.length : end >>> 0\n\n  if (!val) val = 0\n\n  var i\n  if (typeof val === 'number') {\n    for (i = start; i < end; ++i) {\n      this[i] = val\n    }\n  } else {\n    var bytes = Buffer.isBuffer(val)\n      ? val\n      : utf8ToBytes(new Buffer(val, encoding).toString())\n    var len = bytes.length\n    for (i = 0; i < end - start; ++i) {\n      this[i + start] = bytes[i % len]\n    }\n  }\n\n  return this\n}\n\n// HELPER FUNCTIONS\n// ================\n\nvar INVALID_BASE64_RE = /[^+\\/0-9A-Za-z-_]/g\n\nfunction base64clean (str) {\n  // Node strips out invalid characters like \\n and \\t from the string, base64-js does not\n  str = stringtrim(str).replace(INVALID_BASE64_RE, '')\n  // Node converts strings with length < 2 to ''\n  if (str.length < 2) return ''\n  // Node allows for non-padded base64 strings (missing trailing ===), base64-js does not\n  while (str.length % 4 !== 0) {\n    str = str + '='\n  }\n  return str\n}\n\nfunction stringtrim (str) {\n  if (str.trim) return str.trim()\n  return str.replace(/^\\s+|\\s+$/g, '')\n}\n\nfunction toHex (n) {\n  if (n < 16) return '0' + n.toString(16)\n  return n.toString(16)\n}\n\nfunction utf8ToBytes (string, units) {\n  units = units || Infinity\n  var codePoint\n  var length = string.length\n  var leadSurrogate = null\n  var bytes = []\n\n  for (var i = 0; i < length; ++i) {\n    codePoint = string.charCodeAt(i)\n\n    // is surrogate component\n    if (codePoint > 0xD7FF && codePoint < 0xE000) {\n      // last char was a lead\n      if (!leadSurrogate) {\n        // no lead yet\n        if (codePoint > 0xDBFF) {\n          // unexpected trail\n          if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD)\n          continue\n        } else if (i + 1 === length) {\n          // unpaired lead\n          if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD)\n          continue\n        }\n\n        // valid lead\n        leadSurrogate = codePoint\n\n        continue\n      }\n\n      // 2 leads in a row\n      if (codePoint < 0xDC00) {\n        if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD)\n        leadSurrogate = codePoint\n        continue\n      }\n\n      // valid surrogate pair\n      codePoint = (leadSurrogate - 0xD800 << 10 | codePoint - 0xDC00) + 0x10000\n    } else if (leadSurrogate) {\n      // valid bmp char, but last char was a lead\n      if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD)\n    }\n\n    leadSurrogate = null\n\n    // encode utf8\n    if (codePoint < 0x80) {\n      if ((units -= 1) < 0) break\n      bytes.push(codePoint)\n    } else if (codePoint < 0x800) {\n      if ((units -= 2) < 0) break\n      bytes.push(\n        codePoint >> 0x6 | 0xC0,\n        codePoint & 0x3F | 0x80\n      )\n    } else if (codePoint < 0x10000) {\n      if ((units -= 3) < 0) break\n      bytes.push(\n        codePoint >> 0xC | 0xE0,\n        codePoint >> 0x6 & 0x3F | 0x80,\n        codePoint & 0x3F | 0x80\n      )\n    } else if (codePoint < 0x110000) {\n      if ((units -= 4) < 0) break\n      bytes.push(\n        codePoint >> 0x12 | 0xF0,\n        codePoint >> 0xC & 0x3F | 0x80,\n        codePoint >> 0x6 & 0x3F | 0x80,\n        codePoint & 0x3F | 0x80\n      )\n    } else {\n      throw new Error('Invalid code point')\n    }\n  }\n\n  return bytes\n}\n\nfunction asciiToBytes (str) {\n  var byteArray = []\n  for (var i = 0; i < str.length; ++i) {\n    // Node's code seems to be doing this and not & 0x7F..\n    byteArray.push(str.charCodeAt(i) & 0xFF)\n  }\n  return byteArray\n}\n\nfunction utf16leToBytes (str, units) {\n  var c, hi, lo\n  var byteArray = []\n  for (var i = 0; i < str.length; ++i) {\n    if ((units -= 2) < 0) break\n\n    c = str.charCodeAt(i)\n    hi = c >> 8\n    lo = c % 256\n    byteArray.push(lo)\n    byteArray.push(hi)\n  }\n\n  return byteArray\n}\n\nfunction base64ToBytes (str) {\n  return base64.toByteArray(base64clean(str))\n}\n\nfunction blitBuffer (src, dst, offset, length) {\n  for (var i = 0; i < length; ++i) {\n    if ((i + offset >= dst.length) || (i >= src.length)) break\n    dst[i + offset] = src[i]\n  }\n  return i\n}\n\nfunction isnan (val) {\n  return val !== val // eslint-disable-line no-self-compare\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// c:/Users/Antanas/Dropbox/am/Projects/typescript/amcharts4dev/node_modules/buffer/index.js\n// module id = Ul5o\n// module chunks = 71c9 bf3e","'use strict'\n\nexports.byteLength = byteLength\nexports.toByteArray = toByteArray\nexports.fromByteArray = fromByteArray\n\nvar lookup = []\nvar revLookup = []\nvar Arr = typeof Uint8Array !== 'undefined' ? Uint8Array : Array\n\nvar code = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'\nfor (var i = 0, len = code.length; i < len; ++i) {\n  lookup[i] = code[i]\n  revLookup[code.charCodeAt(i)] = i\n}\n\n// Support decoding URL-safe base64 strings, as Node.js does.\n// See: https://en.wikipedia.org/wiki/Base64#URL_applications\nrevLookup['-'.charCodeAt(0)] = 62\nrevLookup['_'.charCodeAt(0)] = 63\n\nfunction getLens (b64) {\n  var len = b64.length\n\n  if (len % 4 > 0) {\n    throw new Error('Invalid string. Length must be a multiple of 4')\n  }\n\n  // Trim off extra bytes after placeholder bytes are found\n  // See: https://github.com/beatgammit/base64-js/issues/42\n  var validLen = b64.indexOf('=')\n  if (validLen === -1) validLen = len\n\n  var placeHoldersLen = validLen === len\n    ? 0\n    : 4 - (validLen % 4)\n\n  return [validLen, placeHoldersLen]\n}\n\n// base64 is 4/3 + up to two characters of the original data\nfunction byteLength (b64) {\n  var lens = getLens(b64)\n  var validLen = lens[0]\n  var placeHoldersLen = lens[1]\n  return ((validLen + placeHoldersLen) * 3 / 4) - placeHoldersLen\n}\n\nfunction _byteLength (b64, validLen, placeHoldersLen) {\n  return ((validLen + placeHoldersLen) * 3 / 4) - placeHoldersLen\n}\n\nfunction toByteArray (b64) {\n  var tmp\n  var lens = getLens(b64)\n  var validLen = lens[0]\n  var placeHoldersLen = lens[1]\n\n  var arr = new Arr(_byteLength(b64, validLen, placeHoldersLen))\n\n  var curByte = 0\n\n  // if there are placeholders, only get up to the last complete 4 chars\n  var len = placeHoldersLen > 0\n    ? validLen - 4\n    : validLen\n\n  var i\n  for (i = 0; i < len; i += 4) {\n    tmp =\n      (revLookup[b64.charCodeAt(i)] << 18) |\n      (revLookup[b64.charCodeAt(i + 1)] << 12) |\n      (revLookup[b64.charCodeAt(i + 2)] << 6) |\n      revLookup[b64.charCodeAt(i + 3)]\n    arr[curByte++] = (tmp >> 16) & 0xFF\n    arr[curByte++] = (tmp >> 8) & 0xFF\n    arr[curByte++] = tmp & 0xFF\n  }\n\n  if (placeHoldersLen === 2) {\n    tmp =\n      (revLookup[b64.charCodeAt(i)] << 2) |\n      (revLookup[b64.charCodeAt(i + 1)] >> 4)\n    arr[curByte++] = tmp & 0xFF\n  }\n\n  if (placeHoldersLen === 1) {\n    tmp =\n      (revLookup[b64.charCodeAt(i)] << 10) |\n      (revLookup[b64.charCodeAt(i + 1)] << 4) |\n      (revLookup[b64.charCodeAt(i + 2)] >> 2)\n    arr[curByte++] = (tmp >> 8) & 0xFF\n    arr[curByte++] = tmp & 0xFF\n  }\n\n  return arr\n}\n\nfunction tripletToBase64 (num) {\n  return lookup[num >> 18 & 0x3F] +\n    lookup[num >> 12 & 0x3F] +\n    lookup[num >> 6 & 0x3F] +\n    lookup[num & 0x3F]\n}\n\nfunction encodeChunk (uint8, start, end) {\n  var tmp\n  var output = []\n  for (var i = start; i < end; i += 3) {\n    tmp =\n      ((uint8[i] << 16) & 0xFF0000) +\n      ((uint8[i + 1] << 8) & 0xFF00) +\n      (uint8[i + 2] & 0xFF)\n    output.push(tripletToBase64(tmp))\n  }\n  return output.join('')\n}\n\nfunction fromByteArray (uint8) {\n  var tmp\n  var len = uint8.length\n  var extraBytes = len % 3 // if we have 1 byte left, pad 2 bytes\n  var parts = []\n  var maxChunkLength = 16383 // must be multiple of 3\n\n  // go through the array every three bytes, we'll deal with trailing stuff later\n  for (var i = 0, len2 = len - extraBytes; i < len2; i += maxChunkLength) {\n    parts.push(encodeChunk(\n      uint8, i, (i + maxChunkLength) > len2 ? len2 : (i + maxChunkLength)\n    ))\n  }\n\n  // pad the end with zeros, but make sure to not forget the extra bytes\n  if (extraBytes === 1) {\n    tmp = uint8[len - 1]\n    parts.push(\n      lookup[tmp >> 2] +\n      lookup[(tmp << 4) & 0x3F] +\n      '=='\n    )\n  } else if (extraBytes === 2) {\n    tmp = (uint8[len - 2] << 8) + uint8[len - 1]\n    parts.push(\n      lookup[tmp >> 10] +\n      lookup[(tmp >> 4) & 0x3F] +\n      lookup[(tmp << 2) & 0x3F] +\n      '='\n    )\n  }\n\n  return parts.join('')\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// c:/Users/Antanas/Dropbox/am/Projects/typescript/amcharts4dev/node_modules/base64-js/index.js\n// module id = ZUfS\n// module chunks = 71c9 bf3e"],"sourceRoot":""}