{"version":3,"sources":["webpack:///./node_modules/fabric/dist/fabric.js"],"names":["global","sqrt","atan2","pow","PiBy180","PiBy2","couldUseAttachEvent","touchEvents","parseEl","supportsOpacity","supportsFilters","reOpacity","setOpacity","proto","min","max","degreesToRadians","originXOffset","originYOffset","clone","toFixed","multipleSpacesRegex","fabric","version","exports","document","window","HTMLDocument","Document","implementation","createHTMLDocument","virtualWindow","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","Buffer","SHARED_ATTRIBUTES","DPI","reNum","rePathCommand","reNonWord","fontPaths","iMatrix","svgNS","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","Observable","fire","options","listenersForEvent","i","len","length","call","filter","value","on","arguments","prop","push","off","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","_setObject","obj","_set","key","toggle","get","Math","PI","cos","angle","sin","sign","removeFromArray","idx","getRandomInt","floor","random","degrees","radiansToDegrees","radians","rotatePoint","point","origin","subtractEquals","v","rotateVector","Point","x","y","addEquals","vector","transformPoint","p","t","ignoreOffset","makeBoundingBoxFromPoints","points","transform","xPoints","minX","yPoints","minY","left","top","invertTransform","a","r","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","multiplyTransformMatrices","b","is2x2","qrDecompose","denom","scaleX","scaleY","skewX","skewY","translateX","translateY","calcRotateMatrix","theta","calcDimensionsMatrix","scaleMatrix","flipX","flipY","multiply","tan","composeMatrix","matrix","resetObjectTransform","target","saveObjectTransform","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","map","NUM_FRACTION_DIGITS","join","sizeAfterTransform","dimX","dimY","transformMatrix","bbox","_join","Array","commandLengths","m","h","c","s","q","repeatedCommands","M","segmentToBezier","th2","th3","cosTh","sinTh","rx","ry","cx1","cy1","mT","fromX","fromY","costh2","sinth2","costh3","sinth3","toX","toY","arcToSegments","large","sweep","rotateX","th","px","py","rx2","abs","ry2","py2","px2","pl","root","cx","cy","mTheta","calcVectorAngle","dtheta","segments","ceil","result","mDelta","ux","uy","vx","vy","ta","tb","getBoundsOfCurve","x0","y0","x1","y1","x3","y3","argsString","t1","t2","b2ac","sqrtb2ac","tvalues","bounds","mt","j","jlen","fromArcToBeizers","fx","fy","coords","segsNorm","calcLineLength","getPointOnCubicBezierIterator","p1x","p1y","p2x","p2y","p3x","p3y","p4x","p4y","pct","c1","c2","CB2","c3","CB3","c4","CB4","getPointOnQuadraticBezierIterator","QB2","QB3","pathIterator","iterator","perc","tempP","tmpLen","getPathSegmentsInfo","tempInfo","totalLength","info","command","destX","destY","parsePath","pathString","currentPath","parsed","match","coordsStr","re","coordsParsed","trim","isNaN","commandLength","repeatedCommand","k","klen","makePathSimpler","converted","previous","controlX","controlY","destinationPath","getPointOnPath","infos","distance","segInfo","segPercent","segment","lerp","getBoundsOfArc","tx","ty","bound","segs","drawArc","unshift","beizer","bezierCurveTo","find","byProperty","condition","invoke","method","args","value1","value2","extend","deep","Element","hasOwnProperty","getWholeChar","str","code","charCodeAt","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","attachEvent","addListener","element","addEventListener","removeListener","removeEventListener","getPointer","event","scroll","getScrollLeftTop","_evt","touchProp","changedTouches","getTouchInfo","clientX","clientY","isTouchEvent","pointerType","opacity","es","currentStyle","hasLayout","zoom","test","setStyle","styles","elementStyle","cssText","styleFloat","_slice","sliceCanConvertNodelists","getElementStyle","selectProp","toArray","arrayLike","childNodes","err","makeElement","tagName","el","className","htmlFor","setAttribute","docElement","documentElement","body","scrollLeft","scrollTop","host","nodeType","arr","defaultView","getComputedStyle","attr","undefined","makeElementUnselectable","onselectstart","unselectable","makeElementSelectable","setImageSmoothing","imageSmoothingEnabled","webkitImageSmoothingEnabled","mozImageSmoothingEnabled","msImageSmoothingEnabled","oImageSmoothingEnabled","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","onreadystatechange","readyState","param","addParamToUrl","open","setRequestHeader","send","warn","noop","defaultEasing","d","_requestAnimFrame","requestAnimationFrame","webkitRequestAnimationFrame","mozRequestAnimationFrame","oRequestAnimationFrame","msRequestAnimationFrame","setTimeout","_cancelAnimFrame","cancelAnimationFrame","clearTimeout","requestAnimFrame","animate","timestamp","time","start","Date","duration","finish","onChange","abort","easing","startValue","endValue","byValue","onStart","tick","ticktime","currentTime","timePerc","valuePerc","cancelAnimFrame","calculateColor","begin","end","pos","color","animateColor","fromColor","toColor","startColor","Color","getSource","endColor","originalOnComplete","originalOnChange","colorEasing","isArray","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","colorAttributes","stroke","normalizeAttr","normalizeValue","parentAttributes","parseTransformAttribute","visible","fillIndex","strokeIndex","getSvgRegex","RegExp","_getMultipleNodes","nodeNames","nodeName","nodeList","nodeArray","getElementsByTagName","elementMatchesRule","selectors","firstMatching","parentMatching","selectorMatches","selector","doesSomeParentMatch","matcher","classNames","getAttribute","elementById","node","nodelist","svgValidTagNamesRegEx","svgViewBoxElementsRegEx","svgInvalidAncestorsRegEx","svgValidParentsRegEx","cssRules","gradientDefs","clipPaths","skewMatrix","commaWsp","reTransformList","reTransform","attributeValue","matrices","operation","translateMatrix","rotateMatrix","multiplierX","multiplierY","combinedMatrix","reViewBoxAttrValue","applyViewboxTransform","viewBoxWidth","viewBoxHeight","viewBoxAttr","widthAttr","heightAttr","preserveAspectRatio","missingViewBox","missingDimAttr","toBeParsed","parsedDim","widthDiff","heightDiff","removeAttribute","createElementNS","firstChild","recursivelyParseGradientsXlink","gradient","referencedGradient","substr","hasAttribute","children","referenceClone","cloneNode","parseSVGDocument","parsingOptions","attrs","xlink","el2","currentTrans","oldLength","el3","setAttributeNS","nodeValue","parseUseDirectives","svgUid","__uid","descendants","selectNodes","hasAncestorWithNodeName","getGradientDefs","getCSSRules","parseElements","instances","reFontDeclaration","parseFontDeclaration","oStyle","fontStyle","fontWeight","lineHeight","elList","parseAttributes","parentFontSize","ownAttributes","cssAttrs","rule","getGlobalStylesForElement","parseStyleAttribute","normalizedAttr","normalizedValue","normalizedStyle","font","mergedAttrs","setAlpha","getAlpha","toRgba","_setStrokeFillOpacity","ElementsParser","parse","chunk","pair","parseStyleString","parseStyleObject","parsePointsAttribute","parsedPoints","allRules","styleContents","textContent","ruleObj","propertyValuePairs","_rule","loadSVGFromURL","xml","responseXML","results","_options","allElements","loadSVGFromString","parseFromString","regexUrl","numElements","createObjects","createObject","findTag","fromElement","createCallback","checkIfDone","resolveGradient","Image","_originalElement","_removeTransformMatrix","resolveClipPath","extractPropertyDefinition","storage","regex","lastIndex","gradientDef","opacityAttr","createClipPathCallback","container","_newObj","fillRule","clipRule","usingElement","objTransformInv","gTransform","clipPath","calcTransformMatrix","clipPathTag","clipPathOwner","setPositionByOrigin","that","scalarAdd","scalar","scalarAddEquals","subtract","scalarSubtract","scalarSubtractEquals","multiplyEquals","divide","divideEquals","eq","lt","lte","gt","gte","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","colorNameMap","sourceFromHex","sourceFromRgb","sourceFromHsl","_rgbToHsl","g","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","scaleMap","skewMap","controls","LEFT","TOP","opposite","bottom","right","center","findCornerQuadrant","fabricObject","control","cornerAngle","fireEvent","canasOptions","assign","scaleIsProportional","eventData","uniformIsToggled","uniScaleKey","uniformScaling","isTransformCentered","originX","originY","scalingIsForbidden","by","scaleProportionally","lockX","lockScalingX","lockY","lockScalingY","commonEventInfo","e","pointer","wrapWithFixedAnchor","actionHandler","getCenterPoint","constraint","translateToOriginPoint","actionPerformed","getLocalPoint","corner","getZoom","padding","localPoint","toLocalPoint","offsetX","offsetY","targetHasOneFlip","compensateScaleForSkew","oppositeSkew","scaleToCompoensate","axis","reference","newValue","_getTransformedDimensions","skewObjectX","newSkew","dimNoSkew","totalSkewSize","currentSkew","hasSkewed","dimBeforeSkewing","skewObjectY","scaleObject","newPoint","dim","signX","signY","forbidScaling","gestureScale","lockScalingFlip","hasScaled","original","oldScaleX","oldScaleY","scaleCursorStyleHandler","n","skewCursorStyleHandler","lockSkewingY","lockSkewingX","scaleSkewCursorStyleHandler","altActionKey","rotationWithSnapping","pivotPoint","lockRotation","hasRotated","lastAngle","ey","ex","curAngle","snapAngle","snapThreshold","rightAngleLocked","leftAngleLocked","scalingEqually","scalingX","scalingY","scalingYOrSkewingX","skewHandlerX","scalingXOrSkewingY","skewHandlerY","changeWidth","strokePadding","strokeWidth","strokeUniform","multiplier","newWidth","finalHandler","scaleOrSkewActionName","isAlternative","rotationStyleHandler","cursorStyle","controlsUtils","renderCircleControl","styleOverride","cornerSize","transparentCorners","cornerStrokeColor","fillStyle","cornerColor","strokeStyle","lineWidth","beginPath","arc","renderSquareControl","sizeBy2","strokeCornerColor","strokeRect","Control","actionName","withConnection","mouseDownHandler","mouseUpHandler","getActionHandler","getMouseDownHandler","getMouseUpHandler","cursorStyleHandler","getActionName","getVisibility","controlKey","objectVisibility","_controlsVisibility","setVisibility","positionHandler","finalMatrix","render","cornerStyle","getColorStop","colorAlpha","keyValuePairs","gradientTransform","gradientUnits","keys","option","addColorStop","toObject","propertiesToInclude","toSVG","markup","commonAttributes","needsSwap","withViewport","additionalTransform","sort","pathOffset","reverse","minRadius","percentageShift","colorStop","toLive","createLinearGradient","createRadialGradient","instance","svgOptions","colorStopEls","getLinearCoords","getRadialCoords","propValue","finalValue","__convertPercentUnitsToValues","repeat","patternTransform","setOptions","isError","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","viewportTransform","backgroundVpt","overlayVpt","enableRetinaScaling","vptCoords","skipOffscreen","cb","_createLowerCanvas","_initOptions","interactive","_initRetinaScaling","setOverlayImage","setBackgroundImage","setBackgroundColor","setOverlayColor","calcOffset","_isRetinaScaling","getRetinaScaling","scaleRatio","__initRetinaScaling","lowerCanvasEl","contextContainer","upperCanvasEl","contextTop","_offset","image","__setBgOverlayImage","__setBgOverlayColor","_createCanvasElement","_applyCanvasStyle","getWidth","getHeight","setWidth","setDimensions","setHeight","dimensions","cssValue","cssOnly","_setBackstoreDimension","hasLostContext","backstoreOnly","_setCssDimension","_isCurrentlyDrawing","freeDrawingBrush","_setBrushStyles","cacheCanvasEl","wrapperEl","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","_renderBackgroundOrOverlay","needsVpt","lineTo","closePath","getCenter","centerObjectH","_centerObject","centerObjectV","centerObject","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","bringToFront","sendBackwards","intersecting","newIdx","objsMoved","_findNewLowerIndex","intersectsWithObject","isContainedWithinObject","bringForward","_findNewUpperIndex","dispose","DataURLExporter","EMPTY_JSON","supports","setLineDash","toJSON","createPNGStream","createJPEGStream","BaseBrush","strokeLineCap","strokeLineJoin","strokeMiterLimit","strokeDashArray","lineCap","miterLimit","lineJoin","_saveAndTransform","_setShadow","shadowColor","shadowBlur","shadowOffsetX","shadowOffsetY","needsFullRender","_resetShadow","PencilBrush","decimate","_points","_drawSegment","p1","p2","midPoint","quadraticCurveTo","onMouseDown","_isMainEvent","_prepareForDrawing","_captureDrawingPath","_render","onMouseMove","oldEnd","onMouseUp","_finalizeAndAddPath","_reset","_addPoint","pointerPoint","convertPointsToSVGPath","multSignX","multSignY","manyPoints","createPath","pathData","Path","decimatePoints","adjustedDistance","lastPoint","newPoints","CircleBrush","drawDot","addPoint","dot","radius","originalRenderOnAddRemove","circles","circle","Circle","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","String","getPattern","topLeft","_getLeftTopCoords","_getPointer","supportLineDash","_initInteractive","_createCacheCanvas","centeredScaling","centeredRotation","centeredKey","selection","selectionKey","altSelectionKey","selectionColor","selectionDashArray","selectionBorderColor","selectionLineWidth","selectionFullyContained","hoverCursor","moveCursor","defaultCursor","freeDrawingCursor","rotationCursor","notAllowedCursor","containerClass","perPixelTargetFind","targetFindTolerance","skipTargetFind","isDrawingMode","preserveObjectStacking","stopContextMenu","fireRightClick","fireMiddleClick","targets","_hoveredTarget","_hoveredTargets","_currentTransform","_groupSelector","_initWrapperElement","_createUpperCanvas","_initEventListeners","_chooseObjectsToRender","objsToRender","activeGroupObjects","activeObjects","getActiveObjects","contextTopDirty","renderTopLayer","_drawSelection","renderTop","_normalizePointer","invertedM","vptPointer","restorePointerVpt","isTargetTransparent","normalizedPointer","targetRelativeX","targetRelativeY","_cacheContext","contextCache","originalColor","selectionBackgroundColor","_renderControls","hasBorders","_isSelectionKeyPressed","_shouldClearSelection","evented","selectable","_shouldCenterTransform","action","altKey","centerTransform","_getOriginFromCorner","_getActionFromCorner","alreadySelected","_setupCurrentTransform","__corner","lastX","lastY","shiftKey","_beforeTransform","_translateObject","newLeft","newTop","moveX","moveY","setCursor","cursor","groupSelector","aleft","atop","_setLineDash","findTarget","skipGroup","activeTarget","activeTargetSubs","aObjects","isTouch","_searchPossibleTargets","_findTargetCorner","_checkTarget","globalPointer","containsPoint","isEditing","subTarget","objToCheck","pointerToUse","subTargetCheck","ignoreZoom","_absolutePointer","_pointer","cssScale","boundsWidth","boundsHeight","retinaScaling","lowerCanvasClass","_copyCanvasStyle","fromEl","toEl","getSelectionContext","getSelectionElement","getActiveObject","active","_discardActiveObject","_fireSelectionEvents","oldObjects","somethingChanged","added","removed","opt","oldObject","selected","deselected","updated","setActiveObject","currentActives","_setActiveObject","onSelect","onDeselect","discardActiveObject","removeListeners","originalProperties","_realizeGroupTransformOnObject","_unwindGroupTransformOnObject","originalValues","realizeTransform","clearContextTop","addEventOptions","passive","checkClick","button","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","_target","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","_onMouseUpInDrawingMode","_finalizeCurrentTransform","targetWasActive","_maybeGroupObjects","isMoving","_setCursorFromEvent","eventType","subTargets","absolutePointer","_scaling","hasStateChanged","_addEventOptions","_fire","_onMouseDownInDrawingMode","_onMouseMoveInDrawingMode","_previousPointer","shouldGroup","_shouldGroup","_handleGrouping","saveState","_transformObject","_fireOverOutEvents","fireSyntheticInOutEvents","oldTarget","evtOut","canvasEvtOut","evtIn","canvasEvtIn","_draggedoverTarget","config","inOpt","outOpt","inFires","targetChanged","previousTarget","nextTarget","reset","_performTransformAction","getCornerCursor","_updateActiveSelection","_createActiveSelection","currentActiveObjects","removeWithUpdate","addWithUpdate","_createGroup","groupObjects","exitEditing","ActiveSelection","_groupSelectedObjects","aGroup","_collectObjects","currentObject","selectionX1Y1","selectionX2Y2","allowIntersect","intersectsWithRect","isContainedWithinRect","toCanvasElement","cropping","scaledWidth","scaledHeight","originalWidth","originalHeight","newZoom","vp","originalInteractive","newVp","originalRetina","originalContextTop","loadFromJSON","json","serialized","JSON","_enlivenObjects","_setBgOverlay","enlivenedCanvasClip","__setupCanvas","loaded","cbIfLoaded","__setBgOverlay","enlivedObject","_toDataURL","_toDataURLWithMultiplier","toDataURLWithMultiplier","stringify","cloneWithoutData","backgroundImageOpacity","backgroundImageStretch","supportsLineDash","objectCaching","touchCornerSize","borderColor","borderDashArray","cornerDashArray","strokeDashOffset","borderOpacityWhenMoving","borderScaleFactor","minScaleLimit","hasControls","lockMovementX","lockMovementY","statefullCache","noScaleCache","dirty","paintFirst","stateProperties","cacheProperties","colorProperties","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","needFullTransform","_removeDefaultValues","getObjectScaling","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","drawBorders","forActiveSelection","drawBordersInGroup","scaling","multX","multY","_applyPatternGradientTransform","_renderPaintInOrder","_renderStroke","_renderFill","_renderDashedStroke","_applyPatternForTransformedGradient","pCtx","pCanvas","_findCenterFromElement","_assignTransformMatrixProps","preserveAspectRatioOptions","cropX","cropY","offsetLeft","offsetTop","objectForm","_fromObject","cloneAsImage","utils","origParams","originalGroup","originalShadow","withoutTransform","withoutShadow","boundingRect","getBoundingRect","shadowOffset","originalCanvas","isType","shouldCenterOrigin","_setOriginToCenter","_resetOrigin","centerH","viewportCenterH","centerV","viewportCenterV","viewportCenter","getLocalPointer","pClicked","objectLeftTop","createAccessors","extraParam","enlivedProps","translateToGivenOrigin","fromOriginX","fromOriginY","toOriginX","toOriginY","translateToCenterPoint","leftTop","getPointByOrigin","adjustPosition","to","offsetFrom","offsetTo","hypotFull","getScaledWidth","xFull","yFull","_originalOriginX","_originalOriginY","originPoint","multiplyMatrices","oCoords","aCoords","lineCoords","ownMatrixCache","matrixCache","_getCoords","absolute","calculate","calcACoords","calcLineCoords","getCoords","pointTL","pointBR","other","otherCoords","lines","_getImageLines","_findCrossPoints","some","_containsCenterOfCanvas","isPartiallyOnScreen","every","topline","rightline","bottomline","leftline","xi","iLine","xcount","lineKey","getScaledHeight","scaleToWidth","boundingRectFactor","scaleToHeight","calcCoords","calcOCoords","cosP","sinP","cosPSinP","cosPMinusSinP","_calcRotateMatrix","_calcTranslateMatrix","startMatrix","_calculateCurrentDimensions","forEachControl","w","skipCorners","_setCornerCoords","transformMatrixKey","prefix","calcOwnMatrix","cache","tMatrix","_calcDimensionsTransformMatrix","flipping","noSkew","_finalizeDimensions","getSvgColorString","getSvgStyles","skipShadow","getSvgFilter","getSvgSpanStyles","useWhiteSpace","textDecoration","getSvgTextDecoration","deltaY","decoration","getSvgCommons","getSvgTransform","full","_setSVGBg","textBgRects","_getFillAttributes","_createBaseSVGMarkup","_toSVG","_createBaseClipPathSVGMarkup","objectMarkup","commonPieces","clipPathMarkup","noStyle","styleInfo","shadowInfo","withShadow","vectorEffect","absoluteClipPath","addPaintOrder","saveProps","props","tmpObj","dashedPropertySet","_isEqual","origValue","currentValue","firstPass","forTouch","isControlVisible","touchCorner","fn","newTheta","cosTheta","sinTheta","cornerHypotenuse","touchHypotenuse","cosHalfOffset","sinHalfOffset","touchCosHalfOffset","touchSinHalfOffset","wh","shouldStroke","setControlVisible","setControlsVisibility","FX_DURATION","fxCenterObjectH","callbacks","empty","_onComplete","_onChange","fxCenterObjectV","_onComplete2","_onChange2","fxRemove","_onComplete3","_onChange3","skipCallbacks","propsToAnimate","_animate","propPair","propIsColor","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","Triangle","widthBy2","heightBy2","piBy2","Ellipse","getRx","getRy","_initRxRy","isRounded","Polyline","_setPositionDimensions","correctLeftTop","calcDim","_calcDimensions","fromSVG","diffX","diffY","commonRender","fromElementGenerator","_class","Polygon","_toString","fromArray","_renderPathCommands","subpathStartX","subpathStartY","_getOffsetTransform","digits","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","imageSmoothing","filters","_initElement","_element","setElement","removeTexture","_initConfig","applyFilters","resizeFilter","applyResizeFilters","backend","filterBackend","evictCachesForKey","getCrossOrigin","getOriginalSize","_stroke","filterObj","getSrc","hasCrop","strokeSvg","imageMarkup","imageRendering","getSvgSrc","origFill","filtered","setSrc","minimumScale","elementToFilter","_filteredEl","sourceWidth","sourceHeight","isNeutralState","imgElement","_needsResize","elementToDraw","elWidth","elHeight","sX","sY","sW","sH","maxDestW","maxDestH","_resetWidthHeight","CSS_CANVAS","_initFilters","pAR","rWidth","rHeight","pWidth","pHeight","_object","resizeFilters","fromURL","imgOptions","_getAngleValueForStraighten","straighten","fxStraighten","_onComplete4","_onChange4","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","HueRotation","rotation","rad","aThirdSqtSin","OneMinusCos","_dimensionAffectingProps","_reNewline","_reSpacesAndTabs","_reSpaceAndTab","_reWords","underline","overline","linethrough","textAlign","superscript","baseline","subscript","textBackgroundColor","_fontSizeFraction","_fontSizeMult","charSpacing","_measuringContext","_styleProperties","__charBounds","CACHE_FONT_SIZE","MIN_TEXT_WIDTH","text","__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","previousBox","__lineHeights","maxHeight","_renderTextCommon","lineHeights","isEmptyStyles","actualStyle","nextStyle","timeToRender","isJustify","charsToRender","shortCut","_renderChar","_hasStyleChanged","_getStyleDeclaration","fullDecl","shouldFill","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","0","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","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","isEndOfLine","numIndex","styleCarriedOver","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","doubleClickHandler","tripleClickHandler","_mouseDownHandler","setCursorByClick","_mouseDownHandlerBefore","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","removeFrom","removeTo","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","moveCursorRightWithShift","moveCursorRightWithoutShift","changed","removeChars","insertChars","_getSVGLeftTopOffsets","textAndBg","_getSVGTextAndBg","textTop","textLeft","_wrapSVGTextAndBg","lineTop","textSpans","textTopOffset","textLeftOffset","_setSVGTextLineBg","_setSVGTextLineText","_createTextCharSpan","styleDecl","shouldUseWhitespace","styleProps","fillStyles","dySpan","_pushTextBgRect","fillColor","_getSVGLineTopOffset","lastHeight","Textbox","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","getMinWidth","linesToKeep","scaleSkewStyleHandler","scaleStyleHandler","objectControls","ml","mr","mb","mtr","textBoxControls"],"mappings":"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","file":"43ea133b-fd8c3cd861a499deb177.js","sourcesContent":["/* build: `node build.js modules=ALL exclude=gestures,accessors requirejs minifier=uglifyjs` */\n\n/*! Fabric.js Copyright 2008-2015, Printio (Juriy Zaytsev, Maxim Chernyak) */\nvar fabric = fabric || {\n version: '4.1.0'\n};\n\nif (typeof exports !== 'undefined') {\n exports.fabric = fabric;\n}\n/* _AMD_START_ */\nelse if (typeof define === 'function' && define.amd) {\n define([], function () {\n return fabric;\n });\n }\n/* _AMD_END_ */\n\n\nif (typeof document !== 'undefined' && typeof window !== 'undefined') {\n if (document instanceof (typeof HTMLDocument !== 'undefined' ? HTMLDocument : Document)) {\n fabric.document = document;\n } else {\n fabric.document = document.implementation.createHTMLDocument('');\n }\n\n fabric.window = window;\n} else {\n // assume we're running under node.js when document/window are not present\n var jsdom = require('jsdom');\n\n var virtualWindow = new jsdom.JSDOM(decodeURIComponent('%3C!DOCTYPE%20html%3E%3Chtml%3E%3Chead%3E%3C%2Fhead%3E%3Cbody%3E%3C%2Fbody%3E%3C%2Fhtml%3E'), {\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 * True when in environment that supports touch events\n * @type boolean\n */\n\n\nfabric.isTouchSupported = 'ontouchstart' in fabric.window || 'ontouchstart' in fabric.document || fabric.window && fabric.window.navigator && fabric.window.navigator.maxTouchPoints > 0;\n/**\n * True when in environment that's probably Node.js\n * @type boolean\n */\n\nfabric.isLikelyNode = typeof Buffer !== 'undefined' && typeof window === 'undefined';\n/* _FROM_SVG_START_ */\n\n/**\n * Attributes parsed from all SVG elements\n * @type array\n */\n\nfabric.SHARED_ATTRIBUTES = ['display', 'transform', 'fill', 'fill-opacity', 'fill-rule', 'opacity', 'stroke', 'stroke-dasharray', 'stroke-linecap', 'stroke-dashoffset', 'stroke-linejoin', 'stroke-miterlimit', 'stroke-opacity', 'stroke-width', 'id', 'paint-order', 'vector-effect', 'instantiated_by_use', 'clip-path'];\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 */\n\nfabric.DPI = 96;\nfabric.reNum = '(?:[-+]?(?:\\\\d+|\\\\d*\\\\.\\\\d+)(?:[eE][-+]?\\\\d+)?)';\nfabric.rePathCommand = /([-+]?((\\d+\\.\\d+)|((\\d+)|(\\.\\d+)))(?:[eE][-+]?\\d+)?)/ig;\nfabric.reNonWord = /[ \\n\\.,;!\\?\\-]/;\nfabric.fontPaths = {};\nfabric.iMatrix = [1, 0, 0, 1, 0, 0];\nfabric.svgNS = 'http://www.w3.org/2000/svg';\n/**\n * Pixel limit for cache canvases. 1Mpx , 4Mpx should be fine.\n * @since 1.7.14\n * @type Number\n * @default\n */\n\nfabric.perfLimitSizeTotal = 2097152;\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 */\n\nfabric.maxCacheSideLimit = 4096;\n/**\n * Lowest pixel limit for cache canvases, set at 256PX\n * @since 1.7.14\n * @type Number\n * @default\n */\n\nfabric.minCacheSideLimit = 256;\n/**\n * Cache Object for widths of chars in text rendering.\n */\n\nfabric.charWidthsCache = {};\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 */\n\nfabric.textureSize = 2048;\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 */\n\nfabric.disableStyleCopyPaste = false;\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 */\n\nfabric.enableGLFiltering = true;\n/**\n * Device Pixel Ratio\n * @see https://developer.apple.com/library/safari/documentation/AudioVideo/Conceptual/HTML-canvas-guide/SettingUptheCanvas/SettingUptheCanvas.html\n */\n\nfabric.devicePixelRatio = fabric.window.devicePixelRatio || fabric.window.webkitDevicePixelRatio || fabric.window.mozDevicePixelRatio || 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 */\n\nfabric.browserShadowBlurConstant = 1;\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 */\n\nfabric.arcToSegmentsCache = {};\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 */\n\nfabric.boundsOfCurveCache = {};\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 */\n\nfabric.cachesBoundsOfCurve = true;\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 */\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({\n tileSize: fabric.textureSize\n });\n } else if (fabric.Canvas2dFilterBackend) {\n return new fabric.Canvas2dFilterBackend();\n }\n};\n\nif (typeof document !== 'undefined' && typeof window !== 'undefined') {\n // ensure globality even if entire library were function wrapped (as in Meteor.js packaging system)\n window.fabric = fabric;\n}\n\n(function () {\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\n var eventListener = this.__eventListeners[eventName];\n\n if (handler) {\n eventListener[eventListener.indexOf(handler)] = false;\n } else {\n fabric.util.array.fill(eventListener, false);\n }\n }\n /**\n * Observes specified event\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\n\n function on(eventName, handler) {\n if (!this.__eventListeners) {\n this.__eventListeners = {};\n } // one object with key/value pairs was passed\n\n\n if (arguments.length === 1) {\n for (var prop in eventName) {\n this.on(prop, eventName[prop]);\n }\n } else {\n if (!this.__eventListeners[eventName]) {\n this.__eventListeners[eventName] = [];\n }\n\n this.__eventListeners[eventName].push(handler);\n }\n\n return this;\n }\n /**\n * Stops event observing for a particular event handler. Calling this method\n * without arguments removes all handlers for all events\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\n\n function off(eventName, handler) {\n if (!this.__eventListeners) {\n return this;\n } // remove all key/value pairs (event name -> event handler)\n\n\n if (arguments.length === 0) {\n for (eventName in this.__eventListeners) {\n _removeEventListener.call(this, eventName);\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 } else {\n _removeEventListener.call(this, eventName, handler);\n }\n\n return this;\n }\n /**\n * Fires event with an optional options object\n * @memberOf fabric.Observable\n * @param {String} eventName Event name to fire\n * @param {Object} [options] Options object\n * @return {Self} thisArg\n * @chainable\n */\n\n\n function fire(eventName, options) {\n if (!this.__eventListeners) {\n return this;\n }\n\n var listenersForEvent = this.__eventListeners[eventName];\n\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\n this.__eventListeners[eventName] = listenersForEvent.filter(function (value) {\n return value !== false;\n });\n return this;\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\n\n fabric.Observable = {\n fire: fire,\n on: on,\n off: off\n };\n})();\n/**\n * @namespace fabric.Collection\n */\n\n\nfabric.Collection = {\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 add() {\n this._objects.push.apply(this._objects, arguments);\n\n if (this._onObjectAdded) {\n for (var i = 0, length = arguments.length; i < length; i++) {\n this._onObjectAdded(arguments[i]);\n }\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 insertAt(object, index, nonSplicing) {\n var objects = this._objects;\n\n if (nonSplicing) {\n objects[index] = object;\n } else {\n objects.splice(index, 0, object);\n }\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 remove() {\n var objects = this._objects,\n index,\n somethingRemoved = false;\n\n for (var i = 0, length = arguments.length; i < length; i++) {\n index = objects.indexOf(arguments[i]); // only call onObjectRemoved if an object was actually removed\n\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 forEachObject(callback, context) {\n var objects = this.getObjects();\n\n for (var i = 0, len = objects.length; i < len; i++) {\n callback.call(context, objects[i], i, objects);\n }\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 getObjects(type) {\n if (typeof type === 'undefined') {\n return this._objects.concat();\n }\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 item(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 isEmpty() {\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 size() {\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 contains(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 complexity() {\n return this._objects.reduce(function (memo, current) {\n memo += current.complexity ? current.complexity() : 0;\n return memo;\n }, 0);\n }\n};\n/**\n * @namespace fabric.CommonMethods\n */\n\nfabric.CommonMethods = {\n /**\n * Sets object's properties from options\n * @param {Object} [options] Options object\n */\n _setOptions: function _setOptions(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 _initGradient(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 _initPattern(filler, property, callback) {\n if (filler && filler.source && !(filler instanceof fabric.Pattern)) {\n this.set(property, new fabric.Pattern(filler, callback));\n } else {\n callback && callback();\n }\n },\n\n /**\n * @private\n */\n _setObject: function _setObject(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 set(key, value) {\n if (typeof key === 'object') {\n this._setObject(key);\n } else {\n this._set(key, value);\n }\n\n return this;\n },\n _set: function _set(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 toggle(property) {\n var value = this.get(property);\n\n if (typeof value === 'boolean') {\n this.set(property, !value);\n }\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 get(property) {\n return this[property];\n }\n};\n\n(function (global) {\n var sqrt = Math.sqrt,\n atan2 = Math.atan2,\n pow = Math.pow,\n PiBy180 = Math.PI / 180,\n PiBy2 = Math.PI / 2;\n /**\n * @namespace fabric.util\n */\n\n fabric.util = {\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 cos(angle) {\n if (angle === 0) {\n return 1;\n }\n\n if (angle < 0) {\n // cos(a) = cos(-a)\n angle = -angle;\n }\n\n var angleSlice = angle / PiBy2;\n\n switch (angleSlice) {\n case 1:\n case 3:\n return 0;\n\n case 2:\n return -1;\n }\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 sin(angle) {\n if (angle === 0) {\n return 0;\n }\n\n var angleSlice = angle / PiBy2,\n sign = 1;\n\n if (angle < 0) {\n // sin(-a) = -sin(a)\n sign = -1;\n }\n\n switch (angleSlice) {\n case 1:\n return sign;\n\n case 2:\n return 0;\n\n case 3:\n return -sign;\n }\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 removeFromArray(array, value) {\n var idx = array.indexOf(value);\n\n if (idx !== -1) {\n array.splice(idx, 1);\n }\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 getRandomInt(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 degreesToRadians(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 radiansToDegrees(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 rotatePoint(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 rotateVector(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 transformPoint(p, t, ignoreOffset) {\n if (ignoreOffset) {\n return new fabric.Point(t[0] * p.x + t[2] * p.y, t[1] * p.x + t[3] * p.y);\n }\n\n return new fabric.Point(t[0] * p.x + t[2] * p.y + t[4], t[1] * p.x + t[3] * p.y + t[5]);\n },\n\n /**\n * Returns coordinates of points's bounding rectangle (left, top, width, height)\n * @param {Array} points 4 points array\n * @param {Array} [transform] an array of 6 numbers representing a 2x3 transform matrix\n * @return {Object} Object with left, top, width, height properties\n */\n makeBoundingBoxFromPoints: function makeBoundingBoxFromPoints(points, transform) {\n if (transform) {\n for (var i = 0; i < points.length; i++) {\n points[i] = fabric.util.transformPoint(points[i], transform);\n }\n }\n\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 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 invertTransform(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({\n x: t[4],\n y: t[5]\n }, 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 toFixed(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 parseUnit(value, fontSize) {\n var unit = /\\D{0,2}$/.exec(value),\n number = parseFloat(value);\n\n if (!fontSize) {\n fontSize = fabric.Text.DEFAULT_SVG_FONT_SIZE;\n }\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;\n // or * 4 / 3\n\n case 'pc':\n return number * fabric.DPI / 72 * 12;\n // 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 falseFunction() {\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 getKlass(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 getSvgAttributes(type) {\n var attributes = ['instantiated_by_use', 'style', 'id', 'class'];\n\n switch (type) {\n case 'linearGradient':\n attributes = attributes.concat(['x1', 'y1', 'x2', 'y2', 'gradientUnits', 'gradientTransform']);\n break;\n\n case 'radialGradient':\n attributes = attributes.concat(['gradientUnits', 'gradientTransform', 'cx', 'cy', 'r', 'fx', 'fy', 'fr']);\n break;\n\n case 'stop':\n attributes = attributes.concat(['offset', 'stop-color', 'stop-opacity']);\n break;\n }\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 resolveNamespace(namespace) {\n if (!namespace) {\n return fabric;\n }\n\n var parts = namespace.split('.'),\n len = parts.length,\n 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 loadImage(url, callback, context, crossOrigin) {\n if (!url) {\n callback && callback.call(context, url);\n return;\n }\n\n var img = fabric.util.createImage();\n /** @ignore */\n\n var onLoadCallback = function onLoadCallback() {\n callback && callback.call(context, img, false);\n img = img.onload = img.onerror = null;\n };\n\n img.onload = onLoadCallback;\n /** @ignore */\n\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 }; // 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 // crossOrigin null is the same as not set.\n\n\n if (url.indexOf('data') !== 0 && crossOrigin !== undefined && crossOrigin !== null) {\n img.crossOrigin = crossOrigin;\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\n\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 loadImageInDom(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\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 enlivenObjects(objects, callback, namespace, reviver) {\n objects = objects || [];\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\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 enlivenPatterns(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 } 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 groupSVGElements(elements, options, path) {\n var object;\n\n if (elements && elements.length === 1) {\n return elements[0];\n }\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 } else {\n delete options.width;\n delete options.height;\n }\n }\n\n object = new fabric.Group(elements, options);\n\n if (typeof path !== 'undefined') {\n object.sourcePath = path;\n }\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 populateWithProperties(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 dotted stroke in canvas\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 drawDashedLine(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 ctx.save();\n ctx.translate(x, y);\n ctx.moveTo(0, 0);\n ctx.rotate(rot);\n x = 0;\n\n while (len > x) {\n x += da[di++ % dc];\n\n if (x > len) {\n x = len;\n }\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 createCanvasElement() {\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 copyCanvasElement(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 toDataURL(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 createImage() {\n return fabric.document.createElement('img');\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 multiplyTransformMatrices(a, b, is2x2) {\n // Matrix multiply a * b\n return [a[0] * b[0] + a[2] * b[1], a[1] * b[0] + a[3] * b[1], a[0] * b[2] + a[2] * b[3], a[1] * b[2] + a[3] * b[3], is2x2 ? 0 : a[0] * b[4] + a[2] * b[5] + a[4], is2x2 ? 0 : a[1] * b[4] + a[3] * b[5] + a[5]];\n },\n\n /**\n * Decomposes standard 2x3 matrix into transform components\n * @static\n * @memberOf fabric.util\n * @param {Array} a transformMatrix\n * @return {Object} Components of transform\n */\n qrDecompose: function qrDecompose(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 /**\n * Returns a transform matrix starting from an object of the same kind of\n * the one returned from qrDecompose, useful also if you want to calculate some\n * transformations from an object that is not enlived yet\n * @static\n * @memberOf fabric.util\n * @param {Object} options\n * @param {Number} [options.angle] angle in degrees\n * @return {Number[]} transform matrix\n */\n calcRotateMatrix: function calcRotateMatrix(options) {\n if (!options.angle) {\n return fabric.iMatrix.concat();\n }\n\n var theta = fabric.util.degreesToRadians(options.angle),\n cos = fabric.util.cos(theta),\n sin = fabric.util.sin(theta);\n return [cos, sin, -sin, cos, 0, 0];\n },\n\n /**\n * Returns a transform matrix starting from an object of the same kind of\n * the one returned from qrDecompose, useful also if you want to calculate some\n * transformations from an object that is not enlived yet.\n * is called DimensionsTransformMatrix because those properties are the one that influence\n * the size of the resulting box of the object.\n * @static\n * @memberOf fabric.util\n * @param {Object} options\n * @param {Number} [options.scaleX]\n * @param {Number} [options.scaleY]\n * @param {Boolean} [options.flipX]\n * @param {Boolean} [options.flipY]\n * @param {Number} [options.skewX]\n * @param {Number} [options.skewX]\n * @return {Number[]} transform matrix\n */\n calcDimensionsMatrix: function calcDimensionsMatrix(options) {\n var scaleX = typeof options.scaleX === 'undefined' ? 1 : options.scaleX,\n scaleY = typeof options.scaleY === 'undefined' ? 1 : options.scaleY,\n scaleMatrix = [options.flipX ? -scaleX : scaleX, 0, 0, options.flipY ? -scaleY : scaleY, 0, 0],\n multiply = fabric.util.multiplyTransformMatrices,\n degreesToRadians = fabric.util.degreesToRadians;\n\n if (options.skewX) {\n scaleMatrix = multiply(scaleMatrix, [1, 0, Math.tan(degreesToRadians(options.skewX)), 1], true);\n }\n\n if (options.skewY) {\n scaleMatrix = multiply(scaleMatrix, [1, Math.tan(degreesToRadians(options.skewY)), 0, 1], true);\n }\n\n return scaleMatrix;\n },\n\n /**\n * Returns a transform matrix starting from an object of the same kind of\n * the one returned from qrDecompose, useful also if you want to calculate some\n * transformations from an object that is not enlived yet\n * @static\n * @memberOf fabric.util\n * @param {Object} options\n * @param {Number} [options.angle]\n * @param {Number} [options.scaleX]\n * @param {Number} [options.scaleY]\n * @param {Boolean} [options.flipX]\n * @param {Boolean} [options.flipY]\n * @param {Number} [options.skewX]\n * @param {Number} [options.skewX]\n * @param {Number} [options.translateX]\n * @param {Number} [options.translateY]\n * @return {Number[]} transform matrix\n */\n composeMatrix: function composeMatrix(options) {\n var matrix = [1, 0, 0, 1, options.translateX || 0, options.translateY || 0],\n multiply = fabric.util.multiplyTransformMatrices;\n\n if (options.angle) {\n matrix = multiply(matrix, fabric.util.calcRotateMatrix(options));\n }\n\n if (options.scaleX !== 1 || options.scaleY !== 1 || options.skewX || options.skewY || options.flipX || options.flipY) {\n matrix = multiply(matrix, fabric.util.calcDimensionsMatrix(options));\n }\n\n return matrix;\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 resetObjectTransform(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 saveObjectTransform(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 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 isTransparent(ctx, x, y, tolerance) {\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 } else {\n x = 0;\n }\n\n if (y > tolerance) {\n y -= tolerance;\n } else {\n y = 0;\n }\n }\n\n var _isTransparent = true,\n i,\n temp,\n imageData = ctx.getImageData(x, y, tolerance * 2 || 1, tolerance * 2 || 1),\n l = imageData.data.length; // Split image data - for tolerance > 1, pixelDataSize = 4;\n\n for (i = 3; i < l; i += 4) {\n temp = imageData.data[i];\n _isTransparent = temp <= 0;\n\n if (_isTransparent === false) {\n break; // Stop if colour found\n }\n }\n\n imageData = null;\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 parsePreserveAspectRatioAttribute(attribute) {\n var meetOrSlice = 'meet',\n alignX = 'Mid',\n alignY = 'Mid',\n aspectRatioAttrs = attribute.split(' '),\n align;\n\n if (aspectRatioAttrs && aspectRatioAttrs.length) {\n meetOrSlice = aspectRatioAttrs.pop();\n\n if (meetOrSlice !== 'meet' && meetOrSlice !== 'slice') {\n align = meetOrSlice;\n meetOrSlice = 'meet';\n } else if (aspectRatioAttrs.length) {\n align = aspectRatioAttrs.pop();\n }\n } //divide align in alignX and alignY\n\n\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 clearFabricFontCache(fontFamily) {\n fontFamily = (fontFamily || '').toLowerCase();\n\n if (!fontFamily) {\n fabric.charWidthsCache = {};\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 limitDimsByArea(ar, maximumArea) {\n var roughWidth = Math.sqrt(maximumArea * ar),\n perfLimitSizeY = Math.floor(maximumArea / roughWidth);\n return {\n x: Math.floor(roughWidth),\n y: perfLimitSizeY\n };\n },\n capValue: function capValue(min, value, max) {\n return Math.max(min, Math.min(value, max));\n },\n\n /**\n * Finds the scale for the object source to fit inside the object destination,\n * keeping aspect ratio intact.\n * respect the total allowed area for the cache.\n * @memberOf fabric.util\n * @param {Object | fabric.Object} source\n * @param {Number} source.height natural unscaled height of the object\n * @param {Number} source.width natural unscaled width of the object\n * @param {Object | fabric.Object} destination\n * @param {Number} destination.height natural unscaled height of the object\n * @param {Number} destination.width natural unscaled width of the object\n * @return {Number} scale factor to apply to source to fit into destination\n */\n findScaleToFit: function findScaleToFit(source, destination) {\n return Math.min(destination.width / source.width, destination.height / source.height);\n },\n\n /**\n * Finds the scale for the object source to cover entirely the object destination,\n * keeping aspect ratio intact.\n * respect the total allowed area for the cache.\n * @memberOf fabric.util\n * @param {Object | fabric.Object} source\n * @param {Number} source.height natural unscaled height of the object\n * @param {Number} source.width natural unscaled width of the object\n * @param {Object | fabric.Object} destination\n * @param {Number} destination.height natural unscaled height of the object\n * @param {Number} destination.width natural unscaled width of the object\n * @return {Number} scale factor to apply to source to cover destination\n */\n findScaleToCover: function findScaleToCover(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 matrixToSVG(transform) {\n return 'matrix(' + transform.map(function (value) {\n return fabric.util.toFixed(value, fabric.Object.NUM_FRACTION_DIGITS);\n }).join(' ') + ')';\n },\n\n /**\n * given a width and height, return the size of the bounding box\n * that can contains the box with width/height with applied transform\n * described in options.\n * Use to calculate the boxes around objects for controls.\n * @memberOf fabric.util\n * @param {Number} width\n * @param {Number} height\n * @param {Object} options\n * @param {Number} options.scaleX\n * @param {Number} options.scaleY\n * @param {Number} options.skewX\n * @param {Number} options.skewY\n * @return {Object.x} width of containing\n * @return {Object.y} height of containing\n */\n sizeAfterTransform: function sizeAfterTransform(width, height, options) {\n var dimX = width / 2,\n dimY = height / 2,\n points = [{\n x: -dimX,\n y: -dimY\n }, {\n x: dimX,\n y: -dimY\n }, {\n x: -dimX,\n y: dimY\n }, {\n x: dimX,\n y: dimY\n }],\n transformMatrix = fabric.util.calcDimensionsMatrix(options),\n bbox = fabric.util.makeBoundingBoxFromPoints(points, transformMatrix);\n return {\n x: bbox.width,\n y: bbox.height\n };\n }\n };\n})(typeof exports !== 'undefined' ? exports : this);\n\n(function () {\n var _join = Array.prototype.join,\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 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 return ['C', cp1X, cp1Y, cp2X, cp2Y, toX, toY];\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\n\n function arcToSegments(toX, toY, rx, ry, large, sweep, rotateX) {\n var PI = Math.PI,\n th = rotateX * PI / 180,\n sinTh = fabric.util.sin(th),\n cosTh = fabric.util.cos(th),\n fromX = 0,\n fromY = 0;\n rx = Math.abs(rx);\n ry = Math.abs(ry);\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,\n ry2 = ry * ry,\n py2 = py * py,\n 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 } else {\n root = (large === sweep ? -1.0 : 1.0) * 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 } else if (sweep === 1 && dtheta < 0) {\n dtheta += 2 * PI;\n } // Convert into cubic bezier segments <= 90deg\n\n\n var segments = Math.ceil(Math.abs(dtheta / PI * 2)),\n result = [],\n 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][5];\n fromY = result[i][6];\n mTheta = th3;\n th3 += mDelta;\n }\n\n return result;\n }\n /*\n * Private\n */\n\n\n function calcVectorAngle(ux, uy, vx, vy) {\n var ta = Math.atan2(uy, ux),\n tb = Math.atan2(vy, vx);\n\n if (tb >= ta) {\n return tb - ta;\n } else {\n return 2 * Math.PI - (ta - tb);\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 // TODO: can we normalize this with the starting points set at 0 and then translated the bbox?\n\n\n function getBoundsOfCurve(x0, y0, x1, y1, x2, y2, x3, y3) {\n var argsString;\n\n if (fabric.cachesBoundsOfCurve) {\n argsString = _join.call(arguments);\n\n if (fabric.boundsOfCurveCache[argsString]) {\n return fabric.boundsOfCurveCache[argsString];\n }\n }\n\n var sqrt = Math.sqrt,\n min = Math.min,\n max = Math.max,\n abs = Math.abs,\n tvalues = [],\n bounds = [[], []],\n a,\n b,\n c,\n t,\n t1,\n t2,\n b2ac,\n sqrtb2ac;\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\n t = -c / b;\n\n if (0 < t && t < 1) {\n tvalues.push(t);\n }\n\n continue;\n }\n\n b2ac = b * b - 4 * c * a;\n\n if (b2ac < 0) {\n continue;\n }\n\n sqrtb2ac = sqrt(b2ac);\n t1 = (-b + sqrtb2ac) / (2 * a);\n\n if (0 < t1 && t1 < 1) {\n tvalues.push(t1);\n }\n\n t2 = (-b - sqrtb2ac) / (2 * a);\n\n if (0 < t2 && t2 < 1) {\n tvalues.push(t2);\n }\n }\n\n var x,\n y,\n j = tvalues.length,\n jlen = j,\n mt;\n\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 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 x: min.apply(null, bounds[0]),\n y: min.apply(null, bounds[1])\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\n return result;\n }\n /**\n * Converts arc to a bunch of beizer curves\n * @param {Number} fx starting point x\n * @param {Number} fy starting point y\n * @param {Array} coords Arc command\n */\n\n\n function fromArcToBeizers(fx, fy, coords) {\n var rx = coords[1],\n ry = coords[2],\n rot = coords[3],\n large = coords[4],\n sweep = coords[5],\n tx = coords[6],\n ty = coords[7],\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 segsNorm[i][1] += fx;\n segsNorm[i][2] += fy;\n segsNorm[i][3] += fx;\n segsNorm[i][4] += fy;\n segsNorm[i][5] += fx;\n segsNorm[i][6] += fy;\n }\n\n return segsNorm;\n }\n\n ;\n\n function makePathSimpler(path) {\n // x and y represent the last point of the path. the previous command point.\n // we add them to each relative command to make it an absolute comment.\n // we also swap the v V h H with L, because are easier to transform.\n var x = 0,\n y = 0,\n len = path.length,\n // x1 and y1 represent the last point of the subpath. the subpath is started with\n // m or M command. When a z or Z command is drawn, x and y need to be resetted to\n // the last x1 and y1.\n x1 = 0,\n y1 = 0,\n current,\n i,\n converted,\n // previous will host the letter of the previous command, to handle S and T.\n // controlX and controlY will host the previous reflected control point\n destinationPath = [],\n previous,\n controlX,\n controlY;\n\n for (i = 0; i < len; ++i) {\n converted = false;\n current = path[i].slice(0);\n\n switch (current[0]) {\n // first letter\n case 'l':\n // lineto, relative\n current[0] = 'L';\n current[1] += x;\n current[2] += y;\n // falls through\n\n case 'L':\n x = current[1];\n y = current[2];\n break;\n\n case 'h':\n // horizontal lineto, relative\n current[1] += x;\n // falls through\n\n case 'H':\n current[0] = 'L';\n current[2] = y;\n x = current[1];\n break;\n\n case 'v':\n // vertical lineto, relative\n current[1] += y;\n // falls through\n\n case 'V':\n current[0] = 'L';\n y = current[1];\n current[1] = x;\n current[2] = y;\n break;\n\n case 'm':\n // moveTo, relative\n current[0] = 'M';\n current[1] += x;\n current[2] += y;\n // falls through\n\n case 'M':\n x = current[1];\n y = current[2];\n x1 = current[1];\n y1 = current[2];\n break;\n\n case 'c':\n // bezierCurveTo, relative\n current[0] = 'C';\n current[1] += x;\n current[2] += y;\n current[3] += x;\n current[4] += y;\n current[5] += x;\n current[6] += y;\n // falls through\n\n case 'C':\n controlX = current[3];\n controlY = current[4];\n x = current[5];\n y = current[6];\n break;\n\n case 's':\n // shorthand cubic bezierCurveTo, relative\n current[0] = 'S';\n current[1] += x;\n current[2] += y;\n current[3] += x;\n current[4] += y;\n // falls through\n\n case 'S':\n // would be sScC but since we are swapping sSc for C, we check just that.\n if (previous === 'C') {\n // calculate reflection of previous control points\n controlX = 2 * x - controlX;\n controlY = 2 * y - controlY;\n } else {\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\n x = current[3];\n y = current[4];\n current[0] = 'C';\n current[5] = current[3];\n current[6] = current[4];\n current[3] = current[1];\n current[4] = current[2];\n current[1] = controlX;\n current[2] = controlY; // current[3] and current[4] are NOW the second control point.\n // we keep it for the next reflection.\n\n controlX = current[3];\n controlY = current[4];\n break;\n\n case 'q':\n // quadraticCurveTo, relative\n current[0] = 'Q';\n current[1] += x;\n current[2] += y;\n current[3] += x;\n current[4] += y;\n // falls through\n\n case 'Q':\n controlX = current[1];\n controlY = current[2];\n x = current[3];\n y = current[4];\n break;\n\n case 't':\n // shorthand quadraticCurveTo, relative\n current[0] = 'T';\n current[1] += x;\n current[2] += y;\n // falls through\n\n case 'T':\n if (previous === 'Q') {\n // calculate reflection of previous control point\n controlX = 2 * x - controlX;\n controlY = 2 * y - controlY;\n } else {\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\n current[0] = 'Q';\n x = current[1];\n y = current[2];\n current[1] = controlX;\n current[2] = controlY;\n current[3] = x;\n current[4] = y;\n break;\n\n case 'a':\n current[0] = 'A';\n current[6] += x;\n current[7] += y;\n // falls through\n\n case 'A':\n converted = true;\n destinationPath = destinationPath.concat(fromArcToBeizers(x, y, current));\n x = current[6];\n y = current[7];\n break;\n\n case 'z':\n case 'Z':\n x = x1;\n y = y1;\n break;\n\n default:\n }\n\n if (!converted) {\n destinationPath.push(current);\n }\n\n previous = current[0];\n }\n\n return destinationPath;\n }\n\n ;\n /**\n * Calc length from point x1,y1 to x2,y2\n * @param {Number} x1 starting point x\n * @param {Number} y1 starting point y\n * @param {Number} x2 starting point x\n * @param {Number} y2 starting point y\n * @return {Number} length of segment\n */\n\n function calcLineLength(x1, y1, x2, y2) {\n return Math.sqrt((x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1));\n } // functions for the Cubic beizer\n // taken from: https://github.com/konvajs/konva/blob/7.0.5/src/shapes/Path.ts#L350\n\n\n function CB1(t) {\n return t * t * t;\n }\n\n function CB2(t) {\n return 3 * t * t * (1 - t);\n }\n\n function CB3(t) {\n return 3 * t * (1 - t) * (1 - t);\n }\n\n function CB4(t) {\n return (1 - t) * (1 - t) * (1 - t);\n }\n\n function getPointOnCubicBezierIterator(p1x, p1y, p2x, p2y, p3x, p3y, p4x, p4y) {\n return function (pct) {\n var c1 = CB1(pct),\n c2 = CB2(pct),\n c3 = CB3(pct),\n c4 = CB4(pct);\n return {\n x: p4x * c1 + p3x * c2 + p2x * c3 + p1x * c4,\n y: p4y * c1 + p3y * c2 + p2y * c3 + p1y * c4\n };\n };\n }\n\n function QB1(t) {\n return t * t;\n }\n\n function QB2(t) {\n return 2 * t * (1 - t);\n }\n\n function QB3(t) {\n return (1 - t) * (1 - t);\n }\n\n function getPointOnQuadraticBezierIterator(p1x, p1y, p2x, p2y, p3x, p3y) {\n return function (pct) {\n var c1 = QB1(pct),\n c2 = QB2(pct),\n c3 = QB3(pct);\n return {\n x: p3x * c1 + p2x * c2 + p1x * c3,\n y: p3y * c1 + p2y * c2 + p1y * c3\n };\n };\n }\n\n function pathIterator(iterator, x1, y1) {\n var tempP = {\n x: x1,\n y: y1\n },\n p,\n tmpLen = 0,\n perc;\n\n for (perc = 0.01; perc <= 1; perc += 0.01) {\n p = iterator(perc);\n tmpLen += calcLineLength(tempP.x, tempP.y, p.x, p.y);\n tempP = p;\n }\n\n return tmpLen;\n } //measures the length of a pre-simplified path\n\n\n function getPathSegmentsInfo(path) {\n var totalLength = 0,\n len = path.length,\n current,\n //x2 and y2 are the coords of segment start\n //x1 and y1 are the coords of the current point\n x1 = 0,\n y1 = 0,\n x2 = 0,\n y2 = 0,\n info = [],\n iterator,\n tempInfo;\n\n for (var i = 0; i < len; i++) {\n current = path[i];\n tempInfo = {\n x: x1,\n y: y1,\n command: current[0]\n };\n\n switch (current[0]) {\n //first letter\n case 'M':\n tempInfo.length = 0;\n x2 = x1 = current[1];\n y2 = y1 = current[2];\n break;\n\n case 'L':\n tempInfo.length = calcLineLength(x1, y1, current[1], current[2]);\n x1 = current[1];\n y1 = current[2];\n break;\n\n case 'C':\n iterator = getPointOnCubicBezierIterator(x1, y1, current[1], current[2], current[3], current[4], current[5], current[6]);\n tempInfo.length = pathIterator(iterator, x1, y1);\n x1 = current[5];\n y1 = current[6];\n break;\n\n case 'Q':\n iterator = getPointOnQuadraticBezierIterator(x1, y1, current[1], current[2], current[3], current[4]);\n tempInfo.length = pathIterator(iterator, x1, y1);\n x1 = current[3];\n y1 = current[4];\n break;\n\n case 'Z':\n case 'z':\n // we add those in order to ease calculations later\n tempInfo.destX = x2;\n tempInfo.destY = y2;\n tempInfo.length = calcLineLength(x1, y1, x2, y2);\n x1 = x2;\n y1 = y2;\n break;\n }\n\n totalLength += tempInfo.length;\n info.push(tempInfo);\n }\n\n info.push({\n length: totalLength,\n x: x1,\n y: y1\n });\n return info;\n }\n\n function getPointOnPath(path, perc, infos) {\n if (!infos) {\n infos = getPathSegmentsInfo(path);\n }\n\n var distance = infos[infos.length - 1] * perc,\n i = 0;\n\n while (distance - infos[i] > 0 && i < infos.length) {\n distance -= infos[i];\n i++;\n }\n\n var segInfo = infos[i],\n segPercent = distance / segInfo.length,\n command = segInfo.length,\n segment = path[i];\n\n switch (command) {\n case 'Z':\n case 'z':\n return new fabric.Point(segInfo.x, segInfo.y).lerp(new fabric.Point(segInfo.destX, segInfo.destY), segPercent);\n break;\n\n case 'L':\n return new fabric.Point(segInfo.x, segInfo.y).lerp(new fabric.Point(segment[1], segment[2]), segPercent);\n break;\n\n case 'C':\n return getPointOnCubicBezierIterator(segInfo.x, segInfo.y, segment[1], segment[2], segment[3], segment[4], segment[5], segment[6])(segPercent);\n break;\n\n case 'Q':\n return getPointOnQuadraticBezierIterator(segInfo.x, segInfo.y, segment[1], segment[2], segment[3], segment[4])(segPercent);\n break;\n }\n }\n\n function parsePath(pathString) {\n var result = [],\n coords = [],\n currentPath,\n parsed,\n re = fabric.rePathCommand,\n match,\n coordsStr,\n // one of commands (m,M,l,L,q,Q,c,C,etc.) followed by non-command characters (i.e. command values)\n path;\n\n if (!pathString || !pathString.match) {\n return result;\n }\n\n path = pathString.match(/[mzlhvcsqta][^mzlhvcsqta]*/gi);\n\n for (var i = 0, coordsParsed, len = path.length; i < len; i++) {\n currentPath = path[i];\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\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 } else {\n result.push(coordsParsed);\n }\n }\n\n return result;\n }\n\n ;\n /**\n * Calculate bounding box of a elliptic-arc\n * @deprecated\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 axis\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\n function getBoundsOfArc(fx, fy, rx, ry, rot, large, sweep, tx, ty) {\n var fromX = 0,\n fromY = 0,\n bound,\n 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][1], segs[i][2], segs[i][3], segs[i][4], segs[i][5], segs[i][6]);\n bounds.push({\n x: bound[0].x + fx,\n y: bound[0].y + fy\n });\n bounds.push({\n x: bound[1].x + fx,\n y: bound[1].y + fy\n });\n fromX = segs[i][5];\n fromY = segs[i][6];\n }\n\n return bounds;\n }\n\n ;\n /**\n * Draws arc\n * @param {CanvasRenderingContext2D} ctx\n * @param {Number} fx\n * @param {Number} fy\n * @param {Array} coords coords of the arc, without the front 'A/a'\n */\n\n function drawArc(ctx, fx, fy, coords) {\n coords = coords.slice(0).unshift('X'); // command A or a does not matter\n\n var beizers = fromArcToBeizers(fx, fy, coords);\n beizers.forEach(function (beizer) {\n ctx.bezierCurveTo.apply(ctx, beizer.slice(1));\n });\n }\n\n ;\n fabric.util.parsePath = parsePath;\n fabric.util.makePathSimpler = makePathSimpler;\n fabric.util.getPathSegmentsInfo = getPathSegmentsInfo;\n fabric.util.fromArcToBeizers = fromArcToBeizers;\n fabric.util.getBoundsOfCurve = getBoundsOfCurve;\n fabric.util.getPointOnPath = getPointOnPath; // kept because we do not want to make breaking changes.\n // but useless and deprecated.\n\n fabric.util.getBoundsOfArc = getBoundsOfArc;\n fabric.util.drawArc = drawArc;\n})();\n\n(function () {\n var slice = Array.prototype.slice;\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\n function invoke(array, method) {\n var args = slice.call(arguments, 2),\n result = [];\n\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\n return result;\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\n\n function max(array, byProperty) {\n return find(array, byProperty, function (value1, value2) {\n return value1 >= value2;\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\n\n function min(array, byProperty) {\n return find(array, byProperty, function (value1, value2) {\n return value1 < value2;\n });\n }\n /**\n * @private\n */\n\n\n function fill(array, value) {\n var k = array.length;\n\n while (k--) {\n array[k] = value;\n }\n\n return array;\n }\n /**\n * @private\n */\n\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\n if (byProperty) {\n while (i--) {\n if (condition(array[i][byProperty], result)) {\n result = array[i][byProperty];\n }\n }\n } else {\n while (i--) {\n if (condition(array[i], result)) {\n result = array[i];\n }\n }\n }\n\n return result;\n }\n /**\n * @namespace fabric.util.array\n */\n\n\n fabric.util.array = {\n fill: fill,\n invoke: invoke,\n min: min,\n max: max\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 and group properties 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 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 } else if (source instanceof Array) {\n destination = [];\n\n for (var i = 0, len = source.length; i < len; i++) {\n destination[i] = extend({}, source[i], deep);\n }\n } else if (source && typeof source === 'object') {\n for (var property in source) {\n if (property === 'canvas' || property === 'group') {\n // we do not want to clone this props at all.\n // we want to keep the keys in the copy\n destination[property] = null;\n } else if (source.hasOwnProperty(property)) {\n destination[property] = extend({}, source[property], deep);\n }\n }\n } else {\n // this sounds odd for an extend but is ok for recursive use\n destination = source;\n }\n } else {\n for (var property in source) {\n destination[property] = source[property];\n }\n }\n\n return destination;\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\n\n function clone(object, deep) {\n return extend({}, object, deep);\n }\n /** @namespace fabric.util.object */\n\n\n fabric.util.object = {\n extend: extend,\n clone: clone\n };\n fabric.util.object.extend(fabric.util, fabric.Observable);\n})();\n\n(function () {\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 * 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\n\n function capitalize(string, firstLetterOnly) {\n return string.charAt(0).toUpperCase() + (firstLetterOnly ? string.slice(1) : string.slice(1).toLowerCase());\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\n\n function escapeXml(string) {\n return string.replace(/&/g, '&').replace(/\"/g, '"').replace(/'/g, ''').replace(//g, '>');\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\n\n function graphemeSplit(textstring) {\n var i = 0,\n chr,\n graphemes = [];\n\n for (i = 0, chr; i < textstring.length; i++) {\n if ((chr = getWholeChar(textstring, i)) === false) {\n continue;\n }\n\n graphemes.push(chr);\n }\n\n return graphemes;\n } // taken from mdn in the charAt doc page.\n\n\n function getWholeChar(str, i) {\n var code = str.charCodeAt(i);\n\n if (isNaN(code)) {\n return ''; // Position not found\n }\n\n if (code < 0xD800 || code > 0xDFFF) {\n return str.charAt(i);\n } // High surrogate (could change last hex to 0xDB7F to treat high private\n // surrogates as single characters)\n\n\n if (0xD800 <= code && code <= 0xDBFF) {\n if (str.length <= i + 1) {\n throw 'High surrogate without following low surrogate';\n }\n\n var next = str.charCodeAt(i + 1);\n\n if (0xDC00 > next || next > 0xDFFF) {\n throw 'High surrogate without following low surrogate';\n }\n\n return str.charAt(i) + str.charAt(i + 1);\n } // Low surrogate (0xDC00 <= code && code <= 0xDFFF)\n\n\n if (i === 0) {\n throw 'Low surrogate without preceding high surrogate';\n }\n\n var prev = str.charCodeAt(i - 1); // (could change last hex to 0xDB7F to treat high private\n // surrogates as single characters)\n\n if (0xD800 > prev || prev > 0xDBFF) {\n throw 'Low surrogate without preceding high surrogate';\n } // We can pass over low surrogates now as the second component\n // in a pair which we have already processed\n\n\n return false;\n }\n /**\n * String utilities\n * @namespace fabric.util.string\n */\n\n\n fabric.util.string = {\n camelize: camelize,\n capitalize: capitalize,\n escapeXml: escapeXml,\n graphemeSplit: graphemeSplit\n };\n})();\n\n(function () {\n var slice = Array.prototype.slice,\n emptyFunction = function emptyFunction() {},\n IS_DONTENUM_BUGGY = function () {\n for (var p in {\n toString: 1\n }) {\n if (p === 'toString') {\n return false;\n }\n }\n\n return true;\n }(),\n\n /** @ignore */\n addMethods = function addMethods(klass, source, parent) {\n for (var property in source) {\n if (property in klass.prototype && typeof klass.prototype[property] === 'function' && (source[property] + '').indexOf('callSuper') > -1) {\n klass.prototype[property] = function (property) {\n return function () {\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 } 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\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; // climb prototype chain to find method not equal to callee's method\n\n\n while (_this.constructor.superclass) {\n var superClassMethod = _this.constructor.superclass.prototype[methodName];\n\n if (_this[methodName] !== superClassMethod) {\n parentMethod = superClassMethod;\n break;\n } // eslint-disable-next-line\n\n\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 ? parentMethod.apply(this, slice.call(arguments, 1)) : parentMethod.call(this);\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\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\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\n for (var i = 0, length = properties.length; i < length; i++) {\n addMethods(klass, properties[i], parent);\n }\n\n if (!klass.prototype.initialize) {\n klass.prototype.initialize = emptyFunction;\n }\n\n klass.prototype.constructor = klass;\n klass.prototype.callSuper = callSuper;\n return klass;\n }\n\n fabric.util.createClass = createClass;\n})();\n\n(function () {\n // since ie11 can use addEventListener but they do not support options, i need to check\n var couldUseAttachEvent = !!fabric.document.createElement('div').attachEvent,\n touchEvents = ['touchstart', 'touchmove', 'touchend'];\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\n fabric.util.addListener = function (element, eventName, handler, options) {\n element && element.addEventListener(eventName, handler, couldUseAttachEvent ? false : options);\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\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\n if (touchProp && touchProp[0]) {\n return touchProp[0];\n }\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\n return {\n x: _evt.clientX + scroll.left,\n y: _evt.clientY + scroll.top\n };\n };\n\n fabric.util.isTouchEvent = function (event) {\n return touchEvents.indexOf(event.type) > -1 || event.pointerType === 'touch';\n };\n})();\n\n(function () {\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\n if (!elementStyle) {\n return element;\n }\n\n if (typeof styles === 'string') {\n element.style.cssText += ';' + styles;\n return styles.indexOf('opacity') > -1 ? setOpacity(element, styles.match(/opacity:\\s*(\\d?\\.?\\d*)/)[1]) : element;\n }\n\n for (var property in styles) {\n if (property === 'opacity') {\n setOpacity(element, styles[property]);\n } else {\n var normalizedProperty = property === 'float' || property === 'cssFloat' ? typeof elementStyle.styleFloat === 'undefined' ? 'cssFloat' : 'styleFloat' : property;\n elementStyle[normalizedProperty] = styles[property];\n }\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 setOpacity(element) {\n return element;\n };\n\n if (supportsOpacity) {\n /** @ignore */\n setOpacity = function setOpacity(element, value) {\n element.style.opacity = value;\n return element;\n };\n } else if (supportsFilters) {\n /** @ignore */\n setOpacity = function setOpacity(element, value) {\n var es = element.style;\n\n if (element.currentStyle && !element.currentStyle.hasLayout) {\n es.zoom = 1;\n }\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 } else {\n es.filter += ' alpha(opacity=' + value * 100 + ')';\n }\n\n return element;\n };\n }\n\n fabric.util.setStyle = setStyle;\n})();\n\n(function () {\n var _slice = Array.prototype.slice;\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\n function getById(id) {\n return typeof id === 'string' ? fabric.document.getElementById(id) : id;\n }\n\n var sliceCanConvertNodelists,\n\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 toArray(arrayLike) {\n return _slice.call(arrayLike, 0);\n };\n\n try {\n sliceCanConvertNodelists = toArray(fabric.document.childNodes) instanceof Array;\n } catch (err) {}\n\n if (!sliceCanConvertNodelists) {\n toArray = function toArray(arrayLike) {\n var arr = new Array(arrayLike.length),\n i = arrayLike.length;\n\n while (i--) {\n arr[i] = arrayLike[i];\n }\n\n return arr;\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\n\n function makeElement(tagName, attributes) {\n var el = fabric.document.createElement(tagName);\n\n for (var prop in attributes) {\n if (prop === 'class') {\n el.className = attributes[prop];\n } else if (prop === 'for') {\n el.htmlFor = attributes[prop];\n } else {\n el.setAttribute(prop, attributes[prop]);\n }\n }\n\n return el;\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\n\n function addClass(element, className) {\n if (element && (' ' + element.className + ' ').indexOf(' ' + className + ' ') === -1) {\n element.className += (element.className ? ' ' : '') + className;\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\n\n function wrapElement(element, wrapper, attributes) {\n if (typeof wrapper === 'string') {\n wrapper = makeElement(wrapper, attributes);\n }\n\n if (element.parentNode) {\n element.parentNode.replaceChild(wrapper, element);\n }\n\n wrapper.appendChild(element);\n return wrapper;\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\n\n function getScrollLeftTop(element) {\n var left = 0,\n top = 0,\n docElement = fabric.document.documentElement,\n body = fabric.document.body || {\n scrollLeft: 0,\n scrollTop: 0\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\n while (element && (element.parentNode || element.host)) {\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 } 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 {\n left: left,\n 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\n\n function getElementOffset(element) {\n var docElem,\n doc = element && element.ownerDocument,\n box = {\n left: 0,\n top: 0\n },\n offset = {\n left: 0,\n top: 0\n },\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\n if (typeof element.getBoundingClientRect !== 'undefined') {\n box = element.getBoundingClientRect();\n }\n\n scrollLeftTop = getScrollLeftTop(element);\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 * 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\n\n var getElementStyle;\n\n if (fabric.document.defaultView && fabric.document.defaultView.getComputedStyle) {\n getElementStyle = function getElementStyle(element, attr) {\n var style = fabric.document.defaultView.getComputedStyle(element, null);\n return style ? style[attr] : undefined;\n };\n } else {\n getElementStyle = function getElementStyle(element, attr) {\n var value = element.style[attr];\n\n if (!value && element.currentStyle) {\n value = element.currentStyle[attr];\n }\n\n return value;\n };\n }\n\n (function () {\n var style = fabric.document.documentElement.style,\n selectProp = 'userSelect' in style ? 'userSelect' : 'MozUserSelect' in style ? 'MozUserSelect' : 'WebkitUserSelect' in style ? 'WebkitUserSelect' : 'KhtmlUserSelect' in style ? 'KhtmlUserSelect' : '';\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\n function makeElementUnselectable(element) {\n if (typeof element.onselectstart !== 'undefined') {\n element.onselectstart = fabric.util.falseFunction;\n }\n\n if (selectProp) {\n element.style[selectProp] = 'none';\n } else if (typeof element.unselectable === 'string') {\n element.unselectable = 'on';\n }\n\n return element;\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\n\n function makeElementSelectable(element) {\n if (typeof element.onselectstart !== 'undefined') {\n element.onselectstart = null;\n }\n\n if (selectProp) {\n element.style[selectProp] = '';\n } else if (typeof element.unselectable === 'string') {\n element.unselectable = '';\n }\n\n return element;\n }\n\n fabric.util.makeElementUnselectable = makeElementUnselectable;\n fabric.util.makeElementSelectable = makeElementSelectable;\n })();\n\n function getNodeCanvas(element) {\n var impl = fabric.jsdomImplForWrapper(element);\n return impl._canvas || impl._image;\n }\n\n ;\n\n function cleanUpJsdomNode(element) {\n if (!fabric.isLikelyNode) {\n return;\n }\n\n var impl = fabric.jsdomImplForWrapper(element);\n\n if (impl) {\n impl._image = null;\n impl._canvas = null; // unsure if necessary\n\n impl._currentSrc = null;\n impl._attributes = null;\n impl._classList = null;\n }\n }\n\n function setImageSmoothing(ctx, value) {\n ctx.imageSmoothingEnabled = ctx.imageSmoothingEnabled || ctx.webkitImageSmoothingEnabled || ctx.mozImageSmoothingEnabled || ctx.msImageSmoothingEnabled || ctx.oImageSmoothingEnabled;\n ctx.imageSmoothingEnabled = value;\n }\n /**\n * setImageSmoothing sets the context imageSmoothingEnabled property.\n * Used by canvas and by ImageObject.\n * @memberOf fabric.util\n * @since 4.0.0\n * @param {HTMLRenderingContext2D} ctx to set on\n * @param {Boolean} value true or false\n */\n\n\n fabric.util.setImageSmoothing = setImageSmoothing;\n fabric.util.getById = getById;\n fabric.util.toArray = toArray;\n fabric.util.addClass = addClass;\n fabric.util.makeElement = makeElement;\n fabric.util.wrapElement = wrapElement;\n fabric.util.getScrollLeftTop = getScrollLeftTop;\n fabric.util.getElementOffset = getElementOffset;\n fabric.util.getNodeCanvas = getNodeCanvas;\n fabric.util.cleanUpJsdomNode = cleanUpJsdomNode;\n})();\n\n(function () {\n function addParamToUrl(url, param) {\n return url + (/\\?/.test(url) ? '&' : '?') + param;\n }\n\n function emptyFn() {}\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\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 /** @ignore */\n\n\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\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 * Wrapper around `console.log` (when available)\n * @param {*} [values] Values to log\n */\n\n\nfabric.log = console.log;\n/**\n * Wrapper around `console.warn` (when available)\n * @param {*} [values] Values to log as a warning\n */\n\nfabric.warn = console.warn;\n\n(function () {\n function noop() {\n return false;\n }\n\n function defaultEasing(t, b, c, d) {\n return -c * Math.cos(t / d * (Math.PI / 2)) + c + b;\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\n\n function animate(options) {\n requestAnimFrame(function (timestamp) {\n options || (options = {});\n var start = timestamp || +new Date(),\n duration = options.duration || 500,\n finish = start + duration,\n time,\n onChange = options.onChange || noop,\n abort = options.abort || noop,\n onComplete = options.onComplete || noop,\n easing = options.easing || defaultEasing,\n startValue = 'startValue' in options ? options.startValue : 0,\n endValue = 'endValue' in options ? options.endValue : 100,\n byValue = options.byValue || endValue - startValue;\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 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\n if (abort()) {\n onComplete(endValue, 1, 1);\n return;\n }\n\n if (time > finish) {\n onChange(endValue, 1, 1);\n onComplete(endValue, 1, 1);\n return;\n } else {\n onChange(current, valuePerc, timePerc);\n requestAnimFrame(tick);\n }\n })(start);\n });\n }\n\n var _requestAnimFrame = fabric.window.requestAnimationFrame || fabric.window.webkitRequestAnimationFrame || fabric.window.mozRequestAnimationFrame || fabric.window.oRequestAnimationFrame || fabric.window.msRequestAnimationFrame || function (callback) {\n return fabric.window.setTimeout(callback, 1000 / 60);\n };\n\n var _cancelAnimFrame = fabric.window.cancelAnimationFrame || fabric.window.clearTimeout;\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\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(function () {\n // Calculate an in-between color. Returns a \"rgba()\" string.\n // Credit: Edwin Martin \n // http://www.bitstorm.org/jquery/color-animation/jquery.animate-colors.js\n function calculateColor(begin, end, pos) {\n var color = 'rgba(' + parseInt(begin[0] + pos * (end[0] - begin[0]), 10) + ',' + parseInt(begin[1] + pos * (end[1] - begin[1]), 10) + ',' + parseInt(begin[2] + pos * (end[2] - begin[2]), 10);\n color += ',' + (begin && end ? parseFloat(begin[3] + pos * (end[3] - begin[3])) : 1);\n color += ')';\n return color;\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\n\n function animateColor(fromColor, toColor, duration, options) {\n var startColor = new fabric.Color(fromColor).getSource(),\n endColor = new fabric.Color(toColor).getSource(),\n originalOnComplete = options.onComplete,\n originalOnChange = options.onChange;\n options = options || {};\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 easing(currentTime, startValue, byValue, duration) {\n var posValue = options.colorEasing ? options.colorEasing(currentTime, duration) : 1 - Math.cos(currentTime / duration * (Math.PI / 2));\n return calculateColor(startValue, byValue, posValue);\n },\n // has to take in account for color restoring;\n onComplete: function onComplete(current, valuePerc, timePerc) {\n if (originalOnComplete) {\n return originalOnComplete(calculateColor(endColor, endColor, 0), valuePerc, timePerc);\n }\n },\n onChange: function onChange(current, valuePerc, timePerc) {\n if (originalOnChange) {\n if (Array.isArray(current)) {\n return originalOnChange(calculateColor(current, current, 0), valuePerc, timePerc);\n }\n\n originalOnChange(current, valuePerc, timePerc);\n }\n }\n }));\n }\n\n fabric.util.animateColor = animateColor;\n})();\n\n(function () {\n function normalize(a, c, p, s) {\n if (a < Math.abs(c)) {\n a = c;\n s = p / 4;\n } else {\n //handle the 0/0 case:\n if (c === 0 && a === 0) {\n s = p / (2 * Math.PI) * Math.asin(1);\n } else {\n s = p / (2 * Math.PI) * Math.asin(c / a);\n }\n }\n\n return {\n a: a,\n c: c,\n p: p,\n s: s\n };\n }\n\n function elastic(opts, t, d) {\n return opts.a * Math.pow(2, 10 * (t -= 1)) * Math.sin((t * d - opts.s) * (2 * Math.PI) / opts.p);\n }\n /**\n * Cubic easing out\n * @memberOf fabric.util.ease\n */\n\n\n function easeOutCubic(t, b, c, d) {\n return c * ((t = t / d - 1) * t * t + 1) + b;\n }\n /**\n * Cubic easing in and out\n * @memberOf fabric.util.ease\n */\n\n\n function easeInOutCubic(t, b, c, d) {\n t /= d / 2;\n\n if (t < 1) {\n return c / 2 * t * t * t + b;\n }\n\n return c / 2 * ((t -= 2) * t * t + 2) + b;\n }\n /**\n * Quartic easing in\n * @memberOf fabric.util.ease\n */\n\n\n function easeInQuart(t, b, c, d) {\n return c * (t /= d) * t * t * t + b;\n }\n /**\n * Quartic easing out\n * @memberOf fabric.util.ease\n */\n\n\n function easeOutQuart(t, b, c, d) {\n return -c * ((t = t / d - 1) * t * t * t - 1) + b;\n }\n /**\n * Quartic easing in and out\n * @memberOf fabric.util.ease\n */\n\n\n function easeInOutQuart(t, b, c, d) {\n t /= d / 2;\n\n if (t < 1) {\n return c / 2 * t * t * t * t + b;\n }\n\n return -c / 2 * ((t -= 2) * t * t * t - 2) + b;\n }\n /**\n * Quintic easing in\n * @memberOf fabric.util.ease\n */\n\n\n function easeInQuint(t, b, c, d) {\n return c * (t /= d) * t * t * t * t + b;\n }\n /**\n * Quintic easing out\n * @memberOf fabric.util.ease\n */\n\n\n function easeOutQuint(t, b, c, d) {\n return c * ((t = t / d - 1) * t * t * t * t + 1) + b;\n }\n /**\n * Quintic easing in and out\n * @memberOf fabric.util.ease\n */\n\n\n function easeInOutQuint(t, b, c, d) {\n t /= d / 2;\n\n if (t < 1) {\n return c / 2 * t * t * t * t * t + b;\n }\n\n return c / 2 * ((t -= 2) * t * t * t * t + 2) + b;\n }\n /**\n * Sinusoidal easing in\n * @memberOf fabric.util.ease\n */\n\n\n function easeInSine(t, b, c, d) {\n return -c * Math.cos(t / d * (Math.PI / 2)) + c + b;\n }\n /**\n * Sinusoidal easing out\n * @memberOf fabric.util.ease\n */\n\n\n function easeOutSine(t, b, c, d) {\n return c * Math.sin(t / d * (Math.PI / 2)) + b;\n }\n /**\n * Sinusoidal easing in and out\n * @memberOf fabric.util.ease\n */\n\n\n function easeInOutSine(t, b, c, d) {\n return -c / 2 * (Math.cos(Math.PI * t / d) - 1) + b;\n }\n /**\n * Exponential easing in\n * @memberOf fabric.util.ease\n */\n\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 * Exponential easing out\n * @memberOf fabric.util.ease\n */\n\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 * Exponential easing in and out\n * @memberOf fabric.util.ease\n */\n\n\n function easeInOutExpo(t, b, c, d) {\n if (t === 0) {\n return b;\n }\n\n if (t === d) {\n return b + c;\n }\n\n t /= d / 2;\n\n if (t < 1) {\n return c / 2 * Math.pow(2, 10 * (t - 1)) + b;\n }\n\n return c / 2 * (-Math.pow(2, -10 * --t) + 2) + b;\n }\n /**\n * Circular easing in\n * @memberOf fabric.util.ease\n */\n\n\n function easeInCirc(t, b, c, d) {\n return -c * (Math.sqrt(1 - (t /= d) * t) - 1) + b;\n }\n /**\n * Circular easing out\n * @memberOf fabric.util.ease\n */\n\n\n function easeOutCirc(t, b, c, d) {\n return c * Math.sqrt(1 - (t = t / d - 1) * t) + b;\n }\n /**\n * Circular easing in and out\n * @memberOf fabric.util.ease\n */\n\n\n function easeInOutCirc(t, b, c, d) {\n t /= d / 2;\n\n if (t < 1) {\n return -c / 2 * (Math.sqrt(1 - t * t) - 1) + b;\n }\n\n return c / 2 * (Math.sqrt(1 - (t -= 2) * t) + 1) + b;\n }\n /**\n * Elastic easing in\n * @memberOf fabric.util.ease\n */\n\n\n function easeInElastic(t, b, c, d) {\n var s = 1.70158,\n p = 0,\n a = c;\n\n if (t === 0) {\n return b;\n }\n\n t /= d;\n\n if (t === 1) {\n return b + c;\n }\n\n if (!p) {\n p = d * 0.3;\n }\n\n var opts = normalize(a, c, p, s);\n return -elastic(opts, t, d) + b;\n }\n /**\n * Elastic easing out\n * @memberOf fabric.util.ease\n */\n\n\n function easeOutElastic(t, b, c, d) {\n var s = 1.70158,\n p = 0,\n a = c;\n\n if (t === 0) {\n return b;\n }\n\n t /= d;\n\n if (t === 1) {\n return b + c;\n }\n\n if (!p) {\n p = d * 0.3;\n }\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 * Elastic easing in and out\n * @memberOf fabric.util.ease\n */\n\n\n function easeInOutElastic(t, b, c, d) {\n var s = 1.70158,\n p = 0,\n a = c;\n\n if (t === 0) {\n return b;\n }\n\n t /= d / 2;\n\n if (t === 2) {\n return b + c;\n }\n\n if (!p) {\n p = d * (0.3 * 1.5);\n }\n\n var opts = normalize(a, c, p, s);\n\n if (t < 1) {\n return -0.5 * elastic(opts, t, d) + b;\n }\n\n return opts.a * Math.pow(2, -10 * (t -= 1)) * Math.sin((t * d - opts.s) * (2 * Math.PI) / opts.p) * 0.5 + opts.c + b;\n }\n /**\n * Backwards easing in\n * @memberOf fabric.util.ease\n */\n\n\n function easeInBack(t, b, c, d, s) {\n if (s === undefined) {\n s = 1.70158;\n }\n\n return c * (t /= d) * t * ((s + 1) * t - s) + b;\n }\n /**\n * Backwards easing out\n * @memberOf fabric.util.ease\n */\n\n\n function easeOutBack(t, b, c, d, s) {\n if (s === undefined) {\n s = 1.70158;\n }\n\n return c * ((t = t / d - 1) * t * ((s + 1) * t + s) + 1) + b;\n }\n /**\n * Backwards easing in and out\n * @memberOf fabric.util.ease\n */\n\n\n function easeInOutBack(t, b, c, d, s) {\n if (s === undefined) {\n s = 1.70158;\n }\n\n t /= d / 2;\n\n if (t < 1) {\n return c / 2 * (t * t * (((s *= 1.525) + 1) * t - s)) + b;\n }\n\n return c / 2 * ((t -= 2) * t * (((s *= 1.525) + 1) * t + s) + 2) + b;\n }\n /**\n * Bouncing easing in\n * @memberOf fabric.util.ease\n */\n\n\n function easeInBounce(t, b, c, d) {\n return c - easeOutBounce(d - t, 0, c, d) + b;\n }\n /**\n * Bouncing easing out\n * @memberOf fabric.util.ease\n */\n\n\n function easeOutBounce(t, b, c, d) {\n if ((t /= d) < 1 / 2.75) {\n return c * (7.5625 * t * t) + b;\n } else if (t < 2 / 2.75) {\n return c * (7.5625 * (t -= 1.5 / 2.75) * t + 0.75) + b;\n } else if (t < 2.5 / 2.75) {\n return c * (7.5625 * (t -= 2.25 / 2.75) * t + 0.9375) + b;\n } else {\n return c * (7.5625 * (t -= 2.625 / 2.75) * t + 0.984375) + b;\n }\n }\n /**\n * Bouncing easing in and out\n * @memberOf fabric.util.ease\n */\n\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\n return easeOutBounce(t * 2 - d, 0, c, d) * 0.5 + c * 0.5 + b;\n }\n /**\n * Easing functions\n * See Easing Equations by Robert Penner\n * @namespace fabric.util.ease\n */\n\n\n fabric.util.ease = {\n /**\n * Quadratic easing in\n * @memberOf fabric.util.ease\n */\n easeInQuad: function easeInQuad(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 easeOutQuad(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 easeInOutQuad(t, b, c, d) {\n t /= d / 2;\n\n if (t < 1) {\n return c / 2 * t * t + b;\n }\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 easeInCubic(t, b, c, d) {\n return c * (t /= d) * t * t + b;\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(function (global) {\n 'use strict';\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 svgValidTagNames = ['path', 'circle', 'polygon', 'polyline', 'ellipse', 'rect', 'line', '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 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 'image-rendering': 'imageSmoothing'\n },\n colorAttributes = {\n stroke: 'strokeOpacity',\n fill: 'fillOpacity'\n },\n fSize = 'font-size',\n cPath = 'clip-path';\n fabric.svgValidTagNamesRegEx = getSvgRegex(svgValidTagNames);\n fabric.svgViewBoxElementsRegEx = getSvgRegex(svgViewBoxElements);\n fabric.svgInvalidAncestorsRegEx = getSvgRegex(svgInvalidAncestors);\n fabric.svgValidParentsRegEx = getSvgRegex(svgValidParents);\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\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 } else if (attr === 'strokeUniform') {\n return value === 'non-scaling-stroke';\n } else if (attr === 'strokeDashArray') {\n if (value === 'none') {\n value = null;\n } else {\n value = value.replace(/,/g, ' ').split(/\\s+/).map(parseFloat);\n }\n } else if (attr === 'transformMatrix') {\n if (parentAttributes && parentAttributes.transformMatrix) {\n value = multiplyTransformMatrices(parentAttributes.transformMatrix, fabric.parseTransformAttribute(value));\n } else {\n value = fabric.parseTransformAttribute(value);\n }\n } else if (attr === 'visible') {\n value = value !== 'none' && value !== 'hidden'; // display=none on parent element always takes precedence over child element\n\n if (parentAttributes && parentAttributes.visible === false) {\n value = false;\n }\n } else if (attr === 'opacity') {\n value = parseFloat(value);\n\n if (parentAttributes && typeof parentAttributes.opacity !== 'undefined') {\n value *= parentAttributes.opacity;\n }\n } else if (attr === 'textAnchor'\n /* text-anchor */\n ) {\n value = value === 'start' ? 'left' : value === 'end' ? 'right' : 'center';\n } else if (attr === 'charSpacing') {\n // parseUnit returns px and we convert it to em\n parsed = parseUnit(value, fontSize) / fontSize * 1000;\n } else if (attr === 'paintFirst') {\n var fillIndex = value.indexOf('fill');\n var strokeIndex = value.indexOf('stroke');\n var value = 'fill';\n\n if (fillIndex > -1 && strokeIndex > -1 && strokeIndex < fillIndex) {\n value = 'stroke';\n } else if (fillIndex === -1 && strokeIndex > -1) {\n value = 'stroke';\n }\n } else if (attr === 'href' || attr === 'xlink:href' || attr === 'font') {\n return value;\n } else if (attr === 'imageSmoothing') {\n return value === 'optimizeQuality' ? true : false;\n } else {\n parsed = isArray ? value.map(parseUnit) : parseUnit(value, fontSize);\n }\n\n return !isArray && isNaN(parsed) ? value : parsed;\n }\n /**\n * @private\n */\n\n\n function getSvgRegex(arr) {\n return new RegExp('^(' + arr.join('|') + ')\\\\b', 'i');\n }\n /**\n * @private\n * @param {Object} attributes Array of attributes to parse\n */\n\n\n function _setStrokeFillOpacity(attributes) {\n for (var attr in colorAttributes) {\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\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\n return attributes;\n }\n /**\n * @private\n */\n\n\n function _getMultipleNodes(doc, nodeNames) {\n var nodeName,\n nodeArray = [],\n nodeList,\n i,\n len;\n\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\n return nodeArray;\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\n\n fabric.parseTransformAttribute = function () {\n function rotateMatrix(matrix, args) {\n var cos = fabric.util.cos(args[0]),\n sin = fabric.util.sin(args[0]),\n x = 0,\n y = 0;\n\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 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\n if (args.length === 2) {\n matrix[5] = args[1];\n }\n } // identity matrix\n\n\n var iMatrix = fabric.iMatrix,\n // == begin transform regexp\n number = fabric.reNum,\n commaWsp = '(?:\\\\s+,?\\\\s*|,\\\\s*)',\n skewX = '(?:(skewX)\\\\s*\\\\(\\\\s*(' + number + ')\\\\s*\\\\))',\n skewY = '(?:(skewY)\\\\s*\\\\(\\\\s*(' + number + ')\\\\s*\\\\))',\n rotate = '(?:(rotate)\\\\s*\\\\(\\\\s*(' + number + ')(?:' + commaWsp + '(' + number + ')' + commaWsp + '(' + number + '))?\\\\s*\\\\))',\n scale = '(?:(scale)\\\\s*\\\\(\\\\s*(' + number + ')(?:' + commaWsp + '(' + number + '))?\\\\s*\\\\))',\n translate = '(?:(translate)\\\\s*\\\\(\\\\s*(' + number + ')(?:' + commaWsp + '(' + number + '))?\\\\s*\\\\))',\n matrix = '(?:(matrix)\\\\s*\\\\(\\\\s*' + '(' + number + ')' + commaWsp + '(' + number + ')' + commaWsp + '(' + number + ')' + commaWsp + '(' + number + ')' + commaWsp + '(' + number + ')' + commaWsp + '(' + number + ')' + '\\\\s*\\\\))',\n transform = '(?:' + matrix + '|' + translate + '|' + scale + '|' + rotate + '|' + skewX + '|' + skewY + ')',\n transforms = '(?:' + transform + '(?:' + commaWsp + '*' + transform + ')*' + ')',\n transformList = '^\\\\s*(?:' + transforms + '?)\\\\s*$',\n // http://www.w3.org/TR/SVG/coords.html#TransformAttribute\n reTransformList = new RegExp(transformList),\n // == end transform regexp\n reTransform = new RegExp(transform, 'g');\n return function (attributeValue) {\n // start with identity matrix\n var matrix = iMatrix.concat(),\n matrices = []; // return if no argument was given or\n // an argument does not match transform attribute regexp\n\n if (!attributeValue || attributeValue && !reTransformList.test(attributeValue)) {\n return matrix;\n }\n\n attributeValue.replace(reTransform, function (match) {\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\n case 'rotate':\n args[0] = fabric.util.degreesToRadians(args[0]);\n rotateMatrix(matrix, args);\n break;\n\n case 'scale':\n scaleMatrix(matrix, args);\n break;\n\n case 'skewX':\n skewMatrix(matrix, args, 2);\n break;\n\n case 'skewY':\n skewMatrix(matrix, args, 1);\n break;\n\n case 'matrix':\n matrix = args;\n break;\n } // snapshot current matrix into matrices array\n\n\n matrices.push(matrix.concat()); // reset\n\n matrix = iMatrix.concat();\n });\n var combinedMatrix = matrices[0];\n\n while (matrices.length > 1) {\n matrices.shift();\n combinedMatrix = fabric.util.multiplyTransformMatrices(combinedMatrix, matrices[0]);\n }\n\n return combinedMatrix;\n };\n }();\n /**\n * @private\n */\n\n\n function parseStyleString(style, oStyle) {\n var attr, value;\n style.replace(/;\\s*$/, '').split(';').forEach(function (chunk) {\n var pair = chunk.split(':');\n attr = pair[0].trim().toLowerCase();\n value = pair[1].trim();\n oStyle[attr] = value;\n });\n }\n /**\n * @private\n */\n\n\n function parseStyleObject(style, oStyle) {\n var attr, value;\n\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 oStyle[attr] = value;\n }\n }\n /**\n * @private\n */\n\n\n function getGlobalStylesForElement(element, svgUid) {\n var styles = {};\n\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\n return styles;\n }\n /**\n * @private\n */\n\n\n function elementMatchesRule(element, selectors) {\n var firstMatching,\n parentMatching = true; //start from rightmost selector.\n\n firstMatching = selectorMatches(element, selectors.pop());\n\n if (firstMatching && selectors.length) {\n parentMatching = doesSomeParentMatch(element, selectors);\n }\n\n return firstMatching && parentMatching && selectors.length === 0;\n }\n\n function doesSomeParentMatch(element, selectors) {\n var selector,\n parentMatching = true;\n\n while (element.parentNode && element.parentNode.nodeType === 1 && selectors.length) {\n if (parentMatching) {\n selector = selectors.pop();\n }\n\n element = element.parentNode;\n parentMatching = selectorMatches(element, selector);\n }\n\n return selectors.length === 0;\n }\n /**\n * @private\n */\n\n\n function selectorMatches(element, selector) {\n var nodeName = element.nodeName,\n classNames = element.getAttribute('class'),\n id = element.getAttribute('id'),\n matcher,\n i; // i check if a selector matches slicing away part from it.\n // if i get empty string i should match\n\n matcher = new RegExp('^' + nodeName, 'i');\n selector = selector.replace(matcher, '');\n\n if (id && selector.length) {\n matcher = new RegExp('#' + id + '(?![a-zA-Z\\\\-]+)', 'i');\n selector = selector.replace(matcher, '');\n }\n\n if (classNames && selector.length) {\n classNames = classNames.split(' ');\n\n for (i = classNames.length; i--;) {\n matcher = new RegExp('\\\\.' + classNames[i] + '(?![a-zA-Z\\\\-]+)', 'i');\n selector = selector.replace(matcher, '');\n }\n }\n\n return selector.length === 0;\n }\n /**\n * @private\n * to support IE8 missing getElementById on SVGdocument and on node xmlDOM\n */\n\n\n function elementById(doc, id) {\n var el;\n doc.getElementById && (el = doc.getElementById(id));\n\n if (el) {\n return el;\n }\n\n var node,\n i,\n len,\n nodelist = doc.getElementsByTagName('*');\n\n for (i = 0, len = nodelist.length; i < len; i++) {\n node = nodelist[i];\n\n if (id === node.getAttribute('id')) {\n return node;\n }\n }\n }\n /**\n * @private\n */\n\n\n function parseUseDirectives(doc) {\n var nodelist = _getMultipleNodes(doc, ['use', 'svg:use']),\n i = 0;\n\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,\n oldLength = nodelist.length,\n attr,\n j,\n attrs,\n len,\n namespace = fabric.svgNS;\n applyViewboxTransform(el2);\n\n if (/^svg$/i.test(el2.nodeName)) {\n var el3 = el2.ownerDocument.createElementNS(namespace, 'g');\n\n for (j = 0, attrs = el2.attributes, len = attrs.length; j < len; j++) {\n attr = attrs.item(j);\n el3.setAttributeNS(namespace, attr.nodeName, attr.nodeValue);\n } // el2.firstChild != null\n\n\n while (el2.firstChild) {\n el3.appendChild(el2.firstChild);\n }\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\n if (attr.nodeName === 'x' || attr.nodeName === 'y' || attr.nodeName === 'xlink:href' || attr.nodeName === 'href') {\n continue;\n }\n\n if (attr.nodeName === 'transform') {\n currentTrans = attr.nodeValue + ' ' + currentTrans;\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); // some browsers do not shorten nodelist after replaceChild (IE8)\n\n if (nodelist.length === oldLength) {\n i++;\n }\n }\n } // http://www.w3.org/TR/SVG/coords.html#ViewBoxAttribute\n // matches, e.g.: +14.56e-12, etc.\n\n\n var reViewBoxAttrValue = new RegExp('^' + '\\\\s*(' + fabric.reNum + '+)\\\\s*,?' + '\\\\s*(' + fabric.reNum + '+)\\\\s*,?' + '\\\\s*(' + fabric.reNum + '+)\\\\s*,?' + '\\\\s*(' + fabric.reNum + '+)\\\\s*' + '$');\n /**\n * Add a element that envelop all child elements and makes the viewbox transformMatrix descend on all elements\n */\n\n function applyViewboxTransform(element) {\n if (!fabric.svgViewBoxElementsRegEx.test(element.nodeName)) {\n return;\n }\n\n var viewBoxAttr = element.getAttribute('viewBox'),\n scaleX = 1,\n scaleY = 1,\n minX = 0,\n minY = 0,\n viewBoxWidth,\n viewBoxHeight,\n matrix,\n 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 || !(viewBoxAttr = viewBoxAttr.match(reViewBoxAttrValue)),\n missingDimAttr = !widthAttr || !heightAttr || widthAttr === '100%' || heightAttr === '100%',\n toBeParsed = missingViewBox && missingDimAttr,\n parsedDim = {},\n translateMatrix = '',\n widthDiff = 0,\n heightDiff = 0;\n parsedDim.width = 0;\n parsedDim.height = 0;\n parsedDim.toBeParsed = toBeParsed;\n\n if (missingViewBox) {\n if ((x || y) && element.parentNode.nodeName !== '#document') {\n translateMatrix = ' translate(' + parseUnit(x) + ' ' + parseUnit(y) + ') ';\n matrix = (element.getAttribute('transform') || '') + translateMatrix;\n element.setAttribute('transform', matrix);\n element.removeAttribute('x');\n element.removeAttribute('y');\n }\n }\n\n if (toBeParsed) {\n return parsedDim;\n }\n\n if (missingViewBox) {\n parsedDim.width = parseUnit(widthAttr);\n parsedDim.height = parseUnit(heightAttr); // set a transform for elements that have x y and are inner(only) SVGs\n\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 parsedDim.minX = minX;\n parsedDim.minY = minY;\n parsedDim.viewBoxWidth = viewBoxWidth;\n parsedDim.viewBoxHeight = viewBoxHeight;\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 } else {\n parsedDim.width = viewBoxWidth;\n parsedDim.height = viewBoxHeight;\n } // default is to preserve aspect ratio\n\n\n preserveAspectRatio = fabric.util.parsePreserveAspectRatioAttribute(preserveAspectRatio);\n\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; // calculate additional translation to move the viewbox\n }\n\n if (preserveAspectRatio.meetOrSlice === 'slice') {\n scaleY = scaleX = scaleX > scaleY ? scaleX : scaleY; // calculate additional translation to move the viewbox\n }\n\n widthDiff = parsedDim.width - viewBoxWidth * scaleX;\n heightDiff = parsedDim.height - viewBoxHeight * scaleX;\n\n if (preserveAspectRatio.alignX === 'Mid') {\n widthDiff /= 2;\n }\n\n if (preserveAspectRatio.alignY === 'Mid') {\n heightDiff /= 2;\n }\n\n if (preserveAspectRatio.alignX === 'Min') {\n widthDiff = 0;\n }\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) && element.parentNode.nodeName !== '#document') {\n translateMatrix = ' translate(' + parseUnit(x) + ' ' + parseUnit(y) + ') ';\n }\n\n matrix = translateMatrix + ' matrix(' + scaleX + ' 0' + ' 0 ' + scaleY + ' ' + (minX * scaleX + widthDiff) + ' ' + (minY * scaleY + heightDiff) + ') '; // seems unused.\n // parsedDim.viewboxTransform = fabric.parseTransformAttribute(matrix);\n\n if (element.nodeName === 'svg') {\n el = element.ownerDocument.createElementNS(fabric.svgNS, 'g'); // element.firstChild != null\n\n while (element.firstChild) {\n el.appendChild(element.firstChild);\n }\n\n element.appendChild(el);\n } else {\n el = element;\n el.removeAttribute('x');\n el.removeAttribute('y');\n matrix = el.getAttribute('transform') + matrix;\n }\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:', '')) && !element.getAttribute('instantiated_by_use')) {\n return true;\n }\n }\n\n return false;\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\n\n fabric.parseSVGDocument = function (doc, callback, reviver, parsingOptions) {\n if (!doc) {\n return;\n }\n\n parseUseDirectives(doc);\n var svgUid = fabric.Object.__uid++,\n i,\n 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\n for (i = 0, len = descendants.length; i < len; i++) {\n arr[i] = descendants[i];\n }\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:', '')) && !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\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; // Precedence of rules: style > class > attribute\n\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\n if (referencedGradient && referencedGradient.getAttribute(xlinkAttr)) {\n recursivelyParseGradientsXlink(doc, referencedGradient);\n }\n\n gradientsAttrs.forEach(function (attr) {\n if (referencedGradient && !gradient.hasAttribute(attr) && referencedGradient.hasAttribute(attr)) {\n gradient.setAttribute(attr, referencedGradient.getAttribute(attr));\n }\n });\n\n if (!gradient.children.length) {\n var referenceClone = referencedGradient.cloneNode(true);\n\n while (referenceClone.firstChild) {\n gradient.appendChild(referenceClone.firstChild);\n }\n }\n\n gradient.removeAttribute(xlinkAttr);\n }\n\n var reFontDeclaration = new RegExp('(normal|italic)?\\\\s*(normal|small-caps)?\\\\s*' + '(normal|bold|bolder|lighter|100|200|300|400|500|600|700|800|900)?\\\\s*(' + fabric.reNum + '(?:px|cm|mm|em|pt|pc|in)*)(?:\\\\/(normal|' + fabric.reNum + '))?\\\\s+(.*)');\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 parseFontDeclaration(value, oStyle) {\n var match = value.match(reFontDeclaration);\n\n if (!match) {\n return;\n }\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\n if (fontWeight) {\n oStyle.fontWeight = isNaN(parseFloat(fontWeight)) ? fontWeight : parseFloat(fontWeight);\n }\n\n if (fontSize) {\n oStyle.fontSize = parseUnit(fontSize);\n }\n\n if (fontFamily) {\n oStyle.fontFamily = fontFamily;\n }\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 getGradientDefs(doc) {\n var tagArray = ['linearGradient', 'radialGradient', 'svg:linearGradient', 'svg:radialGradient'],\n elList = _getMultipleNodes(doc, tagArray),\n el,\n j = 0,\n gradientDefs = {};\n\n j = elList.length;\n\n while (j--) {\n el = elList[j];\n\n if (el.getAttribute('xlink:href')) {\n recursivelyParseGradientsXlink(doc, el);\n }\n\n gradientDefs[el.getAttribute('id')] = el;\n }\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 parseAttributes(element, attributes, svgUid) {\n if (!element) {\n return;\n }\n\n var value,\n parentAttributes = {},\n fontSize,\n parentFontSize;\n\n if (typeof svgUid === 'undefined') {\n svgUid = element.getAttribute('svgUid');\n } // if there's a parent container (`g` or `a` or `symbol` node), parse its attributes recursively upwards\n\n\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\n if (value) {\n // eslint-disable-line\n memo[attr] = value;\n }\n\n return memo;\n }, {}); // add values parsed from style, which take precedence over attributes\n // (see: http://www.w3.org/TR/SVG/styling.html#UsingPresentationAttributes)\n\n var cssAttrs = extend(getGlobalStylesForElement(element, svgUid), fabric.parseStyleAttribute(element));\n ownAttributes = extend(ownAttributes, cssAttrs);\n\n if (cssAttrs[cPath]) {\n element.setAttribute(cPath, cssAttrs[cPath]);\n }\n\n fontSize = parentFontSize = parentAttributes.fontSize || fabric.Text.DEFAULT_SVG_FONT_SIZE;\n\n if (ownAttributes[fSize]) {\n // looks like the minimum should be 9px when dealing with ems. this is what looks like in browsers.\n ownAttributes[fSize] = fontSize = parseUnit(ownAttributes[fSize], parentFontSize);\n }\n\n var normalizedAttr,\n normalizedValue,\n normalizedStyle = {};\n\n for (var attr in ownAttributes) {\n normalizedAttr = normalizeAttr(attr);\n normalizedValue = normalizeValue(normalizedAttr, ownAttributes[attr], parentAttributes, fontSize);\n normalizedStyle[normalizedAttr] = normalizedValue;\n }\n\n if (normalizedStyle && normalizedStyle.font) {\n fabric.parseFontDeclaration(normalizedStyle.font, normalizedStyle);\n }\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 parseElements(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 parseStyleAttribute(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 } 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 parsePointsAttribute(points) {\n // points attribute is required and must not be empty\n if (!points) {\n return null;\n } // replace commas with whitespace and remove bookending whitespace\n\n\n points = points.replace(/,/g, ' ').trim();\n points = points.split(/\\s+/);\n var parsedPoints = [],\n i,\n 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 } // odd number of points is an error\n // if (parsedPoints.length % 2 !== 0) {\n // return null;\n // }\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 getCSSRules(doc) {\n var styles = doc.getElementsByTagName('style'),\n i,\n len,\n allRules = {},\n rules; // very crude parsing of style contents\n\n for (i = 0, len = styles.length; i < len; i++) {\n // \\n'].join('');\n }\n\n return markup;\n },\n\n /**\n * @private\n */\n _setSVGObjects: function _setSVGObjects(markup, reviver) {\n var instance,\n i,\n len,\n objects = this._objects;\n\n for (i = 0, len = objects.length; i < len; i++) {\n instance = objects[i];\n\n if (instance.excludeFromExport) {\n continue;\n }\n\n this._setSVGObject(markup, instance, reviver);\n }\n },\n\n /**\n * @private\n */\n _setSVGObject: function _setSVGObject(markup, instance, reviver) {\n markup.push(instance.toSVG(reviver));\n },\n\n /**\n * @private\n */\n _setSVGBgOverlayImage: function _setSVGBgOverlayImage(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 _setSVGBgOverlayColor(markup, property) {\n var filler = this[property + 'Color'],\n vpt = this.viewportTransform,\n finalWidth = this.width,\n finalHeight = this.height;\n\n if (!filler) {\n return;\n }\n\n if (filler.toLive) {\n var repeat = filler.repeat,\n iVpt = fabric.util.invertTransform(vpt),\n shouldInvert = this[property + 'Vpt'],\n additionalTransform = shouldInvert ? fabric.util.matrixToSVG(iVpt) : '';\n markup.push('\\n');\n } else {\n markup.push('\\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 sendToBack(object) {\n if (!object) {\n return this;\n }\n\n var activeSelection = this._activeObject,\n i,\n obj,\n objs;\n\n if (object === activeSelection && object.type === 'activeSelection') {\n objs = activeSelection._objects;\n\n for (i = objs.length; i--;) {\n obj = objs[i];\n removeFromArray(this._objects, obj);\n\n this._objects.unshift(obj);\n }\n } else {\n removeFromArray(this._objects, object);\n\n this._objects.unshift(object);\n }\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 bringToFront(object) {\n if (!object) {\n return this;\n }\n\n var activeSelection = this._activeObject,\n i,\n obj,\n objs;\n\n if (object === activeSelection && object.type === 'activeSelection') {\n objs = activeSelection._objects;\n\n for (i = 0; i < objs.length; i++) {\n obj = objs[i];\n removeFromArray(this._objects, obj);\n\n this._objects.push(obj);\n }\n } else {\n removeFromArray(this._objects, object);\n\n this._objects.push(object);\n }\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 sendBackwards(object, intersecting) {\n if (!object) {\n return this;\n }\n\n var activeSelection = this._activeObject,\n i,\n obj,\n idx,\n newIdx,\n objs,\n objsMoved = 0;\n\n if (object === activeSelection && object.type === 'activeSelection') {\n objs = activeSelection._objects;\n\n for (i = 0; i < objs.length; i++) {\n obj = objs[i];\n idx = this._objects.indexOf(obj);\n\n if (idx > 0 + objsMoved) {\n newIdx = idx - 1;\n removeFromArray(this._objects, obj);\n\n this._objects.splice(newIdx, 0, obj);\n }\n\n objsMoved++;\n }\n } else {\n idx = this._objects.indexOf(object);\n\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\n this._objects.splice(newIdx, 0, object);\n }\n }\n\n this.renderOnAddRemove && this.requestRenderAll();\n return this;\n },\n\n /**\n * @private\n */\n _findNewLowerIndex: function _findNewLowerIndex(object, idx, intersecting) {\n var newIdx, i;\n\n if (intersecting) {\n newIdx = idx; // traverse down the stack looking for the nearest intersecting object\n\n for (i = idx - 1; i >= 0; --i) {\n var isIntersecting = object.intersectsWithObject(this._objects[i]) || object.isContainedWithinObject(this._objects[i]) || this._objects[i].isContainedWithinObject(object);\n\n if (isIntersecting) {\n newIdx = i;\n break;\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 bringForward(object, intersecting) {\n if (!object) {\n return this;\n }\n\n var activeSelection = this._activeObject,\n i,\n obj,\n idx,\n newIdx,\n objs,\n objsMoved = 0;\n\n if (object === activeSelection && object.type === 'activeSelection') {\n objs = activeSelection._objects;\n\n for (i = objs.length; i--;) {\n obj = objs[i];\n idx = this._objects.indexOf(obj);\n\n if (idx < this._objects.length - 1 - objsMoved) {\n newIdx = idx + 1;\n removeFromArray(this._objects, obj);\n\n this._objects.splice(newIdx, 0, obj);\n }\n\n objsMoved++;\n }\n } else {\n idx = this._objects.indexOf(object);\n\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\n this._objects.splice(newIdx, 0, object);\n }\n }\n\n this.renderOnAddRemove && this.requestRenderAll();\n return this;\n },\n\n /**\n * @private\n */\n _findNewUpperIndex: function _findNewUpperIndex(object, idx, intersecting) {\n var newIdx, i, len;\n\n if (intersecting) {\n newIdx = idx; // traverse up the stack looking for the nearest intersecting object\n\n for (i = idx + 1, len = this._objects.length; i < len; ++i) {\n var isIntersecting = object.intersectsWithObject(this._objects[i]) || object.isContainedWithinObject(this._objects[i]) || this._objects[i].isContainedWithinObject(object);\n\n if (isIntersecting) {\n newIdx = i;\n break;\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 moveTo(object, index) {\n removeFromArray(this._objects, object);\n\n this._objects.splice(index, 0, object);\n\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 dispose() {\n // cancel eventually ongoing renders\n if (this.isRendering) {\n fabric.util.cancelAnimFrame(this.isRendering);\n this.isRendering = 0;\n }\n\n this.forEachObject(function (object) {\n object.dispose && object.dispose();\n });\n this._objects = [];\n\n if (this.backgroundImage && this.backgroundImage.dispose) {\n this.backgroundImage.dispose();\n }\n\n this.backgroundImage = null;\n\n if (this.overlayImage && this.overlayImage.dispose) {\n this.overlayImage.dispose();\n }\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 toString() {\n return '#';\n }\n });\n extend(fabric.StaticCanvas.prototype, fabric.Observable);\n extend(fabric.StaticCanvas.prototype, fabric.Collection);\n extend(fabric.StaticCanvas.prototype, fabric.DataURLExporter);\n extend(fabric.StaticCanvas,\n /** @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 supports(methodName) {\n var el = createCanvasElement();\n\n if (!el || !el.getContext) {\n return null;\n }\n\n var ctx = el.getContext('2d');\n\n if (!ctx) {\n return null;\n }\n\n switch (methodName) {\n case 'setLineDash':\n return typeof ctx.setLineDash !== 'undefined';\n\n default:\n return null;\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 JSON without additional properties\n * var json = canvas.toJSON();\n * @example JSON with additional properties included\n * var json = canvas.toJSON(['lockMovementX', 'lockMovementY', 'lockRotation', 'lockScalingX', 'lockScalingY']);\n * @example JSON without default values\n * canvas.includeDefaultValues = false;\n * var json = canvas.toJSON();\n */\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\n fabric.StaticCanvas.prototype.createJPEGStream = function (opts) {\n var impl = getNodeCanvas(this.lowerCanvasEl);\n return impl && impl.createJPEGStream(opts);\n };\n }\n})();\n/**\n * BaseBrush class\n * @class fabric.BaseBrush\n * @see {@link http://fabricjs.com/freedrawing|Freedrawing demo}\n */\n\n\nfabric.BaseBrush = fabric.util.createClass(\n/** @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 * Backwards incompatibility note: 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 brush styles\n * @private\n */\n _setBrushStyles: function _setBrushStyles() {\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\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 _saveAndTransform(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 _setShadow() {\n if (!this.shadow) {\n return;\n }\n\n var canvas = this.canvas,\n shadow = this.shadow,\n ctx = canvas.contextTop,\n zoom = canvas.getZoom();\n\n if (canvas && canvas._isRetinaScaling()) {\n zoom *= fabric.devicePixelRatio;\n }\n\n ctx.shadowColor = shadow.color;\n ctx.shadowBlur = shadow.blur * zoom;\n ctx.shadowOffsetX = shadow.offsetX * zoom;\n ctx.shadowOffsetY = shadow.offsetY * zoom;\n },\n needsFullRender: function needsFullRender() {\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 _resetShadow() {\n var ctx = this.canvas.contextTop;\n ctx.shadowColor = '';\n ctx.shadowBlur = ctx.shadowOffsetX = ctx.shadowOffsetY = 0;\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,\n /** @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 initialize(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 _drawSegment(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 onMouseDown(pointer, options) {\n if (!this.canvas._isMainEvent(options.e)) {\n return;\n }\n\n this._prepareForDrawing(pointer); // capture coordinates immediately\n // this allows to draw dots (when movement never occurs)\n\n\n this._captureDrawingPath(pointer);\n\n this._render();\n },\n\n /**\n * Inovoked on mouse move\n * @param {Object} pointer\n */\n onMouseMove: function onMouseMove(pointer, options) {\n if (!this.canvas._isMainEvent(options.e)) {\n return;\n }\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\n this._render();\n } else {\n var points = this._points,\n length = points.length,\n ctx = this.canvas.contextTop; // draw the curve update\n\n this._saveAndTransform(ctx);\n\n if (this.oldEnd) {\n ctx.beginPath();\n ctx.moveTo(this.oldEnd.x, this.oldEnd.y);\n }\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 onMouseUp(options) {\n if (!this.canvas._isMainEvent(options.e)) {\n return true;\n }\n\n this.oldEnd = undefined;\n\n this._finalizeAndAddPath();\n\n return false;\n },\n\n /**\n * @private\n * @param {Object} pointer Actual mouse position related to the canvas.\n */\n _prepareForDrawing: function _prepareForDrawing(pointer) {\n var p = new fabric.Point(pointer.x, pointer.y);\n\n this._reset();\n\n this._addPoint(p);\n\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 _addPoint(point) {\n if (this._points.length > 1 && point.eq(this._points[this._points.length - 1])) {\n return false;\n }\n\n this._points.push(point);\n\n return true;\n },\n\n /**\n * Clear points array and set contextTop canvas style.\n * @private\n */\n _reset: function _reset() {\n this._points = [];\n\n this._setBrushStyles();\n\n this._setShadow();\n },\n\n /**\n * @private\n * @param {Object} pointer Actual mouse position related to the canvas.\n */\n _captureDrawingPath: function _captureDrawingPath(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 _render() {\n var ctx = this.canvas.contextTop,\n i,\n len,\n p1 = this._points[0],\n p2 = this._points[1];\n\n this._saveAndTransform(ctx);\n\n ctx.beginPath(); //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\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\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\n p1 = this._points[i];\n p2 = this._points[i + 1];\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\n\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 convertPointsToSVGPath(points) {\n var path = [],\n i,\n 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,\n multSignX = 1,\n multSignY = 0,\n 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\n path.push('M ', p1.x - multSignX * width, ' ', p1.y - multSignY * width, ' ');\n\n for (i = 1; i < len; i++) {\n if (!p1.eq(p2)) {\n var midPoint = p1.midPointFrom(p2); // p1 is our bezier control point\n // midpoint is our endpoint\n // start point is p(i-1) value.\n\n path.push('Q ', p1.x, ' ', p1.y, ' ', midPoint.x, ' ', midPoint.y, ' ');\n }\n\n p1 = points[i];\n\n if (i + 1 < points.length) {\n p2 = points[i + 1];\n }\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\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 createPath(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\n if (this.shadow) {\n this.shadow.affectStroke = true;\n path.shadow = new fabric.Shadow(this.shadow);\n }\n\n return path;\n },\n\n /**\n * Decimate poins array with the decimate value\n */\n decimatePoints: function decimatePoints(points, distance) {\n if (points.length <= 2) {\n return points;\n }\n\n var zoom = this.canvas.getZoom(),\n adjustedDistance = Math.pow(distance / zoom, 2),\n i,\n l = points.length - 1,\n lastPoint = points[0],\n newPoints = [lastPoint],\n cDistance;\n\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\n if (cDistance >= adjustedDistance) {\n lastPoint = points[i];\n newPoints.push(lastPoint);\n }\n }\n\n if (newPoints.length === 1) {\n newPoints.push(new fabric.Point(newPoints[0].x, newPoints[0].y));\n }\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 _finalizeAndAddPath() {\n var ctx = this.canvas.contextTop;\n ctx.closePath();\n\n if (this.decimate) {\n this._points = this.decimatePoints(this._points, this.decimate);\n }\n\n var pathData = this.convertPointsToSVGPath(this._points).join('');\n\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.fire('before:path:created', {\n path: path\n });\n this.canvas.add(path);\n this.canvas.requestRenderAll();\n path.setCoords();\n\n this._resetShadow(); // fire event 'path' created\n\n\n this.canvas.fire('path:created', {\n path: path\n });\n }\n });\n})();\n/**\n * CircleBrush class\n * @class fabric.CircleBrush\n */\n\n\nfabric.CircleBrush = fabric.util.createClass(fabric.BaseBrush,\n/** @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 initialize(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 drawDot(pointer) {\n var point = this.addPoint(pointer),\n ctx = this.canvas.contextTop;\n\n this._saveAndTransform(ctx);\n\n this.dot(ctx, point);\n ctx.restore();\n },\n dot: function dot(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 onMouseDown(pointer) {\n this.points.length = 0;\n this.canvas.clearContext(this.canvas.contextTop);\n\n this._setShadow();\n\n this.drawDot(pointer);\n },\n\n /**\n * Render the full state of the brush\n * @private\n */\n _render: function _render() {\n var ctx = this.canvas.contextTop,\n i,\n len,\n points = this.points;\n\n this._saveAndTransform(ctx);\n\n for (i = 0, len = points.length; i < len; i++) {\n this.dot(ctx, points[i]);\n }\n\n ctx.restore();\n },\n\n /**\n * Invoked on mouse move\n * @param {Object} pointer\n */\n onMouseMove: function onMouseMove(pointer) {\n if (this.needsFullRender()) {\n this.canvas.clearContext(this.canvas.contextTop);\n this.addPoint(pointer);\n\n this._render();\n } else {\n this.drawDot(pointer);\n }\n },\n\n /**\n * Invoked on mouse up\n */\n onMouseUp: function onMouseUp() {\n var originalRenderOnAddRemove = this.canvas.renderOnAddRemove,\n i,\n len;\n this.canvas.renderOnAddRemove = false;\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 this.shadow && (circle.shadow = new fabric.Shadow(this.shadow));\n circles.push(circle);\n }\n\n var group = new fabric.Group(circles);\n group.canvas = this.canvas;\n this.canvas.fire('before:path:created', {\n path: group\n });\n this.canvas.add(group);\n this.canvas.fire('path:created', {\n path: group\n });\n this.canvas.clearContext(this.canvas.contextTop);\n\n this._resetShadow();\n\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 addPoint(pointer) {\n var pointerPoint = new fabric.Point(pointer.x, pointer.y),\n circleRadius = fabric.util.getRandomInt(Math.max(0, this.width - 20), this.width + 20) / 2,\n circleColor = new fabric.Color(this.color).setAlpha(fabric.util.getRandomInt(0, 100) / 100).toRgba();\n pointerPoint.radius = circleRadius;\n pointerPoint.fill = circleColor;\n this.points.push(pointerPoint);\n return pointerPoint;\n }\n});\n/**\n * SprayBrush class\n * @class fabric.SprayBrush\n */\n\nfabric.SprayBrush = fabric.util.createClass(fabric.BaseBrush,\n/** @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 initialize(canvas) {\n this.canvas = canvas;\n this.sprayChunks = [];\n },\n\n /**\n * Invoked on mouse down\n * @param {Object} pointer\n */\n onMouseDown: function onMouseDown(pointer) {\n this.sprayChunks.length = 0;\n this.canvas.clearContext(this.canvas.contextTop);\n\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 onMouseMove(pointer) {\n this.addSprayChunk(pointer);\n this.render(this.sprayChunkPoints);\n },\n\n /**\n * Invoked on mouse up\n */\n onMouseUp: function onMouseUp() {\n var originalRenderOnAddRemove = this.canvas.renderOnAddRemove;\n this.canvas.renderOnAddRemove = false;\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 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.set('shadow', new fabric.Shadow(this.shadow));\n this.canvas.fire('before:path:created', {\n path: group\n });\n this.canvas.add(group);\n this.canvas.fire('path:created', {\n path: group\n });\n this.canvas.clearContext(this.canvas.contextTop);\n\n this._resetShadow();\n\n this.canvas.renderOnAddRemove = originalRenderOnAddRemove;\n this.canvas.requestRenderAll();\n },\n\n /**\n * @private\n * @param {Array} rects\n */\n _getOptimizedRects: function _getOptimizedRects(rects) {\n // avoid creating duplicate rects at the same coordinates\n var uniqueRects = {},\n key,\n i,\n len;\n\n for (i = 0, len = rects.length; i < len; i++) {\n key = rects[i].left + '' + rects[i].top;\n\n if (!uniqueRects[key]) {\n uniqueRects[key] = rects[i];\n }\n }\n\n var uniqueRectsArray = [];\n\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 render(sprayChunk) {\n var ctx = this.canvas.contextTop,\n i,\n 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\n if (typeof point.opacity !== 'undefined') {\n ctx.globalAlpha = point.opacity;\n }\n\n ctx.fillRect(point.x, point.y, point.width, point.width);\n }\n\n ctx.restore();\n },\n\n /**\n * Render all spray chunks\n */\n _render: function _render() {\n var ctx = this.canvas.contextTop,\n i,\n 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\n ctx.restore();\n },\n\n /**\n * @param {Object} pointer\n */\n addSprayChunk: function addSprayChunk(pointer) {\n this.sprayChunkPoints = [];\n var x,\n y,\n width,\n radius = this.width / 2,\n i;\n\n for (i = 0; i < this.density; i++) {\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( // bottom clamp width to 1\n Math.max(1, this.dotWidth - this.dotWidthVariance), this.dotWidth + this.dotWidthVariance);\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 * PatternBrush class\n * @class fabric.PatternBrush\n * @extends fabric.BaseBrush\n */\n\nfabric.PatternBrush = fabric.util.createClass(fabric.PencilBrush,\n/** @lends fabric.PatternBrush.prototype */\n{\n getPatternSrc: function getPatternSrc() {\n var dotWidth = 20,\n dotDistance = 5,\n patternCanvas = fabric.util.createCanvasElement(),\n patternCtx = patternCanvas.getContext('2d');\n patternCanvas.width = patternCanvas.height = dotWidth + dotDistance;\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 return patternCanvas;\n },\n getPatternSrcFunction: function getPatternSrcFunction() {\n return String(this.getPatternSrc).replace('this.color', '\"' + this.color + '\"');\n },\n\n /**\n * Creates \"pattern\" instance property\n */\n getPattern: function getPattern() {\n return this.canvas.contextTop.createPattern(this.source || this.getPatternSrc(), 'repeat');\n },\n\n /**\n * Sets brush styles\n */\n _setBrushStyles: function _setBrushStyles() {\n this.callSuper('_setBrushStyles');\n this.canvas.contextTop.strokeStyle = this.getPattern();\n },\n\n /**\n * Creates path\n */\n createPath: function createPath(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(function () {\n var _getPointer = fabric.util.getPointer,\n degreesToRadians = fabric.util.degreesToRadians,\n abs = Math.abs,\n supportLineDash = fabric.StaticCanvas.supports('setLineDash'),\n isTouchEvent = fabric.util.isTouchEvent,\n STROKE_OFFSET = 0.5;\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 at the end of a transform or any change when statefull is true\n * @fires object:rotated at the end of a rotation transform\n * @fires object:scaled at the end of a scale transform\n * @fires object:moved at the end of translation transform\n * @fires object:skewed at the end of a skew transform\n * @fires object:rotating while an object is being rotated from the control\n * @fires object:scaling while an object is being scaled by controls\n * @fires object:moving while an object is being dragged\n * @fires object:skewing while an object is being skewed from the controls\n *\n * @fires before:transform before a transform is is started\n * @fires before:selection:cleared\n * @fires selection:cleared\n * @fires selection:updated\n * @fires selection:created\n *\n * @fires path:created after a drawing operation ends and the path is added\n * @fires mouse:down\n * @fires mouse:move\n * @fires mouse:up\n * @fires mouse:down:before on mouse down, before the inner fabric logic runs\n * @fires mouse:move:before on mouse move, before the inner fabric logic runs\n * @fires mouse:up:before on mouse up, before the inner fabric logic runs\n * @fires mouse:over\n * @fires mouse:out\n * @fires mouse:dblclick whenever a native dbl click event fires on the canvas.\n *\n * @fires dragover\n * @fires dragenter\n * @fires dragleave\n * @fires drop\n * @fires after:render at the end of the render process, receives the context in the callback\n * @fires before:render at start the render process, receives the context in the callback\n *\n */\n\n fabric.Canvas = fabric.util.createClass(fabric.StaticCanvas,\n /** @lends fabric.Canvas.prototype */\n {\n /**\n * Constructor\n * @param {HTMLElement | String} el <canvas> element to initialize instance on\n * @param {Object} [options] Options object\n * @return {Object} thisArg\n */\n initialize: function initialize(el, options) {\n options || (options = {});\n this.renderAndResetBound = this.renderAndReset.bind(this);\n this.requestRenderAllBound = this.requestRenderAll.bind(this);\n\n this._initStatic(el, options);\n\n this._initInteractive();\n\n this._createCacheCanvas();\n },\n\n /**\n * When true, objects can be transformed by one side (unproportionally)\n * when dragged on the corners that normally would not do that.\n * @type Boolean\n * @default\n * @since fabric 4.0 // changed name and default value\n */\n uniformScaling: true,\n\n /**\n * Indicates which key switches uniform 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.\n * totally wrong named. this sounds like `uniform scaling`\n * if Canvas.uniformScaling is true, pressing this will set it to false\n * and viceversa.\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 * Backwards incompatibility note: 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 * Backwards incompatibility note: 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)',\n // 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 * Keep track of the subTargets for Mouse Events\n * @type fabric.Object[]\n */\n targets: [],\n\n /**\n * Keep track of the hovered target\n * @type fabric.Object\n * @private\n */\n _hoveredTarget: null,\n\n /**\n * hold the list of nested targets hovered\n * @type fabric.Object[]\n * @private\n */\n _hoveredTargets: [],\n\n /**\n * @private\n */\n _initInteractive: function _initInteractive() {\n this._currentTransform = null;\n this._groupSelector = null;\n\n this._initWrapperElement();\n\n this._createUpperCanvas();\n\n this._initEventListeners();\n\n this._initRetinaScaling();\n\n this.freeDrawingBrush = fabric.PencilBrush && new fabric.PencilBrush(this);\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 _chooseObjectsToRender() {\n var activeObjects = this.getActiveObjects(),\n object,\n objsToRender,\n activeGroupObjects;\n\n if (activeObjects.length > 0 && !this.preserveObjectStacking) {\n objsToRender = [];\n activeGroupObjects = [];\n\n for (var i = 0, length = this._objects.length; i < length; i++) {\n object = this._objects[i];\n\n if (activeObjects.indexOf(object) === -1) {\n objsToRender.push(object);\n } else {\n activeGroupObjects.push(object);\n }\n }\n\n if (activeObjects.length > 1) {\n this._activeObject._objects = activeGroupObjects;\n }\n\n objsToRender.push.apply(objsToRender, activeGroupObjects);\n } else {\n objsToRender = this._objects;\n }\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 renderAll() {\n if (this.contextTopDirty && !this._groupSelector && !this.isDrawingMode) {\n this.clearContext(this.contextTop);\n this.contextTopDirty = false;\n }\n\n if (this.hasLostContext) {\n this.renderTopLayer(this.contextTop);\n }\n\n var canvasToDrawOn = this.contextContainer;\n this.renderCanvas(canvasToDrawOn, this._chooseObjectsToRender());\n return this;\n },\n renderTopLayer: function renderTopLayer(ctx) {\n ctx.save();\n\n if (this.isDrawingMode && this._isCurrentlyDrawing) {\n this.freeDrawingBrush && this.freeDrawingBrush._render();\n this.contextTopDirty = true;\n } // we render the top context - last object\n\n\n if (this.selection && this._groupSelector) {\n this._drawSelection(ctx);\n\n this.contextTopDirty = true;\n }\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 renderTop() {\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 * @private\n */\n _normalizePointer: function _normalizePointer(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 isTargetTransparent(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, {\n x: x,\n y: y\n }),\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(target._cacheContext, Math.round(targetRelativeX), Math.round(targetRelativeY), this.targetFindTolerance);\n return isTransparent;\n }\n\n var ctx = this.contextCache,\n originalColor = target.selectionBackgroundColor,\n v = this.viewportTransform;\n target.selectionBackgroundColor = '';\n this.clearContext(ctx);\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 target === this._activeObject && target._renderControls(ctx, {\n hasBorders: false,\n transparentCorners: false\n }, {\n hasBorders: false\n });\n target.selectionBackgroundColor = originalColor;\n var isTransparent = fabric.util.isTransparent(ctx, x, y, this.targetFindTolerance);\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 _isSelectionKeyPressed(e) {\n var selectionKeyPressed = false;\n\n if (Object.prototype.toString.call(this.selectionKey) === '[object Array]') {\n selectionKeyPressed = !!this.selectionKey.find(function (key) {\n 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 _shouldClearSelection(e, target) {\n var activeObjects = this.getActiveObjects(),\n activeObject = this._activeObject;\n return !target || target && activeObject && activeObjects.length > 1 && activeObjects.indexOf(target) === -1 && activeObject !== target && !this._isSelectionKeyPressed(e) || target && !target.evented || target && !target.selectable && activeObject && activeObject !== target;\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 * also this should be something that will be migrated in the control properties.\n * as ability to define the origin of the transformation that the control provide.\n * @private\n * @param {fabric.Object} target\n * @param {String} action\n * @param {Boolean} altKey\n */\n _shouldCenterTransform: function _shouldCenterTransform(target, action, altKey) {\n if (!target) {\n return;\n }\n\n var centerTransform;\n\n if (action === 'scale' || action === 'scaleX' || action === 'scaleY' || action === 'resizing') {\n centerTransform = this.centeredScaling || target.centeredScaling;\n } else if (action === 'rotate') {\n centerTransform = this.centeredRotation || target.centeredRotation;\n }\n\n return centerTransform ? !altKey : altKey;\n },\n\n /**\n * should disappear before release 4.0\n * @private\n */\n _getOriginFromCorner: function _getOriginFromCorner(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 } 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 } else if (corner === 'bl' || corner === 'mb' || corner === 'br') {\n origin.y = 'top';\n } else if (corner === 'mtr') {\n origin.x = 'center';\n origin.y = 'center';\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 _getActionFromCorner(alreadySelected, corner, e, target) {\n if (!corner || !alreadySelected) {\n return 'drag';\n }\n\n var control = target.controls[corner];\n return control.getActionName(e, control, target);\n },\n\n /**\n * @private\n * @param {Event} e Event object\n * @param {fabric.Object} target\n */\n _setupCurrentTransform: function _setupCurrentTransform(e, target, alreadySelected) {\n if (!target) {\n return;\n }\n\n var pointer = this.getPointer(e),\n corner = target.__corner,\n actionHandler = !!corner && target.controls[corner].getActionHandler(),\n action = this._getActionFromCorner(alreadySelected, corner, e, target),\n origin = this._getOriginFromCorner(target, corner),\n altKey = e[this.centeredKey],\n transform = {\n target: target,\n action: action,\n actionHandler: actionHandler,\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 useful 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 shiftKey: e.shiftKey,\n altKey: altKey,\n original: fabric.util.saveObjectTransform(target)\n };\n\n if (this._shouldCenterTransform(target, action, altKey)) {\n transform.originX = 'center';\n transform.originY = 'center';\n }\n\n transform.original.originX = origin.x;\n transform.original.originY = origin.y;\n this._currentTransform = transform;\n\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 _translateObject(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 moveX && target.set('left', newLeft);\n moveY && target.set('top', newTop);\n return moveX || moveY;\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 setCursor(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 _drawSelection(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 ctx.fillRect(groupSelector.ex - (left > 0 ? 0 : -left), groupSelector.ey - (top > 0 ? 0 : -top), aleft, atop);\n }\n\n if (!this.selectionLineWidth || !this.selectionBorderColor) {\n return;\n }\n\n ctx.lineWidth = this.selectionLineWidth;\n ctx.strokeStyle = this.selectionBorderColor; // selection border\n\n if (this.selectionDashArray.length > 1 && !supportLineDash) {\n var px = groupSelector.ex + STROKE_OFFSET - (left > 0 ? 0 : aleft),\n py = groupSelector.ey + STROKE_OFFSET - (top > 0 ? 0 : atop);\n ctx.beginPath();\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 ctx.closePath();\n ctx.stroke();\n } else {\n fabric.Object.prototype._setLineDash.call(this, ctx, this.selectionDashArray);\n\n ctx.strokeRect(groupSelector.ex + STROKE_OFFSET - (left > 0 ? 0 : aleft), groupSelector.ey + STROKE_OFFSET - (top > 0 ? 0 : atop), aleft, atop);\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 findTarget(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,\n activeTargetSubs,\n isTouch = isTouchEvent(e); // 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\n this.targets = [];\n\n if (aObjects.length > 1 && !skipGroup && activeObject === this._searchPossibleTargets([activeObject], pointer)) {\n return activeObject;\n } // if we hit the corner of an activeObject, let's return that.\n\n\n if (aObjects.length === 1 && activeObject._findTargetCorner(pointer, isTouch)) {\n return activeObject;\n }\n\n if (aObjects.length === 1 && activeObject === this._searchPossibleTargets([activeObject], pointer)) {\n if (!this.preserveObjectStacking) {\n return activeObject;\n } else {\n activeTarget = activeObject;\n activeTargetSubs = this.targets;\n this.targets = [];\n }\n }\n\n var target = this._searchPossibleTargets(this._objects, pointer);\n\n if (e[this.altSelectionKey] && target && activeTarget && target !== activeTarget) {\n target = activeTarget;\n this.targets = activeTargetSubs;\n }\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 _checkTarget(pointer, obj, globalPointer) {\n if (obj && obj.visible && obj.evented && ( // http://www.geog.ubc.ca/courses/klink/gis.notes/ncgia/u32.html\n // http://idav.ucdavis.edu/~okreylos/TAship/Spring2000/PointInPolygon.html\n obj.containsPoint(pointer) || !!obj._findTargetCorner(pointer))) {\n if ((this.perPixelTargetFind || obj.perPixelTargetFind) && !obj.isEditing) {\n var isTransparent = this.isTargetTransparent(obj, globalPointer.x, globalPointer.y);\n\n if (!isTransparent) {\n return true;\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 _searchPossibleTargets(objects, pointer) {\n // Cache all targets where their bounding box contains point.\n var target,\n i = objects.length,\n subTarget; // 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\n while (i--) {\n var objToCheck = objects[i];\n var pointerToUse = objToCheck.group ? this._normalizePointer(objToCheck.group, pointer) : pointer;\n\n if (this._checkTarget(pointerToUse, objToCheck, pointer)) {\n target = objects[i];\n\n if (target.subTargetCheck && target instanceof fabric.Group) {\n subTarget = this._searchPossibleTargets(target._objects, pointer);\n subTarget && this.targets.push(subTarget);\n }\n\n break;\n }\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 restorePointerVpt(pointer) {\n return fabric.util.transformPoint(pointer, fabric.util.invertTransform(this.viewportTransform));\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 getPointer(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\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\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\n if (!ignoreZoom) {\n pointer = this.restorePointerVpt(pointer);\n }\n\n var retinaScaling = this.getRetinaScaling();\n\n if (retinaScaling !== 1) {\n pointer.x /= retinaScaling;\n pointer.y /= retinaScaling;\n }\n\n if (boundsWidth === 0 || boundsHeight === 0) {\n // If bounds are not available (i.e. not visible), do not apply scale.\n cssScale = {\n width: 1,\n 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 _createUpperCanvas() {\n var lowerCanvasClass = this.lowerCanvasEl.className.replace(/\\s*lower-canvas\\s*/, ''),\n lowerCanvasEl = this.lowerCanvasEl,\n upperCanvasEl = this.upperCanvasEl; // there is no need to create a new upperCanvas element if we have already one.\n\n if (upperCanvasEl) {\n upperCanvasEl.className = '';\n } else {\n upperCanvasEl = this._createCanvasElement();\n this.upperCanvasEl = upperCanvasEl;\n }\n\n fabric.util.addClass(upperCanvasEl, 'upper-canvas ' + lowerCanvasClass);\n this.wrapperEl.appendChild(upperCanvasEl);\n\n this._copyCanvasStyle(lowerCanvasEl, upperCanvasEl);\n\n this._applyCanvasStyle(upperCanvasEl);\n\n this.contextTop = upperCanvasEl.getContext('2d');\n },\n\n /**\n * @private\n */\n _createCacheCanvas: function _createCacheCanvas() {\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 _initWrapperElement() {\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 _applyCanvasStyle(element) {\n var width = this.width || element.width,\n height = this.height || element.height;\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 _copyCanvasStyle(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 getSelectionContext() {\n return this.contextTop;\n },\n\n /**\n * Returns <canvas> element on which object selection is drawn\n * @return {HTMLCanvasElement}\n */\n getSelectionElement: function getSelectionElement() {\n return this.upperCanvasEl;\n },\n\n /**\n * Returns currently active object\n * @return {fabric.Object} active object\n */\n getActiveObject: function getActiveObject() {\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 getActiveObjects() {\n var active = this._activeObject;\n\n if (active) {\n if (active.type === 'activeSelection' && active._objects) {\n return active._objects.slice(0);\n } else {\n return [active];\n }\n }\n\n return [];\n },\n\n /**\n * @private\n * @param {fabric.Object} obj Object that was removed\n */\n _onObjectRemoved: function _onObjectRemoved(obj) {\n // removing active object should fire \"selection:cleared\" events\n if (obj === this._activeObject) {\n this.fire('before:selection:cleared', {\n target: obj\n });\n\n this._discardActiveObject();\n\n this.fire('selection:cleared', {\n target: obj\n });\n obj.fire('deselected');\n }\n\n if (obj === this._hoveredTarget) {\n this._hoveredTarget = null;\n this._hoveredTargets = [];\n }\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 _fireSelectionEvents(oldObjects, e) {\n var somethingChanged = false,\n objects = this.getActiveObjects(),\n added = [],\n removed = [],\n opt = {\n e: e\n };\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\n if (oldObjects.length > 0 && objects.length > 0) {\n opt.selected = added;\n opt.deselected = removed; // added for backward compatibility\n\n opt.updated = added[0] || removed[0];\n opt.target = this._activeObject;\n somethingChanged && this.fire('selection:updated', opt);\n } else if (objects.length > 0) {\n opt.selected = added; // added for backward compatibility\n\n opt.target = this._activeObject;\n this.fire('selection:created', opt);\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 setActiveObject(object, e) {\n var currentActives = this.getActiveObjects();\n\n this._setActiveObject(object, e);\n\n this._fireSelectionEvents(currentActives, e);\n\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 _setActiveObject(object, e) {\n if (this._activeObject === object) {\n return false;\n }\n\n if (!this._discardActiveObject(e, object)) {\n return false;\n }\n\n if (object.onSelect({\n e: e\n })) {\n return false;\n }\n\n this._activeObject = object;\n return true;\n },\n\n /**\n * @private\n */\n _discardActiveObject: function _discardActiveObject(e, object) {\n var obj = this._activeObject;\n\n if (obj) {\n // onDeselect return TRUE to cancel selection;\n if (obj.onDeselect({\n e: e,\n object: object\n })) {\n return false;\n }\n\n this._activeObject = null;\n }\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 discardActiveObject(e) {\n var currentActives = this.getActiveObjects(),\n activeObject = this.getActiveObject();\n\n if (currentActives.length) {\n this.fire('before:selection:cleared', {\n target: activeObject,\n e: e\n });\n }\n\n this._discardActiveObject(e);\n\n this._fireSelectionEvents(currentActives, e);\n\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 dispose() {\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\n if (wrapper.parentNode) {\n wrapper.parentNode.replaceChild(this.lowerCanvasEl, this.wrapperEl);\n }\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 clear() {\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 drawControls(ctx) {\n var activeObject = this._activeObject;\n\n if (activeObject) {\n activeObject._renderControls(ctx);\n }\n },\n\n /**\n * @private\n */\n _toObject: function _toObject(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); //Undo the damage we did by changing all of its properties\n\n\n this._unwindGroupTransformOnObject(instance, originalProperties);\n\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 _realizeGroupTransformOnObject(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']; //Copy all the positionally relevant properties across now\n\n var originalValues = {};\n layoutProps.forEach(function (prop) {\n originalValues[prop] = instance[prop];\n });\n\n this._activeObject.realizeTransform(instance);\n\n return originalValues;\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 _unwindGroupTransformOnObject(instance, originalValues) {\n if (originalValues) {\n instance.set(originalValues);\n }\n },\n\n /**\n * @private\n */\n _setSVGObject: function _setSVGObject(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\n this.callSuper('_setSVGObject', markup, instance, reviver);\n\n this._unwindGroupTransformOnObject(instance, originalProperties);\n },\n setViewportTransform: function setViewportTransform(vpt) {\n if (this.renderOnAddRemove && this._activeObject && this._activeObject.isEditing) {\n this._activeObject.clearContextTop();\n }\n\n fabric.StaticCanvas.prototype.setViewportTransform.call(this, vpt);\n }\n }); // copying static properties manually to work around Opera's bug,\n // where \"prototype\" property is enumerable and overrides existing prototype\n\n for (var prop in fabric.StaticCanvas) {\n if (prop !== 'prototype') {\n fabric.Canvas[prop] = fabric.StaticCanvas[prop];\n }\n }\n})();\n\n(function () {\n var addListener = fabric.util.addListener,\n removeListener = fabric.util.removeListener,\n RIGHT_CLICK = 3,\n MIDDLE_CLICK = 2,\n LEFT_CLICK = 1,\n addEventOptions = {\n passive: false\n };\n\n function checkClick(e, value) {\n return e.button && e.button === value - 1;\n }\n\n fabric.util.object.extend(fabric.Canvas.prototype,\n /** @lends fabric.Canvas.prototype */\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 _initEventListeners() {\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\n this._bindEvents();\n\n this.addOrRemove(addListener, 'add');\n },\n\n /**\n * return an event prefix pointer or mouse.\n * @private\n */\n _getEventPrefix: function _getEventPrefix() {\n return this.enablePointerEvents ? 'pointer' : 'mouse';\n },\n addOrRemove: function addOrRemove(functor, eventjsFunctor) {\n var canvasElement = this.upperCanvasEl,\n eventTypePrefix = this._getEventPrefix();\n\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\n if (!this.enablePointerEvents) {\n functor(canvasElement, 'touchstart', this._onTouchStart, addEventOptions);\n }\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 removeListeners() {\n this.addOrRemove(removeListener, 'remove'); // if you dispose on a mouseDown, before mouse up, you need to clean document to...\n\n var eventTypePrefix = this._getEventPrefix();\n\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 _bindEvents() {\n if (this.eventsBound) {\n // for any reason we pass here twice we do not want to bind events twice.\n return;\n }\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 _onGesture(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 _onDrag(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 _onMouseWheel(e) {\n this.__onMouseWheel(e);\n },\n\n /**\n * @private\n * @param {Event} e Event object fired on mousedown\n */\n _onMouseOut: function _onMouseOut(e) {\n var target = this._hoveredTarget;\n this.fire('mouse:out', {\n target: target,\n e: e\n });\n this._hoveredTarget = null;\n target && target.fire('mouseout', {\n e: e\n });\n\n var _this = this;\n\n this._hoveredTargets.forEach(function (_target) {\n _this.fire('mouse:out', {\n target: target,\n e: e\n });\n\n _target && target.fire('mouseout', {\n e: e\n });\n });\n\n this._hoveredTargets = [];\n\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 _onMouseEnter(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', {\n target: null,\n e: e\n });\n this._hoveredTarget = null;\n this._hoveredTargets = [];\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 _onOrientationChange(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 _onShake(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 _onLongPress(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 _onDragOver(e) {\n e.preventDefault();\n\n var target = this._simpleEventHandler('dragover', e);\n\n this._fireEnterLeaveEvents(target, e);\n },\n\n /**\n * @private\n * @param {Event} e Event object fired on mousedown\n */\n _onContextMenu: function _onContextMenu(e) {\n if (this.stopContextMenu) {\n e.stopPropagation();\n e.preventDefault();\n }\n\n return false;\n },\n\n /**\n * @private\n * @param {Event} e Event object fired on mousedown\n */\n _onDoubleClick: function _onDoubleClick(e) {\n this._cacheTransformEventData(e);\n\n this._handleEvent(e, 'dblclick');\n\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 getPointerId(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 _isMainEvent(evt) {\n if (evt.isPrimary === true) {\n return true;\n }\n\n if (evt.isPrimary === false) {\n return false;\n }\n\n if (evt.type === 'touchend' && evt.touches.length === 0) {\n return true;\n }\n\n if (evt.changedTouches) {\n return evt.changedTouches[0].identifier === this.mainTouchId;\n }\n\n return true;\n },\n\n /**\n * @private\n * @param {Event} e Event object fired on mousedown\n */\n _onTouchStart: function _onTouchStart(e) {\n e.preventDefault();\n\n if (this.mainTouchId === null) {\n this.mainTouchId = this.getPointerId(e);\n }\n\n this.__onMouseDown(e);\n\n this._resetTransformEventData();\n\n var canvasElement = this.upperCanvasEl,\n eventTypePrefix = this._getEventPrefix();\n\n addListener(fabric.document, 'touchend', this._onTouchEnd, addEventOptions);\n addListener(fabric.document, 'touchmove', this._onMouseMove, addEventOptions); // Unbind mousedown to prevent double triggers from touch devices\n\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 _onMouseDown(e) {\n this.__onMouseDown(e);\n\n this._resetTransformEventData();\n\n var canvasElement = this.upperCanvasEl,\n eventTypePrefix = this._getEventPrefix();\n\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 _onTouchEnd(e) {\n if (e.touches.length > 0) {\n // if there are still touches stop here\n return;\n }\n\n this.__onMouseUp(e);\n\n this._resetTransformEventData();\n\n this.mainTouchId = null;\n\n var eventTypePrefix = this._getEventPrefix();\n\n removeListener(fabric.document, 'touchend', this._onTouchEnd, addEventOptions);\n removeListener(fabric.document, 'touchmove', this._onMouseMove, addEventOptions);\n\n var _this = this;\n\n if (this._willAddMouseDown) {\n clearTimeout(this._willAddMouseDown);\n }\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 _onMouseUp(e) {\n this.__onMouseUp(e);\n\n this._resetTransformEventData();\n\n var canvasElement = this.upperCanvasEl,\n eventTypePrefix = this._getEventPrefix();\n\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 _onMouseMove(e) {\n !this.allowTouchScrolling && e.preventDefault && e.preventDefault();\n\n this.__onMouseMove(e);\n },\n\n /**\n * @private\n */\n _onResize: function _onResize() {\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 _shouldRender(target) {\n var activeObject = this._activeObject;\n\n if (!!activeObject !== !!target || activeObject && target && activeObject !== target) {\n // this covers: switch of target, from target to no target, selection of target\n // multiSelection with key and mouse\n return true;\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\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 __onMouseUp(e) {\n var target,\n transform = this._currentTransform,\n groupSelector = this._groupSelector,\n shouldRender = false,\n isClick = !groupSelector || groupSelector.left === 0 && groupSelector.top === 0;\n\n this._cacheTransformEventData(e);\n\n target = this._target;\n\n this._handleEvent(e, 'up:before'); // if right/middle click just fire events and return\n // target undefined will make the _handleEvent search the target\n\n\n if (checkClick(e, RIGHT_CLICK)) {\n if (this.fireRightClick) {\n this._handleEvent(e, 'up', RIGHT_CLICK, isClick);\n }\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\n this._resetTransformEventData();\n\n return;\n }\n\n if (this.isDrawingMode && this._isCurrentlyDrawing) {\n this._onMouseUpInDrawingMode(e);\n\n return;\n }\n\n if (!this._isMainEvent(e)) {\n return;\n }\n\n if (transform) {\n this._finalizeCurrentTransform(e);\n\n shouldRender = transform.actionPerformed;\n }\n\n if (!isClick) {\n var targetWasActive = target === this._activeObject;\n\n this._maybeGroupObjects(e);\n\n if (!shouldRender) {\n shouldRender = this._shouldRender(target) || !targetWasActive && target === this._activeObject;\n }\n }\n\n if (target) {\n var corner = target._findTargetCorner(this.getPointer(e, true), fabric.util.isTouchEvent(e));\n\n var control = target.controls[corner],\n mouseUpHandler = control && control.getMouseUpHandler(e, target, control);\n\n if (mouseUpHandler) {\n mouseUpHandler(e, target, control);\n }\n\n target.isMoving = false;\n }\n\n this._setCursorFromEvent(e, target);\n\n this._handleEvent(e, 'up', LEFT_CLICK, isClick);\n\n this._groupSelector = null;\n this._currentTransform = null; // reset the target information about which corner is selected\n\n target && (target.__corner = 0);\n\n if (shouldRender) {\n this.requestRenderAll();\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 _simpleEventHandler(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\n if (!targets) {\n return target;\n }\n\n for (var i = 0; i < targets.length; i++) {\n targets[i].fire(eventType, options);\n }\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 _handleEvent(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\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 _finalizeCurrentTransform(e) {\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\n this._fire(eventName, options);\n }\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 _addEventOptions(options, transform) {\n // we can probably add more details at low cost\n // scale change, rotation changes, translation changes\n var eventName, by;\n\n switch (transform.action) {\n case 'scaleX':\n eventName = 'scaled';\n by = 'x';\n break;\n\n case 'scaleY':\n eventName = 'scaled';\n by = 'y';\n break;\n\n case 'skewX':\n eventName = 'skewed';\n by = 'x';\n break;\n\n case 'skewY':\n eventName = 'skewed';\n by = 'y';\n break;\n\n case 'scale':\n eventName = 'scaled';\n by = 'equally';\n break;\n\n case 'rotate':\n eventName = 'rotated';\n break;\n\n case 'drag':\n eventName = 'moved';\n break;\n }\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 _onMouseDownInDrawingMode(e) {\n this._isCurrentlyDrawing = true;\n\n if (this.getActiveObject()) {\n this.discardActiveObject(e).requestRenderAll();\n }\n\n var pointer = this.getPointer(e);\n this.freeDrawingBrush.onMouseDown(pointer, {\n e: e,\n pointer: pointer\n });\n\n this._handleEvent(e, 'down');\n },\n\n /**\n * @private\n * @param {Event} e Event object fired on mousemove\n */\n _onMouseMoveInDrawingMode: function _onMouseMoveInDrawingMode(e) {\n if (this._isCurrentlyDrawing) {\n var pointer = this.getPointer(e);\n this.freeDrawingBrush.onMouseMove(pointer, {\n e: e,\n pointer: pointer\n });\n }\n\n this.setCursor(this.freeDrawingCursor);\n\n this._handleEvent(e, 'move');\n },\n\n /**\n * @private\n * @param {Event} e Event object fired on mouseup\n */\n _onMouseUpInDrawingMode: function _onMouseUpInDrawingMode(e) {\n var pointer = this.getPointer(e);\n this._isCurrentlyDrawing = this.freeDrawingBrush.onMouseUp({\n e: e,\n pointer: pointer\n });\n\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 __onMouseDown(e) {\n this._cacheTransformEventData(e);\n\n this._handleEvent(e, 'down:before');\n\n var target = this._target; // if right click just fire events\n\n if (checkClick(e, RIGHT_CLICK)) {\n if (this.fireRightClick) {\n this._handleEvent(e, 'down', RIGHT_CLICK);\n }\n\n return;\n }\n\n if (checkClick(e, MIDDLE_CLICK)) {\n if (this.fireMiddleClick) {\n this._handleEvent(e, 'down', MIDDLE_CLICK);\n }\n\n return;\n }\n\n if (this.isDrawingMode) {\n this._onMouseDownInDrawingMode(e);\n\n return;\n }\n\n if (!this._isMainEvent(e)) {\n return;\n } // ignore if some object is being transformed at this moment\n\n\n if (this._currentTransform) {\n return;\n }\n\n var pointer = this._pointer; // save pointer for check in __onMouseUp event\n\n this._previousPointer = pointer;\n\n var shouldRender = this._shouldRender(target),\n shouldGroup = this._shouldGroup(e, target);\n\n if (this._shouldClearSelection(e, target)) {\n this.discardActiveObject(e);\n } else if (shouldGroup) {\n this._handleGrouping(e, target);\n\n target = this._activeObject;\n }\n\n if (this.selection && (!target || !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\n if (target.selectable) {\n this.setActiveObject(target, e);\n }\n\n var corner = target._findTargetCorner(this.getPointer(e, true), fabric.util.isTouchEvent(e));\n\n target.__corner = corner;\n\n if (target === this._activeObject && (corner || !shouldGroup)) {\n var control = target.controls[corner],\n mouseDownHandler = control && control.getMouseDownHandler(e, target, control);\n\n if (mouseDownHandler) {\n mouseDownHandler(e, target, control);\n }\n\n this._setupCurrentTransform(e, target, alreadySelected);\n }\n }\n\n this._handleEvent(e, 'down'); // we must renderAll so that we update the visuals\n\n\n (shouldRender || shouldGroup) && this.requestRenderAll();\n },\n\n /**\n * reset cache form common information needed during event processing\n * @private\n */\n _resetTransformEventData: function _resetTransformEventData() {\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 _cacheTransformEventData(e) {\n // reset in order to avoid stale caching\n this._resetTransformEventData();\n\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 _beforeTransform(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 },\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 __onMouseMove(e) {\n this._handleEvent(e, 'move:before');\n\n this._cacheTransformEventData(e);\n\n var target, pointer;\n\n if (this.isDrawingMode) {\n this._onMouseMoveInDrawingMode(e);\n\n return;\n }\n\n if (!this._isMainEvent(e)) {\n return;\n }\n\n var groupSelector = this._groupSelector; // We initially clicked in an empty area, so we draw a box for multiple selection\n\n if (groupSelector) {\n pointer = this._pointer;\n groupSelector.left = pointer.x - groupSelector.ex;\n groupSelector.top = pointer.y - groupSelector.ey;\n this.renderTop();\n } else if (!this._currentTransform) {\n target = this.findTarget(e) || null;\n\n this._setCursorFromEvent(e, target);\n\n this._fireOverOutEvents(target, e);\n } else {\n this._transformObject(e);\n }\n\n this._handleEvent(e, 'move');\n\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 _fireOverOutEvents(target, e) {\n var _hoveredTarget = this._hoveredTarget,\n _hoveredTargets = this._hoveredTargets,\n targets = this.targets,\n length = Math.max(_hoveredTargets.length, targets.length);\n this.fireSyntheticInOutEvents(target, e, {\n oldTarget: _hoveredTarget,\n evtOut: 'mouseout',\n canvasEvtOut: 'mouse:out',\n evtIn: 'mouseover',\n canvasEvtIn: 'mouse:over'\n });\n\n for (var i = 0; i < length; i++) {\n this.fireSyntheticInOutEvents(targets[i], e, {\n oldTarget: _hoveredTargets[i],\n evtOut: 'mouseout',\n evtIn: 'mouseover'\n });\n }\n\n this._hoveredTarget = target;\n this._hoveredTargets = this.targets.concat();\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 _fireEnterLeaveEvents(target, e) {\n var _draggedoverTarget = this._draggedoverTarget,\n _hoveredTargets = this._hoveredTargets,\n targets = this.targets,\n length = Math.max(_hoveredTargets.length, targets.length);\n this.fireSyntheticInOutEvents(target, e, {\n oldTarget: _draggedoverTarget,\n evtOut: 'dragleave',\n evtIn: 'dragenter'\n });\n\n for (var i = 0; i < length; i++) {\n this.fireSyntheticInOutEvents(targets[i], e, {\n oldTarget: _hoveredTargets[i],\n evtOut: 'dragleave',\n evtIn: 'dragenter'\n });\n }\n\n this._draggedoverTarget = target;\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 fireSyntheticInOutEvents(target, e, config) {\n var inOpt,\n outOpt,\n oldTarget = config.oldTarget,\n outFires,\n inFires,\n targetChanged = oldTarget !== target,\n canvasEvtIn = config.canvasEvtIn,\n canvasEvtOut = config.canvasEvtOut;\n\n if (targetChanged) {\n inOpt = {\n e: e,\n target: target,\n previousTarget: oldTarget\n };\n outOpt = {\n e: e,\n target: oldTarget,\n nextTarget: target\n };\n }\n\n inFires = target && targetChanged;\n outFires = oldTarget && targetChanged;\n\n if (outFires) {\n canvasEvtOut && this.fire(canvasEvtOut, outOpt);\n oldTarget.fire(config.evtOut, outOpt);\n }\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 __onMouseWheel(e) {\n this._cacheTransformEventData(e);\n\n this._handleEvent(e, 'wheel');\n\n this._resetTransformEventData();\n },\n\n /**\n * @private\n * @param {Event} e Event fired on mousemove\n */\n _transformObject: function _transformObject(e) {\n var pointer = this.getPointer(e),\n transform = this._currentTransform;\n transform.reset = false;\n transform.target.isMoving = true;\n transform.shiftKey = e.shiftKey;\n transform.altKey = e[this.centeredKey];\n\n this._performTransformAction(e, transform, pointer);\n\n transform.actionPerformed && this.requestRenderAll();\n },\n\n /**\n * @private\n */\n _performTransformAction: function _performTransformAction(e, transform, pointer) {\n var x = pointer.x,\n y = pointer.y,\n action = transform.action,\n actionPerformed = false,\n actionHandler = transform.actionHandler,\n // this object could be created from the function in the control handlers\n options = {\n target: transform.target,\n e: e,\n transform: transform,\n pointer: pointer\n };\n\n if (action === 'drag') {\n actionPerformed = this._translateObject(x, y);\n\n if (actionPerformed) {\n this._fire('moving', options);\n\n this.setCursor(options.target.moveCursor || this.moveCursor);\n }\n } else if (actionHandler) {\n (actionPerformed = actionHandler(e, transform, x, y)) && this._fire(action, options);\n }\n\n transform.actionPerformed = transform.actionPerformed || actionPerformed;\n },\n\n /**\n * @private\n */\n _fire: fabric.controlsUtils.fireEvent,\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 _setCursorFromEvent(e, target) {\n if (!target) {\n this.setCursor(this.defaultCursor);\n return false;\n }\n\n var hoverCursor = target.hoverCursor || this.hoverCursor,\n activeSelection = this._activeObject && this._activeObject.type === 'activeSelection' ? this._activeObject : null,\n // only show proper corner when group selection is not active\n corner = (!activeSelection || !activeSelection.contains(target)) && // here we call findTargetCorner always with undefined for the touch parameter.\n // we assume that if you are using a cursor you do not need to interact with\n // the bigger touch area.\n target._findTargetCorner(this.getPointer(e, true));\n\n if (!corner) {\n if (target.subTargetCheck) {\n // hoverCursor should come from top-most subTarget,\n // so we walk the array backwards\n this.targets.concat().reverse().map(function (_target) {\n hoverCursor = _target.hoverCursor || hoverCursor;\n });\n }\n\n this.setCursor(hoverCursor);\n } else {\n this.setCursor(this.getCornerCursor(corner, target, e));\n }\n },\n\n /**\n * @private\n */\n getCornerCursor: function getCornerCursor(corner, target, e) {\n var control = target.controls[corner];\n return control.cursorStyleHandler(e, control, target);\n }\n });\n})();\n\n(function () {\n var min = Math.min,\n max = Math.max;\n fabric.util.object.extend(fabric.Canvas.prototype,\n /** @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 _shouldGroup(e, target) {\n var activeObject = this._activeObject;\n return activeObject && this._isSelectionKeyPressed(e) && target && target.selectable && this.selection && (activeObject !== target || activeObject.type === 'activeSelection') && !target.onSelect({\n e: e\n });\n },\n\n /**\n * @private\n * @param {Event} e Event object\n * @param {fabric.Object} target\n */\n _handleGrouping: function _handleGrouping(e, target) {\n var activeObject = this._activeObject; // avoid multi select when shift click on a corner\n\n if (activeObject.__corner) {\n return;\n }\n\n if (target === activeObject) {\n // if it's a group, find target again, using activeGroup objects\n target = this.findTarget(e, true); // if even object is not found or we are on activeObjectCorner, bail out\n\n if (!target || !target.selectable) {\n return;\n }\n }\n\n if (activeObject && activeObject.type === 'activeSelection') {\n this._updateActiveSelection(target, e);\n } else {\n this._createActiveSelection(target, e);\n }\n },\n\n /**\n * @private\n */\n _updateActiveSelection: function _updateActiveSelection(target, e) {\n var activeSelection = this._activeObject,\n currentActiveObjects = activeSelection._objects.slice(0);\n\n if (activeSelection.contains(target)) {\n activeSelection.removeWithUpdate(target);\n this._hoveredTarget = target;\n this._hoveredTargets = this.targets.concat();\n\n if (activeSelection.size() === 1) {\n // activate last remaining object\n this._setActiveObject(activeSelection.item(0), e);\n }\n } else {\n activeSelection.addWithUpdate(target);\n this._hoveredTarget = activeSelection;\n this._hoveredTargets = this.targets.concat();\n }\n\n this._fireSelectionEvents(currentActiveObjects, e);\n },\n\n /**\n * @private\n */\n _createActiveSelection: function _createActiveSelection(target, e) {\n var currentActives = this.getActiveObjects(),\n group = this._createGroup(target);\n\n this._hoveredTarget = group; // ISSUE 4115: should we consider subTargets here?\n // this._hoveredTargets = [];\n // this._hoveredTargets = this.targets.concat();\n\n this._setActiveObject(group, e);\n\n this._fireSelectionEvents(currentActives, e);\n },\n\n /**\n * @private\n * @param {Object} target\n */\n _createGroup: function _createGroup(target) {\n var objects = this._objects,\n isActiveLower = objects.indexOf(this._activeObject) < objects.indexOf(target),\n groupObjects = isActiveLower ? [this._activeObject, target] : [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 _groupSelectedObjects(e) {\n var group = this._collectObjects(e),\n aGroup; // do not create group for 1 element only\n\n\n if (group.length === 1) {\n this.setActiveObject(group[0], e);\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 _collectObjects(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; // we iterate reverse order to collect top first in case of click.\n\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) || currentObject.isContainedWithinRect(selectionX1Y1, selectionX2Y2) || allowIntersect && currentObject.containsPoint(selectionX1Y1) || allowIntersect && currentObject.containsPoint(selectionX2Y2)) {\n group.push(currentObject); // only add one object if it's a click\n\n if (isClick) {\n break;\n }\n }\n }\n\n if (group.length > 1) {\n group = group.filter(function (object) {\n return !object.onSelect({\n e: e\n });\n });\n }\n\n return group;\n },\n\n /**\n * @private\n */\n _maybeGroupObjects: function _maybeGroupObjects(e) {\n if (this.selection && this._groupSelector) {\n this._groupSelectedObjects(e);\n }\n\n this.setCursor(this.defaultCursor); // clear selection and current transformation\n\n this._groupSelector = null;\n }\n });\n})();\n\n(function () {\n fabric.util.object.extend(fabric.StaticCanvas.prototype,\n /** @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 Generate jpeg dataURL with lower quality\n * var dataURL = canvas.toDataURL({\n * format: 'jpeg',\n * quality: 0.8\n * });\n * @example Generate cropped png dataURL (clipping of canvas)\n * var dataURL = canvas.toDataURL({\n * format: 'png',\n * left: 100,\n * top: 100,\n * width: 200,\n * height: 200\n * });\n * @example Generate double scaled png dataURL\n * var dataURL = canvas.toDataURL({\n * format: 'png',\n * multiplier: 2\n * });\n */\n toDataURL: function toDataURL(options) {\n options || (options = {});\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 toCanvasElement(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\nfabric.util.object.extend(fabric.StaticCanvas.prototype,\n/** @lends fabric.StaticCanvas.prototype */\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 loadFromJSON\n * canvas.loadFromJSON(json, canvas.renderAll.bind(canvas));\n * @example loadFromJSON with reviver\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 loadFromJSON(json, callback, reviver) {\n if (!json) {\n return;\n } // serialize if it wasn't already\n\n\n var serialized = typeof json === 'string' ? JSON.parse(json) : fabric.util.object.clone(json);\n\n var _this = this,\n clipPath = serialized.clipPath,\n renderOnAddRemove = this.renderOnAddRemove;\n\n this.renderOnAddRemove = false;\n delete serialized.clipPath;\n\n this._enlivenObjects(serialized.objects, function (enlivenedObjects) {\n _this.clear();\n\n _this._setBgOverlay(serialized, function () {\n if (clipPath) {\n _this._enlivenObjects([clipPath], function (enlivenedCanvasClip) {\n _this.clipPath = enlivenedCanvasClip[0];\n\n _this.__setupCanvas.call(_this, serialized, enlivenedObjects, renderOnAddRemove, callback);\n });\n } else {\n _this.__setupCanvas.call(_this, serialized, enlivenedObjects, renderOnAddRemove, callback);\n }\n });\n }, reviver);\n\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 __setupCanvas(serialized, enlivenedObjects, renderOnAddRemove, callback) {\n var _this = this;\n\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; // remove parts i cannot set as options\n\n delete serialized.objects;\n delete serialized.backgroundImage;\n delete serialized.overlayImage;\n delete serialized.background;\n delete serialized.overlay; // 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\n this._setOptions(serialized);\n\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 _setBgOverlay(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 cbIfLoaded() {\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\n this.__setBgOverlay('overlayImage', serialized.overlayImage, loaded, cbIfLoaded);\n\n this.__setBgOverlay('backgroundColor', serialized.background, loaded, cbIfLoaded);\n\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 __setBgOverlay(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 } 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 _enlivenObjects(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 _toDataURL(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 _toDataURLWithMultiplier(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 clone(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 cloneWithoutData(callback) {\n var el = fabric.util.createCanvasElement();\n el.width = this.width;\n el.height = this.height;\n var clone = new fabric.Canvas(el);\n\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 } else {\n callback && callback(clone);\n }\n }\n});\n\n(function (global) {\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 * 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\n\n fabric.Object = fabric.util.createClass(fabric.CommonMethods,\n /** @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 * Size of object's controlling corners when touch interaction is detected\n * @type Number\n * @default\n */\n touchCornerSize: 24,\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: 'rgb(178,204,255)',\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: 'rgb(178,204,255)',\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 * Backwards incompatibility note: 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 * Backwards incompatibility note: 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 * Backwards incompatibility note: 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 * bigger number will make a thicker border\n * border is 1, so this is basically a border tickness\n * since there is no way to change the border itself.\n * @type Number\n * @default\n */\n borderScaleFactor: 1,\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 `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 * 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 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: ('top left width height scaleX scaleY flipX flipY originX originY transformMatrix ' + 'stroke strokeWidth strokeDashArray strokeLineCap strokeDashOffset strokeLineJoin strokeMiterLimit ' + 'angle opacity fill globalCompositeOperation shadow visible backgroundColor ' + 'skewX skewY fillRule paintFirst clipPath strokeUniform').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: ('fill stroke strokeWidth strokeDashArray width height paintFirst strokeUniform' + ' strokeLineCap strokeDashOffset strokeLineJoin strokeMiterLimit backgroundColor clipPath').split(' '),\n\n /**\n * List of properties to consider for animating colors.\n * @type Array\n */\n colorProperties: 'fill stroke backgroundColor'.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 initialize(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 _createCacheCanvas() {\n this._cacheProperties = {};\n this._cacheCanvas = fabric.util.createCanvasElement();\n this._cacheContext = this._cacheCanvas.getContext('2d');\n\n this._updateCacheCanvas(); // if canvas gets created, is empty, so dirty.\n\n\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 _limitCacheSize(dims) {\n var perfLimitSizeTotal = fabric.perfLimitSizeTotal,\n width = dims.width,\n height = dims.height,\n max = fabric.maxCacheSideLimit,\n min = fabric.minCacheSideLimit;\n\n if (width <= max && height <= max && width * height <= perfLimitSizeTotal) {\n if (width < min) {\n dims.width = min;\n }\n\n if (height < min) {\n dims.height = min;\n }\n\n return dims;\n }\n\n var ar = width / height,\n 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\n if (width > x) {\n dims.zoomX /= width / x;\n dims.width = x;\n dims.capped = true;\n }\n\n if (height > y) {\n dims.zoomY /= height / y;\n dims.height = y;\n dims.capped = true;\n }\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 _getCacheCanvasDimensions() {\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\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 _updateCacheCanvas() {\n var targetCanvas = this.canvas;\n\n if (this.noScaleCache && targetCanvas && targetCanvas._currentTransform) {\n var target = targetCanvas._currentTransform.target,\n action = targetCanvas._currentTransform.action;\n\n if (this === target && action.slice && action.slice(0, 5) === 'scale') {\n return false;\n }\n }\n\n var canvas = this._cacheCanvas,\n dims = this._limitCacheSize(this._getCacheCanvasDimensions()),\n minCacheSize = fabric.minCacheSideLimit,\n width = dims.width,\n height = dims.height,\n drawingWidth,\n drawingHeight,\n zoomX = dims.zoomX,\n 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,\n additionalHeight = 0,\n shouldResizeCanvas = false;\n\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) && canvasWidth > minCacheSize && canvasHeight > minCacheSize;\n shouldResizeCanvas = sizeGrowing || sizeShrinking;\n\n if (sizeGrowing && !dims.capped && (width > minCacheSize || height > minCacheSize)) {\n additionalWidth = width * 0.1;\n additionalHeight = height * 0.1;\n }\n }\n\n if (shouldRedraw) {\n if (shouldResizeCanvas) {\n canvas.width = Math.ceil(width + additionalWidth);\n canvas.height = Math.ceil(height + additionalHeight);\n } else {\n this._cacheContext.setTransform(1, 0, 0, 1, 0, 0);\n\n this._cacheContext.clearRect(0, 0, canvas.width, canvas.height);\n }\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\n this._cacheContext.translate(this.cacheTranslationX, this.cacheTranslationY);\n\n this._cacheContext.scale(zoomX, zoomY);\n\n this.zoomX = zoomX;\n this.zoomY = zoomY;\n return true;\n }\n\n return false;\n },\n\n /**\n * Sets object's properties from options\n * @param {Object} [options] Options object\n */\n setOptions: function setOptions(options) {\n this._setOptions(options);\n\n this._initGradient(options.fill, 'fill');\n\n this._initGradient(options.stroke, 'stroke');\n\n this._initPattern(options.fill, 'fill');\n\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 transform(ctx) {\n var needFullTransform = this.group && !this.group._transformDone || this.group && this.canvas && ctx === this.canvas.contextTop;\n var m = this.calcTransformMatrix(!needFullTransform);\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 toObject(propertiesToInclude) {\n var NUM_FRACTION_DIGITS = fabric.Object.NUM_FRACTION_DIGITS,\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 // strokeUniform: this.strokeUniform,\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 backgroundColor: this.backgroundColor,\n fillRule: this.fillRule,\n paintFirst: this.paintFirst,\n globalCompositeOperation: this.globalCompositeOperation,\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\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 toDatalessObject(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 _removeDefaultValues(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\n if (object[prop] === prototype[prop]) {\n delete object[prop];\n }\n\n var isArray = Object.prototype.toString.call(object[prop]) === '[object Array]' && Object.prototype.toString.call(prototype[prop]) === '[object Array]'; // basically a check for [] === []\n\n if (isArray && object[prop].length === 0 && prototype[prop].length === 0) {\n delete object[prop];\n }\n });\n return object;\n },\n\n /**\n * Returns a string representation of an instance\n * @return {String}\n */\n toString: function toString() {\n return '#';\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 getObjectScaling() {\n var options = fabric.util.qrDecompose(this.calcTransformMatrix());\n return {\n scaleX: Math.abs(options.scaleX),\n scaleY: Math.abs(options.scaleY)\n };\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 getTotalObjectScaling() {\n var scale = this.getObjectScaling(),\n scaleX = scale.scaleX,\n scaleY = scale.scaleY;\n\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\n return {\n scaleX: scaleX,\n scaleY: scaleY\n };\n },\n\n /**\n * Return the object opacity counting also the group property\n * @return {Number}\n */\n getObjectOpacity: function getObjectOpacity() {\n var opacity = this.opacity;\n\n if (this.group) {\n opacity *= this.group.getObjectOpacity();\n }\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 _set(key, value) {\n var shouldConstrainValue = key === 'scaleX' || key === 'scaleY',\n isChanged = this[key] !== value,\n groupNeedsUpdate = false;\n\n if (shouldConstrainValue) {\n value = this._constrainScale(value);\n }\n\n if (key === 'scaleX' && value < 0) {\n this.flipX = !this.flipX;\n value *= -1;\n } else if (key === 'scaleY' && value < 0) {\n this.flipY = !this.flipY;\n value *= -1;\n } else if (key === 'shadow' && value && !(value instanceof fabric.Shadow)) {\n value = new fabric.Shadow(value);\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\n if (this.cacheProperties.indexOf(key) > -1) {\n this.dirty = true;\n groupNeedsUpdate && this.group.set('dirty', true);\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 setOnGroup() {// 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 getViewportTransform() {\n if (this.canvas && this.canvas.viewportTransform) {\n return this.canvas.viewportTransform;\n }\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 isNotVisible() {\n return this.opacity === 0 || !this.width && !this.height && this.strokeWidth === 0 || !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 render(ctx) {\n // do not render if width/height are zeros or object is not visible\n if (this.isNotVisible()) {\n return;\n }\n\n if (this.canvas && this.canvas.skipOffscreen && !this.group && !this.isOnScreen()) {\n return;\n }\n\n ctx.save();\n\n this._setupCompositeOperation(ctx);\n\n this.drawSelectionBackground(ctx);\n this.transform(ctx);\n\n this._setOpacity(ctx);\n\n this._setShadow(ctx, this);\n\n if (this.shouldCache()) {\n this.renderCache();\n this.drawCacheOnCanvas(ctx);\n } else {\n this._removeCacheCanvas();\n\n this.dirty = false;\n this.drawObject(ctx);\n\n if (this.objectCaching && this.statefullCache) {\n this.saveState({\n propertySet: 'cacheProperties'\n });\n }\n }\n\n ctx.restore();\n },\n renderCache: function renderCache(options) {\n options = options || {};\n\n if (!this._cacheCanvas) {\n this._createCacheCanvas();\n }\n\n if (this.isCacheDirty()) {\n this.statefullCache && this.saveState({\n propertySet: 'cacheProperties'\n });\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 _removeCacheCanvas() {\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 hasStroke() {\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 hasFill() {\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 needsItsOwnCache() {\n if (this.paintFirst === 'stroke' && this.hasFill() && this.hasStroke() && typeof this.shadow === 'object') {\n return true;\n }\n\n if (this.clipPath) {\n return true;\n }\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 shouldCache() {\n this.ownCaching = this.needsItsOwnCache() || this.objectCaching && (!this.group || !this.group.isOnACache());\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 willDrawShadow() {\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 drawClipPathOnCache(ctx) {\n var path = this.clipPath;\n ctx.save(); // DEBUG: uncomment this line, comment the following\n // ctx.globalAlpha = 0.4\n\n if (path.inverted) {\n ctx.globalCompositeOperation = 'destination-out';\n } else {\n ctx.globalCompositeOperation = 'destination-in';\n } //ctx.scale(1 / 2, 1 / 2);\n\n\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\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 drawObject(ctx, forClipping) {\n var originalFill = this.fill,\n originalStroke = this.stroke;\n\n if (forClipping) {\n this.fill = 'black';\n this.stroke = '';\n\n this._setClippingProperties(ctx);\n } else {\n this._renderBackground(ctx);\n\n this._setStrokeStyles(ctx, this);\n\n this._setFillStyles(ctx, this);\n }\n\n this._render(ctx);\n\n this._drawClipPath(ctx);\n\n this.fill = originalFill;\n this.stroke = originalStroke;\n },\n _drawClipPath: function _drawClipPath(ctx) {\n var path = this.clipPath;\n\n if (!path) {\n return;\n } // needed to setup a couple of variables\n // path canvas gets overridden with this one.\n // TODO find a better solution?\n\n\n path.canvas = this.canvas;\n path.shouldCache();\n path._transformDone = true;\n path.renderCache({\n forClipping: true\n });\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 drawCacheOnCanvas(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 isCacheDirty(skipCanvas) {\n if (this.isNotVisible()) {\n return false;\n }\n\n if (this._cacheCanvas && !skipCanvas && this._updateCacheCanvas()) {\n // in this case the context is already cleared.\n return true;\n } else {\n if (this.dirty || this.clipPath && this.clipPath.absolutePositioned || this.statefullCache && this.hasStateChanged('cacheProperties')) {\n if (this._cacheCanvas && !skipCanvas) {\n var width = this.cacheWidth / this.zoomX;\n var height = this.cacheHeight / this.zoomY;\n\n this._cacheContext.clearRect(-width / 2, -height / 2, width, height);\n }\n\n return true;\n }\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 _renderBackground(ctx) {\n if (!this.backgroundColor) {\n return;\n }\n\n var dim = this._getNonTransformedDimensions();\n\n ctx.fillStyle = this.backgroundColor;\n ctx.fillRect(-dim.x / 2, -dim.y / 2, dim.x, dim.y); // if there is background color no other shadows\n // should be casted\n\n this._removeShadow(ctx);\n },\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx Context to render on\n */\n _setOpacity: function _setOpacity(ctx) {\n if (this.group && !this.group._transformDone) {\n ctx.globalAlpha = this.getObjectOpacity();\n } else {\n ctx.globalAlpha *= this.opacity;\n }\n },\n _setStrokeStyles: function _setStrokeStyles(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 ? decl.stroke.toLive(ctx, this) : decl.stroke;\n }\n },\n _setFillStyles: function _setFillStyles(ctx, decl) {\n if (decl.fill) {\n ctx.fillStyle = decl.fill.toLive ? decl.fill.toLive(ctx, this) : decl.fill;\n }\n },\n _setClippingProperties: function _setClippingProperties(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 _setLineDash(ctx, dashArray, alternative) {\n if (!dashArray || dashArray.length === 0) {\n return;\n } // Spec requires the concatenation of two copies the dash list when the number of elements is odd\n\n\n if (1 & dashArray.length) {\n dashArray.push.apply(dashArray, dashArray);\n }\n\n if (supportsLineDash) {\n ctx.setLineDash(dashArray);\n } else {\n alternative && alternative(ctx);\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 _renderControls(ctx, styleOverride) {\n var vpt = this.getViewportTransform(),\n matrix = this.calcTransformMatrix(),\n options,\n drawBorders,\n 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\n if (!this.group) {\n ctx.globalAlpha = this.isMoving ? this.borderOpacityWhenMoving : 1;\n }\n\n if (styleOverride.forActiveSelection) {\n ctx.rotate(degreesToRadians(options.angle));\n drawBorders && this.drawBordersInGroup(ctx, options, styleOverride);\n } else {\n ctx.rotate(degreesToRadians(this.angle));\n drawBorders && this.drawBorders(ctx, styleOverride);\n }\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 _setShadow(ctx) {\n if (!this.shadow) {\n return;\n }\n\n var shadow = this.shadow,\n canvas = this.canvas,\n scaling,\n multX = canvas && canvas.viewportTransform[0] || 1,\n multY = canvas && canvas.viewportTransform[3] || 1;\n\n if (shadow.nonScaling) {\n scaling = {\n scaleX: 1,\n scaleY: 1\n };\n } else {\n scaling = this.getObjectScaling();\n }\n\n if (canvas && canvas._isRetinaScaling()) {\n multX *= fabric.devicePixelRatio;\n multY *= fabric.devicePixelRatio;\n }\n\n ctx.shadowColor = shadow.color;\n ctx.shadowBlur = shadow.blur * fabric.browserShadowBlurConstant * (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 _removeShadow(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 _applyPatternGradientTransform(ctx, filler) {\n if (!filler || !filler.toLive) {\n return {\n offsetX: 0,\n offsetY: 0\n };\n }\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\n if (filler.gradientUnits === 'percentage') {\n ctx.transform(this.width, 0, 0, this.height, offsetX, offsetY);\n } else {\n ctx.transform(1, 0, 0, 1, offsetX, offsetY);\n }\n\n if (t) {\n ctx.transform(t[0], t[1], t[2], t[3], t[4], t[5]);\n }\n\n return {\n offsetX: offsetX,\n offsetY: offsetY\n };\n },\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx Context to render on\n */\n _renderPaintInOrder: function _renderPaintInOrder(ctx) {\n if (this.paintFirst === 'stroke') {\n this._renderStroke(ctx);\n\n this._renderFill(ctx);\n } else {\n this._renderFill(ctx);\n\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 _render()\n /* ctx */\n {},\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx Context to render on\n */\n _renderFill: function _renderFill(ctx) {\n if (!this.fill) {\n return;\n }\n\n ctx.save();\n\n this._applyPatternGradientTransform(ctx, this.fill);\n\n if (this.fillRule === 'evenodd') {\n ctx.fill('evenodd');\n } else {\n ctx.fill();\n }\n\n ctx.restore();\n },\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx Context to render on\n */\n _renderStroke: function _renderStroke(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\n if (this.strokeUniform && this.group) {\n var scaling = this.getObjectScaling();\n ctx.scale(1 / scaling.scaleX, 1 / scaling.scaleY);\n } else if (this.strokeUniform) {\n ctx.scale(1 / this.scaleX, 1 / this.scaleY);\n }\n\n this._setLineDash(ctx, this.strokeDashArray, this._renderDashedStroke);\n\n if (this.stroke.toLive && this.stroke.gradientUnits === 'percentage') {\n // need to transform gradient in a pattern.\n // this is a slow process. If you are hitting this codepath, and the object\n // is not using caching, you should consider switching it on.\n // we need a canvas as big as the current object caching canvas.\n this._applyPatternForTransformedGradient(ctx, this.stroke);\n } else {\n this._applyPatternGradientTransform(ctx, this.stroke);\n }\n\n ctx.stroke();\n ctx.restore();\n },\n\n /**\n * This function try to patch the missing gradientTransform on canvas gradients.\n * transforming a context to transform the gradient, is going to transform the stroke too.\n * we want to transform the gradient but not the stroke operation, so we create\n * a transformed gradient on a pattern and then we use the pattern instead of the gradient.\n * this method has drwabacks: is slow, is in low resolution, needs a patch for when the size\n * is limited.\n * @private\n * @param {CanvasRenderingContext2D} ctx Context to render on\n * @param {fabric.Gradient} filler a fabric gradient instance\n */\n _applyPatternForTransformedGradient: function _applyPatternForTransformedGradient(ctx, filler) {\n var dims = this._limitCacheSize(this._getCacheCanvasDimensions()),\n pCanvas = fabric.util.createCanvasElement(),\n pCtx,\n retinaScaling = this.canvas.getRetinaScaling(),\n width = dims.x / this.scaleX / retinaScaling,\n height = dims.y / this.scaleY / retinaScaling;\n\n pCanvas.width = width;\n pCanvas.height = height;\n pCtx = pCanvas.getContext('2d');\n pCtx.beginPath();\n pCtx.moveTo(0, 0);\n pCtx.lineTo(width, 0);\n pCtx.lineTo(width, height);\n pCtx.lineTo(0, height);\n pCtx.closePath();\n pCtx.translate(width / 2, height / 2);\n pCtx.scale(dims.zoomX / this.scaleX / retinaScaling, dims.zoomY / this.scaleY / retinaScaling);\n\n this._applyPatternGradientTransform(pCtx, filler);\n\n pCtx.fillStyle = filler.toLive(ctx);\n pCtx.fill();\n ctx.translate(-this.width / 2 - this.strokeWidth / 2, -this.height / 2 - this.strokeWidth / 2);\n ctx.scale(retinaScaling * this.scaleX / dims.zoomX, retinaScaling * this.scaleY / dims.zoomY);\n ctx.strokeStyle = pCtx.createPattern(pCanvas, 'no-repeat');\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 _findCenterFromElement() {\n return {\n x: this.left + this.width / 2,\n y: this.top + this.height / 2\n };\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 _assignTransformMatrixProps() {\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 _removeTransformMatrix(preserveAspectRatioOptions) {\n var center = this._findCenterFromElement();\n\n if (this.transformMatrix) {\n this._assignTransformMatrixProps();\n\n center = fabric.util.transformPoint(center, this.transformMatrix);\n }\n\n this.transformMatrix = null;\n\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\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 clone(callback, propertiesToInclude) {\n var objectForm = this.toObject(propertiesToInclude);\n\n if (this.constructor.fromObject) {\n this.constructor.fromObject(objectForm, callback);\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 cloneAsImage(callback, options) {\n var canvasEl = this.toCanvasElement(options);\n\n if (callback) {\n callback(new fabric.Image(canvasEl));\n }\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 {HTMLCanvasElement} Returns DOM element with the fabric.Object\n */\n toCanvasElement: function toCanvasElement(options) {\n options || (options = {});\n var utils = fabric.util,\n origParams = utils.saveObjectTransform(this),\n originalGroup = this.group,\n originalShadow = this.shadow,\n abs = Math.abs,\n multiplier = (options.multiplier || 1) * (options.enableRetinaScaling ? fabric.devicePixelRatio : 1);\n delete this.group;\n\n if (options.withoutTransform) {\n utils.resetObjectTransform(this);\n }\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,\n scaling,\n shadowOffset = {\n x: 0,\n y: 0\n },\n shadowBlur,\n width,\n height;\n\n if (shadow) {\n shadowBlur = shadow.blur;\n\n if (shadow.nonScaling) {\n scaling = {\n scaleX: 1,\n scaleY: 1\n };\n } else {\n scaling = this.getObjectScaling();\n } // consider non scaling shadow.\n\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\n width = boundingRect.width + shadowOffset.x;\n height = boundingRect.height + shadowOffset.y; // if the current width/height is not an integer\n // we need to make it so.\n\n el.width = Math.ceil(width);\n el.height = Math.ceil(height);\n var canvas = new fabric.StaticCanvas(el, {\n enableRetinaScaling: false,\n renderOnAddRemove: false,\n skipOffscreen: false\n });\n\n if (options.format === 'jpeg') {\n canvas.backgroundColor = '#fff';\n }\n\n this.setPositionByOrigin(new fabric.Point(canvas.width / 2, canvas.height / 2), 'center', 'center');\n var originalCanvas = this.canvas;\n canvas.add(this);\n var canvasEl = canvas.toCanvasElement(multiplier || 1, options);\n this.shadow = originalShadow;\n this.set('canvas', originalCanvas);\n\n if (originalGroup) {\n this.group = originalGroup;\n }\n\n this.set(origParams).setCoords(); // 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\n canvas._objects = [];\n canvas.dispose();\n canvas = null;\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 toDataURL(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 isType(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 complexity() {\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 toJSON(propertiesToInclude) {\n // delegate, not alias\n return this.toObject(propertiesToInclude);\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 rotate(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 centerH() {\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 viewportCenterH() {\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 centerV() {\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 viewportCenterV() {\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 center() {\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 viewportCenter() {\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 getLocalPointer(e, pointer) {\n pointer = pointer || this.canvas.getPointer(e);\n\n var pClicked = new fabric.Point(pointer.x, pointer.y),\n objectLeftTop = this._getLeftTopCoords();\n\n if (this.angle) {\n pClicked = fabric.util.rotatePoint(pClicked, objectLeftTop, degreesToRadians(-this.angle));\n }\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 _setupCompositeOperation(ctx) {\n if (this.globalCompositeOperation) {\n ctx.globalCompositeOperation = this.globalCompositeOperation;\n }\n }\n });\n fabric.util.createAccessors && fabric.util.createAccessors(fabric.Object);\n extend(fabric.Object.prototype, fabric.Observable);\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\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\n if (typeof patterns[1] !== 'undefined') {\n object.stroke = patterns[1];\n }\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 * Unique id used internally when creating SVG elements\n * @static\n * @memberOf fabric.Object\n * @type Number\n */\n\n\n fabric.Object.__uid = 0;\n})(typeof exports !== 'undefined' ? exports : this);\n\n(function () {\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 fabric.util.object.extend(fabric.Object.prototype,\n /** @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 translateToGivenOrigin(point, fromOriginX, fromOriginY, toOriginX, toOriginY) {\n var x = point.x,\n y = point.y,\n offsetX,\n offsetY,\n dim;\n\n if (typeof fromOriginX === 'string') {\n fromOriginX = originXOffset[fromOriginX];\n } else {\n fromOriginX -= 0.5;\n }\n\n if (typeof toOriginX === 'string') {\n toOriginX = originXOffset[toOriginX];\n } else {\n toOriginX -= 0.5;\n }\n\n offsetX = toOriginX - fromOriginX;\n\n if (typeof fromOriginY === 'string') {\n fromOriginY = originYOffset[fromOriginY];\n } else {\n fromOriginY -= 0.5;\n }\n\n if (typeof toOriginY === 'string') {\n toOriginY = originYOffset[toOriginY];\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 translateToCenterPoint(point, originX, originY) {\n var p = this.translateToGivenOrigin(point, originX, originY, 'center', 'center');\n\n if (this.angle) {\n return fabric.util.rotatePoint(p, point, degreesToRadians(this.angle));\n }\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 translateToOriginPoint(center, originX, originY) {\n var p = this.translateToGivenOrigin(center, 'center', 'center', originX, originY);\n\n if (this.angle) {\n return fabric.util.rotatePoint(p, center, degreesToRadians(this.angle));\n }\n\n return p;\n },\n\n /**\n * Returns the real center coordinates of the object\n * @return {fabric.Point}\n */\n getCenterPoint: function getCenterPoint() {\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 getPointByOrigin(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 toLocalPoint(point, originX, originY) {\n var center = this.getCenterPoint(),\n p,\n p2;\n\n if (typeof originX !== 'undefined' && typeof originY !== 'undefined') {\n p = this.translateToGivenOrigin(center, 'center', 'center', originX, originY);\n } else {\n p = new fabric.Point(this.left, this.top);\n }\n\n p2 = new fabric.Point(point.x, point.y);\n\n if (this.angle) {\n p2 = fabric.util.rotatePoint(p2, center, -degreesToRadians(this.angle));\n }\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 setPositionByOrigin(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 adjustPosition(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,\n offsetTo; //TODO: this function does not consider mixed situation like top, center.\n\n if (typeof this.originX === 'string') {\n offsetFrom = originXOffset[this.originX];\n } else {\n offsetFrom = this.originX - 0.5;\n }\n\n if (typeof to === 'string') {\n offsetTo = originXOffset[to];\n } else {\n offsetTo = to - 0.5;\n }\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 _setOriginToCenter() {\n this._originalOriginX = this.originX;\n this._originalOriginY = this.originY;\n var center = this.getCenterPoint();\n this.originX = 'center';\n this.originY = 'center';\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 _resetOrigin() {\n var originPoint = this.translateToOriginPoint(this.getCenterPoint(), this._originalOriginX, this._originalOriginY);\n this.originX = this._originalOriginX;\n this.originY = this._originalOriginY;\n this.left = originPoint.x;\n this.top = originPoint.y;\n this._originalOriginX = null;\n this._originalOriginY = null;\n },\n\n /**\n * @private\n */\n _getLeftTopCoords: function _getLeftTopCoords() {\n return this.translateToOriginPoint(this.getCenterPoint(), 'left', 'top');\n }\n });\n})();\n\n(function () {\n function arrayFromCoords(coords) {\n return [new fabric.Point(coords.tl.x, coords.tl.y), new fabric.Point(coords.tr.x, coords.tr.y), new fabric.Point(coords.br.x, coords.br.y), new fabric.Point(coords.bl.x, coords.bl.y)];\n }\n\n var util = fabric.util,\n degreesToRadians = util.degreesToRadians,\n multiplyMatrices = util.multiplyTransformMatrices,\n transformPoint = util.transformPoint;\n util.object.extend(fabric.Object.prototype,\n /** @lends fabric.Object.prototype */\n {\n /**\n * Describe object's corner position in canvas element coordinates.\n * properties are depending on control keys and padding 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 the controls positionHandler and are used\n * to draw and locate controls\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 calcACoords();\n * @memberOf fabric.Object.prototype\n */\n aCoords: null,\n\n /**\n * Describe object's corner position in canvas element coordinates.\n * includes padding. Used of object detection.\n * set and refreshed with setCoords and calcCoords.\n * @memberOf fabric.Object.prototype\n */\n lineCoords: 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 * custom controls interface\n * controls are added by default_controls.js\n */\n controls: {},\n\n /**\n * return correct set of coordinates for intersection\n * this will return either aCoords or lineCoords.\n * @param {Boolean} absolute will return aCoords if true or lineCoords\n * @return {Object} {tl, tr, br, bl} points\n */\n _getCoords: function _getCoords(absolute, calculate) {\n if (calculate) {\n return absolute ? this.calcACoords() : this.calcLineCoords();\n }\n\n if (!this.aCoords || !this.lineCoords) {\n this.setCoords(true);\n }\n\n return absolute ? this.aCoords : this.lineCoords;\n },\n\n /**\n * return correct set of coordinates for intersection\n * this will return either aCoords or lineCoords.\n * The coords are returned in an array.\n * @return {Array} [tl, tr, br, bl] of points\n */\n getCoords: function getCoords(absolute, calculate) {\n return arrayFromCoords(this._getCoords(absolute, calculate));\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 intersectsWithRect(pointTL, pointBR, absolute, calculate) {\n var coords = this.getCoords(absolute, calculate),\n intersection = fabric.Intersection.intersectPolygonRectangle(coords, pointTL, pointBR);\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 intersectsWithObject(other, absolute, calculate) {\n var intersection = fabric.Intersection.intersectPolygonPolygon(this.getCoords(absolute, calculate), other.getCoords(absolute, calculate));\n return intersection.status === 'Intersection' || other.isContainedWithinObject(this, absolute, calculate) || 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 isContainedWithinObject(other, absolute, calculate) {\n var points = this.getCoords(absolute, calculate),\n otherCoords = absolute ? other.aCoords : other.lineCoords,\n i = 0,\n lines = other._getImageLines(otherCoords);\n\n for (; i < 4; i++) {\n if (!other.containsPoint(points[i], lines)) {\n return false;\n }\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 isContainedWithinRect(pointTL, pointBR, absolute, calculate) {\n var boundingRect = this.getBoundingRect(absolute, calculate);\n return boundingRect.left >= pointTL.x && boundingRect.left + boundingRect.width <= pointBR.x && boundingRect.top >= pointTL.y && boundingRect.top + boundingRect.height <= pointBR.y;\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 containsPoint(point, lines, absolute, calculate) {\n var coords = this._getCoords(absolute, calculate),\n lines = lines || this._getImageLines(coords),\n xPoints = this._findCrossPoints(point, lines); // if xPoints is odd then point is inside the object\n\n\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 isOnScreen(calculate) {\n if (!this.canvas) {\n return false;\n }\n\n var pointTL = this.canvas.vptCoords.tl,\n pointBR = this.canvas.vptCoords.br;\n var points = this.getCoords(true, calculate); // if some point is on screen, the object is on screen.\n\n if (points.some(function (point) {\n return point.x <= pointBR.x && point.x >= pointTL.x && point.y <= pointBR.y && point.y >= pointTL.y;\n })) {\n return true;\n } // no points on screen, check intersection with absolute coordinates\n\n\n if (this.intersectsWithRect(pointTL, pointBR, true, calculate)) {\n return true;\n }\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 _containsCenterOfCanvas(pointTL, pointBR, calculate) {\n // worst case scenario the object is so big that contains the screen\n var centerPoint = {\n x: (pointTL.x + pointBR.x) / 2,\n y: (pointTL.y + pointBR.y) / 2\n };\n\n if (this.containsPoint(centerPoint, null, true, calculate)) {\n return true;\n }\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 isPartiallyOnScreen(calculate) {\n if (!this.canvas) {\n return false;\n }\n\n var pointTL = this.canvas.vptCoords.tl,\n pointBR = this.canvas.vptCoords.br;\n\n if (this.intersectsWithRect(pointTL, pointBR, true, calculate)) {\n return true;\n }\n\n var allPointsAreOutside = this.getCoords(true, calculate).every(function (point) {\n return (point.x >= pointBR.x || point.x <= pointTL.x) && (point.y >= pointBR.y || point.y <= pointTL.y);\n });\n return allPointsAreOutside && 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 _getImageLines(oCoords) {\n var lines = {\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 }; // // debugging\n // if (this.canvas.contextTop) {\n // this.canvas.contextTop.fillRect(lines.bottomline.d.x, lines.bottomline.d.y, 2, 2);\n // this.canvas.contextTop.fillRect(lines.bottomline.o.x, lines.bottomline.o.y, 2, 2);\n //\n // this.canvas.contextTop.fillRect(lines.leftline.d.x, lines.leftline.d.y, 2, 2);\n // this.canvas.contextTop.fillRect(lines.leftline.o.x, lines.leftline.o.y, 2, 2);\n //\n // this.canvas.contextTop.fillRect(lines.topline.d.x, lines.topline.d.y, 2, 2);\n // this.canvas.contextTop.fillRect(lines.topline.o.x, lines.topline.o.y, 2, 2);\n //\n // this.canvas.contextTop.fillRect(lines.rightline.d.x, lines.rightline.d.y, 2, 2);\n // this.canvas.contextTop.fillRect(lines.rightline.o.x, lines.rightline.o.y, 2, 2);\n // }\n\n return lines;\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 _findCrossPoints(point, lines) {\n var b1,\n b2,\n a1,\n a2,\n xi,\n // yi,\n xcount = 0,\n iLine;\n\n for (var lineKey in lines) {\n iLine = lines[lineKey]; // optimisation 1: line below point. no cross\n\n if (iLine.o.y < point.y && iLine.d.y < point.y) {\n continue;\n } // optimisation 2: line above point. no cross\n\n\n if (iLine.o.y >= point.y && iLine.d.y >= point.y) {\n continue;\n } // optimisation 3: vertical line case\n\n\n if (iLine.o.x === iLine.d.x && iLine.o.x >= point.x) {\n xi = iLine.o.x; // yi = point.y;\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 xi = -(a1 - a2) / (b1 - b2); // yi = a1 + b1 * xi;\n } // dont count xi < point.x cases\n\n\n if (xi >= point.x) {\n xcount += 1;\n } // optimisation 4: specific for square images\n\n\n if (xcount === 2) {\n break;\n }\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 getBoundingRect(absolute, calculate) {\n var coords = this.getCoords(absolute, calculate);\n return 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 getScaledWidth() {\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 getScaledHeight() {\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 _constrainScale(value) {\n if (Math.abs(value) < this.minScaleLimit) {\n if (value < 0) {\n return -this.minScaleLimit;\n } else {\n return this.minScaleLimit;\n }\n } else if (value === 0) {\n return 0.0001;\n }\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 scale(value) {\n this._set('scaleX', value);\n\n this._set('scaleY', value);\n\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 scaleToWidth(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 scaleToHeight(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 * unused by the library, only for the end dev.\n * @return {Object} Object with tl, tr, br, bl ....\n * @chainable\n * @deprecated\n */\n calcCoords: function calcCoords(absolute) {\n // this is a compatibility function to avoid removing calcCoords now.\n if (absolute) {\n return this.calcACoords();\n }\n\n return this.calcOCoords();\n },\n calcLineCoords: function calcLineCoords() {\n var vpt = this.getViewportTransform(),\n padding = this.padding,\n angle = degreesToRadians(this.angle),\n cos = util.cos(angle),\n sin = util.sin(angle),\n cosP = cos * padding,\n sinP = sin * padding,\n cosPSinP = cosP + sinP,\n cosPMinusSinP = cosP - sinP,\n aCoords = this.calcACoords();\n var lineCoords = {\n tl: transformPoint(aCoords.tl, vpt),\n tr: transformPoint(aCoords.tr, vpt),\n bl: transformPoint(aCoords.bl, vpt),\n br: transformPoint(aCoords.br, vpt)\n };\n\n if (padding) {\n lineCoords.tl.x -= cosPMinusSinP;\n lineCoords.tl.y -= cosPSinP;\n lineCoords.tr.x += cosPSinP;\n lineCoords.tr.y -= cosPMinusSinP;\n lineCoords.bl.x -= cosPSinP;\n lineCoords.bl.y += cosPMinusSinP;\n lineCoords.br.x += cosPMinusSinP;\n lineCoords.br.y += cosPSinP;\n }\n\n return lineCoords;\n },\n calcOCoords: function calcOCoords() {\n var rotateMatrix = this._calcRotateMatrix(),\n translateMatrix = this._calcTranslateMatrix(),\n vpt = this.getViewportTransform(),\n startMatrix = multiplyMatrices(vpt, translateMatrix),\n finalMatrix = multiplyMatrices(startMatrix, rotateMatrix),\n finalMatrix = multiplyMatrices(finalMatrix, [1 / vpt[0], 0, 0, 1 / vpt[3], 0, 0]),\n dim = this._calculateCurrentDimensions(),\n coords = {};\n\n this.forEachControl(function (control, key, fabricObject) {\n coords[key] = control.positionHandler(dim, finalMatrix, fabricObject);\n }); // debug code\n // var canvas = this.canvas;\n // setTimeout(function() {\n // canvas.contextTop.clearRect(0, 0, 700, 700);\n // canvas.contextTop.fillStyle = 'green';\n // Object.keys(coords).forEach(function(key) {\n // var control = coords[key];\n // canvas.contextTop.fillRect(control.x, control.y, 3, 3);\n // });\n // }, 50);\n\n return coords;\n },\n calcACoords: function calcACoords() {\n var rotateMatrix = this._calcRotateMatrix(),\n translateMatrix = this._calcTranslateMatrix(),\n finalMatrix = multiplyMatrices(translateMatrix, rotateMatrix),\n dim = this._getTransformedDimensions(),\n w = dim.x / 2,\n h = dim.y / 2;\n\n return {\n // corners\n tl: transformPoint({\n x: -w,\n y: -h\n }, finalMatrix),\n tr: transformPoint({\n x: w,\n y: -h\n }, finalMatrix),\n bl: transformPoint({\n x: -w,\n y: h\n }, finalMatrix),\n br: transformPoint({\n x: w,\n y: h\n }, finalMatrix)\n };\n },\n\n /**\n * Sets corner position coordinates based on current angle, width and height.\n * oCoords are used to find the corners\n * aCoords are used to quickly find an object on the canvas\n * lineCoords are used to quickly find object during pointer events.\n * See {@link https://github.com/kangax/fabric.js/wiki/When-to-call-setCoords|When-to-call-setCoords}\n * @param {Boolean} [skipCorners] skip calculation of oCoords.\n * @return {fabric.Object} thisArg\n * @chainable\n */\n setCoords: function setCoords(skipCorners) {\n this.aCoords = this.calcACoords(); // in case we are in a group, for how the inner group target check works,\n // lineCoords are exactly aCoords. Since the vpt gets absorbed by the normalized pointer.\n\n this.lineCoords = this.group ? this.aCoords : this.calcLineCoords();\n\n if (skipCorners) {\n return this;\n } // set coordinates of the draggable boxes in the corners used to scale/rotate the image\n\n\n this.oCoords = this.calcOCoords();\n this._setCornerCoords && this._setCornerCoords();\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 _calcRotateMatrix() {\n return util.calcRotateMatrix(this);\n },\n\n /**\n * calculate the translation matrix for an object transform\n * @return {Array} rotation matrix for the object\n */\n _calcTranslateMatrix: function _calcTranslateMatrix() {\n var center = this.getCenterPoint();\n return [1, 0, 0, 1, center.x, center.y];\n },\n transformMatrixKey: function transformMatrixKey(skipGroup) {\n var sep = '_',\n prefix = '';\n\n if (!skipGroup && this.group) {\n prefix = this.group.transformMatrixKey(skipGroup) + sep;\n }\n\n ;\n return prefix + this.top + sep + this.left + sep + this.scaleX + sep + this.scaleY + sep + this.skewX + sep + this.skewY + sep + this.angle + sep + this.originX + sep + this.originY + 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 * There are some situation in which this is useful to avoid the fake rotation.\n * @return {Array} transform matrix for the object\n */\n calcTransformMatrix: function calcTransformMatrix(skipGroup) {\n var matrix = this.calcOwnMatrix();\n\n if (skipGroup || !this.group) {\n return matrix;\n }\n\n var key = this.transformMatrixKey(skipGroup),\n cache = this.matrixCache || (this.matrixCache = {});\n\n if (cache.key === key) {\n return cache.value;\n }\n\n if (this.group) {\n matrix = multiplyMatrices(this.group.calcTransformMatrix(false), matrix);\n }\n\n cache.key = key;\n cache.value = matrix;\n return matrix;\n },\n\n /**\n * calculate transform matrix that represents the current transformations from the\n * object's properties, this matrix does not include the group transformation\n * @return {Array} transform matrix for the object\n */\n calcOwnMatrix: function calcOwnMatrix() {\n var key = this.transformMatrixKey(true),\n cache = this.ownMatrixCache || (this.ownMatrixCache = {});\n\n if (cache.key === key) {\n return cache.value;\n }\n\n var tMatrix = this._calcTranslateMatrix(),\n options = {\n angle: this.angle,\n translateX: tMatrix[4],\n translateY: tMatrix[5],\n scaleX: this.scaleX,\n scaleY: this.scaleY,\n skewX: this.skewX,\n skewY: this.skewY,\n flipX: this.flipX,\n flipY: this.flipY\n };\n\n cache.key = key;\n cache.value = util.composeMatrix(options);\n return cache.value;\n },\n\n /*\n * Calculate object dimensions from its properties\n * @private\n * @deprecated since 3.4.0, please use fabric.util._calcDimensionsTransformMatrix\n * not including or including flipX, flipY to emulate the flipping boolean\n * @return {Object} .x width dimension\n * @return {Object} .y height dimension\n */\n _calcDimensionsTransformMatrix: function _calcDimensionsTransformMatrix(skewX, skewY, flipping) {\n return util.calcDimensionsMatrix({\n skewX: skewX,\n skewY: skewY,\n scaleX: this.scaleX * (flipping && this.flipX ? -1 : 1),\n scaleY: this.scaleY * (flipping && this.flipY ? -1 : 1)\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 _getNonTransformedDimensions() {\n var strokeWidth = this.strokeWidth,\n w = this.width + strokeWidth,\n h = this.height + strokeWidth;\n return {\n x: w,\n y: h\n };\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 _getTransformedDimensions(skewX, skewY) {\n if (typeof skewX === 'undefined') {\n skewX = this.skewX;\n }\n\n if (typeof skewY === 'undefined') {\n skewY = this.skewY;\n }\n\n var dimensions = this._getNonTransformedDimensions(),\n dimX,\n dimY,\n noSkew = skewX === 0 && skewY === 0;\n\n if (this.strokeUniform) {\n dimX = this.width;\n dimY = this.height;\n } else {\n dimX = dimensions.x;\n dimY = dimensions.y;\n }\n\n if (noSkew) {\n return this._finalizeDimensions(dimX * this.scaleX, dimY * this.scaleY);\n }\n\n var bbox = util.sizeAfterTransform(dimX, dimY, {\n scaleX: this.scaleX,\n scaleY: this.scaleY,\n skewX: skewX,\n skewY: skewY\n });\n return this._finalizeDimensions(bbox.x, bbox.y);\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 _finalizeDimensions(width, height) {\n return this.strokeUniform ? {\n x: width + this.strokeWidth,\n y: height + this.strokeWidth\n } : {\n x: width,\n y: height\n };\n },\n\n /*\n * Calculate object dimensions for controls box, including padding and canvas zoom.\n * and active selection\n * private\n */\n _calculateCurrentDimensions: function _calculateCurrentDimensions() {\n var vpt = this.getViewportTransform(),\n dim = this._getTransformedDimensions(),\n p = transformPoint(dim, vpt, true);\n\n return p.scalarAdd(2 * this.padding);\n }\n });\n})();\n\nfabric.util.object.extend(fabric.Object.prototype,\n/** @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 sendToBack() {\n if (this.group) {\n fabric.StaticCanvas.prototype.sendToBack.call(this.group, this);\n } else if (this.canvas) {\n this.canvas.sendToBack(this);\n }\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 bringToFront() {\n if (this.group) {\n fabric.StaticCanvas.prototype.bringToFront.call(this.group, this);\n } else if (this.canvas) {\n this.canvas.bringToFront(this);\n }\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 sendBackwards(intersecting) {\n if (this.group) {\n fabric.StaticCanvas.prototype.sendBackwards.call(this.group, this, intersecting);\n } else if (this.canvas) {\n this.canvas.sendBackwards(this, intersecting);\n }\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 bringForward(intersecting) {\n if (this.group) {\n fabric.StaticCanvas.prototype.bringForward.call(this.group, this, intersecting);\n } else if (this.canvas) {\n this.canvas.bringForward(this, intersecting);\n }\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 moveTo(index) {\n if (this.group && this.group.type !== 'activeSelection') {\n fabric.StaticCanvas.prototype.moveTo.call(this.group, this, index);\n } else if (this.canvas) {\n this.canvas.moveTo(this, index);\n }\n\n return this;\n }\n});\n/* _TO_SVG_START_ */\n\n(function () {\n function getSvgColorString(prop, value) {\n if (!value) {\n return prop + ': none; ';\n } else if (value.toLive) {\n return prop + ': url(#SVGID_' + value.id + '); ';\n } else {\n var color = new fabric.Color(value),\n str = prop + ': ' + color.toRgb() + '; ',\n opacity = color.getAlpha();\n\n if (opacity !== 1) {\n //change the color in rgb + opacity\n str += prop + '-opacity: ' + opacity.toString() + '; ';\n }\n\n return str;\n }\n }\n\n var toFixed = fabric.util.toFixed;\n fabric.util.object.extend(fabric.Object.prototype,\n /** @lends fabric.Object.prototype */\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 getSvgStyles(skipShadow) {\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 return [stroke, 'stroke-width: ', strokeWidth, '; ', 'stroke-dasharray: ', strokeDashArray, '; ', 'stroke-linecap: ', strokeLineCap, '; ', 'stroke-dashoffset: ', strokeDashOffset, '; ', 'stroke-linejoin: ', strokeLineJoin, '; ', 'stroke-miterlimit: ', strokeMiterLimit, '; ', fill, 'fill-rule: ', fillRule, '; ', 'opacity: ', opacity, ';', filter, visibility].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 getSvgSpanStyles(style, useWhiteSpace) {\n var term = '; ';\n var fontFamily = style.fontFamily ? 'font-family: ' + (style.fontFamily.indexOf('\\'') === -1 && style.fontFamily.indexOf('\"') === -1 ? '\\'' + 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\n if (textDecoration) {\n textDecoration = 'text-decoration: ' + textDecoration + term;\n }\n\n return [stroke, strokeWidth, fontFamily, fontSize, fontStyle, fontWeight, textDecoration, fill, deltaY, useWhiteSpace ? 'white-space: pre; ' : ''].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 getSvgTextDecoration(style) {\n return ['overline', 'underline', 'line-through'].filter(function (decoration) {\n return style[decoration.replace('-', '')];\n }).join(' ');\n },\n\n /**\n * Returns filter for svg shadow\n * @return {String}\n */\n getSvgFilter: function getSvgFilter() {\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 getSvgCommons() {\n return [this.id ? 'id=\"' + this.id + '\" ' : '', this.clipPath ? 'clip-path=\"url(#' + this.clipPath.clipPathId + ')\" ' : ''].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 getSvgTransform(full, additionalTransform) {\n var transform = full ? this.calcTransformMatrix() : this.calcOwnMatrix(),\n svgTransform = 'transform=\"' + fabric.util.matrixToSVG(transform);\n return svgTransform + (additionalTransform || '') + '\" ';\n },\n _setSVGBg: function _setSVGBg(textBgRects) {\n if (this.backgroundColor) {\n var NUM_FRACTION_DIGITS = fabric.Object.NUM_FRACTION_DIGITS;\n textBgRects.push('\\t\\t\\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 toSVG(reviver) {\n return this._createBaseSVGMarkup(this._toSVG(reviver), {\n reviver: reviver\n });\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 toClipPathSVG(reviver) {\n return '\\t' + this._createBaseClipPathSVGMarkup(this._toSVG(reviver), {\n reviver: reviver\n });\n },\n\n /**\n * @private\n */\n _createBaseClipPathSVGMarkup: function _createBaseClipPathSVGMarkup(objectMarkup, options) {\n options = options || {};\n var reviver = options.reviver,\n additionalTransform = options.additionalTransform || '',\n commonPieces = [this.getSvgTransform(true, additionalTransform), this.getSvgCommons()].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 _createBaseSVGMarkup(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,\n fill = this.fill,\n shadow = this.shadow,\n commonPieces,\n markup = [],\n clipPathMarkup,\n // insert commons in the markup, style and svgCommons\n index = objectMarkup.indexOf('COMMON_PARTS'),\n additionalTransform = options.additionalTransform;\n\n if (clipPath) {\n clipPath.clipPathId = 'CLIPPATH_' + fabric.Object.__uid++;\n clipPathMarkup = '\\n' + clipPath.toClipPathSVG(reviver) + '\\n';\n }\n\n if (absoluteClipPath) {\n markup.push('\\n');\n }\n\n markup.push('\\n');\n commonPieces = [styleInfo, vectorEffect, noStyle ? '' : this.addPaintOrder(), ' ', additionalTransform ? 'transform=\"' + additionalTransform + '\" ' : ''].join('');\n objectMarkup[index] = commonPieces;\n\n if (fill && fill.toLive) {\n markup.push(fill.toSVG(this));\n }\n\n if (stroke && stroke.toLive) {\n markup.push(stroke.toSVG(this));\n }\n\n if (shadow) {\n markup.push(shadow.toSVG(this));\n }\n\n if (clipPath) {\n markup.push(clipPathMarkup);\n }\n\n markup.push(objectMarkup.join(''));\n markup.push('\\n');\n absoluteClipPath && markup.push('\\n');\n return reviver ? reviver(markup.join('')) : markup.join('');\n },\n addPaintOrder: function addPaintOrder() {\n return this.paintFirst !== 'fill' ? ' paint-order=\"' + this.paintFirst + '\" ' : '';\n }\n });\n})();\n/* _TO_SVG_END_ */\n\n\n(function () {\n var extend = fabric.util.object.extend,\n originalSet = 'stateProperties';\n /*\n Depends on `stateProperties`\n */\n\n function saveProps(origin, destination, props) {\n var tmpObj = {},\n 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 } else if (Array.isArray(origValue)) {\n if (!Array.isArray(currentValue) || origValue.length !== currentValue.length) {\n return false;\n }\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\n return true;\n } else if (origValue && typeof origValue === 'object') {\n var keys = Object.keys(origValue),\n key;\n\n if (!currentValue || typeof currentValue !== 'object' || !firstPass && keys.length !== Object.keys(currentValue).length) {\n return false;\n }\n\n for (var i = 0, len = keys.length; i < len; i++) {\n key = keys[i]; // 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 // we do not want to compare those.\n\n if (key === 'canvas' || key === 'group') {\n continue;\n }\n\n if (!_isEqual(origValue[key], currentValue[key])) {\n return false;\n }\n }\n\n return true;\n }\n }\n\n fabric.util.object.extend(fabric.Object.prototype,\n /** @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 hasStateChanged(propertySet) {\n propertySet = propertySet || originalSet;\n var dashedPropertySet = '_' + propertySet;\n\n if (Object.keys(this[dashedPropertySet]).length < this[propertySet].length) {\n return true;\n }\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 saveState(options) {\n var propertySet = options && options.propertySet || originalSet,\n destination = '_' + propertySet;\n\n if (!this[destination]) {\n return this.setupState(options);\n }\n\n saveProps(this, destination, this[propertySet]);\n\n if (options && options.stateProperties) {\n saveProps(this, destination, options.stateProperties);\n }\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 setupState(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(function () {\n var degreesToRadians = fabric.util.degreesToRadians;\n fabric.util.object.extend(fabric.Object.prototype,\n /** @lends fabric.Object.prototype */\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 _findTargetCorner(pointer, forTouch) {\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 keys = Object.keys(this.oCoords),\n j = keys.length - 1,\n i;\n this.__corner = 0; // cycle in reverse order so we pick first the one on top\n\n for (; j >= 0; j--) {\n i = keys[j];\n\n if (!this.isControlVisible(i)) {\n continue;\n }\n\n lines = this._getImageLines(forTouch ? this.oCoords[i].touchCorner : this.oCoords[i].corner); // debugging\n // this.canvas.contextTop.fillRect(lines.bottomline.d.x, lines.bottomline.d.y, 2, 2);\n // this.canvas.contextTop.fillRect(lines.bottomline.o.x, lines.bottomline.o.y, 2, 2);\n //\n // this.canvas.contextTop.fillRect(lines.leftline.d.x, lines.leftline.d.y, 2, 2);\n // this.canvas.contextTop.fillRect(lines.leftline.o.x, lines.leftline.o.y, 2, 2);\n //\n // this.canvas.contextTop.fillRect(lines.topline.d.x, lines.topline.d.y, 2, 2);\n // this.canvas.contextTop.fillRect(lines.topline.o.x, lines.topline.o.y, 2, 2);\n //\n // this.canvas.contextTop.fillRect(lines.rightline.d.x, lines.rightline.d.y, 2, 2);\n // this.canvas.contextTop.fillRect(lines.rightline.o.x, lines.rightline.o.y, 2, 2);\n\n xPoints = this._findCrossPoints({\n x: ex,\n y: ey\n }, lines);\n\n if (xPoints !== 0 && xPoints % 2 === 1) {\n this.__corner = i;\n return i;\n }\n }\n\n return false;\n },\n\n /**\n * Calls a function for each control. The function gets called,\n * with the control, the object that is calling the iterator and the control's key\n * @param {Function} fn function to iterate over the controls over\n */\n forEachControl: function forEachControl(fn) {\n for (var i in this.controls) {\n fn(this.controls[i], i, this);\n }\n\n ;\n },\n\n /**\n * Sets the coordinates of the draggable boxes in the corners of\n * the image used to scale/rotate it.\n * note: if we would switch to ROUND corner area, all of this would disappear.\n * everything would resolve to a single point and a pythagorean theorem for the distance\n * @private\n */\n _setCornerCoords: function _setCornerCoords() {\n var coords = this.oCoords,\n newTheta = degreesToRadians(45 - this.angle),\n cosTheta = fabric.util.cos(newTheta),\n sinTheta = fabric.util.sin(newTheta),\n\n /* Math.sqrt(2 * Math.pow(this.cornerSize, 2)) / 2, */\n\n /* 0.707106 stands for sqrt(2)/2 */\n cornerHypotenuse = this.cornerSize * 0.707106,\n touchHypotenuse = this.touchCornerSize * 0.707106,\n cosHalfOffset = cornerHypotenuse * cosTheta,\n sinHalfOffset = cornerHypotenuse * sinTheta,\n touchCosHalfOffset = touchHypotenuse * cosTheta,\n touchSinHalfOffset = touchHypotenuse * sinTheta,\n x,\n y;\n\n for (var control in coords) {\n x = coords[control].x;\n y = coords[control].y;\n coords[control].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 coords[control].touchCorner = {\n tl: {\n x: x - touchSinHalfOffset,\n y: y - touchCosHalfOffset\n },\n tr: {\n x: x + touchCosHalfOffset,\n y: y - touchSinHalfOffset\n },\n bl: {\n x: x - touchCosHalfOffset,\n y: y + touchSinHalfOffset\n },\n br: {\n x: x + touchSinHalfOffset,\n y: y + touchCosHalfOffset\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 drawSelectionBackground(ctx) {\n if (!this.selectionBackgroundColor || this.canvas && !this.canvas.interactive || this.canvas && this.canvas._activeObject !== this) {\n return this;\n }\n\n ctx.save();\n\n var center = this.getCenterPoint(),\n wh = this._calculateCurrentDimensions(),\n vpt = this.canvas.viewportTransform;\n\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 drawBorders(ctx, styleOverride) {\n styleOverride = styleOverride || {};\n\n var wh = this._calculateCurrentDimensions(),\n strokeWidth = this.borderScaleFactor,\n width = wh.x + strokeWidth,\n height = wh.y + strokeWidth,\n hasControls = typeof styleOverride.hasControls !== 'undefined' ? styleOverride.hasControls : this.hasControls,\n shouldStroke = false;\n\n ctx.save();\n ctx.strokeStyle = styleOverride.borderColor || this.borderColor;\n\n this._setLineDash(ctx, styleOverride.borderDashArray || this.borderDashArray, null);\n\n ctx.strokeRect(-width / 2, -height / 2, width, height);\n\n if (hasControls) {\n ctx.beginPath();\n this.forEachControl(function (control, key, fabricObject) {\n // in this moment, the ctx is centered on the object.\n // width and height of the above function are the size of the bbox.\n if (control.withConnection && control.getVisibility(fabricObject, key)) {\n // reset movement for each control\n shouldStroke = true;\n ctx.moveTo(control.x * width, control.y * height);\n ctx.lineTo(control.x * width + control.offsetX, control.y * height + control.offsetY);\n }\n });\n\n if (shouldStroke) {\n ctx.stroke();\n }\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 drawBordersInGroup(ctx, options, styleOverride) {\n styleOverride = styleOverride || {};\n var bbox = fabric.util.sizeAfterTransform(this.width, this.height, options),\n strokeWidth = this.strokeWidth,\n strokeUniform = this.strokeUniform,\n borderScaleFactor = this.borderScaleFactor,\n width = bbox.x + strokeWidth * (strokeUniform ? this.canvas.getZoom() : options.scaleX) + borderScaleFactor,\n height = bbox.y + strokeWidth * (strokeUniform ? this.canvas.getZoom() : options.scaleY) + borderScaleFactor;\n ctx.save();\n\n this._setLineDash(ctx, styleOverride.borderDashArray || this.borderDashArray, null);\n\n ctx.strokeStyle = styleOverride.borderColor || this.borderColor;\n ctx.strokeRect(-width / 2, -height / 2, width, height);\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 drawControls(ctx, styleOverride) {\n styleOverride = styleOverride || {};\n ctx.save();\n ctx.setTransform(this.canvas.getRetinaScaling(), 0, 0, this.canvas.getRetinaScaling(), 0, 0);\n ctx.strokeStyle = ctx.fillStyle = styleOverride.cornerColor || this.cornerColor;\n\n if (!this.transparentCorners) {\n ctx.strokeStyle = styleOverride.cornerStrokeColor || this.cornerStrokeColor;\n }\n\n this._setLineDash(ctx, styleOverride.cornerDashArray || this.cornerDashArray, null);\n\n this.setCoords();\n this.forEachControl(function (control, key, fabricObject) {\n if (control.getVisibility(fabricObject, key)) {\n control.render(ctx, fabricObject.oCoords[key].x, fabricObject.oCoords[key].y, styleOverride, fabricObject);\n }\n });\n ctx.restore();\n return this;\n },\n\n /**\n * Returns true if the specified control is visible, false otherwise.\n * @param {String} controlKey The key 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 isControlVisible(controlKey) {\n return this.controls[controlKey] && this.controls[controlKey].getVisibility(this, controlKey);\n },\n\n /**\n * Sets the visibility of the specified control.\n * @param {String} controlKey The key 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 setControlVisible(controlKey, visible) {\n if (!this._controlsVisibility) {\n this._controlsVisibility = {};\n }\n\n this._controlsVisibility[controlKey] = 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 setControlsVisibility(options) {\n options || (options = {});\n\n for (var p in options) {\n this.setControlVisible(p, options[p]);\n }\n\n return this;\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 onDeselect() {// implemented by sub-classes, as needed.\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 onSelect() {// implemented by sub-classes, as needed.\n }\n });\n})();\n\nfabric.util.object.extend(fabric.StaticCanvas.prototype,\n/** @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 fxCenterObjectH(object, callbacks) {\n callbacks = callbacks || {};\n\n var empty = function empty() {},\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 onChange(value) {\n object.set('left', value);\n\n _this.requestRenderAll();\n\n _onChange();\n },\n onComplete: function onComplete() {\n object.setCoords();\n\n _onComplete();\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 fxCenterObjectV(object, callbacks) {\n callbacks = callbacks || {};\n\n var empty = function empty() {},\n _onComplete2 = callbacks.onComplete || empty,\n _onChange2 = 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 onChange(value) {\n object.set('top', value);\n\n _this.requestRenderAll();\n\n _onChange2();\n },\n onComplete: function onComplete() {\n object.setCoords();\n\n _onComplete2();\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 fxRemove(object, callbacks) {\n callbacks = callbacks || {};\n\n var empty = function empty() {},\n _onComplete3 = callbacks.onComplete || empty,\n _onChange3 = 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 onChange(value) {\n object.set('opacity', value);\n\n _this.requestRenderAll();\n\n _onChange3();\n },\n onComplete: function onComplete() {\n _this.remove(object);\n\n _onComplete3();\n }\n });\n return this;\n }\n});\nfabric.util.object.extend(fabric.Object.prototype,\n/** @lends fabric.Object.prototype */\n{\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 animate() {\n if (arguments[0] && typeof arguments[0] === 'object') {\n var propsToAnimate = [],\n prop,\n skipCallbacks;\n\n for (prop in arguments[0]) {\n propsToAnimate.push(prop);\n }\n\n for (var i = 0, len = propsToAnimate.length; i < len; i++) {\n prop = propsToAnimate[i];\n skipCallbacks = i !== len - 1;\n\n this._animate(prop, arguments[0][prop], arguments[1], skipCallbacks);\n }\n } else {\n this._animate.apply(this, arguments);\n }\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 _animate(property, to, options, skipCallbacks) {\n var _this = this,\n propPair;\n\n to = to.toString();\n\n if (!options) {\n options = {};\n } else {\n options = fabric.util.object.clone(options);\n }\n\n if (~property.indexOf('.')) {\n propPair = property.split('.');\n }\n\n var propIsColor = _this.colorProperties.indexOf(property) > -1 || propPair && _this.colorProperties.indexOf(propPair[1]) > -1;\n var currentValue = propPair ? this.get(propPair[0])[propPair[1]] : this.get(property);\n\n if (!('from' in options)) {\n options.from = currentValue;\n }\n\n if (!propIsColor) {\n if (~to.indexOf('=')) {\n to = currentValue + parseFloat(to.replace('=', ''));\n } else {\n to = parseFloat(to);\n }\n }\n\n var _options = {\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 onChange(value, valueProgress, timeProgress) {\n if (propPair) {\n _this[propPair[0]][propPair[1]] = value;\n } else {\n _this.set(property, value);\n }\n\n if (skipCallbacks) {\n return;\n }\n\n options.onChange && options.onChange(value, valueProgress, timeProgress);\n },\n onComplete: function onComplete(value, valueProgress, timeProgress) {\n if (skipCallbacks) {\n return;\n }\n\n _this.setCoords();\n\n options.onComplete && options.onComplete(value, valueProgress, timeProgress);\n }\n };\n\n if (propIsColor) {\n fabric.util.animateColor(_options.startValue, _options.endValue, _options.duration, _options);\n } else {\n fabric.util.animate(_options);\n }\n }\n});\n\n(function (global) {\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 = {\n x1: 1,\n x2: 1,\n y1: 1,\n y2: 1\n },\n supportsLineDash = fabric.StaticCanvas.supports('setLineDash');\n\n if (fabric.Line) {\n fabric.warn('fabric.Line is already defined');\n return;\n }\n /**\n * Line class\n * @class fabric.Line\n * @extends fabric.Object\n * @see {@link fabric.Line#initialize} for constructor definition\n */\n\n\n fabric.Line = fabric.util.createClass(fabric.Object,\n /** @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 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 initialize(points, options) {\n if (!points) {\n points = [0, 0, 0, 0];\n }\n\n this.callSuper('initialize', options);\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 _setWidthHeight(options) {\n options || (options = {});\n this.width = Math.abs(this.x2 - this.x1);\n this.height = Math.abs(this.y2 - this.y1);\n this.left = 'left' in options ? options.left : this._getLeftToOriginX();\n this.top = 'top' in options ? options.top : this._getTopToOriginY();\n },\n\n /**\n * @private\n * @param {String} key\n * @param {*} value\n */\n _set: function _set(key, value) {\n this.callSuper('_set', key, value);\n\n if (typeof coordProps[key] !== 'undefined') {\n this._setWidthHeight();\n }\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 * @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 * @private\n * @param {CanvasRenderingContext2D} ctx Context to render on\n */\n _render: function _render(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; // 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\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 _renderDashedStroke(ctx) {\n var p = this.calcLinePoints();\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 _findCenterFromElement() {\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 toObject(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 _getNonTransformedDimensions() {\n var dim = this.callSuper('_getNonTransformedDimensions');\n\n if (this.strokeLineCap === 'butt') {\n if (this.width === 0) {\n dim.y -= this.strokeWidth;\n }\n\n if (this.height === 0) {\n dim.x -= this.strokeWidth;\n }\n }\n\n return dim;\n },\n\n /**\n * Recalculates line points given width and height\n * @private\n */\n calcLinePoints: function calcLinePoints() {\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 return {\n x1: x1,\n x2: x2,\n y1: y1,\n y2: y2\n };\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 _toSVG() {\n var p = this.calcLinePoints();\n return ['\\n'];\n }\n /* _TO_SVG_END_ */\n\n });\n /* _FROM_SVG_START_ */\n\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\n fabric.Line.ATTRIBUTE_NAMES = fabric.SHARED_ATTRIBUTES.concat('x1 y1 x2 y2'.split(' '));\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\n fabric.Line.fromElement = function (element, callback, options) {\n options = options || {};\n var parsedAttributes = fabric.parseAttributes(element, fabric.Line.ATTRIBUTE_NAMES),\n points = [parsedAttributes.x1 || 0, parsedAttributes.y1 || 0, parsedAttributes.x2 || 0, parsedAttributes.y2 || 0];\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\n\n fabric.Line.fromObject = function (object, callback) {\n function _callback(instance) {\n delete instance.points;\n callback && callback(instance);\n }\n\n ;\n var options = clone(object, true);\n options.points = [object.x1, object.y1, object.x2, object.y2];\n\n fabric.Object._fromObject('Line', options, _callback, 'points');\n };\n /**\n * Produces a function that calculates distance from canvas edge to Line origin.\n */\n\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 return function () {\n switch (this.get(origin)) {\n case nearest:\n return Math.min(this.get(axis1), this.get(axis2));\n\n case center:\n return Math.min(this.get(axis1), this.get(axis2)) + 0.5 * this.get(dimension);\n\n case farthest:\n return Math.max(this.get(axis1), this.get(axis2));\n }\n };\n }\n})(typeof exports !== 'undefined' ? exports : this);\n\n(function (global) {\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 * Circle class\n * @class fabric.Circle\n * @extends fabric.Object\n * @see {@link fabric.Circle#initialize} for constructor definition\n */\n\n\n fabric.Circle = fabric.util.createClass(fabric.Object,\n /** @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 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 _set(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 toObject(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 _toSVG() {\n var svgString,\n x = 0,\n y = 0,\n angle = (this.endAngle - this.startAngle) % (2 * pi);\n\n if (angle === 0) {\n svgString = ['\\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'];\n }\n\n return svgString;\n },\n\n /* _TO_SVG_END_ */\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx context to render on\n */\n _render: function _render(ctx) {\n ctx.beginPath();\n ctx.arc(0, 0, this.radius, this.startAngle, this.endAngle, false);\n\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 getRadiusX() {\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 getRadiusY() {\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 setRadius(value) {\n this.radius = value;\n return this.set('width', value * 2).set('height', value * 2);\n }\n });\n /* _FROM_SVG_START_ */\n\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\n fabric.Circle.ATTRIBUTE_NAMES = fabric.SHARED_ATTRIBUTES.concat('cx cy r'.split(' '));\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\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 * @private\n */\n\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\n\n fabric.Circle.fromObject = function (object, callback) {\n return fabric.Object._fromObject('Circle', object, callback);\n };\n})(typeof exports !== 'undefined' ? exports : this);\n\n(function (global) {\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 * 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\n\n fabric.Triangle = fabric.util.createClass(fabric.Object,\n /** @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 _render(ctx) {\n var widthBy2 = this.width / 2,\n heightBy2 = this.height / 2;\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 _renderDashedStroke(ctx) {\n var widthBy2 = this.width / 2,\n heightBy2 = this.height / 2;\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 /**\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 _toSVG() {\n var widthBy2 = this.width / 2,\n heightBy2 = this.height / 2,\n points = [-widthBy2 + ' ' + heightBy2, '0 ' + -heightBy2, widthBy2 + ' ' + heightBy2].join(',');\n return [''];\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\n fabric.Triangle.fromObject = function (object, callback) {\n return fabric.Object._fromObject('Triangle', object, callback);\n };\n})(typeof exports !== 'undefined' ? exports : this);\n\n(function (global) {\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 * 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\n\n fabric.Ellipse = fabric.util.createClass(fabric.Object,\n /** @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 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 initialize(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 _set(key, value) {\n this.callSuper('_set', key, value);\n\n switch (key) {\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 getRx() {\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 getRy() {\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 toObject(propertiesToInclude) {\n return this.callSuper('toObject', ['rx', 'ry'].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 _toSVG() {\n return ['\\n'];\n },\n\n /* _TO_SVG_END_ */\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx context to render on\n */\n _render: function _render(ctx) {\n ctx.beginPath();\n ctx.save();\n ctx.transform(1, 0, 0, this.ry / this.rx, 0, 0);\n ctx.arc(0, 0, this.rx, 0, piBy2, false);\n ctx.restore();\n\n this._renderPaintInOrder(ctx);\n }\n });\n /* _FROM_SVG_START_ */\n\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\n fabric.Ellipse.ATTRIBUTE_NAMES = fabric.SHARED_ATTRIBUTES.concat('cx cy rx ry'.split(' '));\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\n fabric.Ellipse.fromElement = function (element, callback) {\n var parsedAttributes = fabric.parseAttributes(element, fabric.Ellipse.ATTRIBUTE_NAMES);\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\n\n fabric.Ellipse.fromObject = function (object, callback) {\n return fabric.Object._fromObject('Ellipse', object, callback);\n };\n})(typeof exports !== 'undefined' ? exports : this);\n\n(function (global) {\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 * 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\n\n fabric.Rect = fabric.util.createClass(fabric.Object,\n /** @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 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 initialize(options) {\n this.callSuper('initialize', options);\n\n this._initRxRy();\n },\n\n /**\n * Initializes rx/ry attributes\n * @private\n */\n _initRxRy: function _initRxRy() {\n if (this.rx && !this.ry) {\n this.ry = this.rx;\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 _render(ctx) {\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 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\n /* \"magic number\" for bezier approximations of arcs (http://itc.ktu.lt/itc354/Riskus354.pdf) */\n k = 1 - 0.5522847498;\n ctx.beginPath();\n ctx.moveTo(x + rx, y);\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 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 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 ctx.lineTo(x, y + ry);\n isRounded && ctx.bezierCurveTo(x, y + k * ry, x + k * rx, y, x + rx, y);\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 _renderDashedStroke(ctx) {\n var x = -this.width / 2,\n y = -this.height / 2,\n w = this.width,\n h = this.height;\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 toObject(propertiesToInclude) {\n return this.callSuper('toObject', ['rx', 'ry'].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 _toSVG() {\n var x = -this.width / 2,\n y = -this.height / 2;\n return ['\\n'];\n }\n /* _TO_SVG_END_ */\n\n });\n /* _FROM_SVG_START_ */\n\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\n fabric.Rect.ATTRIBUTE_NAMES = fabric.SHARED_ATTRIBUTES.concat('x y rx ry width height'.split(' '));\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\n fabric.Rect.fromElement = function (element, callback, options) {\n if (!element) {\n return callback(null);\n }\n\n options = options || {};\n var parsedAttributes = fabric.parseAttributes(element, fabric.Rect.ATTRIBUTE_NAMES);\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\n\n fabric.Rect.fromObject = function (object, callback) {\n return fabric.Object._fromObject('Rect', object, callback);\n };\n})(typeof exports !== 'undefined' ? exports : this);\n\n(function (global) {\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 * Polyline class\n * @class fabric.Polyline\n * @extends fabric.Object\n * @see {@link fabric.Polyline#initialize} for constructor definition\n */\n\n\n fabric.Polyline = fabric.util.createClass(fabric.Object,\n /** @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 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 initialize(points, options) {\n options = options || {};\n this.points = points || [];\n this.callSuper('initialize', options);\n\n this._setPositionDimensions(options);\n },\n _setPositionDimensions: function _setPositionDimensions(options) {\n var calcDim = this._calcDimensions(options),\n correctLeftTop;\n\n this.width = calcDim.width;\n this.height = calcDim.height;\n\n if (!options.fromSVG) {\n correctLeftTop = this.translateToGivenOrigin({\n x: calcDim.left - this.strokeWidth / 2,\n y: calcDim.top - this.strokeWidth / 2\n }, 'left', 'top', this.originX, this.originY);\n }\n\n if (typeof options.left === 'undefined') {\n this.left = options.fromSVG ? calcDim.left : correctLeftTop.x;\n }\n\n if (typeof options.top === 'undefined') {\n this.top = options.fromSVG ? calcDim.top : correctLeftTop.y;\n }\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 _calcDimensions() {\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 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 toObject(propertiesToInclude) {\n return extend(this.callSuper('toObject', propertiesToInclude), {\n points: this.points.concat()\n });\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 _toSVG() {\n var points = [],\n diffX = this.pathOffset.x,\n 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(toFixed(this.points[i].x - diffX, NUM_FRACTION_DIGITS), ',', toFixed(this.points[i].y - diffY, NUM_FRACTION_DIGITS), ' ');\n }\n\n return ['<' + this.type + ' ', 'COMMON_PARTS', 'points=\"', points.join(''), '\" />\\n'];\n },\n\n /* _TO_SVG_END_ */\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx Context to render on\n */\n commonRender: function commonRender(ctx) {\n var point,\n 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\n ctx.beginPath();\n ctx.moveTo(this.points[0].x - x, this.points[0].y - y);\n\n for (var i = 0; i < len; i++) {\n point = this.points[i];\n ctx.lineTo(point.x - x, point.y - y);\n }\n\n return true;\n },\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx Context to render on\n */\n _render: function _render(ctx) {\n if (!this.commonRender(ctx)) {\n return;\n }\n\n this._renderPaintInOrder(ctx);\n },\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx Context to render on\n */\n _renderDashedStroke: function _renderDashedStroke(ctx) {\n var p1, p2;\n ctx.beginPath();\n\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 complexity() {\n return this.get('points').length;\n }\n });\n /* _FROM_SVG_START_ */\n\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\n fabric.Polyline.ATTRIBUTE_NAMES = fabric.SHARED_ATTRIBUTES.concat();\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\n fabric.Polyline.fromElementGenerator = function (_class) {\n return function (element, callback, options) {\n if (!element) {\n return callback(null);\n }\n\n options || (options = {});\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 /* _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\n fabric.Polyline.fromObject = function (object, callback) {\n return fabric.Object._fromObject('Polyline', object, callback, 'points');\n };\n})(typeof exports !== 'undefined' ? exports : this);\n\n(function (global) {\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 * Polygon class\n * @class fabric.Polygon\n * @extends fabric.Polyline\n * @see {@link fabric.Polygon#initialize} for constructor definition\n */\n\n\n fabric.Polygon = fabric.util.createClass(fabric.Polyline,\n /** @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 _render(ctx) {\n if (!this.commonRender(ctx)) {\n return;\n }\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 _renderDashedStroke(ctx) {\n this.callSuper('_renderDashedStroke', ctx);\n ctx.closePath();\n }\n });\n /* _FROM_SVG_START_ */\n\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\n fabric.Polygon.ATTRIBUTE_NAMES = fabric.SHARED_ATTRIBUTES.concat();\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\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\n fabric.Polygon.fromObject = function (object, callback) {\n return fabric.Object._fromObject('Polygon', object, callback, 'points');\n };\n})(typeof exports !== 'undefined' ? exports : this);\n\n(function (global) {\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 toFixed = fabric.util.toFixed;\n\n if (fabric.Path) {\n fabric.warn('fabric.Path is already defined');\n return;\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\n\n fabric.Path = fabric.util.createClass(fabric.Object,\n /** @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 cacheProperties: fabric.Object.prototype.cacheProperties.concat('path', 'fillRule'),\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 initialize(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 this.path = fromArray ? fabric.util.makePathSimpler(path) : fabric.util.makePathSimpler(fabric.util.parsePath(path));\n\n if (!this.path) {\n return;\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 _renderPathCommands(ctx) {\n var current,\n // current instruction\n subpathStartX = 0,\n subpathStartY = 0,\n x = 0,\n // current x\n y = 0,\n // current y\n controlX = 0,\n // current control point x\n controlY = 0,\n // current control point y\n l = -this.pathOffset.x,\n t = -this.pathOffset.y;\n ctx.beginPath();\n\n for (var i = 0, len = this.path.length; i < len; ++i) {\n current = this.path[i];\n\n switch (current[0]) {\n // first letter\n case 'L':\n // lineto, absolute\n x = current[1];\n y = current[2];\n ctx.lineTo(x + l, y + t);\n break;\n\n case 'M':\n // 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':\n // bezierCurveTo, absolute\n x = current[5];\n y = current[6];\n controlX = current[3];\n controlY = current[4];\n ctx.bezierCurveTo(current[1] + l, current[2] + t, controlX + l, controlY + t, x + l, y + t);\n break;\n\n case 'Q':\n // quadraticCurveTo, absolute\n ctx.quadraticCurveTo(current[1] + l, current[2] + t, current[3] + l, current[4] + t);\n x = current[3];\n y = current[4];\n controlX = current[1];\n controlY = current[2];\n break;\n\n case 'z':\n case 'Z':\n x = subpathStartX;\n y = subpathStartY;\n ctx.closePath();\n break;\n }\n }\n },\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx context to render path on\n */\n _render: function _render(ctx) {\n this._renderPathCommands(ctx);\n\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 toString() {\n return '#';\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 toObject(propertiesToInclude) {\n return extend(this.callSuper('toObject', propertiesToInclude), {\n path: this.path.map(function (item) {\n return item.slice();\n })\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 toDatalessObject(propertiesToInclude) {\n var o = this.toObject(['sourcePath'].concat(propertiesToInclude));\n\n if (o.sourcePath) {\n delete o.path;\n }\n\n return o;\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 _toSVG() {\n var path = this.path.map(function (path) {\n return path.join(' ');\n }).join(' ');\n return ['\\n'];\n },\n _getOffsetTransform: function _getOffsetTransform() {\n var digits = fabric.Object.NUM_FRACTION_DIGITS;\n return ' translate(' + toFixed(-this.pathOffset.x, digits) + ', ' + 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 toClipPathSVG(reviver) {\n var additionalTransform = this._getOffsetTransform();\n\n return '\\t' + this._createBaseClipPathSVGMarkup(this._toSVG(), {\n reviver: reviver,\n 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 toSVG(reviver) {\n var additionalTransform = this._getOffsetTransform();\n\n return this._createBaseSVGMarkup(this._toSVG(), {\n reviver: reviver,\n additionalTransform: additionalTransform\n });\n },\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 complexity() {\n return this.path.length;\n },\n\n /**\n * @private\n */\n _calcDimensions: function _calcDimensions() {\n var aX = [],\n aY = [],\n current,\n // current instruction\n subpathStartX = 0,\n subpathStartY = 0,\n x = 0,\n // current x\n y = 0,\n // current y\n bounds;\n\n for (var i = 0, len = this.path.length; i < len; ++i) {\n current = this.path[i];\n\n switch (current[0]) {\n // first letter\n case 'L':\n // lineto, absolute\n x = current[1];\n y = current[2];\n bounds = [];\n break;\n\n case 'M':\n // moveTo, absolute\n x = current[1];\n y = current[2];\n subpathStartX = x;\n subpathStartY = y;\n bounds = [];\n break;\n\n case 'C':\n // bezierCurveTo, absolute\n bounds = fabric.util.getBoundsOfCurve(x, y, current[1], current[2], current[3], current[4], current[5], current[6]);\n x = current[5];\n y = current[6];\n break;\n\n case 'Q':\n // quadraticCurveTo, absolute\n bounds = fabric.util.getBoundsOfCurve(x, y, current[1], current[2], current[1], current[2], current[3], current[4]);\n x = current[3];\n y = current[4];\n break;\n\n case 'z':\n case 'Z':\n x = subpathStartX;\n y = subpathStartY;\n break;\n }\n\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 return {\n left: minX,\n top: minY,\n width: deltaX,\n height: deltaY\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\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 } else {\n fabric.Object._fromObject('Path', object, callback, 'path');\n }\n };\n /* _FROM_SVG_START_ */\n\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\n\n fabric.Path.ATTRIBUTE_NAMES = fabric.SHARED_ATTRIBUTES.concat(['d']);\n /**\n * Creates an instance of fabric.Path from an SVG 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\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(function (global) {\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 * 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\n\n fabric.Group = fabric.util.createClass(fabric.Object, fabric.Collection,\n /** @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, mouseover, mouseout events & hoverCursor 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 initialize(objects, options, isAlreadyGrouped) {\n options = options || {};\n this._objects = []; // 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\n isAlreadyGrouped && this.callSuper('initialize', options);\n this._objects = objects || [];\n\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; // 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\n if (options.originX !== undefined) {\n this.originX = options.originX;\n }\n\n if (options.originY !== undefined) {\n this.originY = options.originY;\n } // if coming from svg i do not want to calc bounds.\n // i assume width and height are passed along options\n\n\n center || this._calcBounds();\n\n this._updateObjectsCoords(center);\n\n delete options.centerPoint;\n this.callSuper('initialize', options);\n } else {\n this._updateObjectsACoords();\n }\n\n this.setCoords();\n },\n\n /**\n * @private\n */\n _updateObjectsACoords: function _updateObjectsACoords() {\n var skipControls = true;\n\n for (var i = this._objects.length; i--;) {\n this._objects[i].setCoords(skipControls);\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 _updateObjectsCoords(center) {\n var center = center || this.getCenterPoint();\n\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 _updateObjectCoords(object, center) {\n var objectLeft = object.left,\n objectTop = object.top,\n skipControls = true;\n object.set({\n left: objectLeft - center.x,\n top: objectTop - center.y\n });\n object.group = this;\n object.setCoords(skipControls);\n },\n\n /**\n * Returns string represenation of a group\n * @return {String}\n */\n toString: function toString() {\n return '#';\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 addWithUpdate(object) {\n this._restoreObjectsState();\n\n fabric.util.resetObjectTransform(this);\n\n if (object) {\n this._objects.push(object);\n\n object.group = this;\n\n object._set('canvas', this.canvas);\n }\n\n this._calcBounds();\n\n this._updateObjectsCoords();\n\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 removeWithUpdate(object) {\n this._restoreObjectsState();\n\n fabric.util.resetObjectTransform(this);\n this.remove(object);\n\n this._calcBounds();\n\n this._updateObjectsCoords();\n\n this.setCoords();\n this.dirty = true;\n return this;\n },\n\n /**\n * @private\n */\n _onObjectAdded: function _onObjectAdded(object) {\n this.dirty = true;\n object.group = this;\n\n object._set('canvas', this.canvas);\n },\n\n /**\n * @private\n */\n _onObjectRemoved: function _onObjectRemoved(object) {\n this.dirty = true;\n delete object.group;\n },\n\n /**\n * @private\n */\n _set: function _set(key, value) {\n var i = this._objects.length;\n\n if (this.useSetOnGroup) {\n while (i--) {\n this._objects[i].setOnGroup(key, value);\n }\n }\n\n if (key === 'canvas') {\n while (i--) {\n this._objects[i]._set(key, value);\n }\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 toObject(propertiesToInclude) {\n var _includeDefaultValues = this.includeDefaultValues;\n\n var objsToObject = this._objects.map(function (obj) {\n var originalDefaults = obj.includeDefaultValues;\n obj.includeDefaultValues = _includeDefaultValues;\n\n var _obj = obj.toObject(propertiesToInclude);\n\n obj.includeDefaultValues = originalDefaults;\n return _obj;\n });\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 toDatalessObject(propertiesToInclude) {\n var objsToObject,\n sourcePath = this.sourcePath;\n\n if (sourcePath) {\n objsToObject = sourcePath;\n } else {\n var _includeDefaultValues = this.includeDefaultValues;\n objsToObject = this._objects.map(function (obj) {\n var originalDefaults = obj.includeDefaultValues;\n obj.includeDefaultValues = _includeDefaultValues;\n\n var _obj = obj.toDatalessObject(propertiesToInclude);\n\n obj.includeDefaultValues = originalDefaults;\n return _obj;\n });\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 render(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 shouldCache() {\n var ownCache = fabric.Object.prototype.shouldCache.call(this);\n\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\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 willDrawShadow() {\n if (fabric.Object.prototype.willDrawShadow.call(this)) {\n return true;\n }\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\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 isOnACache() {\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 drawObject(ctx) {\n for (var i = 0, len = this._objects.length; i < len; i++) {\n this._objects[i].render(ctx);\n }\n\n this._drawClipPath(ctx);\n },\n\n /**\n * Check if cache is dirty\n */\n isCacheDirty: function isCacheDirty(skipCanvas) {\n if (this.callSuper('isCacheDirty', skipCanvas)) {\n return true;\n }\n\n if (!this.statefullCache) {\n return false;\n }\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,\n y = this.cacheHeight / this.zoomY;\n\n this._cacheContext.clearRect(-x / 2, -y / 2, x, y);\n }\n\n return true;\n }\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 _restoreObjectsState() {\n this._objects.forEach(this._restoreObjectState, this);\n\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 realizeTransform(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 _restoreObjectState(object) {\n this.realizeTransform(object);\n delete object.group;\n object.setCoords();\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 destroy() {\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\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 toActiveSelection() {\n if (!this.canvas) {\n return;\n }\n\n var objects = this._objects,\n 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 ungroupOnCanvas() {\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 setObjectsCoords() {\n var skipControls = true;\n this.forEachObject(function (object) {\n object.setCoords(skipControls);\n });\n return this;\n },\n\n /**\n * @private\n */\n _calcBounds: function _calcBounds(onlyWidthHeight) {\n var aX = [],\n aY = [],\n o,\n prop,\n props = ['tr', 'br', 'bl', 'tl'],\n i = 0,\n iLen = this._objects.length,\n j,\n jLen = props.length;\n\n for (; i < iLen; ++i) {\n o = this._objects[i];\n o.aCoords = o.calcACoords();\n\n for (j = 0; j < jLen; j++) {\n prop = props[j];\n aX.push(o.aCoords[prop].x);\n aY.push(o.aCoords[prop].y);\n }\n }\n\n this._getBounds(aX, aY, onlyWidthHeight);\n },\n\n /**\n * @private\n */\n _getBounds: function _getBounds(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,\n 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\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({\n x: left,\n y: top\n }, 'left', 'top');\n }\n },\n\n /* _TO_SVG_START_ */\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 _toSVG(reviver) {\n var svgString = ['\\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\n svgString.push('\\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 getSvgStyles() {\n var opacity = typeof this.opacity !== 'undefined' && this.opacity !== 1 ? 'opacity: ' + this.opacity + ';' : '',\n visibility = this.visible ? '' : ' visibility: hidden;';\n return [opacity, this.getSvgFilter(), visibility].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 toClipPathSVG(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, {\n reviver: reviver\n });\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\n fabric.Group.fromObject = function (object, callback) {\n var objects = object.objects,\n options = fabric.util.object.clone(object, true);\n delete options.objects;\n\n if (typeof objects === 'string') {\n // it has to be an url or something went wrong.\n fabric.loadSVGFromURL(objects, function (elements) {\n var group = fabric.util.groupSVGElements(elements, object, objects);\n group.set(options);\n callback && callback(group);\n });\n return;\n }\n\n fabric.util.enlivenObjects(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})(typeof exports !== 'undefined' ? exports : this);\n\n(function (global) {\n 'use strict';\n\n var fabric = global.fabric || (global.fabric = {});\n\n if (fabric.ActiveSelection) {\n return;\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\n\n fabric.ActiveSelection = fabric.util.createClass(fabric.Group,\n /** @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 initialize(objects, options) {\n options = options || {};\n this._objects = objects || [];\n\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\n if (options.originY) {\n this.originY = options.originY;\n }\n\n this._calcBounds();\n\n this._updateObjectsCoords();\n\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 toGroup() {\n var objects = this._objects.concat();\n\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\n if (!this.canvas) {\n return newGroup;\n }\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 onDeselect() {\n this.destroy();\n return false;\n },\n\n /**\n * Returns string representation of a group\n * @return {String}\n */\n toString: function toString() {\n return '#';\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 shouldCache() {\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 isOnACache() {\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 _renderControls(ctx, styleOverride, childrenOverride) {\n ctx.save();\n ctx.globalAlpha = this.isMoving ? this.borderOpacityWhenMoving : 1;\n this.callSuper('_renderControls', ctx, styleOverride);\n childrenOverride = childrenOverride || {};\n\n if (typeof childrenOverride.hasControls === 'undefined') {\n childrenOverride.hasControls = false;\n }\n\n childrenOverride.forActiveSelection = true;\n\n for (var i = 0, len = this._objects.length; i < len; i++) {\n this._objects[i]._renderControls(ctx, childrenOverride);\n }\n\n ctx.restore();\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\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})(typeof exports !== 'undefined' ? exports : this);\n\n(function (global) {\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 * 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\n\n fabric.Image = fabric.util.createClass(fabric.Object,\n /** @lends fabric.Image.prototype */\n {\n /**\n * Type of an object\n * @type String\n * @default\n */\n type: 'image',\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 * Indicates whether this canvas will use image smoothing when painting this image.\n * Also influence if the cacheCanvas for this image uses imageSmoothing\n * @since 4.0.0-beta.11\n * @type Boolean\n * @default\n */\n imageSmoothing: true,\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 initialize(element, options) {\n options || (options = {});\n this.filters = [];\n this.cacheKey = 'texture' + fabric.Object.__uid++;\n this.callSuper('initialize', options);\n\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 getElement() {\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 setElement(element, options) {\n this.removeTexture(this.cacheKey);\n this.removeTexture(this.cacheKey + '_filtered');\n this._element = element;\n this._originalElement = element;\n\n this._initConfig(options);\n\n if (this.filters.length !== 0) {\n this.applyFilters();\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\n\n if (this.resizeFilter) {\n this.applyResizeFilters();\n }\n\n return this;\n },\n\n /**\n * Delete a single texture if in webgl mode\n */\n removeTexture: function removeTexture(key) {\n var backend = fabric.filterBackend;\n\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 dispose() {\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 * Get the crossOrigin value (of the corresponding image element)\n */\n getCrossOrigin: function getCrossOrigin() {\n return this._originalElement && (this._originalElement.crossOrigin || null);\n },\n\n /**\n * Returns original size of an image\n * @return {Object} Object with \"width\" and \"height\" properties\n */\n getOriginalSize: function getOriginalSize() {\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 _stroke(ctx) {\n if (!this.stroke || this.strokeWidth === 0) {\n return;\n }\n\n var w = this.width / 2,\n 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 _renderDashedStroke(ctx) {\n var x = -this.width / 2,\n y = -this.height / 2,\n w = this.width,\n h = this.height;\n ctx.save();\n\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 toObject(propertiesToInclude) {\n var filters = [];\n this.filters.forEach(function (filterObj) {\n if (filterObj) {\n filters.push(filterObj.toObject());\n }\n });\n var object = extend(this.callSuper('toObject', ['cropX', 'cropY'].concat(propertiesToInclude)), {\n src: this.getSrc(),\n crossOrigin: this.getCrossOrigin(),\n filters: filters\n });\n\n if (this.resizeFilter) {\n object.resizeFilter = this.resizeFilter.toObject();\n }\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 hasCrop() {\n return this.cropX || this.cropY || this.width < this._element.width || this.height < this._element.height;\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 _toSVG() {\n var svgString = [],\n imageMarkup = [],\n strokeSvg,\n element = this._element,\n x = -this.width / 2,\n y = -this.height / 2,\n clipPath = '',\n imageRendering = '';\n\n if (!element) {\n return [];\n }\n\n if (this.hasCrop()) {\n var clipPathId = fabric.Object.__uid++;\n svgString.push('\\n', '\\t\\n', '\\n');\n clipPath = ' clip-path=\"url(#imageCrop_' + clipPathId + ')\" ';\n }\n\n if (!this.imageSmoothing) {\n imageRendering = '\" image-rendering=\"optimizeSpeed';\n }\n\n imageMarkup.push('\\t 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=\"', element.width || element.naturalWidth, '\" height=\"', element.height || element.height, imageRendering, '\"', clipPath, '>\\n');\n\n if (this.stroke || this.strokeDashArray) {\n var origFill = this.fill;\n this.fill = null;\n strokeSvg = ['\\t\\n'];\n this.fill = origFill;\n }\n\n if (this.paintFirst !== 'fill') {\n svgString = svgString.concat(strokeSvg, imageMarkup);\n } else {\n svgString = svgString.concat(imageMarkup, strokeSvg);\n }\n\n return svgString;\n },\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 getSrc(filtered) {\n var element = filtered ? this._element : this._originalElement;\n\n if (element) {\n if (element.toDataURL) {\n return element.toDataURL();\n }\n\n if (this.srcFromAttribute) {\n return element.getAttribute('src');\n } else {\n return element.src;\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 * @param {String} [options.crossOrigin] crossOrigin value (one of \"\", \"anonymous\", \"use-credentials\")\n * @see https://developer.mozilla.org/en-US/docs/HTML/CORS_settings_attributes\n * @return {fabric.Image} thisArg\n * @chainable\n */\n setSrc: function setSrc(src, callback, options) {\n fabric.util.loadImage(src, function (img, isError) {\n this.setElement(img, options);\n\n this._setWidthHeight();\n\n callback && callback(this, isError);\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 toString() {\n return '#';\n },\n applyResizeFilters: function applyResizeFilters() {\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\n if (this.group) {\n this.set('dirty', true);\n }\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\n if (!fabric.filterBackend) {\n fabric.filterBackend = fabric.initFilterBackend();\n }\n\n var canvasEl = fabric.util.createCanvasElement(),\n cacheKey = this._filteredEl ? this.cacheKey + '_filtered' : this.cacheKey,\n sourceWidth = elementToFilter.width,\n 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([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 applyFilters(filters) {\n filters = filters || this.filters || [];\n filters = filters.filter(function (filter) {\n return filter && !filter.isNeutralState();\n });\n this.set('dirty', true); // needs to clear out or WEBGL will not resize correctly\n\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 } else {\n // clear the existing element to get new filter data\n // also dereference the eventual resized _element\n this._element = this._filteredEl;\n\n this._filteredEl.getContext('2d').clearRect(0, 0, sourceWidth, sourceHeight); // we also need to resize again at next renderAll, so remove saved _lastScaleX/Y\n\n\n this._lastScaleX = 1;\n this._lastScaleY = 1;\n }\n\n if (!fabric.filterBackend) {\n fabric.filterBackend = fabric.initFilterBackend();\n }\n\n fabric.filterBackend.applyFilters(filters, this._originalElement, sourceWidth, sourceHeight, this._element, this.cacheKey);\n\n if (this._originalElement.width !== this._element.width || 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\n return this;\n },\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx Context to render on\n */\n _render: function _render(ctx) {\n fabric.util.setImageSmoothing(ctx, this.imageSmoothing);\n\n if (this.isMoving !== true && this.resizeFilter && this._needsResize()) {\n this.applyResizeFilters();\n }\n\n this._stroke(ctx);\n\n this._renderPaintInOrder(ctx);\n },\n\n /**\n * Paint the cached copy of the object on the target context.\n * it will set the imageSmoothing for the draw operation\n * @param {CanvasRenderingContext2D} ctx Context to render on\n */\n drawCacheOnCanvas: function drawCacheOnCanvas(ctx) {\n fabric.util.setImageSmoothing(ctx, this.imageSmoothing);\n fabric.Object.prototype.drawCacheOnCanvas.call(this, 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 shouldCache() {\n return this.needsItsOwnCache();\n },\n _renderFill: function _renderFill(ctx) {\n var elementToDraw = this._element;\n\n if (!elementToDraw) {\n return;\n }\n\n var scaleX = this._filterScalingX,\n scaleY = this._filterScalingY,\n w = this.width,\n h = this.height,\n min = Math.min,\n max = Math.max,\n // crop values cannot be lesser than 0.\n cropX = max(this.cropX, 0),\n cropY = max(this.cropY, 0),\n elWidth = elementToDraw.naturalWidth || elementToDraw.width,\n elHeight = elementToDraw.naturalHeight || elementToDraw.height,\n sX = cropX * scaleX,\n sY = cropY * scaleY,\n // the width height cannot exceed element width/height, starting from the crop offset.\n sW = min(w * scaleX, elWidth - sX),\n sH = min(h * scaleY, elHeight - sY),\n x = -w / 2,\n y = -h / 2,\n maxDestW = min(w, elWidth / scaleX - cropX),\n maxDestH = min(h, elHeight / scaleX - cropY);\n elementToDraw && ctx.drawImage(elementToDraw, sX, sY, sW, sH, x, y, maxDestW, maxDestH);\n },\n\n /**\n * needed to check if image needs resize\n * @private\n */\n _needsResize: function _needsResize() {\n var scale = this.getTotalObjectScaling();\n return scale.scaleX !== this._lastScaleX || scale.scaleY !== this._lastScaleY;\n },\n\n /**\n * @private\n */\n _resetWidthHeight: function _resetWidthHeight() {\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 _initElement(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 _initConfig(options) {\n options || (options = {});\n this.setOptions(options);\n\n this._setWidthHeight(options);\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 _initFilters(filters, callback) {\n if (filters && filters.length) {\n fabric.util.enlivenObjects(filters, function (enlivenedObjects) {\n callback && callback(enlivenedObjects);\n }, 'fabric.Image.filters');\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 _setWidthHeight(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 parsePreserveAspectRatioAttribute() {\n var pAR = fabric.util.parsePreserveAspectRatioAttribute(this.preserveAspectRatio || ''),\n rWidth = this._element.width,\n rHeight = this._element.height,\n scaleX = 1,\n scaleY = 1,\n offsetLeft = 0,\n offsetTop = 0,\n cropX = 0,\n cropY = 0,\n offset,\n pWidth = this.width,\n pHeight = this.height,\n parsedAttributes = {\n width: pWidth,\n height: pHeight\n };\n\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\n if (pAR.alignX === 'Min') {\n offsetLeft = -offset;\n }\n\n if (pAR.alignX === 'Max') {\n offsetLeft = offset;\n }\n\n offset = (pHeight - rHeight * scaleY) / 2;\n\n if (pAR.alignY === 'Min') {\n offsetTop = -offset;\n }\n\n if (pAR.alignY === 'Max') {\n offsetTop = offset;\n }\n }\n\n if (pAR.meetOrSlice === 'slice') {\n scaleX = scaleY = fabric.util.findScaleToCover(this._element, parsedAttributes);\n offset = rWidth - pWidth / scaleX;\n\n if (pAR.alignX === 'Mid') {\n cropX = offset / 2;\n }\n\n if (pAR.alignX === 'Max') {\n cropX = offset;\n }\n\n offset = rHeight - pHeight / scaleY;\n\n if (pAR.alignY === 'Mid') {\n cropY = offset / 2;\n }\n\n if (pAR.alignY === 'Max') {\n cropY = offset;\n }\n\n rWidth = pWidth / scaleX;\n rHeight = pHeight / scaleY;\n }\n } else {\n scaleX = pWidth / rWidth;\n scaleY = pHeight / rHeight;\n }\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 * Default CSS class name for canvas\n * @static\n * @type String\n * @default\n */\n\n fabric.Image.CSS_CANVAS = 'canvas-img';\n /**\n * Alias for getSrc\n * @static\n */\n\n fabric.Image.prototype.getSvgSrc = fabric.Image.prototype.getSrc;\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\n fabric.Image.fromObject = function (_object, callback) {\n var object = fabric.util.object.clone(_object);\n fabric.util.loadImage(object.src, function (img, isError) {\n if (isError) {\n callback && callback(null, true);\n return;\n }\n\n fabric.Image.prototype._initFilters.call(object, object.filters, function (filters) {\n object.filters = filters || [];\n\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, false);\n });\n });\n });\n }, null, object.crossOrigin);\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). Second argument is a boolean indicating if an error occured or not.\n * @param {Object} [imgOptions] Options object\n */\n\n\n fabric.Image.fromURL = function (url, callback, imgOptions) {\n fabric.util.loadImage(url, function (img, isError) {\n callback && callback(new fabric.Image(img, imgOptions), isError);\n }, null, imgOptions && imgOptions.crossOrigin);\n };\n /* _FROM_SVG_START_ */\n\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\n\n fabric.Image.ATTRIBUTE_NAMES = fabric.SHARED_ATTRIBUTES.concat('x y width height preserveAspectRatio xlink:href crossOrigin image-rendering'.split(' '));\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\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, extend(options ? fabric.util.object.clone(options) : {}, parsedAttributes));\n };\n /* _FROM_SVG_END_ */\n\n})(typeof exports !== 'undefined' ? exports : this);\n\nfabric.util.object.extend(fabric.Object.prototype,\n/** @lends fabric.Object.prototype */\n{\n /**\n * @private\n * @return {Number} angle value\n */\n _getAngleValueForStraighten: function _getAngleValueForStraighten() {\n var angle = this.angle % 360;\n\n if (angle > 0) {\n return Math.round((angle - 1) / 90) * 90;\n }\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 straighten() {\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 fxStraighten(callbacks) {\n callbacks = callbacks || {};\n\n var empty = function empty() {},\n _onComplete4 = callbacks.onComplete || empty,\n _onChange4 = 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 onChange(value) {\n _this.rotate(value);\n\n _onChange4();\n },\n onComplete: function onComplete() {\n _this.setCoords();\n\n _onComplete4();\n }\n });\n return this;\n }\n});\nfabric.util.object.extend(fabric.StaticCanvas.prototype,\n/** @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 straightenObject(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 fxStraightenObject(object) {\n object.fxStraighten({\n onChange: this.requestRenderAllBound\n });\n return this;\n }\n});\n\n(function () {\n 'use strict';\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\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\n if (!gl.getShaderParameter(fragmentShader, gl.COMPILE_STATUS)) {\n return false;\n }\n\n return true;\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\n\n fabric.isWebglSupported = function (tileSize) {\n if (fabric.isLikelyNode) {\n return false;\n }\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; // eslint-disable-next-line\n\n if (gl) {\n fabric.maxTextureSize = gl.getParameter(gl.MAX_TEXTURE_SIZE);\n isSupported = fabric.maxTextureSize >= tileSize;\n var precisions = ['highp', 'mediump', 'lowp'];\n\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 }\n }\n\n this.isSupported = isSupported;\n return isSupported;\n };\n\n fabric.WebglFilterBackend = WebglFilterBackend;\n /**\n * WebGL filter backend.\n */\n\n function WebglFilterBackend(options) {\n if (options && options.tileSize) {\n this.tileSize = options.tileSize;\n }\n\n this.setupGLContext(this.tileSize, this.tileSize);\n this.captureGPUInfo();\n }\n\n ;\n WebglFilterBackend.prototype =\n /** @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 * Setup a WebGL context suitable for filtering, and bind any needed event handlers.\n */\n setupGLContext: function setupGLContext(width, height) {\n this.dispose();\n this.createWebGLCanvas(width, height); // eslint-disable-next-line\n\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 chooseFastestCopyGLTo2DMethod(width, height) {\n var canMeasurePerf = typeof window.performance !== 'undefined',\n canUseImageData;\n\n try {\n new ImageData(1, 1);\n canUseImageData = true;\n } catch (e) {\n canUseImageData = false;\n } // eslint-disable-next-line no-undef\n\n\n var canUseArrayBuffer = typeof ArrayBuffer !== 'undefined'; // eslint-disable-next-line no-undef\n\n var canUseUint8Clamped = typeof Uint8ClampedArray !== 'undefined';\n\n if (!(canMeasurePerf && canUseImageData && canUseArrayBuffer && canUseUint8Clamped)) {\n return;\n }\n\n var targetCanvas = fabric.util.createCanvasElement(); // eslint-disable-next-line no-undef\n\n var imageBuffer = new ArrayBuffer(width * height * 4);\n\n if (fabric.forceGLPutImageData) {\n this.imageBuffer = imageBuffer;\n this.copyGLTo2D = copyGLTo2DPutImageData;\n return;\n }\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 startTime = window.performance.now();\n copyGLTo2DDrawImage.call(testContext, this.gl, testContext);\n drawImageTime = window.performance.now() - startTime;\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 } 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 createWebGLCanvas(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\n if (!gl) {\n gl = canvas.getContext('experimental-webgl', glOptions);\n }\n\n if (!gl) {\n return;\n }\n\n gl.clearColor(0, 0, 0, 0); // this canvas can fire webglcontextlost and webglcontextrestored\n\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 applyFilters(filters, source, width, height, targetCanvas, cacheKey) {\n var gl = this.gl;\n var cachedTexture;\n\n if (cacheKey) {\n cachedTexture = this.getCachedTexture(cacheKey, source);\n }\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 || 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) {\n filter && filter.applyTo(pipelineState);\n });\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 dispose() {\n if (this.canvas) {\n this.canvas = null;\n this.gl = null;\n }\n\n this.clearWebGLCaches();\n },\n\n /**\n * Wipe out WebGL-related caches.\n */\n clearWebGLCaches: function clearWebGLCaches() {\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 createTexture(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\n if (textureImageSource) {\n gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, textureImageSource);\n } else {\n gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, width, height, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);\n }\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 getCachedTexture(uniqueId, textureImageSource) {\n if (this.textureCache[uniqueId]) {\n return this.textureCache[uniqueId];\n } else {\n var texture = this.createTexture(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 evictCachesForKey(cacheKey) {\n if (this.textureCache[cacheKey]) {\n this.gl.deleteTexture(this.textureCache[cacheKey]);\n delete this.textureCache[cacheKey];\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 captureGPUInfo() {\n if (this.gpuInfo) {\n return this.gpuInfo;\n }\n\n var gl = this.gl,\n gpuInfo = {\n renderer: '',\n vendor: ''\n };\n\n if (!gl) {\n return gpuInfo;\n }\n\n var ext = gl.getExtension('WEBGL_debug_renderer_info');\n\n if (ext) {\n var renderer = gl.getParameter(ext.UNMASKED_RENDERER_WEBGL);\n var vendor = gl.getParameter(ext.UNMASKED_VENDOR_WEBGL);\n\n if (renderer) {\n gpuInfo.renderer = renderer.toLowerCase();\n }\n\n if (vendor) {\n gpuInfo.vendor = vendor.toLowerCase();\n }\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,\n 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 * 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 */\n\n\nfunction copyGLTo2DDrawImage(gl, pipelineState) {\n var glCanvas = gl.canvas,\n targetCanvas = pipelineState.targetCanvas,\n ctx = targetCanvas.getContext('2d');\n ctx.translate(0, targetCanvas.height); // move it down again\n\n ctx.scale(1, -1); // vertical flip\n // where is my image on the big glcanvas?\n\n var sourceY = glCanvas.height - targetCanvas.height;\n ctx.drawImage(glCanvas, 0, sourceY, targetCanvas.width, targetCanvas.height, 0, 0, targetCanvas.width, targetCanvas.height);\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 */\n\n\nfunction copyGLTo2DPutImageData(gl, pipelineState) {\n var targetCanvas = pipelineState.targetCanvas,\n ctx = targetCanvas.getContext('2d'),\n dWidth = pipelineState.destinationWidth,\n dHeight = pipelineState.destinationHeight,\n numBytes = dWidth * dHeight * 4; // eslint-disable-next-line no-undef\n\n var u8 = new Uint8Array(this.imageBuffer, 0, numBytes); // eslint-disable-next-line no-undef\n\n var u8Clamped = new Uint8ClampedArray(this.imageBuffer, 0, numBytes);\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(function () {\n 'use strict';\n\n var noop = function noop() {};\n\n fabric.Canvas2dFilterBackend = Canvas2dFilterBackend;\n /**\n * Canvas 2D filter backend.\n */\n\n function Canvas2dFilterBackend() {}\n\n ;\n Canvas2dFilterBackend.prototype =\n /** @lends fabric.Canvas2dFilterBackend.prototype */\n {\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 * 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 applyFilters(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) {\n filter.applyTo(pipelineState);\n });\n\n if (pipelineState.imageData.width !== sourceWidth || pipelineState.imageData.height !== sourceHeight) {\n targetCanvas.width = pipelineState.imageData.width;\n targetCanvas.height = pipelineState.imageData.height;\n }\n\n ctx.putImageData(pipelineState.imageData, 0, 0);\n return pipelineState;\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 */\n\n\nfabric.Image = fabric.Image || {};\nfabric.Image.filters = fabric.Image.filters || {};\n/**\n * Root filter class from which all filter classes inherit from\n * @class fabric.Image.filters.BaseFilter\n * @memberOf fabric.Image.filters\n */\n\nfabric.Image.filters.BaseFilter = fabric.util.createClass(\n/** @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 vertexSource: 'attribute vec2 aPosition;\\n' + 'varying vec2 vTexCoord;\\n' + 'void main() {\\n' + 'vTexCoord = aPosition;\\n' + 'gl_Position = vec4(aPosition * 2.0 - 1.0, 0.0, 1.0);\\n' + '}',\n fragmentSource: 'precision highp float;\\n' + 'varying vec2 vTexCoord;\\n' + 'uniform sampler2D uTexture;\\n' + 'void main() {\\n' + 'gl_FragColor = texture2D(uTexture, vTexCoord);\\n' + '}',\n\n /**\n * Constructor\n * @param {Object} [options] Options object\n */\n initialize: function initialize(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 setOptions(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 createProgram(gl, fragmentSource, vertexSource) {\n fragmentSource = fragmentSource || this.fragmentSource;\n vertexSource = vertexSource || this.vertexSource;\n\n if (fabric.webGlPrecision !== 'highp') {\n fragmentSource = fragmentSource.replace(/precision highp float/g, 'precision ' + fabric.webGlPrecision + ' float');\n }\n\n var vertexShader = gl.createShader(gl.VERTEX_SHADER);\n gl.shaderSource(vertexShader, vertexSource);\n gl.compileShader(vertexShader);\n\n if (!gl.getShaderParameter(vertexShader, gl.COMPILE_STATUS)) {\n throw new Error( // eslint-disable-next-line prefer-template\n 'Vertex shader compile error for ' + this.type + ': ' + gl.getShaderInfoLog(vertexShader));\n }\n\n var fragmentShader = gl.createShader(gl.FRAGMENT_SHADER);\n gl.shaderSource(fragmentShader, fragmentSource);\n gl.compileShader(fragmentShader);\n\n if (!gl.getShaderParameter(fragmentShader, gl.COMPILE_STATUS)) {\n throw new Error( // eslint-disable-next-line prefer-template\n 'Fragment shader compile error for ' + this.type + ': ' + gl.getShaderInfoLog(fragmentShader));\n }\n\n var program = gl.createProgram();\n gl.attachShader(program, vertexShader);\n gl.attachShader(program, fragmentShader);\n gl.linkProgram(program);\n\n if (!gl.getProgramParameter(program, gl.LINK_STATUS)) {\n throw new Error( // eslint-disable-next-line prefer-template\n 'Shader link error for \"${this.type}\" ' + gl.getProgramInfoLog(program));\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 getAttributeLocations(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 getUniformLocations()\n /* gl, program */\n {\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 sendAttributeData(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 _setupFrameBuffer: function _setupFrameBuffer(options) {\n var gl = options.context,\n width,\n height;\n\n if (options.passes > 1) {\n width = options.destinationWidth;\n height = options.destinationHeight;\n\n if (options.sourceWidth !== width || options.sourceHeight !== height) {\n gl.deleteTexture(options.targetTexture);\n options.targetTexture = options.filterBackend.createTexture(gl, width, height);\n }\n\n gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, options.targetTexture, 0);\n } else {\n // draw last filter on canvas and not to framebuffer.\n gl.bindFramebuffer(gl.FRAMEBUFFER, null);\n gl.finish();\n }\n },\n _swapTextures: function _swapTextures(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 isNeutralState()\n /* options */\n {\n var main = this.mainParameter,\n _class = fabric.Image.filters[this.type].prototype;\n\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\n return true;\n } else {\n return _class[main] === this[main];\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 applyTo(options) {\n if (options.webgl) {\n this._setupFrameBuffer(options);\n\n this.applyToWebGL(options);\n\n this._swapTextures(options);\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 retrieveShader(options) {\n if (!options.programCache.hasOwnProperty(this.type)) {\n options.programCache[this.type] = this.createProgram(options.context);\n }\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 applyToWebGL(options) {\n var gl = options.context;\n var shader = this.retrieveShader(options);\n\n if (options.pass === 0 && options.originalTexture) {\n gl.bindTexture(gl.TEXTURE_2D, options.originalTexture);\n } else {\n gl.bindTexture(gl.TEXTURE_2D, options.sourceTexture);\n }\n\n gl.useProgram(shader.program);\n this.sendAttributeData(gl, shader.attributeLocations, options.aPosition);\n gl.uniform1f(shader.uniformLocations.uStepW, 1 / options.sourceWidth);\n gl.uniform1f(shader.uniformLocations.uStepH, 1 / options.sourceHeight);\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 bindAdditionalTexture: function bindAdditionalTexture(gl, texture, textureUnit) {\n gl.activeTexture(textureUnit);\n gl.bindTexture(gl.TEXTURE_2D, texture); // reset active texture to 0 as usual\n\n gl.activeTexture(gl.TEXTURE0);\n },\n unbindAdditionalTexture: function unbindAdditionalTexture(gl, textureUnit) {\n gl.activeTexture(textureUnit);\n gl.bindTexture(gl.TEXTURE_2D, null);\n gl.activeTexture(gl.TEXTURE0);\n },\n getMainParameter: function getMainParameter() {\n return this[this.mainParameter];\n },\n setMainParameter: function setMainParameter(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 sendUniformData()\n /* 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 createHelpLayer(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 toObject() {\n var object = {\n type: this.type\n },\n mainP = this.mainParameter;\n\n if (mainP) {\n object[mainP] = this[mainP];\n }\n\n return object;\n },\n\n /**\n * Returns a JSON representation of an instance\n * @return {Object} JSON\n */\n toJSON: function toJSON() {\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(function (global) {\n 'use strict';\n\n var fabric = global.fabric || (global.fabric = {}),\n filters = fabric.Image.filters,\n createClass = fabric.util.createClass;\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 Kodachrome filter\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\n filters.ColorMatrix = createClass(filters.BaseFilter,\n /** @lends fabric.Image.filters.ColorMatrix.prototype */\n {\n /**\n * Filter type\n * @param {String} type\n * @default\n */\n type: 'ColorMatrix',\n fragmentSource: 'precision highp float;\\n' + 'uniform sampler2D uTexture;\\n' + 'varying vec2 vTexCoord;\\n' + 'uniform mat4 uColorMatrix;\\n' + 'uniform vec4 uConstants;\\n' + 'void main() {\\n' + 'vec4 color = texture2D(uTexture, vTexCoord);\\n' + 'color *= uColorMatrix;\\n' + 'color += uConstants;\\n' + 'gl_FragColor = color;\\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: [1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0],\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 initialize(options) {\n this.callSuper('initialize', options); // create a new array instead mutating the prototype with push\n\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 applyTo2d(options) {\n var imageData = options.imageData,\n data = imageData.data,\n iLen = data.length,\n m = this.matrix,\n r,\n g,\n b,\n a,\n i,\n 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\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 } 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 getUniformLocations(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 sendUniformData(gl, uniformLocations) {\n var m = this.matrix,\n matrix = [m[0], m[1], m[2], m[3], m[5], m[6], m[7], m[8], m[10], m[11], m[12], m[13], m[15], m[16], m[17], m[18]],\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 * 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\n fabric.Image.filters.ColorMatrix.fromObject = fabric.Image.filters.BaseFilter.fromObject;\n})(typeof exports !== 'undefined' ? exports : this);\n\n(function (global) {\n 'use strict';\n\n var fabric = global.fabric || (global.fabric = {}),\n filters = fabric.Image.filters,\n createClass = fabric.util.createClass;\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\n filters.Brightness = createClass(filters.BaseFilter,\n /** @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' + 'uniform sampler2D uTexture;\\n' + 'uniform float uBrightness;\\n' + 'varying vec2 vTexCoord;\\n' + 'void main() {\\n' + 'vec4 color = texture2D(uTexture, vTexCoord);\\n' + 'color.rgb += uBrightness;\\n' + 'gl_FragColor = color;\\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 applyTo2d(options) {\n if (this.brightness === 0) {\n return;\n }\n\n var imageData = options.imageData,\n data = imageData.data,\n i,\n len = data.length,\n brightness = Math.round(this.brightness * 255);\n\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 getUniformLocations(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 sendUniformData(gl, uniformLocations) {\n gl.uniform1f(uniformLocations.uBrightness, this.brightness);\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\n fabric.Image.filters.Brightness.fromObject = fabric.Image.filters.BaseFilter.fromObject;\n})(typeof exports !== 'undefined' ? exports : this);\n\n(function (global) {\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 * Adapted from html5rocks article\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 Sharpen filter\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 Blur filter\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 Emboss filter\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 Emboss filter with opaqueness\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\n filters.Convolute = createClass(filters.BaseFilter,\n /** @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' + 'uniform sampler2D uTexture;\\n' + 'uniform float uMatrix[9];\\n' + 'uniform float uStepW;\\n' + 'uniform float uStepH;\\n' + 'varying vec2 vTexCoord;\\n' + 'void main() {\\n' + 'vec4 color = vec4(0, 0, 0, 0);\\n' + 'for (float h = 0.0; h < 3.0; h+=1.0) {\\n' + 'for (float w = 0.0; w < 3.0; w+=1.0) {\\n' + 'vec2 matrixPos = vec2(uStepW * (w - 1), uStepH * (h - 1));\\n' + 'color += texture2D(uTexture, vTexCoord + matrixPos) * uMatrix[int(h * 3.0 + w)];\\n' + '}\\n' + '}\\n' + 'gl_FragColor = color;\\n' + '}',\n Convolute_3_0: 'precision highp float;\\n' + 'uniform sampler2D uTexture;\\n' + 'uniform float uMatrix[9];\\n' + 'uniform float uStepW;\\n' + 'uniform float uStepH;\\n' + 'varying vec2 vTexCoord;\\n' + 'void main() {\\n' + 'vec4 color = vec4(0, 0, 0, 1);\\n' + 'for (float h = 0.0; h < 3.0; h+=1.0) {\\n' + 'for (float w = 0.0; w < 3.0; w+=1.0) {\\n' + 'vec2 matrixPos = vec2(uStepW * (w - 1.0), uStepH * (h - 1.0));\\n' + 'color.rgb += texture2D(uTexture, vTexCoord + matrixPos).rgb * uMatrix[int(h * 3.0 + w)];\\n' + '}\\n' + '}\\n' + 'float alpha = texture2D(uTexture, vTexCoord).a;\\n' + 'gl_FragColor = color;\\n' + 'gl_FragColor.a = alpha;\\n' + '}',\n Convolute_5_1: 'precision highp float;\\n' + 'uniform sampler2D uTexture;\\n' + 'uniform float uMatrix[25];\\n' + 'uniform float uStepW;\\n' + 'uniform float uStepH;\\n' + 'varying vec2 vTexCoord;\\n' + 'void main() {\\n' + 'vec4 color = vec4(0, 0, 0, 0);\\n' + 'for (float h = 0.0; h < 5.0; h+=1.0) {\\n' + 'for (float w = 0.0; w < 5.0; w+=1.0) {\\n' + 'vec2 matrixPos = vec2(uStepW * (w - 2.0), uStepH * (h - 2.0));\\n' + 'color += texture2D(uTexture, vTexCoord + matrixPos) * uMatrix[int(h * 5.0 + w)];\\n' + '}\\n' + '}\\n' + 'gl_FragColor = color;\\n' + '}',\n Convolute_5_0: 'precision highp float;\\n' + 'uniform sampler2D uTexture;\\n' + 'uniform float uMatrix[25];\\n' + 'uniform float uStepW;\\n' + 'uniform float uStepH;\\n' + 'varying vec2 vTexCoord;\\n' + 'void main() {\\n' + 'vec4 color = vec4(0, 0, 0, 1);\\n' + 'for (float h = 0.0; h < 5.0; h+=1.0) {\\n' + 'for (float w = 0.0; w < 5.0; w+=1.0) {\\n' + 'vec2 matrixPos = vec2(uStepW * (w - 2.0), uStepH * (h - 2.0));\\n' + 'color.rgb += texture2D(uTexture, vTexCoord + matrixPos).rgb * uMatrix[int(h * 5.0 + w)];\\n' + '}\\n' + '}\\n' + 'float alpha = texture2D(uTexture, vTexCoord).a;\\n' + 'gl_FragColor = color;\\n' + 'gl_FragColor.a = alpha;\\n' + '}',\n Convolute_7_1: 'precision highp float;\\n' + 'uniform sampler2D uTexture;\\n' + 'uniform float uMatrix[49];\\n' + 'uniform float uStepW;\\n' + 'uniform float uStepH;\\n' + 'varying vec2 vTexCoord;\\n' + 'void main() {\\n' + 'vec4 color = vec4(0, 0, 0, 0);\\n' + 'for (float h = 0.0; h < 7.0; h+=1.0) {\\n' + 'for (float w = 0.0; w < 7.0; w+=1.0) {\\n' + 'vec2 matrixPos = vec2(uStepW * (w - 3.0), uStepH * (h - 3.0));\\n' + 'color += texture2D(uTexture, vTexCoord + matrixPos) * uMatrix[int(h * 7.0 + w)];\\n' + '}\\n' + '}\\n' + 'gl_FragColor = color;\\n' + '}',\n Convolute_7_0: 'precision highp float;\\n' + 'uniform sampler2D uTexture;\\n' + 'uniform float uMatrix[49];\\n' + 'uniform float uStepW;\\n' + 'uniform float uStepH;\\n' + 'varying vec2 vTexCoord;\\n' + 'void main() {\\n' + 'vec4 color = vec4(0, 0, 0, 1);\\n' + 'for (float h = 0.0; h < 7.0; h+=1.0) {\\n' + 'for (float w = 0.0; w < 7.0; w+=1.0) {\\n' + 'vec2 matrixPos = vec2(uStepW * (w - 3.0), uStepH * (h - 3.0));\\n' + 'color.rgb += texture2D(uTexture, vTexCoord + matrixPos).rgb * uMatrix[int(h * 7.0 + w)];\\n' + '}\\n' + '}\\n' + 'float alpha = texture2D(uTexture, vTexCoord).a;\\n' + 'gl_FragColor = color;\\n' + 'gl_FragColor.a = alpha;\\n' + '}',\n Convolute_9_1: 'precision highp float;\\n' + 'uniform sampler2D uTexture;\\n' + 'uniform float uMatrix[81];\\n' + 'uniform float uStepW;\\n' + 'uniform float uStepH;\\n' + 'varying vec2 vTexCoord;\\n' + 'void main() {\\n' + 'vec4 color = vec4(0, 0, 0, 0);\\n' + 'for (float h = 0.0; h < 9.0; h+=1.0) {\\n' + 'for (float w = 0.0; w < 9.0; w+=1.0) {\\n' + 'vec2 matrixPos = vec2(uStepW * (w - 4.0), uStepH * (h - 4.0));\\n' + 'color += texture2D(uTexture, vTexCoord + matrixPos) * uMatrix[int(h * 9.0 + w)];\\n' + '}\\n' + '}\\n' + 'gl_FragColor = color;\\n' + '}',\n Convolute_9_0: 'precision highp float;\\n' + 'uniform sampler2D uTexture;\\n' + 'uniform float uMatrix[81];\\n' + 'uniform float uStepW;\\n' + 'uniform float uStepH;\\n' + 'varying vec2 vTexCoord;\\n' + 'void main() {\\n' + 'vec4 color = vec4(0, 0, 0, 1);\\n' + 'for (float h = 0.0; h < 9.0; h+=1.0) {\\n' + 'for (float w = 0.0; w < 9.0; w+=1.0) {\\n' + 'vec2 matrixPos = vec2(uStepW * (w - 4.0), uStepH * (h - 4.0));\\n' + 'color.rgb += texture2D(uTexture, vTexCoord + matrixPos).rgb * uMatrix[int(h * 9.0 + w)];\\n' + '}\\n' + '}\\n' + 'float alpha = texture2D(uTexture, vTexCoord).a;\\n' + 'gl_FragColor = color;\\n' + 'gl_FragColor.a = alpha;\\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 * 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 retrieveShader(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\n if (!options.programCache.hasOwnProperty(cacheKey)) {\n options.programCache[cacheKey] = this.createProgram(options.context, shaderSource);\n }\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 applyTo2d(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,\n g,\n b,\n a,\n dstOff,\n scx,\n scy,\n srcOff,\n wt,\n x,\n y,\n cx,\n cy;\n\n for (y = 0; y < sh; y++) {\n for (x = 0; x < sw; x++) {\n dstOff = (y * sw + x) * 4; // calculate the weighed sum of the source image pixels that\n // fall under the convolution matrix\n\n r = 0;\n g = 0;\n b = 0;\n 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; // eslint-disable-next-line max-depth\n\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 r += data[srcOff] * wt;\n g += data[srcOff + 1] * wt;\n b += data[srcOff + 2] * wt; // eslint-disable-next-line max-depth\n\n if (!alphaFac) {\n a += data[srcOff + 3] * wt;\n }\n }\n }\n\n dst[dstOff] = r;\n dst[dstOff + 1] = g;\n dst[dstOff + 2] = b;\n\n if (!alphaFac) {\n dst[dstOff + 3] = a;\n } else {\n dst[dstOff + 3] = data[dstOff + 3];\n }\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 getUniformLocations(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 sendUniformData(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 toObject() {\n return extend(this.callSuper('toObject'), {\n opaque: this.opaque,\n matrix: this.matrix\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\n fabric.Image.filters.Convolute.fromObject = fabric.Image.filters.BaseFilter.fromObject;\n})(typeof exports !== 'undefined' ? exports : this);\n\n(function (global) {\n 'use strict';\n\n var fabric = global.fabric || (global.fabric = {}),\n filters = fabric.Image.filters,\n createClass = fabric.util.createClass;\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\n filters.Grayscale = createClass(filters.BaseFilter,\n /** @lends fabric.Image.filters.Grayscale.prototype */\n {\n /**\n * Filter type\n * @param {String} type\n * @default\n */\n type: 'Grayscale',\n fragmentSource: {\n average: 'precision highp float;\\n' + 'uniform sampler2D uTexture;\\n' + 'varying vec2 vTexCoord;\\n' + 'void main() {\\n' + 'vec4 color = texture2D(uTexture, vTexCoord);\\n' + 'float average = (color.r + color.b + color.g) / 3.0;\\n' + 'gl_FragColor = vec4(average, average, average, color.a);\\n' + '}',\n lightness: 'precision highp float;\\n' + 'uniform sampler2D uTexture;\\n' + 'uniform int uMode;\\n' + 'varying vec2 vTexCoord;\\n' + 'void main() {\\n' + 'vec4 col = texture2D(uTexture, vTexCoord);\\n' + 'float average = (max(max(col.r, col.g),col.b) + min(min(col.r, col.g),col.b)) / 2.0;\\n' + 'gl_FragColor = vec4(average, average, average, col.a);\\n' + '}',\n luminosity: 'precision highp float;\\n' + 'uniform sampler2D uTexture;\\n' + 'uniform int uMode;\\n' + 'varying vec2 vTexCoord;\\n' + 'void main() {\\n' + 'vec4 col = texture2D(uTexture, vTexCoord);\\n' + 'float average = 0.21 * col.r + 0.72 * col.g + 0.07 * col.b;\\n' + 'gl_FragColor = vec4(average, average, average, col.a);\\n' + '}'\n },\n\n /**\n * Grayscale mode, between 'average', 'lightness', 'luminosity'\n * @param {String} type\n * @default\n */\n mode: 'average',\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 applyTo2d(options) {\n var imageData = options.imageData,\n data = imageData.data,\n i,\n len = data.length,\n value,\n mode = this.mode;\n\n for (i = 0; i < len; i += 4) {\n if (mode === 'average') {\n value = (data[i] + data[i + 1] + data[i + 2]) / 3;\n } else if (mode === 'lightness') {\n value = (Math.min(data[i], data[i + 1], data[i + 2]) + Math.max(data[i], data[i + 1], data[i + 2])) / 2;\n } else if (mode === 'luminosity') {\n value = 0.21 * data[i] + 0.72 * data[i + 1] + 0.07 * data[i + 2];\n }\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 retrieveShader(options) {\n var cacheKey = this.type + '_' + this.mode;\n\n if (!options.programCache.hasOwnProperty(cacheKey)) {\n var shaderSource = this.fragmentSource[this.mode];\n options.programCache[cacheKey] = this.createProgram(options.context, shaderSource);\n }\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 getUniformLocations(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 sendUniformData(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 isNeutralState() {\n return false;\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\n fabric.Image.filters.Grayscale.fromObject = fabric.Image.filters.BaseFilter.fromObject;\n})(typeof exports !== 'undefined' ? exports : this);\n\n(function (global) {\n 'use strict';\n\n var fabric = global.fabric || (global.fabric = {}),\n filters = fabric.Image.filters,\n createClass = fabric.util.createClass;\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\n filters.Invert = createClass(filters.BaseFilter,\n /** @lends fabric.Image.filters.Invert.prototype */\n {\n /**\n * Filter type\n * @param {String} type\n * @default\n */\n type: 'Invert',\n fragmentSource: 'precision highp float;\\n' + 'uniform sampler2D uTexture;\\n' + 'uniform int uInvert;\\n' + 'varying vec2 vTexCoord;\\n' + 'void main() {\\n' + 'vec4 color = texture2D(uTexture, vTexCoord);\\n' + 'if (uInvert == 1) {\\n' + 'gl_FragColor = vec4(1.0 - color.r,1.0 -color.g,1.0 -color.b,color.a);\\n' + '} else {\\n' + 'gl_FragColor = color;\\n' + '}\\n' + '}',\n\n /**\n * Filter invert. if false, does nothing\n * @param {Boolean} invert\n * @default\n */\n invert: true,\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 applyTo2d(options) {\n var imageData = options.imageData,\n data = imageData.data,\n i,\n len = data.length;\n\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 isNeutralState() {\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 getUniformLocations(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 sendUniformData(gl, uniformLocations) {\n gl.uniform1i(uniformLocations.uInvert, this.invert);\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\n fabric.Image.filters.Invert.fromObject = fabric.Image.filters.BaseFilter.fromObject;\n})(typeof exports !== 'undefined' ? exports : this);\n\n(function (global) {\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 * 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\n filters.Noise = createClass(filters.BaseFilter,\n /** @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' + 'uniform sampler2D uTexture;\\n' + 'uniform float uStepH;\\n' + 'uniform float uNoise;\\n' + 'uniform float uSeed;\\n' + 'varying vec2 vTexCoord;\\n' + 'float rand(vec2 co, float seed, float vScale) {\\n' + 'return fract(sin(dot(co.xy * vScale ,vec2(12.9898 , 78.233))) * 43758.5453 * (seed + 0.01) / 2.0);\\n' + '}\\n' + 'void main() {\\n' + 'vec4 color = texture2D(uTexture, vTexCoord);\\n' + 'color.rgb += (0.5 - rand(vTexCoord, uSeed, 0.1 / uStepH)) * uNoise;\\n' + 'gl_FragColor = color;\\n' + '}',\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 applyTo2d(options) {\n if (this.noise === 0) {\n return;\n }\n\n var imageData = options.imageData,\n data = imageData.data,\n i,\n len = data.length,\n noise = this.noise,\n rand;\n\n for (i = 0, len = data.length; i < len; i += 4) {\n rand = (0.5 - Math.random()) * noise;\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 getUniformLocations(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 sendUniformData(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 toObject() {\n return extend(this.callSuper('toObject'), {\n noise: this.noise\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\n fabric.Image.filters.Noise.fromObject = fabric.Image.filters.BaseFilter.fromObject;\n})(typeof exports !== 'undefined' ? exports : this);\n\n(function (global) {\n 'use strict';\n\n var fabric = global.fabric || (global.fabric = {}),\n filters = fabric.Image.filters,\n createClass = fabric.util.createClass;\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\n filters.Pixelate = createClass(filters.BaseFilter,\n /** @lends fabric.Image.filters.Pixelate.prototype */\n {\n /**\n * Filter type\n * @param {String} type\n * @default\n */\n type: 'Pixelate',\n blocksize: 4,\n mainParameter: 'blocksize',\n\n /**\n * Fragment source for the Pixelate program\n */\n fragmentSource: 'precision highp float;\\n' + 'uniform sampler2D uTexture;\\n' + 'uniform float uBlocksize;\\n' + 'uniform float uStepW;\\n' + 'uniform float uStepH;\\n' + 'varying vec2 vTexCoord;\\n' + 'void main() {\\n' + 'float blockW = uBlocksize * uStepW;\\n' + 'float blockH = uBlocksize * uStepW;\\n' + 'int posX = int(vTexCoord.x / blockW);\\n' + 'int posY = int(vTexCoord.y / blockH);\\n' + 'float fposX = float(posX);\\n' + 'float fposY = float(posY);\\n' + 'vec2 squareCoords = vec2(fposX * blockW, fposY * blockH);\\n' + 'vec4 color = texture2D(uTexture, squareCoords);\\n' + 'gl_FragColor = color;\\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 applyTo2d(options) {\n var imageData = options.imageData,\n data = imageData.data,\n iLen = imageData.height,\n jLen = imageData.width,\n index,\n i,\n j,\n r,\n g,\n b,\n a,\n _i,\n _j,\n _iLen,\n _jLen;\n\n for (i = 0; i < iLen; i += this.blocksize) {\n for (j = 0; j < jLen; j += this.blocksize) {\n index = i * 4 * jLen + j * 4;\n r = data[index];\n g = data[index + 1];\n b = data[index + 2];\n a = data[index + 3];\n _iLen = Math.min(i + this.blocksize, iLen);\n _jLen = Math.min(j + this.blocksize, jLen);\n\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 isNeutralState() {\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 getUniformLocations(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 sendUniformData(gl, uniformLocations) {\n gl.uniform1f(uniformLocations.uBlocksize, this.blocksize);\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\n fabric.Image.filters.Pixelate.fromObject = fabric.Image.filters.BaseFilter.fromObject;\n})(typeof exports !== 'undefined' ? exports : this);\n\n(function (global) {\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 * 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\n filters.RemoveColor = createClass(filters.BaseFilter,\n /** @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' + 'uniform sampler2D uTexture;\\n' + 'uniform vec4 uLow;\\n' + 'uniform vec4 uHigh;\\n' + 'varying vec2 vTexCoord;\\n' + 'void main() {\\n' + 'gl_FragColor = texture2D(uTexture, vTexCoord);\\n' + 'if(all(greaterThan(gl_FragColor.rgb,uLow.rgb)) && all(greaterThan(uHigh.rgb,gl_FragColor.rgb))) {\\n' + 'gl_FragColor.a = 0.0;\\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 applyTo2d(options) {\n var imageData = options.imageData,\n data = imageData.data,\n i,\n distance = this.distance * 255,\n r,\n g,\n b,\n source = new fabric.Color(this.color).getSource(),\n lowC = [source[0] - distance, source[1] - distance, source[2] - distance],\n highC = [source[0] + distance, source[1] + distance, source[2] + distance];\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] && g > lowC[1] && b > lowC[2] && r < highC[0] && g < highC[1] && 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 getUniformLocations(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 sendUniformData(gl, uniformLocations) {\n var source = new fabric.Color(this.color).getSource(),\n distance = parseFloat(this.distance),\n lowC = [0 + source[0] / 255 - distance, 0 + source[1] / 255 - distance, 0 + source[2] / 255 - distance, 1],\n highC = [source[0] / 255 + distance, source[1] / 255 + distance, source[2] / 255 + distance, 1];\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 toObject() {\n return extend(this.callSuper('toObject'), {\n color: this.color,\n distance: this.distance\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\n fabric.Image.filters.RemoveColor.fromObject = fabric.Image.filters.BaseFilter.fromObject;\n})(typeof exports !== 'undefined' ? exports : this);\n\n(function (global) {\n 'use strict';\n\n var fabric = global.fabric || (global.fabric = {}),\n filters = fabric.Image.filters,\n createClass = fabric.util.createClass;\n var matrices = {\n Brownie: [0.59970, 0.34553, -0.27082, 0, 0.186, -0.03770, 0.86095, 0.15059, 0, -0.1449, 0.24113, -0.07441, 0.44972, 0, -0.02965, 0, 0, 0, 1, 0],\n Vintage: [0.62793, 0.32021, -0.03965, 0, 0.03784, 0.02578, 0.64411, 0.03259, 0, 0.02926, 0.04660, -0.08512, 0.52416, 0, 0.02023, 0, 0, 0, 1, 0],\n Kodachrome: [1.12855, -0.39673, -0.03992, 0, 0.24991, -0.16404, 1.08352, -0.05498, 0, 0.09698, -0.16786, -0.56034, 1.60148, 0, 0.13972, 0, 0, 0, 1, 0],\n Technicolor: [1.91252, -0.85453, -0.09155, 0, 0.04624, -0.30878, 1.76589, -0.10601, 0, -0.27589, -0.23110, -0.75018, 1.84759, 0, 0.12137, 0, 0, 0, 1, 0],\n Polaroid: [1.438, -0.062, -0.062, 0, 0, -0.122, 1.378, -0.122, 0, 0, -0.016, -0.016, 1.483, 0, 0, 0, 0, 0, 1, 0],\n Sepia: [0.393, 0.769, 0.189, 0, 0, 0.349, 0.686, 0.168, 0, 0, 0.272, 0.534, 0.131, 0, 0, 0, 0, 0, 1, 0],\n BlackWhite: [1.5, 1.5, 1.5, 0, -1, 1.5, 1.5, 1.5, 0, -1, 1.5, 1.5, 1.5, 0, -1, 0, 0, 0, 1, 0]\n };\n\n for (var key in matrices) {\n filters[key] = createClass(filters.ColorMatrix,\n /** @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 /**\n * Lock the colormatrix on the color part, skipping alpha\n */\n colorsOnly: true\n });\n fabric.Image.filters[key].fromObject = fabric.Image.filters.BaseFilter.fromObject;\n }\n})(typeof exports !== 'undefined' ? exports : this);\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 * 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,\n /** @lends fabric.Image.filters.Blend.prototype */\n {\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' + 'gl_FragColor.r *= 2.0 * uColor.r;\\n' + '} else {\\n' + 'gl_FragColor.r = 1.0 - 2.0 * (1.0 - gl_FragColor.r) * (1.0 - uColor.r);\\n' + '}\\n' + 'if (uColor.g < 0.5) {\\n' + 'gl_FragColor.g *= 2.0 * uColor.g;\\n' + '} else {\\n' + 'gl_FragColor.g = 1.0 - 2.0 * (1.0 - gl_FragColor.g) * (1.0 - uColor.g);\\n' + '}\\n' + 'if (uColor.b < 0.5) {\\n' + 'gl_FragColor.b *= 2.0 * uColor.b;\\n' + '} else {\\n' + 'gl_FragColor.b = 1.0 - 2.0 * (1.0 - gl_FragColor.b) * (1.0 - uColor.b);\\n' + '}\\n',\n tint: 'gl_FragColor.rgb *= (1.0 - uColor.a);\\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 buildSource(mode) {\n return 'precision highp float;\\n' + 'uniform sampler2D uTexture;\\n' + 'uniform vec4 uColor;\\n' + 'varying vec2 vTexCoord;\\n' + 'void main() {\\n' + 'vec4 color = texture2D(uTexture, vTexCoord);\\n' + 'gl_FragColor = color;\\n' + 'if (color.a > 0.0) {\\n' + this.fragmentSource[mode] + '}\\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 retrieveShader(options) {\n var cacheKey = this.type + '_' + this.mode,\n shaderSource;\n\n if (!options.programCache.hasOwnProperty(cacheKey)) {\n shaderSource = this.buildSource(this.mode);\n options.programCache[cacheKey] = this.createProgram(options.context, shaderSource);\n }\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 applyTo2d(options) {\n var imageData = options.imageData,\n data = imageData.data,\n iLen = data.length,\n tr,\n tg,\n tb,\n r,\n g,\n b,\n source,\n alpha1 = 1 - this.alpha;\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 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\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\n case 'add':\n data[i] = r + tr;\n data[i + 1] = g + tg;\n data[i + 2] = b + tb;\n break;\n\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\n case 'subtract':\n data[i] = r - tr;\n data[i + 1] = g - tg;\n data[i + 2] = b - tb;\n break;\n\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\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\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\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\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 getUniformLocations(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 sendUniformData(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 toObject() {\n return {\n type: this.type,\n color: this.color,\n mode: this.mode,\n alpha: this.alpha\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\n fabric.Image.filters.BlendColor.fromObject = fabric.Image.filters.BaseFilter.fromObject;\n})(typeof exports !== 'undefined' ? exports : this);\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 * 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,\n /** @lends fabric.Image.filters.BlendImage.prototype */\n {\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 vertexSource: 'attribute vec2 aPosition;\\n' + 'varying vec2 vTexCoord;\\n' + 'varying vec2 vTexCoord2;\\n' + 'uniform mat3 uTransformMatrix;\\n' + 'void main() {\\n' + 'vTexCoord = aPosition;\\n' + 'vTexCoord2 = (uTransformMatrix * vec3(aPosition, 1.0)).xy;\\n' + 'gl_Position = vec4(aPosition * 2.0 - 1.0, 0.0, 1.0);\\n' + '}',\n\n /**\n * Fragment source for the Multiply program\n */\n fragmentSource: {\n multiply: 'precision highp float;\\n' + 'uniform sampler2D uTexture;\\n' + 'uniform sampler2D uImage;\\n' + 'uniform vec4 uColor;\\n' + 'varying vec2 vTexCoord;\\n' + 'varying vec2 vTexCoord2;\\n' + 'void main() {\\n' + 'vec4 color = texture2D(uTexture, vTexCoord);\\n' + 'vec4 color2 = texture2D(uImage, vTexCoord2);\\n' + 'color.rgba *= color2.rgba;\\n' + 'gl_FragColor = color;\\n' + '}',\n mask: 'precision highp float;\\n' + 'uniform sampler2D uTexture;\\n' + 'uniform sampler2D uImage;\\n' + 'uniform vec4 uColor;\\n' + 'varying vec2 vTexCoord;\\n' + 'varying vec2 vTexCoord2;\\n' + 'void main() {\\n' + 'vec4 color = texture2D(uTexture, vTexCoord);\\n' + 'vec4 color2 = texture2D(uImage, vTexCoord2);\\n' + 'color.a = color2.a;\\n' + 'gl_FragColor = color;\\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 retrieveShader(options) {\n var cacheKey = this.type + '_' + this.mode;\n var shaderSource = this.fragmentSource[this.mode];\n\n if (!options.programCache.hasOwnProperty(cacheKey)) {\n options.programCache[cacheKey] = this.createProgram(options.context, shaderSource);\n }\n\n return options.programCache[cacheKey];\n },\n applyToWebGL: function applyToWebGL(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 createTexture: function createTexture(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 calculateMatrix() {\n var image = this.image,\n width = image._element.width,\n height = image._element.height;\n return [1 / image.scaleX, 0, 0, 0, 1 / image.scaleY, 0, -image.left / width, -image.top / height, 1];\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 applyTo2d(options) {\n var imageData = options.imageData,\n resources = options.filterBackend.resources,\n data = imageData.data,\n iLen = data.length,\n width = imageData.width,\n height = imageData.height,\n tr,\n tg,\n tb,\n ta,\n r,\n g,\n b,\n a,\n canvas1,\n context,\n image = this.image,\n blendData;\n\n if (!resources.blendImage) {\n resources.blendImage = fabric.util.createCanvasElement();\n }\n\n canvas1 = resources.blendImage;\n context = canvas1.getContext('2d');\n\n if (canvas1.width !== width || canvas1.height !== height) {\n canvas1.width = width;\n canvas1.height = height;\n } else {\n context.clearRect(0, 0, width, height);\n }\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\n for (var i = 0; i < iLen; i += 4) {\n r = data[i];\n g = data[i + 1];\n b = data[i + 2];\n a = data[i + 3];\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\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 getUniformLocations(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 sendUniformData(gl, uniformLocations) {\n var matrix = this.calculateMatrix();\n gl.uniform1i(uniformLocations.uImage, 1); // texture unit 1.\n\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 toObject() {\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 * 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\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})(typeof exports !== 'undefined' ? exports : this);\n\n(function (global) {\n 'use strict';\n\n var fabric = global.fabric || (global.fabric = {}),\n pow = Math.pow,\n floor = Math.floor,\n sqrt = Math.sqrt,\n abs = Math.abs,\n round = Math.round,\n sin = Math.sin,\n ceil = Math.ceil,\n filters = fabric.Image.filters,\n createClass = fabric.util.createClass;\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\n filters.Resize = createClass(filters.BaseFilter,\n /** @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 * 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 getUniformLocations(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 sendUniformData(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 retrieveShader(options) {\n var filterWindow = this.getFilterWindow(),\n cacheKey = this.type + '_' + filterWindow;\n\n if (!options.programCache.hasOwnProperty(cacheKey)) {\n var fragmentShader = this.generateShader(filterWindow);\n options.programCache[cacheKey] = this.createProgram(options.context, fragmentShader);\n }\n\n return options.programCache[cacheKey];\n },\n getFilterWindow: function getFilterWindow() {\n var scale = this.tempScale;\n return Math.ceil(this.lanczosLobes / scale);\n },\n getTaps: function getTaps() {\n var lobeFunction = this.lanczosCreate(this.lanczosLobes),\n scale = this.tempScale,\n filterWindow = this.getFilterWindow(),\n taps = new Array(filterWindow);\n\n for (var i = 1; i <= filterWindow; i++) {\n taps[i - 1] = lobeFunction(i * scale);\n }\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 generateShader(filterWindow) {\n var offsets = new Array(filterWindow),\n fragmentShader = this.fragmentSourceTOP,\n 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 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 fragmentSourceTOP: 'precision highp float;\\n' + 'uniform sampler2D uTexture;\\n' + 'uniform vec2 uDelta;\\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 applyTo(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\n this._setupFrameBuffer(options);\n\n this.applyToWebGL(options);\n\n this._swapTextures(options);\n\n options.sourceWidth = options.destinationWidth;\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\n this._setupFrameBuffer(options);\n\n this.applyToWebGL(options);\n\n this._swapTextures(options);\n\n options.sourceHeight = options.destinationHeight;\n } else {\n this.applyTo2d(options);\n }\n },\n isNeutralState: function isNeutralState() {\n return this.scaleX === 1 && this.scaleY === 1;\n },\n lanczosCreate: function lanczosCreate(lobes) {\n return function (x) {\n if (x >= lobes || x <= -lobes) {\n return 0.0;\n }\n\n if (x < 1.19209290E-07 && x > -1.19209290E-07) {\n return 1.0;\n }\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 applyTo2d(options) {\n var imageData = options.imageData,\n scaleX = this.scaleX,\n scaleY = this.scaleY;\n this.rcpScaleX = 1 / scaleX;\n this.rcpScaleY = 1 / scaleY;\n var oW = imageData.width,\n oH = imageData.height,\n dW = round(oW * scaleX),\n dH = round(oH * scaleY),\n newData;\n\n if (this.resizeType === 'sliceHack') {\n newData = this.sliceByTwo(options, oW, oH, dW, dH);\n } else if (this.resizeType === 'hermite') {\n newData = this.hermiteFastResize(options, oW, oH, dW, dH);\n } else if (this.resizeType === 'bilinear') {\n newData = this.bilinearFiltering(options, oW, oH, dW, dH);\n } else if (this.resizeType === 'lanczos') {\n newData = this.lanczosResize(options, oW, oH, dW, dH);\n }\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 sliceByTwo(options, oW, oH, dW, dH) {\n var imageData = options.imageData,\n mult = 0.5,\n doneW = false,\n doneH = false,\n stepW = oW * mult,\n stepH = oH * mult,\n resources = fabric.filterBackend.resources,\n tmpCanvas,\n ctx,\n sX = 0,\n sY = 0,\n dX = oW,\n dY = 0;\n\n if (!resources.sliceByTwo) {\n resources.sliceByTwo = document.createElement('canvas');\n }\n\n tmpCanvas = resources.sliceByTwo;\n\n if (tmpCanvas.width < oW * 1.5 || tmpCanvas.height < oH) {\n tmpCanvas.width = oW * 1.5;\n tmpCanvas.height = oH;\n }\n\n ctx = tmpCanvas.getContext('2d');\n ctx.clearRect(0, 0, oW * 1.5, oH);\n ctx.putImageData(imageData, 0, 0);\n dW = floor(dW);\n dH = floor(dH);\n\n while (!doneW || !doneH) {\n oW = stepW;\n oH = stepH;\n\n if (dW < floor(stepW * mult)) {\n stepW = floor(stepW * mult);\n } else {\n stepW = dW;\n doneW = true;\n }\n\n if (dH < floor(stepH * mult)) {\n stepH = floor(stepH * mult);\n } else {\n stepH = dH;\n doneH = true;\n }\n\n ctx.drawImage(tmpCanvas, sX, sY, oW, oH, dX, dY, stepW, stepH);\n sX = dX;\n sY = dY;\n dY += stepH;\n }\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 lanczosResize(options, oW, oH, dW, dH) {\n function process(u) {\n var v, i, weight, idx, a, red, green, blue, alpha, fX, fY;\n center.x = (u + 0.5) * ratioX;\n icenter.x = floor(center.x);\n\n for (v = 0; v < dH; v++) {\n center.y = (v + 0.5) * ratioY;\n icenter.y = floor(center.y);\n a = 0;\n red = 0;\n green = 0;\n blue = 0;\n alpha = 0;\n\n for (i = icenter.x - range2X; i <= icenter.x + range2X; i++) {\n if (i < 0 || i >= oW) {\n continue;\n }\n\n fX = floor(1000 * abs(i - center.x));\n\n if (!cacheLanc[fX]) {\n cacheLanc[fX] = {};\n }\n\n for (var j = icenter.y - range2Y; j <= icenter.y + range2Y; j++) {\n if (j < 0 || j >= oH) {\n continue;\n }\n\n fY = floor(1000 * abs(j - center.y));\n\n if (!cacheLanc[fX][fY]) {\n cacheLanc[fX][fY] = lanczos(sqrt(pow(fX * rcpRatioX, 2) + pow(fY * rcpRatioY, 2)) / 1000);\n }\n\n weight = cacheLanc[fX][fY];\n\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\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 } 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,\n ratioY = this.rcpScaleY,\n rcpRatioX = 2 / this.rcpScaleX,\n rcpRatioY = 2 / this.rcpScaleY,\n range2X = ceil(ratioX * this.lanczosLobes / 2),\n range2Y = ceil(ratioY * this.lanczosLobes / 2),\n cacheLanc = {},\n center = {},\n icenter = {};\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 bilinearFiltering(options, oW, oH, dW, dH) {\n var a,\n b,\n c,\n d,\n x,\n y,\n i,\n j,\n xDiff,\n yDiff,\n chnl,\n color,\n offset = 0,\n origPix,\n ratioX = this.rcpScaleX,\n ratioY = this.rcpScaleY,\n w4 = 4 * (oW - 1),\n img = options.imageData,\n pixels = img.data,\n destImage = options.ctx.createImageData(dW, dH),\n destPixels = destImage.data;\n\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) + c * yDiff * (1 - xDiff) + d * xDiff * yDiff;\n destPixels[offset++] = color;\n }\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 hermiteFastResize(options, oW, oH, dW, dH) {\n var ratioW = this.rcpScaleX,\n ratioH = this.rcpScaleY,\n ratioWHalf = ceil(ratioW / 2),\n ratioHHalf = ceil(ratioH / 2),\n img = options.imageData,\n data = img.data,\n img2 = options.ctx.createImageData(dW, dH),\n data2 = img2.data;\n\n for (var j = 0; j < dH; j++) {\n for (var i = 0; i < dW; i++) {\n var x2 = (i + j * dW) * 4,\n weight = 0,\n weights = 0,\n weightsAlpha = 0,\n gxR = 0,\n gxG = 0,\n gxB = 0,\n gxA = 0,\n centerY = (j + 0.5) * ratioH;\n\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,\n w0 = dy * dy;\n\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\n if (w > 1 && w < -1) {\n continue;\n } //hermite filter\n\n\n weight = 2 * w * w * w - 3 * w * w + 1;\n\n if (weight > 0) {\n dx = 4 * (xx + yy * oW); //alpha\n\n gxA += weight * data[dx + 3];\n weightsAlpha += weight; //colors\n\n if (data[dx + 3] < 255) {\n weight = weight * data[dx + 3] / 250;\n }\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 }\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\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 toObject() {\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 * 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\n fabric.Image.filters.Resize.fromObject = fabric.Image.filters.BaseFilter.fromObject;\n})(typeof exports !== 'undefined' ? exports : this);\n\n(function (global) {\n 'use strict';\n\n var fabric = global.fabric || (global.fabric = {}),\n filters = fabric.Image.filters,\n createClass = fabric.util.createClass;\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: 0.25\n * });\n * object.filters.push(filter);\n * object.applyFilters();\n */\n\n filters.Contrast = createClass(filters.BaseFilter,\n /** @lends fabric.Image.filters.Contrast.prototype */\n {\n /**\n * Filter type\n * @param {String} type\n * @default\n */\n type: 'Contrast',\n fragmentSource: 'precision highp float;\\n' + 'uniform sampler2D uTexture;\\n' + 'uniform float uContrast;\\n' + 'varying vec2 vTexCoord;\\n' + 'void main() {\\n' + 'vec4 color = texture2D(uTexture, vTexCoord);\\n' + 'float contrastF = 1.015 * (uContrast + 1.0) / (1.0 * (1.015 - uContrast));\\n' + 'color.rgb = contrastF * (color.rgb - 0.5) + 0.5;\\n' + 'gl_FragColor = color;\\n' + '}',\n\n /**\n * contrast value, range from -1 to 1.\n * @param {Number} contrast\n * @default 0\n */\n contrast: 0,\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 applyTo2d(options) {\n if (this.contrast === 0) {\n return;\n }\n\n var imageData = options.imageData,\n i,\n len,\n data = imageData.data,\n 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 getUniformLocations(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 sendUniformData(gl, uniformLocations) {\n gl.uniform1f(uniformLocations.uContrast, this.contrast);\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\n fabric.Image.filters.Contrast.fromObject = fabric.Image.filters.BaseFilter.fromObject;\n})(typeof exports !== 'undefined' ? exports : this);\n\n(function (global) {\n 'use strict';\n\n var fabric = global.fabric || (global.fabric = {}),\n filters = fabric.Image.filters,\n createClass = fabric.util.createClass;\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\n filters.Saturation = createClass(filters.BaseFilter,\n /** @lends fabric.Image.filters.Saturation.prototype */\n {\n /**\n * Filter type\n * @param {String} type\n * @default\n */\n type: 'Saturation',\n fragmentSource: 'precision highp float;\\n' + 'uniform sampler2D uTexture;\\n' + 'uniform float uSaturation;\\n' + 'varying vec2 vTexCoord;\\n' + 'void main() {\\n' + 'vec4 color = texture2D(uTexture, vTexCoord);\\n' + 'float rgMax = max(color.r, color.g);\\n' + 'float rgbMax = max(rgMax, color.b);\\n' + 'color.r += rgbMax != color.r ? (rgbMax - color.r) * uSaturation : 0.00;\\n' + 'color.g += rgbMax != color.g ? (rgbMax - color.g) * uSaturation : 0.00;\\n' + 'color.b += rgbMax != color.b ? (rgbMax - color.b) * uSaturation : 0.00;\\n' + 'gl_FragColor = color;\\n' + '}',\n saturation: 0,\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 applyTo2d(options) {\n if (this.saturation === 0) {\n return;\n }\n\n var imageData = options.imageData,\n data = imageData.data,\n len = data.length,\n adjust = -this.saturation,\n i,\n 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 getUniformLocations(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 sendUniformData(gl, uniformLocations) {\n gl.uniform1f(uniformLocations.uSaturation, -this.saturation);\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\n fabric.Image.filters.Saturation.fromObject = fabric.Image.filters.BaseFilter.fromObject;\n})(typeof exports !== 'undefined' ? exports : this);\n\n(function (global) {\n 'use strict';\n\n var fabric = global.fabric || (global.fabric = {}),\n filters = fabric.Image.filters,\n createClass = fabric.util.createClass;\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\n filters.Blur = createClass(filters.BaseFilter,\n /** @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' + 'uniform sampler2D uTexture;\\n' + 'uniform vec2 uDelta;\\n' + 'varying vec2 vTexCoord;\\n' + 'const float nSamples = 15.0;\\n' + 'vec3 v3offset = vec3(12.9898, 78.233, 151.7182);\\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' + 'void main() {\\n' + 'vec4 color = vec4(0.0);\\n' + 'float total = 0.0;\\n' + 'float offset = random(v3offset);\\n' + 'for (float t = -nSamples; t <= nSamples; t++) {\\n' + 'float percent = (t + offset - 0.5) / nSamples;\\n' + 'float weight = 1.0 - abs(percent);\\n' + 'color += texture2D(uTexture, vTexCoord + uDelta * percent) * weight;\\n' + 'total += weight;\\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 mainParameter: 'blur',\n applyTo: function applyTo(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\n this._setupFrameBuffer(options);\n\n this.horizontal = true;\n this.applyToWebGL(options);\n\n this._swapTextures(options);\n\n this._setupFrameBuffer(options);\n\n this.horizontal = false;\n this.applyToWebGL(options);\n\n this._swapTextures(options);\n } else {\n this.applyTo2d(options);\n }\n },\n applyTo2d: function applyTo2d(options) {\n // paint canvasEl with current image data.\n //options.ctx.putImageData(options.imageData, 0, 0);\n options.imageData = this.simpleBlur(options);\n },\n simpleBlur: function simpleBlur(options) {\n var resources = options.filterBackend.resources,\n canvas1,\n 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\n canvas1 = resources.blurLayer1;\n canvas2 = resources.blurLayer2;\n\n if (canvas1.width !== width || canvas1.height !== height) {\n canvas2.width = canvas1.width = width;\n canvas2.height = canvas1.height = height;\n }\n\n var ctx1 = canvas1.getContext('2d'),\n ctx2 = canvas2.getContext('2d'),\n nSamples = 15,\n random,\n percent,\n j,\n i,\n blur = this.blur * 0.06 * 0.5; // load first canvas\n\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\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\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 getUniformLocations(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 sendUniformData(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 chooseRightDelta() {\n var blurScale = 1,\n delta = [0, 0],\n blur;\n\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 } else {\n if (this.aspectRatio < 1) {\n // image is tall, i want to shrink radius vertical\n blurScale = this.aspectRatio;\n }\n }\n\n blur = blurScale * this.blur * 0.12;\n\n if (this.horizontal) {\n delta[0] = blur;\n } else {\n delta[1] = blur;\n }\n\n return delta;\n }\n });\n /**\n * Deserialize a JSON definition of a BlurFilter into a concrete instance.\n */\n\n filters.Blur.fromObject = fabric.Image.filters.BaseFilter.fromObject;\n})(typeof exports !== 'undefined' ? exports : this);\n\n(function (global) {\n 'use strict';\n\n var fabric = global.fabric || (global.fabric = {}),\n filters = fabric.Image.filters,\n createClass = fabric.util.createClass;\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 * gamma: [1, 0.5, 2.1]\n * });\n * object.filters.push(filter);\n * object.applyFilters();\n */\n\n filters.Gamma = createClass(filters.BaseFilter,\n /** @lends fabric.Image.filters.Gamma.prototype */\n {\n /**\n * Filter type\n * @param {String} type\n * @default\n */\n type: 'Gamma',\n fragmentSource: 'precision highp float;\\n' + 'uniform sampler2D uTexture;\\n' + 'uniform vec3 uGamma;\\n' + 'varying vec2 vTexCoord;\\n' + 'void main() {\\n' + 'vec4 color = texture2D(uTexture, vTexCoord);\\n' + 'vec3 correction = (1.0 / uGamma);\\n' + 'color.r = pow(color.r, correction.r);\\n' + 'color.g = pow(color.g, correction.g);\\n' + 'color.b = pow(color.b, correction.b);\\n' + 'gl_FragColor = color;\\n' + 'gl_FragColor.rgb *= color.a;\\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 initialize(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 applyTo2d(options) {\n var imageData = options.imageData,\n data = imageData.data,\n gamma = this.gamma,\n len = data.length,\n rInv = 1 / gamma[0],\n gInv = 1 / gamma[1],\n bInv = 1 / gamma[2],\n i;\n\n if (!this.rVals) {\n // eslint-disable-next-line\n this.rVals = new Uint8Array(256); // eslint-disable-next-line\n\n this.gVals = new Uint8Array(256); // eslint-disable-next-line\n\n this.bVals = new Uint8Array(256);\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\n\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\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 getUniformLocations(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 sendUniformData(gl, uniformLocations) {\n gl.uniform3fv(uniformLocations.uGamma, this.gamma);\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\n fabric.Image.filters.Gamma.fromObject = fabric.Image.filters.BaseFilter.fromObject;\n})(typeof exports !== 'undefined' ? exports : this);\n\n(function (global) {\n 'use strict';\n\n var fabric = global.fabric || (global.fabric = {}),\n filters = fabric.Image.filters,\n createClass = fabric.util.createClass;\n /**\n * A container class that knows how to apply a sequence of filters to an input image.\n */\n\n filters.Composed = createClass(filters.BaseFilter,\n /** @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 initialize(options) {\n this.callSuper('initialize', options); // create a new array instead mutating the prototype with push\n\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 applyTo(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 toObject() {\n return fabric.util.object.extend(this.callSuper('toObject'), {\n subFilters: this.subFilters.map(function (filter) {\n return filter.toObject();\n })\n });\n },\n isNeutralState: function isNeutralState() {\n return !this.subFilters.some(function (filter) {\n return !filter.isNeutralState();\n });\n }\n });\n /**\n * Deserialize a JSON definition of a ComposedFilter into a concrete instance.\n */\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({\n subFilters: subFilters\n });\n callback && callback(instance);\n return instance;\n };\n})(typeof exports !== 'undefined' ? exports : this);\n\n(function (global) {\n 'use strict';\n\n var fabric = global.fabric || (global.fabric = {}),\n filters = fabric.Image.filters,\n createClass = fabric.util.createClass;\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\n filters.HueRotation = createClass(filters.ColorMatrix,\n /** @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 calculateMatrix: function calculateMatrix() {\n var rad = this.rotation * Math.PI,\n cos = fabric.util.cos(rad),\n sin = fabric.util.sin(rad),\n aThird = 1 / 3,\n aThirdSqtSin = Math.sqrt(aThird) * sin,\n OneMinusCos = 1 - cos;\n this.matrix = [1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0];\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 isNeutralState(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 applyTo(options) {\n this.calculateMatrix();\n filters.BaseFilter.prototype.applyTo.call(this, options);\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\n fabric.Image.filters.HueRotation.fromObject = fabric.Image.filters.BaseFilter.fromObject;\n})(typeof exports !== 'undefined' ? exports : this);\n\n(function (global) {\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 * 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\n\n fabric.Text = fabric.util.createClass(fabric.Object,\n /** @lends fabric.Text.prototype */\n {\n /**\n * Properties which when set cause object to change dimensions\n * @type Array\n * @private\n */\n _dimensionAffectingProps: ['fontSize', 'fontWeight', 'fontFamily', 'fontStyle', 'lineHeight', 'text', 'charSpacing', 'textAlign', 'styles'],\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,\n // fontSize factor\n baseline: -0.35 // baseline-shift factor (upwards)\n\n },\n\n /**\n * Subscript schema object (minimum overlap)\n * @type {Object}\n * @default\n */\n subscript: {\n size: 0.60,\n // fontSize factor\n baseline: 0.11 // baseline-shift factor (downwards)\n\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', 'fontWeight', 'fontSize', 'text', 'underline', 'overline', 'linethrough', 'textAlign', 'fontStyle', 'lineHeight', 'textBackgroundColor', 'charSpacing', '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', 'fontWeight', 'fontSize', 'text', 'underline', 'overline', 'linethrough', 'textAlign', 'fontStyle', 'lineHeight', 'textBackgroundColor', 'charSpacing', 'styles'),\n\n /**\n * When defined, an object is rendered via stroke and this property specifies its color.\n * Backwards incompatibility note: 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 * Backwards incompatibility note: 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: ['stroke', 'strokeWidth', 'fill', 'fontFamily', 'fontSize', 'fontWeight', 'fontStyle', 'underline', 'overline', 'linethrough', 'deltaY', 'textBackgroundColor'],\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 initialize(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({\n propertySet: '_dimensionAffectingProps'\n });\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 getMeasuringContext() {\n // if we did not return we have to measure something.\n if (!fabric._measuringContext) {\n fabric._measuringContext = this.canvas && this.canvas.contextCache || fabric.util.createCanvasElement().getContext('2d');\n }\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 _splitText() {\n var newLines = this._splitTextIntoLines(this.text);\n\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 initDimensions() {\n if (this.__skipDimension) {\n return;\n }\n\n this._splitText();\n\n this._clearCache();\n\n this.width = this.calcTextWidth() || this.cursorWidth || this.MIN_TEXT_WIDTH;\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\n this.height = this.calcTextHeight();\n this.saveState({\n propertySet: '_dimensionAffectingProps'\n });\n },\n\n /**\n * Enlarge space boxes and shift the others\n */\n enlargeSpaces: function enlargeSpaces() {\n var diffSpace, currentLineWidth, numberOfSpaces, accumulatedSpace, line, charBound, spaces;\n\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\n accumulatedSpace = 0;\n line = this._textLines[i];\n currentLineWidth = this.getLineWidth(i);\n\n if (currentLineWidth < this.width && (spaces = this.textLines[i].match(this._reSpacesAndTabs))) {\n numberOfSpaces = spaces.length;\n diffSpace = (this.width - currentLineWidth) / numberOfSpaces;\n\n for (var j = 0, jlen = line.length; j <= jlen; j++) {\n charBound = this.__charBounds[i][j];\n\n if (this._reSpaceAndTab.test(line[j])) {\n charBound.width += diffSpace;\n charBound.kernedWidth += diffSpace;\n charBound.left += accumulatedSpace;\n accumulatedSpace += diffSpace;\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 isEndOfWrapping(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 missingNewlineOffset() {\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 toString() {\n return '#';\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 _getCacheCanvasDimensions() {\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 _render(ctx) {\n this._setTextStyles(ctx);\n\n this._renderTextLinesBackground(ctx);\n\n this._renderTextDecoration(ctx, 'underline');\n\n this._renderText(ctx);\n\n this._renderTextDecoration(ctx, 'overline');\n\n this._renderTextDecoration(ctx, 'linethrough');\n },\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx Context to render on\n */\n _renderText: function _renderText(ctx) {\n if (this.paintFirst === 'stroke') {\n this._renderTextStroke(ctx);\n\n this._renderTextFill(ctx);\n } else {\n this._renderTextFill(ctx);\n\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 _setTextStyles(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 calcTextWidth() {\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\n if (currentLineWidth > maxWidth) {\n maxWidth = currentLineWidth;\n }\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 _renderTextLine(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 _renderTextLinesBackground(ctx) {\n if (!this.textBackgroundColor && !this.styleHas('textBackgroundColor')) {\n return;\n }\n\n var lineTopOffset = 0,\n heightOfLine,\n lineLeftOffset,\n originalFill = ctx.fillStyle,\n line,\n lastColor,\n leftOffset = this._getLeftOffset(),\n topOffset = this._getTopOffset(),\n boxStart = 0,\n boxWidth = 0,\n charBox,\n currentColor;\n\n for (var i = 0, len = this._textLines.length; i < len; i++) {\n heightOfLine = this.getHeightOfLine(i);\n\n if (!this.textBackgroundColor && !this.styleHas('textBackgroundColor', i)) {\n lineTopOffset += heightOfLine;\n continue;\n }\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\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\n if (currentColor !== lastColor) {\n ctx.fillStyle = lastColor;\n lastColor && ctx.fillRect(leftOffset + lineLeftOffset + boxStart, topOffset + lineTopOffset, boxWidth, heightOfLine / this.lineHeight);\n boxStart = charBox.left;\n boxWidth = charBox.width;\n lastColor = currentColor;\n } else {\n boxWidth += charBox.kernedWidth;\n }\n }\n\n if (currentColor) {\n ctx.fillStyle = currentColor;\n ctx.fillRect(leftOffset + lineLeftOffset + boxStart, topOffset + lineTopOffset, boxWidth, heightOfLine / this.lineHeight);\n }\n\n lineTopOffset += heightOfLine;\n }\n\n ctx.fillStyle = originalFill; // if there is text background color no\n // other shadows should be casted\n\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 getFontCache(decl) {\n var fontFamily = decl.fontFamily.toLowerCase();\n\n if (!fabric.charWidthsCache[fontFamily]) {\n fabric.charWidthsCache[fontFamily] = {};\n }\n\n var cache = fabric.charWidthsCache[fontFamily],\n cacheProp = decl.fontStyle.toLowerCase() + '_' + (decl.fontWeight + '').toLowerCase();\n\n if (!cache[cacheProp]) {\n cache[cacheProp] = {};\n }\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 _applyCharStyles(method, ctx, lineIndex, charIndex, styleDeclaration) {\n this._setFillStyles(ctx, styleDeclaration);\n\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 _measureChar(_char, charStyle, previousChar, prevCharStyle) {\n // first i try to return from cache\n var fontCache = this.getFontCache(charStyle),\n fontDeclaration = this._getFontDeclaration(charStyle),\n previousFontDeclaration = this._getFontDeclaration(prevCharStyle),\n couple = previousChar + _char,\n stylesAreEqual = fontDeclaration === previousFontDeclaration,\n width,\n coupleWidth,\n previousWidth,\n fontMultiplier = charStyle.fontSize / this.CACHE_FONT_SIZE,\n kernedWidth;\n\n if (previousChar && fontCache[previousChar] !== undefined) {\n previousWidth = fontCache[previousChar];\n }\n\n if (fontCache[_char] !== undefined) {\n kernedWidth = width = fontCache[_char];\n }\n\n if (stylesAreEqual && fontCache[couple] !== undefined) {\n coupleWidth = fontCache[couple];\n kernedWidth = coupleWidth - previousWidth;\n }\n\n if (width === undefined || previousWidth === undefined || coupleWidth === undefined) {\n var ctx = this.getMeasuringContext(); // send a TRUE to specify measuring font size CACHE_FONT_SIZE\n\n this._setTextStyles(ctx, charStyle, true);\n }\n\n if (width === undefined) {\n kernedWidth = width = ctx.measureText(_char).width;\n fontCache[_char] = width;\n }\n\n if (previousWidth === undefined && stylesAreEqual && previousChar) {\n previousWidth = ctx.measureText(previousChar).width;\n fontCache[previousChar] = previousWidth;\n }\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\n return {\n width: width * fontMultiplier,\n kernedWidth: kernedWidth * fontMultiplier\n };\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 getHeightOfChar(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 measureLine(lineIndex) {\n var lineInfo = this._measureLine(lineIndex);\n\n if (this.charSpacing !== 0) {\n lineInfo.width -= this._getWidthOfCharSpacing();\n }\n\n if (lineInfo.width < 0) {\n lineInfo.width = 0;\n }\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 _measureLine(lineIndex) {\n var width = 0,\n i,\n grapheme,\n line = this._textLines[lineIndex],\n prevGrapheme,\n graphemeInfo,\n numOfSpaces = 0,\n lineBounds = new Array(line.length);\n this.__charBounds[lineIndex] = lineBounds;\n\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 } // this latest bound box represent the last character of the line\n // to simplify cursor handling in interactive mode.\n\n\n lineBounds[i] = {\n left: graphemeInfo ? graphemeInfo.left + graphemeInfo.width : 0,\n width: 0,\n kernedWidth: 0,\n height: this.fontSize\n };\n return {\n width: width,\n numOfSpaces: numOfSpaces\n };\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 _getGraphemeBox(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,\n 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\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\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 getHeightOfLine(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\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 calcTextHeight() {\n var lineHeight,\n height = 0;\n\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\n return height;\n },\n\n /**\n * @private\n * @return {Number} Left offset\n */\n _getLeftOffset: function _getLeftOffset() {\n return -this.width / 2;\n },\n\n /**\n * @private\n * @return {Number} Top offset\n */\n _getTopOffset: function _getTopOffset() {\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 _renderTextCommon(ctx, method) {\n ctx.save();\n\n var lineHeights = 0,\n left = this._getLeftOffset(),\n top = this._getTopOffset(),\n offsets = this._applyPatternGradientTransform(ctx, method === 'fillText' ? this.fill : this.stroke);\n\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\n this._renderTextLine(method, ctx, this._textLines[i], left + leftOffset - offsets.offsetX, top + lineHeights + maxHeight - offsets.offsetY, i);\n\n lineHeights += heightOfLine;\n }\n\n ctx.restore();\n },\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx Context to render on\n */\n _renderTextFill: function _renderTextFill(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 _renderTextStroke(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\n this._setLineDash(ctx, this.strokeDashArray);\n\n ctx.beginPath();\n\n this._renderTextCommon(ctx, 'strokeText');\n\n ctx.closePath();\n ctx.restore();\n },\n\n /**\n * @private\n * @param {String} method fillText or strokeText.\n * @param {CanvasRenderingContext2D} ctx Context to render on\n * @param {Array} line Content of the line, splitted in an array by grapheme\n * @param {Number} left\n * @param {Number} top\n * @param {Number} lineIndex\n */\n _renderChars: function _renderChars(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 ctx.save();\n top -= lineHeight * this._fontSizeFraction / this.lineHeight;\n\n if (shortCut) {\n // render all the line in one pass without checking\n this._renderChar(method, ctx, lineIndex, 0, line.join(''), left, top, lineHeight);\n\n ctx.restore();\n return;\n }\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\n if (boxWidth === 0) {\n left += charBox.kernedWidth - charBox.width;\n boxWidth += charBox.width;\n } else {\n boxWidth += charBox.kernedWidth;\n }\n\n if (isJustify && !timeToRender) {\n if (this._reSpaceAndTab.test(line[i])) {\n timeToRender = true;\n }\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\n if (timeToRender) {\n this._renderChar(method, ctx, lineIndex, i, charsToRender, left, top, lineHeight);\n\n charsToRender = '';\n actualStyle = nextStyle;\n left += boxWidth;\n boxWidth = 0;\n }\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 _renderChar(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\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\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 setSuperscript(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 setSubscript(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 _setScript(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 = {\n fontSize: fontSize * schema.size,\n deltaY: dy + fontSize * schema.baseline\n };\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 _hasStyleChanged(prevStyle, thisStyle) {\n return prevStyle.fill !== thisStyle.fill || prevStyle.stroke !== thisStyle.stroke || prevStyle.strokeWidth !== thisStyle.strokeWidth || prevStyle.fontSize !== thisStyle.fontSize || prevStyle.fontFamily !== thisStyle.fontFamily || prevStyle.fontWeight !== thisStyle.fontWeight || prevStyle.fontStyle !== thisStyle.fontStyle || prevStyle.deltaY !== thisStyle.deltaY;\n },\n\n /**\n * @private\n * @param {Object} prevStyle\n * @param {Object} thisStyle\n */\n _hasStyleChangedForSvg: function _hasStyleChangedForSvg(prevStyle, thisStyle) {\n return this._hasStyleChanged(prevStyle, thisStyle) || prevStyle.overline !== thisStyle.overline || prevStyle.underline !== thisStyle.underline || 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 _getLineLeftOffset(lineIndex) {\n var lineWidth = this.getLineWidth(lineIndex);\n\n if (this.textAlign === 'center') {\n return (this.width - lineWidth) / 2;\n }\n\n if (this.textAlign === 'right') {\n return this.width - lineWidth;\n }\n\n if (this.textAlign === 'justify-center' && this.isEndOfWrapping(lineIndex)) {\n return (this.width - lineWidth) / 2;\n }\n\n if (this.textAlign === 'justify-right' && this.isEndOfWrapping(lineIndex)) {\n return this.width - lineWidth;\n }\n\n return 0;\n },\n\n /**\n * @private\n */\n _clearCache: function _clearCache() {\n this.__lineWidths = [];\n this.__lineHeights = [];\n this.__charBounds = [];\n },\n\n /**\n * @private\n */\n _shouldClearDimensionCache: function _shouldClearDimensionCache() {\n var shouldClear = this._forceClearCache;\n shouldClear || (shouldClear = this.hasStateChanged('_dimensionAffectingProps'));\n\n if (shouldClear) {\n this.dirty = true;\n this._forceClearCache = false;\n }\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 getLineWidth(lineIndex) {\n if (this.__lineWidths[lineIndex]) {\n return this.__lineWidths[lineIndex];\n }\n\n var width,\n line = this._textLines[lineIndex],\n lineInfo;\n\n if (line === '') {\n width = 0;\n } else {\n lineInfo = this.measureLine(lineIndex);\n width = lineInfo.width;\n }\n\n this.__lineWidths[lineIndex] = width;\n return width;\n },\n _getWidthOfCharSpacing: function _getWidthOfCharSpacing() {\n if (this.charSpacing !== 0) {\n return this.fontSize * this.charSpacing / 1000;\n }\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 getValueOfPropertyAt(lineIndex, charIndex, property) {\n var charStyle = this._getStyleDeclaration(lineIndex, charIndex);\n\n if (charStyle && typeof charStyle[property] !== 'undefined') {\n return charStyle[property];\n }\n\n return this[property];\n },\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx Context to render on\n */\n _renderTextDecoration: function _renderTextDecoration(ctx, type) {\n if (!this[type] && !this.styleHas(type)) {\n return;\n }\n\n var heightOfLine,\n size,\n _size,\n lineLeftOffset,\n dy,\n _dy,\n line,\n lastDecoration,\n leftOffset = this._getLeftOffset(),\n topOffset = this._getTopOffset(),\n top,\n boxStart,\n boxWidth,\n charBox,\n currentDecoration,\n maxHeight,\n currentFill,\n lastFill,\n charSpacing = this._getWidthOfCharSpacing();\n\n for (var i = 0, len = this._textLines.length; i < len; i++) {\n heightOfLine = this.getHeightOfLine(i);\n\n if (!this[type] && !this.styleHas(type, i)) {\n topOffset += heightOfLine;\n continue;\n }\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\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\n if ((currentDecoration !== lastDecoration || currentFill !== lastFill || _size !== size || _dy !== dy) && boxWidth > 0) {\n ctx.fillStyle = lastFill;\n lastDecoration && lastFill && ctx.fillRect(leftOffset + lineLeftOffset + boxStart, top + this.offsets[type] * size + dy, boxWidth, this.fontSize / 15);\n boxStart = charBox.left;\n boxWidth = charBox.width;\n lastDecoration = currentDecoration;\n lastFill = currentFill;\n size = _size;\n dy = _dy;\n } else {\n boxWidth += charBox.kernedWidth;\n }\n }\n\n ctx.fillStyle = currentFill;\n currentDecoration && currentFill && ctx.fillRect(leftOffset + lineLeftOffset + boxStart, top + this.offsets[type] * size + dy, boxWidth - charSpacing, this.fontSize / 15);\n topOffset += heightOfLine;\n } // if there is text background color no\n // other shadows should be casted\n\n\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 _getFontDeclaration(styleObject, forMeasuring) {\n var style = styleObject || this,\n family = this.fontFamily,\n fontIsGeneric = fabric.Text.genericFonts.indexOf(family.toLowerCase()) > -1;\n var fontFamily = family === undefined || family.indexOf('\\'') > -1 || family.indexOf(',') > -1 || family.indexOf('\"') > -1 || fontIsGeneric ? style.fontFamily : '\"' + style.fontFamily + '\"';\n return [// 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, fabric.isLikelyNode ? style.fontStyle : style.fontWeight, forMeasuring ? this.CACHE_FONT_SIZE + 'px' : style.fontSize + 'px', fontFamily].join(' ');\n },\n\n /**\n * Renders text instance on a specified context\n * @param {CanvasRenderingContext2D} ctx Context to render on\n */\n render: function render(ctx) {\n // do not render if object is not visible\n if (!this.visible) {\n return;\n }\n\n if (this.canvas && this.canvas.skipOffscreen && !this.group && !this.isOnScreen()) {\n return;\n }\n\n if (this._shouldClearDimensionCache()) {\n this.initDimensions();\n }\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 _splitTextIntoLines(text) {\n var lines = text.split(this._reNewline),\n newLines = new Array(lines.length),\n newLine = ['\\n'],\n newText = [];\n\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\n newText.pop();\n return {\n _unwrappedLines: newLines,\n lines: lines,\n graphemeText: newText,\n graphemeLines: newLines\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 toObject(propertiesToInclude) {\n var additionalProperties = ['text', 'fontSize', 'fontWeight', 'fontFamily', 'fontStyle', 'lineHeight', 'underline', 'overline', 'linethrough', 'textAlign', 'textBackgroundColor', 'charSpacing'].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 set(key, value) {\n this.callSuper('set', key, value);\n var needsDims = false;\n\n if (typeof key === 'object') {\n for (var _key in key) {\n needsDims = needsDims || this._dimensionAffectingProps.indexOf(_key) !== -1;\n }\n } else {\n needsDims = this._dimensionAffectingProps.indexOf(key) !== -1;\n }\n\n if (needsDims) {\n this.initDimensions();\n this.setCoords();\n }\n\n return this;\n },\n\n /**\n * Returns complexity of an instance\n * @return {Number} complexity\n */\n complexity: function complexity() {\n return 1;\n }\n });\n /* _FROM_SVG_START_ */\n\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\n fabric.Text.ATTRIBUTE_NAMES = fabric.SHARED_ATTRIBUTES.concat('x y dx dy font-family font-style font-weight font-size letter-spacing text-decoration text-anchor'.split(' '));\n /**\n * Default SVG font size\n * @static\n * @memberOf fabric.Text\n */\n\n fabric.Text.DEFAULT_SVG_FONT_SIZE = 16;\n /**\n * Returns fabric.Text instance from an SVG element (not yet implemented)\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\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 options.top = options.top || 0;\n options.left = options.left || 0;\n\n if (parsedAttributes.textDecoration) {\n var textDecoration = parsedAttributes.textDecoration;\n\n if (textDecoration.indexOf('underline') !== -1) {\n options.underline = true;\n }\n\n if (textDecoration.indexOf('overline') !== -1) {\n options.overline = true;\n }\n\n if (textDecoration.indexOf('line-through') !== -1) {\n options.linethrough = true;\n }\n\n delete options.textDecoration;\n }\n\n if ('dx' in parsedAttributes) {\n options.left += parsedAttributes.dx;\n }\n\n if ('dy' in parsedAttributes) {\n options.top += parsedAttributes.dy;\n }\n\n if (!('fontSize' in options)) {\n options.fontSize = fabric.Text.DEFAULT_SVG_FONT_SIZE;\n }\n\n var textContent = ''; // 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\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 } 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 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\n if (parsedAnchor === 'center') {\n offX = text.getScaledWidth() / 2;\n }\n\n if (parsedAnchor === 'right') {\n offX = text.getScaledWidth();\n }\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\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 fabric.util.createAccessors && fabric.util.createAccessors(fabric.Text);\n})(typeof exports !== 'undefined' ? exports : this);\n\n(function () {\n fabric.util.object.extend(fabric.Text.prototype,\n /** @lends fabric.Text.prototype */\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 isEmptyStyles(lineIndex) {\n if (!this.styles) {\n return true;\n }\n\n if (typeof lineIndex !== 'undefined' && !this.styles[lineIndex]) {\n return true;\n }\n\n var obj = typeof lineIndex === 'undefined' ? this.styles : {\n line: this.styles[lineIndex]\n };\n\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\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 styleHas(property, lineIndex) {\n if (!this.styles || !property || property === '') {\n return false;\n }\n\n if (typeof lineIndex !== 'undefined' && !this.styles[lineIndex]) {\n return false;\n }\n\n var obj = typeof lineIndex === 'undefined' ? this.styles : {\n 0: this.styles[lineIndex]\n }; // eslint-disable-next-line\n\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\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 cleanStyle(property) {\n if (!this.styles || !property || property === '') {\n return false;\n }\n\n var obj = this.styles,\n stylesCount = 0,\n letterCount,\n stylePropertyValue,\n allStyleObjectPropertiesMatch = true,\n graphemeCount = 0,\n styleObject; // eslint-disable-next-line\n\n for (var p1 in obj) {\n letterCount = 0; // eslint-disable-next-line\n\n for (var p2 in obj[p1]) {\n var styleObject = obj[p1][p2],\n stylePropertyHasBeenSet = styleObject.hasOwnProperty(property);\n stylesCount++;\n\n if (stylePropertyHasBeenSet) {\n if (!stylePropertyValue) {\n stylePropertyValue = styleObject[property];\n } else if (styleObject[property] !== stylePropertyValue) {\n allStyleObjectPropertiesMatch = false;\n }\n\n if (styleObject[property] === this[property]) {\n delete styleObject[property];\n }\n } else {\n allStyleObjectPropertiesMatch = false;\n }\n\n if (Object.keys(styleObject).length !== 0) {\n letterCount++;\n } else {\n delete obj[p1][p2];\n }\n }\n\n if (letterCount === 0) {\n delete obj[p1];\n }\n } // if every grapheme has the same style set then\n // delete those styles and set it on the parent\n\n\n for (var i = 0; i < this._textLines.length; i++) {\n graphemeCount += this._textLines[i].length;\n }\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 removeStyle(property) {\n if (!this.styles || !property || property === '') {\n return;\n }\n\n var obj = this.styles,\n line,\n lineNum,\n charNum;\n\n for (lineNum in obj) {\n line = obj[lineNum];\n\n for (charNum in line) {\n delete line[charNum][property];\n\n if (Object.keys(line[charNum]).length === 0) {\n delete line[charNum];\n }\n }\n\n if (Object.keys(line).length === 0) {\n delete obj[lineNum];\n }\n }\n },\n\n /**\n * @private\n */\n _extendStyles: function _extendStyles(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. useful to manage styles.\n */\n get2DCursorLocation: function get2DCursorLocation(selectionStart, skipWrapping) {\n if (typeof selectionStart === 'undefined') {\n selectionStart = this.selectionStart;\n }\n\n var lines = skipWrapping ? this._unwrappedTextLines : this._textLines,\n len = lines.length;\n\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\n selectionStart -= lines[i].length + this.missingNewlineOffset(i);\n }\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 getSelectionStyles(startIndex, endIndex, complete) {\n if (typeof startIndex === 'undefined') {\n startIndex = this.selectionStart || 0;\n }\n\n if (typeof endIndex === 'undefined') {\n endIndex = this.selectionEnd || startIndex;\n }\n\n var styles = [];\n\n for (var i = startIndex; i < endIndex; i++) {\n styles.push(this.getStyleAtPosition(i, complete));\n }\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 getStyleAtPosition(position, complete) {\n var loc = this.get2DCursorLocation(position),\n style = complete ? this.getCompleteStyleDeclaration(loc.lineIndex, loc.charIndex) : 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 setSelectionStyles(styles, startIndex, endIndex) {\n if (typeof startIndex === 'undefined') {\n startIndex = this.selectionStart || 0;\n }\n\n if (typeof endIndex === 'undefined') {\n endIndex = this.selectionEnd || startIndex;\n }\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\n\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 _getStyleDeclaration(lineIndex, charIndex) {\n var lineStyle = this.styles && this.styles[lineIndex];\n\n if (!lineStyle) {\n return null;\n }\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 getCompleteStyleDeclaration(lineIndex, charIndex) {\n var style = this._getStyleDeclaration(lineIndex, charIndex) || {},\n styleObject = {},\n prop;\n\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\n return styleObject;\n },\n\n /**\n * @param {Number} lineIndex\n * @param {Number} charIndex\n * @param {Object} style\n * @private\n */\n _setStyleDeclaration: function _setStyleDeclaration(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 _deleteStyleDeclaration(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 _getLineStyle(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 _setLineStyle(lineIndex) {\n this.styles[lineIndex] = {};\n },\n\n /**\n * @param {Number} lineIndex\n * @private\n */\n _deleteLineStyle: function _deleteLineStyle(lineIndex) {\n delete this.styles[lineIndex];\n }\n });\n})();\n\n(function () {\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 * IText class (introduced in v1.4) 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 *

Supported key combinations:

\n *
\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   * 
\n *\n *

Supported mouse/touch combination

\n *
\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   * 
\n */\n\n\n fabric.IText = fabric.util.createClass(fabric.Text, fabric.Observable,\n /** @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 text cursor color in editing mode.\n * if not set (default) will take color from the text.\n * if set to a color value that fabric can understand, it will\n * be used instead of the color of the text at the current position.\n * @type String\n * @default\n */\n cursorColor: '',\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 initialize(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 setSelectionStart(index) {\n index = Math.max(index, 0);\n\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 setSelectionEnd(index) {\n index = Math.min(index, this.text.length);\n\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 _updateAndFire(property, index) {\n if (this[property] !== index) {\n this._fireSelectionChanged();\n\n this[property] = index;\n }\n\n this._updateTextarea();\n },\n\n /**\n * Fires the even of selection changed\n * @private\n */\n _fireSelectionChanged: function _fireSelectionChanged() {\n this.fire('selection:changed');\n this.canvas && this.canvas.fire('text:selection:changed', {\n target: this\n });\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 initDimensions() {\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 render(ctx) {\n this.clearContextTop();\n this.callSuper('render', ctx); // clear the cursorOffsetCache, so we ensure to calculate once per renderCursor\n // the correct position but not at every cursor animation.\n\n this.cursorOffsetCache = {};\n this.renderCursorOrSelection();\n },\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx Context to render on\n */\n _render: function _render(ctx) {\n this.callSuper('_render', ctx);\n },\n\n /**\n * Prepare and clean the contextTop\n */\n clearContextTop: function clearContextTop(skipRestore) {\n if (!this.isEditing || !this.canvas || !this.canvas.contextTop) {\n return;\n }\n\n var ctx = this.canvas.contextTop,\n 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\n this._clearTextArea(ctx);\n\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 renderCursorOrSelection() {\n if (!this.isEditing || !this.canvas || !this.canvas.contextTop) {\n return;\n }\n\n var boundaries = this._getCursorBoundaries(),\n ctx = this.canvas.contextTop;\n\n this.clearContextTop(true);\n\n if (this.selectionStart === this.selectionEnd) {\n this.renderCursor(boundaries, ctx);\n } else {\n this.renderSelection(boundaries, ctx);\n }\n\n ctx.restore();\n },\n _clearTextArea: function _clearTextArea(ctx) {\n // we add 4 pixel, to be sure to do not leave any pixel out\n var width = this.width + 4,\n 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 _getCursorBoundaries(position) {\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 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 _getCursorBoundariesOffsets(position) {\n if (this.cursorOffsetCache && 'top' in this.cursorOffsetCache) {\n return this.cursorOffsetCache;\n }\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\n for (var i = 0; i < lineIndex; i++) {\n topOffset += this.getHeightOfLine(i);\n }\n\n lineLeftOffset = this._getLineLeftOffset(lineIndex);\n var bound = this.__charBounds[lineIndex][charIndex];\n bound && (leftOffset = bound.left);\n\n if (this.charSpacing !== 0 && charIndex === this._textLines[lineIndex].length) {\n leftOffset -= this._getWidthOfCharSpacing();\n }\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 renderCursor(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 topOffset += (1 - this._fontSizeFraction) * this.getHeightOfLine(lineIndex) / this.lineHeight - charHeight * (1 - this._fontSizeFraction);\n\n if (this.inCompositionMode) {\n this.renderSelection(boundaries, ctx);\n }\n\n ctx.fillStyle = this.cursorColor || this.getValueOfPropertyAt(lineIndex, charIndex, 'fill');\n ctx.globalAlpha = this.__isMousedown ? 1 : this._currentCursorOpacity;\n ctx.fillRect(boundaries.left + boundaries.leftOffset - cursorWidth / 2, topOffset + boundaries.top + dy, cursorWidth, 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 renderSelection(boundaries, ctx) {\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,\n boxStart = 0,\n boxEnd = 0;\n\n if (i === startLine) {\n boxStart = this.__charBounds[startLine][startChar].left;\n }\n\n if (i >= startLine && i < endLine) {\n boxEnd = isJustify && !this.isEndOfWrapping(i) ? this.width : this.getLineWidth(i) || 5; // WTF is this 5?\n } else if (i === endLine) {\n if (endChar === 0) {\n boxEnd = this.__charBounds[endLine][endChar].left;\n } else {\n var charSpacing = this._getWidthOfCharSpacing();\n\n boxEnd = this.__charBounds[endLine][endChar - 1].left + this.__charBounds[endLine][endChar - 1].width - charSpacing;\n }\n }\n\n realLineHeight = lineHeight;\n\n if (this.lineHeight < 1 || i === endLine && this.lineHeight > 1) {\n lineHeight /= this.lineHeight;\n }\n\n if (this.inCompositionMode) {\n ctx.fillStyle = this.compositionColor || 'black';\n ctx.fillRect(boundaries.left + lineOffset + boxStart, boundaries.top + boundaries.topOffset + lineHeight, boxEnd - boxStart, 1);\n } else {\n ctx.fillStyle = this.selectionColor;\n ctx.fillRect(boundaries.left + lineOffset + boxStart, boundaries.top + boundaries.topOffset, boxEnd - boxStart, lineHeight);\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 * Unused from the library, is for the end user\n * @return {Number} Character font size\n */\n getCurrentCharFontSize: function getCurrentCharFontSize() {\n var cp = this._getCurrentCharIndex();\n\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 * Unused from the library, is for the end user\n * @return {String} Character color (fill)\n */\n getCurrentCharColor: function getCurrentCharColor() {\n var cp = this._getCurrentCharIndex();\n\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 _getCurrentCharIndex() {\n var cursorPosition = this.get2DCursorLocation(this.selectionStart, true),\n charIndex = cursorPosition.charIndex > 0 ? cursorPosition.charIndex - 1 : 0;\n return {\n l: cursorPosition.lineIndex,\n 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\n fabric.IText.fromObject = function (object, callback) {\n parseDecoration(object);\n\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\n fabric.Object._fromObject('IText', object, callback, 'text');\n };\n})();\n\n(function () {\n var clone = fabric.util.object.clone;\n fabric.util.object.extend(fabric.IText.prototype,\n /** @lends fabric.IText.prototype */\n {\n /**\n * Initializes all the interactive behavior of IText\n */\n initBehavior: function initBehavior() {\n this.initAddedHandler();\n this.initRemovedHandler();\n this.initCursorSelectionHandlers();\n this.initDoubleClickSimulation();\n this.mouseMoveHandler = this.mouseMoveHandler.bind(this);\n },\n onDeselect: function onDeselect() {\n this.isEditing && this.exitEditing();\n this.selected = false;\n },\n\n /**\n * Initializes \"added\" event handler\n */\n initAddedHandler: function initAddedHandler() {\n var _this = this;\n\n this.on('added', function () {\n var canvas = _this.canvas;\n\n if (canvas) {\n if (!canvas._hasITextHandlers) {\n canvas._hasITextHandlers = true;\n\n _this._initCanvasHandlers(canvas);\n }\n\n canvas._iTextInstances = canvas._iTextInstances || [];\n\n canvas._iTextInstances.push(_this);\n }\n });\n },\n initRemovedHandler: function initRemovedHandler() {\n var _this = this;\n\n this.on('removed', function () {\n var canvas = _this.canvas;\n\n if (canvas) {\n canvas._iTextInstances = canvas._iTextInstances || [];\n fabric.util.removeFromArray(canvas._iTextInstances, _this);\n\n if (canvas._iTextInstances.length === 0) {\n canvas._hasITextHandlers = false;\n\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 _initCanvasHandlers(canvas) {\n canvas._mouseUpITextHandler = function () {\n if (canvas._iTextInstances) {\n canvas._iTextInstances.forEach(function (obj) {\n obj.__isMousedown = false;\n });\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 _removeCanvasHandlers(canvas) {\n canvas.off('mouse:up', canvas._mouseUpITextHandler);\n },\n\n /**\n * @private\n */\n _tick: function _tick() {\n this._currentTickState = this._animateCursor(this, 1, this.cursorDuration, '_onTickComplete');\n },\n\n /**\n * @private\n */\n _animateCursor: function _animateCursor(obj, targetOpacity, duration, completeMethod) {\n var tickState;\n tickState = {\n isAborted: false,\n abort: function abort() {\n this.isAborted = true;\n }\n };\n obj.animate('_currentCursorOpacity', targetOpacity, {\n duration: duration,\n onComplete: function onComplete() {\n if (!tickState.isAborted) {\n obj[completeMethod]();\n }\n },\n onChange: function onChange() {\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 abort() {\n return tickState.isAborted;\n }\n });\n return tickState;\n },\n\n /**\n * @private\n */\n _onTickComplete: function _onTickComplete() {\n var _this = this;\n\n if (this._cursorTimeout1) {\n clearTimeout(this._cursorTimeout1);\n }\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 initDelayedCursor(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 abortCursorAnimation() {\n var shouldClear = this._currentTickState || this._currentTickCompleteState,\n canvas = this.canvas;\n this._currentTickState && this._currentTickState.abort();\n this._currentTickCompleteState && this._currentTickCompleteState.abort();\n clearTimeout(this._cursorTimeout1);\n clearTimeout(this._cursorTimeout2);\n this._currentCursorOpacity = 0; // to clear just itext area we need to transform the context\n // it may not be worth it\n\n if (shouldClear && canvas) {\n canvas.clearContext(canvas.contextTop || canvas.contextContainer);\n }\n },\n\n /**\n * Selects entire text\n * @return {fabric.IText} thisArg\n * @chainable\n */\n selectAll: function selectAll() {\n this.selectionStart = 0;\n this.selectionEnd = this._text.length;\n\n this._fireSelectionChanged();\n\n this._updateTextarea();\n\n return this;\n },\n\n /**\n * Returns selected text\n * @return {String}\n */\n getSelectedText: function getSelectedText() {\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 findWordBoundaryLeft(startFrom) {\n var offset = 0,\n index = startFrom - 1; // remove space before cursor first\n\n if (this._reSpace.test(this._text[index])) {\n while (this._reSpace.test(this._text[index])) {\n offset++;\n index--;\n }\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 findWordBoundaryRight(startFrom) {\n var offset = 0,\n index = startFrom; // remove space after cursor first\n\n if (this._reSpace.test(this._text[index])) {\n while (this._reSpace.test(this._text[index])) {\n offset++;\n index++;\n }\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 findLineBoundaryLeft(startFrom) {\n var offset = 0,\n 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 findLineBoundaryRight(startFrom) {\n var offset = 0,\n 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 searchWordBoundary(selectionStart, direction) {\n var text = this._text,\n index = this._reSpace.test(text[selectionStart]) ? selectionStart - 1 : selectionStart,\n _char = text[index],\n // wrong\n reNonWord = fabric.reNonWord;\n\n while (!reNonWord.test(_char) && index > 0 && index < text.length) {\n index += direction;\n _char = text[index];\n }\n\n if (reNonWord.test(_char)) {\n index += direction === 1 ? 0 : 1;\n }\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 selectWord(selectionStart) {\n selectionStart = selectionStart || this.selectionStart;\n var newSelectionStart = this.searchWordBoundary(selectionStart, -1),\n\n /* search backwards */\n newSelectionEnd = this.searchWordBoundary(selectionStart, 1);\n /* search forward */\n\n this.selectionStart = newSelectionStart;\n this.selectionEnd = newSelectionEnd;\n\n this._fireSelectionChanged();\n\n this._updateTextarea();\n\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 selectLine(selectionStart) {\n selectionStart = selectionStart || this.selectionStart;\n var newSelectionStart = this.findLineBoundaryLeft(selectionStart),\n newSelectionEnd = this.findLineBoundaryRight(selectionStart);\n this.selectionStart = newSelectionStart;\n this.selectionEnd = newSelectionEnd;\n\n this._fireSelectionChanged();\n\n this._updateTextarea();\n\n return this;\n },\n\n /**\n * Enters editing state\n * @return {fabric.IText} thisArg\n * @chainable\n */\n enterEditing: function enterEditing(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 this.initHiddenTextarea(e);\n this.hiddenTextarea.focus();\n this.hiddenTextarea.value = this.text;\n\n this._updateTextarea();\n\n this._saveEditingProps();\n\n this._setEditingProps();\n\n this._textBeforeEdit = this.text;\n\n this._tick();\n\n this.fire('editing:entered');\n\n this._fireSelectionChanged();\n\n if (!this.canvas) {\n return this;\n }\n\n this.canvas.fire('text:editing:entered', {\n target: this\n });\n this.initMouseMoveHandler();\n this.canvas.requestRenderAll();\n return this;\n },\n exitEditingOnOthers: function exitEditingOnOthers(canvas) {\n if (canvas._iTextInstances) {\n canvas._iTextInstances.forEach(function (obj) {\n obj.selected = false;\n\n if (obj.isEditing) {\n obj.exitEditing();\n }\n });\n }\n },\n\n /**\n * Initializes \"mousemove\" event handler\n */\n initMouseMoveHandler: function initMouseMoveHandler() {\n this.canvas.on('mouse:move', this.mouseMoveHandler);\n },\n\n /**\n * @private\n */\n mouseMoveHandler: function mouseMoveHandler(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\n if ((newSelectionStart !== this.__selectionStartOnMouseDown || currentStart === currentEnd) && (currentStart === newSelectionStart || currentEnd === newSelectionStart)) {\n return;\n }\n\n if (newSelectionStart > this.__selectionStartOnMouseDown) {\n this.selectionStart = this.__selectionStartOnMouseDown;\n this.selectionEnd = newSelectionStart;\n } else {\n this.selectionStart = newSelectionStart;\n this.selectionEnd = this.__selectionStartOnMouseDown;\n }\n\n if (this.selectionStart !== currentStart || this.selectionEnd !== currentEnd) {\n this.restartCursorIfNeeded();\n\n this._fireSelectionChanged();\n\n this._updateTextarea();\n\n this.renderCursorOrSelection();\n }\n },\n\n /**\n * @private\n */\n _setEditingProps: function _setEditingProps() {\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 fromStringToGraphemeSelection(start, end, text) {\n var smallerTextStart = text.slice(0, start),\n graphemeStart = fabric.util.string.graphemeSplit(smallerTextStart).length;\n\n if (start === end) {\n return {\n selectionStart: graphemeStart,\n selectionEnd: graphemeStart\n };\n }\n\n var smallerTextEnd = text.slice(start, end),\n graphemeEnd = fabric.util.string.graphemeSplit(smallerTextEnd).length;\n return {\n selectionStart: graphemeStart,\n selectionEnd: graphemeStart + graphemeEnd\n };\n },\n\n /**\n * convert from fabric to textarea values\n */\n fromGraphemeToStringSelection: function fromGraphemeToStringSelection(start, end, _text) {\n var smallerTextStart = _text.slice(0, start),\n graphemeStart = smallerTextStart.join('').length;\n\n if (start === end) {\n return {\n selectionStart: graphemeStart,\n selectionEnd: graphemeStart\n };\n }\n\n var smallerTextEnd = _text.slice(start, end),\n graphemeEnd = smallerTextEnd.join('').length;\n\n return {\n selectionStart: graphemeStart,\n selectionEnd: graphemeStart + graphemeEnd\n };\n },\n\n /**\n * @private\n */\n _updateTextarea: function _updateTextarea() {\n this.cursorOffsetCache = {};\n\n if (!this.hiddenTextarea) {\n return;\n }\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\n this.updateTextareaPosition();\n },\n\n /**\n * @private\n */\n updateFromTextArea: function updateFromTextArea() {\n if (!this.hiddenTextarea) {\n return;\n }\n\n this.cursorOffsetCache = {};\n this.text = this.hiddenTextarea.value;\n\n if (this._shouldClearDimensionCache()) {\n this.initDimensions();\n this.setCoords();\n }\n\n var newSelection = this.fromStringToGraphemeSelection(this.hiddenTextarea.selectionStart, this.hiddenTextarea.selectionEnd, this.hiddenTextarea.value);\n this.selectionEnd = this.selectionStart = newSelection.selectionEnd;\n\n if (!this.inCompositionMode) {\n this.selectionStart = newSelection.selectionStart;\n }\n\n this.updateTextareaPosition();\n },\n\n /**\n * @private\n */\n updateTextareaPosition: function updateTextareaPosition() {\n if (this.selectionStart === this.selectionEnd) {\n var style = this._calcTextareaPosition();\n\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 _calcTextareaPosition() {\n if (!this.canvas) {\n return {\n x: 1,\n y: 1\n };\n }\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 retinaScaling = this.canvas.getRetinaScaling(),\n upperCanvas = this.canvas.upperCanvasEl,\n upperCanvasWidth = upperCanvas.width / retinaScaling,\n upperCanvasHeight = upperCanvas.height / retinaScaling,\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\n if (p.x < 0) {\n p.x = 0;\n }\n\n if (p.x > maxWidth) {\n p.x = maxWidth;\n }\n\n if (p.y < 0) {\n p.y = 0;\n }\n\n if (p.y > maxHeight) {\n p.y = maxHeight;\n } // add canvas offset on document\n\n\n p.x += this.canvas._offset.left;\n p.y += this.canvas._offset.top;\n return {\n left: p.x + 'px',\n top: p.y + 'px',\n fontSize: charHeight + 'px',\n charHeight: charHeight\n };\n },\n\n /**\n * @private\n */\n _saveEditingProps: function _saveEditingProps() {\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 _restoreEditingProps() {\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 exitEditing() {\n var isTextChanged = this._textBeforeEdit !== this.text;\n var hiddenTextarea = this.hiddenTextarea;\n this.selected = false;\n this.isEditing = false;\n this.selectionEnd = this.selectionStart;\n\n if (hiddenTextarea) {\n hiddenTextarea.blur && hiddenTextarea.blur();\n hiddenTextarea.parentNode && hiddenTextarea.parentNode.removeChild(hiddenTextarea);\n }\n\n this.hiddenTextarea = null;\n this.abortCursorAnimation();\n\n this._restoreEditingProps();\n\n this._currentCursorOpacity = 0;\n\n if (this._shouldClearDimensionCache()) {\n this.initDimensions();\n this.setCoords();\n }\n\n this.fire('editing:exited');\n isTextChanged && this.fire('modified');\n\n if (this.canvas) {\n this.canvas.off('mouse:move', this.mouseMoveHandler);\n this.canvas.fire('text:editing:exited', {\n target: this\n });\n isTextChanged && this.canvas.fire('object:modified', {\n target: this\n });\n }\n\n return this;\n },\n\n /**\n * @private\n */\n _removeExtraneousStyles: function _removeExtraneousStyles() {\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 removeStyleFromTo(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,\n styleObj;\n\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 } // step2 move the trailing of lineEnd to lineStart if needed\n\n\n if (this.styles[lineEnd]) {\n for (i = charEnd; i < this._unwrappedTextLines[lineEnd].length; i++) {\n styleObj = this.styles[lineEnd][i];\n\n if (styleObj) {\n this.styles[lineStart] || (this.styles[lineStart] = {});\n this.styles[lineStart][charStart + i - charEnd] = styleObj;\n }\n }\n } // step3 detects lines will be completely removed.\n\n\n for (i = lineStart + 1; i <= lineEnd; i++) {\n delete this.styles[i];\n } // step4 shift remaining lines.\n\n\n this.shiftLineStyles(lineEnd, lineStart - lineEnd);\n } else {\n // remove and shift left on the same line\n if (this.styles[lineStart]) {\n styleObj = this.styles[lineStart];\n\n var diff = charEnd - charStart,\n numericChar,\n _char;\n\n for (i = charStart; i < charEnd; i++) {\n delete styleObj[i];\n }\n\n for (_char in this.styles[lineStart]) {\n numericChar = parseInt(_char, 10);\n\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 shiftLineStyles(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\n for (var line in this.styles) {\n var numericLine = parseInt(line, 10);\n\n if (numericLine > lineIndex) {\n this.styles[numericLine + offset] = clonedStyles[numericLine];\n\n if (!clonedStyles[numericLine - offset]) {\n delete this.styles[numericLine];\n }\n }\n }\n },\n restartCursorIfNeeded: function restartCursorIfNeeded() {\n if (!this._currentTickState || this._currentTickState.isAborted || !this._currentTickCompleteState || this._currentTickCompleteState.isAborted) {\n this.initDelayedCursor();\n }\n },\n\n /**\n * Handle insertion of more consecutive style lines for when one or more\n * newlines gets added to the text. Since current style needs to be shifted\n * first we shift the current style of the number lines needed, then we add\n * new lines from the last to the first.\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 insertNewlineStyleObject(lineIndex, charIndex, qty, copiedStyle) {\n var currentCharStyle,\n newLineStyles = {},\n somethingAdded = false,\n isEndOfLine = this._unwrappedTextLines[lineIndex].length === charIndex;\n qty || (qty = 1);\n this.shiftLineStyles(lineIndex, qty);\n\n if (this.styles[lineIndex]) {\n currentCharStyle = this.styles[lineIndex][charIndex === 0 ? charIndex : charIndex - 1];\n } // we clone styles of all chars\n // after cursor onto the current line\n\n\n for (var index in this.styles[lineIndex]) {\n var numIndex = parseInt(index, 10);\n\n if (numIndex >= charIndex) {\n somethingAdded = true;\n newLineStyles[numIndex - charIndex] = this.styles[lineIndex][index]; // remove lines from the previous line since they're on a new line now\n\n if (!(isEndOfLine && charIndex === 0)) {\n delete this.styles[lineIndex][index];\n }\n }\n }\n\n var styleCarriedOver = false;\n\n if (somethingAdded && !isEndOfLine) {\n // if is end of line, the extra style we copied\n // is probably not something we want\n this.styles[lineIndex + qty] = newLineStyles;\n styleCarriedOver = true;\n }\n\n if (styleCarriedOver) {\n // skip the last line of since we already prepared it.\n qty--;\n } // for the all the lines or all the other lines\n // we clone current char style onto the next (otherwise empty) line\n\n\n while (qty > 0) {\n if (copiedStyle && copiedStyle[qty - 1]) {\n this.styles[lineIndex + qty] = {\n 0: clone(copiedStyle[qty - 1])\n };\n } else if (currentCharStyle) {\n this.styles[lineIndex + qty] = {\n 0: clone(currentCharStyle)\n };\n } else {\n delete this.styles[lineIndex + qty];\n }\n\n 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 insertCharStyleObject(lineIndex, charIndex, quantity, copiedStyle) {\n if (!this.styles) {\n this.styles = {};\n }\n\n var currentLineStyles = this.styles[lineIndex],\n currentLineStylesCloned = currentLineStyles ? clone(currentLineStyles) : {};\n quantity || (quantity = 1); // 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\n for (var index in currentLineStylesCloned) {\n var numericIndex = parseInt(index, 10);\n\n if (numericIndex >= charIndex) {\n currentLineStyles[numericIndex + quantity] = currentLineStylesCloned[numericIndex]; // only delete the style if there was nothing moved there\n\n if (!currentLineStylesCloned[numericIndex - quantity]) {\n delete currentLineStyles[numericIndex];\n }\n }\n }\n\n this._forceClearCache = true;\n\n if (copiedStyle) {\n while (quantity--) {\n if (!Object.keys(copiedStyle[quantity]).length) {\n continue;\n }\n\n if (!this.styles[lineIndex]) {\n this.styles[lineIndex] = {};\n }\n\n this.styles[lineIndex][charIndex + quantity] = clone(copiedStyle[quantity]);\n }\n\n return;\n }\n\n if (!currentLineStyles) {\n return;\n }\n\n var newStyle = currentLineStyles[charIndex ? charIndex - 1 : 1];\n\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 insertNewStyleBlock(insertedText, start, copiedStyle) {\n var cursorLoc = this.get2DCursorLocation(start, true),\n addedLines = [0],\n linesLength = 0; // get an array of how many char per lines are being added.\n\n for (var i = 0; i < insertedText.length; i++) {\n if (insertedText[i] === '\\n') {\n linesLength++;\n addedLines[linesLength] = 0;\n } else {\n addedLines[linesLength]++;\n }\n } // for the first line copy the style from the current char position.\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\n linesLength && this.insertNewlineStyleObject(cursorLoc.lineIndex, cursorLoc.charIndex + addedLines[0], linesLength);\n\n for (var i = 1; i < linesLength; i++) {\n if (addedLines[i] > 0) {\n this.insertCharStyleObject(cursorLoc.lineIndex + i, 0, addedLines[i], copiedStyle);\n } else if (copiedStyle) {\n this.styles[cursorLoc.lineIndex + i][0] = copiedStyle[0];\n }\n\n copiedStyle = copiedStyle && copiedStyle.slice(addedLines[i] + 1);\n } // we use i outside the loop to get it like linesLength\n\n\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 setSelectionStartEndWithShift(start, end, newSelection) {\n if (newSelection <= start) {\n if (end === start) {\n this._selectionDirection = 'left';\n } else if (this._selectionDirection === 'right') {\n this._selectionDirection = 'left';\n this.selectionEnd = start;\n }\n\n this.selectionStart = newSelection;\n } else if (newSelection > start && newSelection < end) {\n if (this._selectionDirection === 'right') {\n this.selectionEnd = newSelection;\n } else {\n this.selectionStart = newSelection;\n }\n } else {\n // newSelection is > selection start and end\n if (end === start) {\n this._selectionDirection = 'right';\n } else if (this._selectionDirection === 'left') {\n this._selectionDirection = 'right';\n this.selectionStart = end;\n }\n\n this.selectionEnd = newSelection;\n }\n },\n setSelectionInBoundaries: function setSelectionInBoundaries() {\n var length = this.text.length;\n\n if (this.selectionStart > length) {\n this.selectionStart = length;\n } else if (this.selectionStart < 0) {\n this.selectionStart = 0;\n }\n\n if (this.selectionEnd > length) {\n this.selectionEnd = length;\n } else if (this.selectionEnd < 0) {\n this.selectionEnd = 0;\n }\n }\n });\n})();\n\nfabric.util.object.extend(fabric.IText.prototype,\n/** @lends fabric.IText.prototype */\n{\n /**\n * Initializes \"dbclick\" event handler\n */\n initDoubleClickSimulation: function initDoubleClickSimulation() {\n // for double click\n this.__lastClickTime = +new Date(); // for triple click\n\n this.__lastLastClickTime = +new Date();\n this.__lastPointer = {};\n this.on('mousedown', this.onMouseDown);\n },\n\n /**\n * Default event handler to simulate triple click\n * @private\n */\n onMouseDown: function onMouseDown(options) {\n if (!this.canvas) {\n return;\n }\n\n this.__newClickTime = +new Date();\n var newPointer = options.pointer;\n\n if (this.isTripleClick(newPointer)) {\n this.fire('tripleclick', options);\n\n this._stopEvent(options.e);\n }\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 isTripleClick: function isTripleClick(newPointer) {\n return this.__newClickTime - this.__lastClickTime < 500 && this.__lastClickTime - this.__lastLastClickTime < 500 && this.__lastPointer.x === newPointer.x && this.__lastPointer.y === newPointer.y;\n },\n\n /**\n * @private\n */\n _stopEvent: function _stopEvent(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 initCursorSelectionHandlers() {\n this.initMousedownHandler();\n this.initMouseupHandler();\n this.initClicks();\n },\n\n /**\n * Default handler for double click, select a word\n */\n doubleClickHandler: function doubleClickHandler(options) {\n if (!this.isEditing) {\n return;\n }\n\n this.selectWord(this.getSelectionStartFromPointer(options.e));\n },\n\n /**\n * Default handler for triple click, select a line\n */\n tripleClickHandler: function tripleClickHandler(options) {\n if (!this.isEditing) {\n return;\n }\n\n this.selectLine(this.getSelectionStartFromPointer(options.e));\n },\n\n /**\n * Initializes double and triple click event handlers\n */\n initClicks: function initClicks() {\n this.on('mousedblclick', this.doubleClickHandler);\n this.on('tripleclick', this.tripleClickHandler);\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 * initializing a mousedDown on a text area will cancel fabricjs knowledge of\n * current compositionMode. It will be set to false.\n */\n _mouseDownHandler: function _mouseDownHandler(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.inCompositionMode = false;\n this.setCursorByClick(options.e);\n }\n\n if (this.isEditing) {\n this.__selectionStartOnMouseDown = this.selectionStart;\n\n if (this.selectionStart === this.selectionEnd) {\n this.abortCursorAnimation();\n }\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 _mouseDownHandlerBefore(options) {\n if (!this.canvas || !this.editable || options.e.button && options.e.button !== 1) {\n return;\n } // we want to avoid that an object that was selected and then becomes unselectable,\n // may trigger editing mode in some way.\n\n\n this.selected = this === this.canvas._activeObject;\n },\n\n /**\n * Initializes \"mousedown\" event handler\n */\n initMousedownHandler: function initMousedownHandler() {\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 initMouseupHandler() {\n this.on('mouseup', this.mouseUpHandler);\n },\n\n /**\n * standard hander for mouse up, overridable\n * @private\n */\n mouseUpHandler: function mouseUpHandler(options) {\n this.__isMousedown = false;\n\n if (!this.editable || this.group || options.transform && options.transform.actionPerformed || options.e.button && options.e.button !== 1) {\n return;\n }\n\n if (this.canvas) {\n var currentActive = this.canvas._activeObject;\n\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\n if (this.selectionStart === this.selectionEnd) {\n this.initDelayedCursor(true);\n } else {\n this.renderCursorOrSelection();\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 setCursorByClick(e) {\n var newSelection = this.getSelectionStartFromPointer(e),\n start = this.selectionStart,\n end = this.selectionEnd;\n\n if (e.shiftKey) {\n this.setSelectionStartEndWithShift(start, end, newSelection);\n } else {\n this.selectionStart = newSelection;\n this.selectionEnd = newSelection;\n }\n\n if (this.isEditing) {\n this._fireSelectionChanged();\n\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 getSelectionStartFromPointer(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\n if (i > 0) {\n charIndex += this._textLines[i - 1].length + this.missingNewlineOffset(i - 1);\n }\n } else {\n break;\n }\n }\n\n lineLeftOffset = this._getLineLeftOffset(lineIndex);\n width = lineLeftOffset * this.scaleX;\n line = this._textLines[lineIndex];\n\n for (var j = 0, jlen = line.length; j < jlen; j++) {\n prevWidth = width; // i removed something about flipX here, check.\n\n width += this.__charBounds[lineIndex][j].kernedWidth * this.scaleX;\n\n if (width <= mouseOffset.x) {\n charIndex++;\n } else {\n break;\n }\n }\n\n return this._getNewSelectionStartFromOffset(mouseOffset, prevWidth, width, charIndex, jlen);\n },\n\n /**\n * @private\n */\n _getNewSelectionStartFromOffset: function _getNewSelectionStartFromOffset(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 || distanceBtwNextCharAndCursor < 0 ? 0 : 1,\n newSelectionStart = index + offset; // if object is horizontally flipped, mirror cursor location from the end\n\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});\nfabric.util.object.extend(fabric.IText.prototype,\n/** @lends fabric.IText.prototype */\n{\n /**\n * Initializes hidden textarea (needed to bring up keyboard in iOS)\n */\n initHiddenTextarea: function initHiddenTextarea() {\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\n var style = this._calcTextareaPosition(); // line-height: 1px; was removed from the style to fix this:\n // https://bugs.chromium.org/p/chromium/issues/detail?id=870966\n\n\n this.hiddenTextarea.style.cssText = 'position: absolute; top: ' + style.top + '; left: ' + style.left + '; z-index: -999; opacity: 0; width: 1px; height: 1px; font-size: 1px;' + ' paddingーtop: ' + style.fontSize + ';';\n fabric.document.body.appendChild(this.hiddenTextarea);\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 onClick: function onClick() {\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 keydown event\n * only used for arrows and combination of modifier keys.\n * @param {Event} e Event object\n */\n onKeyDown: function onKeyDown(e) {\n if (!this.isEditing) {\n return;\n }\n\n if (e.keyCode in this.keysMap) {\n this[this.keysMap[e.keyCode]](e);\n } else if (e.keyCode in this.ctrlKeysMapDown && (e.ctrlKey || e.metaKey)) {\n this[this.ctrlKeysMapDown[e.keyCode]](e);\n } else {\n return;\n }\n\n e.stopImmediatePropagation();\n e.preventDefault();\n\n if (e.keyCode >= 33 && e.keyCode <= 40) {\n // if i press an arrow key just update selection\n this.inCompositionMode = false;\n this.clearContextTop();\n this.renderCursorOrSelection();\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 onKeyUp(e) {\n if (!this.isEditing || this._copyDone || this.inCompositionMode) {\n this._copyDone = false;\n return;\n }\n\n if (e.keyCode in this.ctrlKeysMapUp && (e.ctrlKey || e.metaKey)) {\n this[this.ctrlKeysMapUp[e.keyCode]](e);\n } else {\n return;\n }\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 onInput(e) {\n var fromPaste = this.fromPaste;\n this.fromPaste = false;\n e && e.stopPropagation();\n\n if (!this.isEditing) {\n return;\n } // decisions about style changes.\n\n\n var nextText = this._splitTextIntoLines(this.hiddenTextarea.value).graphemeText,\n charCount = this._text.length,\n nextCharCount = nextText.length,\n removedText,\n insertedText,\n charDiff = nextCharCount - charCount,\n selectionStart = this.selectionStart,\n selectionEnd = this.selectionEnd,\n selection = selectionStart !== selectionEnd,\n copiedStyle,\n removeFrom,\n removeTo;\n\n if (this.hiddenTextarea.value === '') {\n this.styles = {};\n this.updateFromTextArea();\n this.fire('changed');\n\n if (this.canvas) {\n this.canvas.fire('text:changed', {\n target: this\n });\n this.canvas.requestRenderAll();\n }\n\n return;\n }\n\n var textareaSelection = this.fromStringToGraphemeSelection(this.hiddenTextarea.selectionStart, this.hiddenTextarea.selectionEnd, this.hiddenTextarea.value);\n var backDelete = selectionStart > textareaSelection.selectionStart;\n\n if (selection) {\n removedText = this._text.slice(selectionStart, selectionEnd);\n charDiff += selectionEnd - selectionStart;\n } else if (nextCharCount < charCount) {\n if (backDelete) {\n removedText = this._text.slice(selectionEnd + charDiff, selectionEnd);\n } else {\n removedText = this._text.slice(selectionStart, selectionStart - charDiff);\n }\n }\n\n insertedText = nextText.slice(textareaSelection.selectionEnd - charDiff, textareaSelection.selectionEnd);\n\n if (removedText && removedText.length) {\n if (insertedText.length) {\n // let's copy some style before deleting.\n // we want to copy the style before the cursor OR the style at the cursor if selection\n // is bigger than 0.\n copiedStyle = this.getSelectionStyles(selectionStart, selectionStart + 1, false); // now duplicate the style one for each inserted text.\n\n copiedStyle = insertedText.map(function () {\n // this return an array of references, but that is fine since we are\n // copying the style later.\n return copiedStyle[0];\n });\n }\n\n if (selection) {\n removeFrom = selectionStart;\n removeTo = selectionEnd;\n } else if (backDelete) {\n // detect differencies between forwardDelete and backDelete\n removeFrom = selectionEnd - removedText.length;\n removeTo = selectionEnd;\n } else {\n removeFrom = selectionEnd;\n removeTo = selectionEnd + removedText.length;\n }\n\n this.removeStyleFromTo(removeFrom, removeTo);\n }\n\n if (insertedText.length) {\n if (fromPaste && insertedText.join('') === fabric.copiedText && !fabric.disableStyleCopyPaste) {\n copiedStyle = fabric.copiedTextStyle;\n }\n\n this.insertNewStyleBlock(insertedText, selectionStart, copiedStyle);\n }\n\n this.updateFromTextArea();\n this.fire('changed');\n\n if (this.canvas) {\n this.canvas.fire('text:changed', {\n target: this\n });\n this.canvas.requestRenderAll();\n }\n },\n\n /**\n * Composition start\n */\n onCompositionStart: function onCompositionStart() {\n this.inCompositionMode = true;\n },\n\n /**\n * Composition end\n */\n onCompositionEnd: function onCompositionEnd() {\n this.inCompositionMode = false;\n },\n // /**\n // * Composition update\n // */\n onCompositionUpdate: function onCompositionUpdate(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 copy() {\n if (this.selectionStart === this.selectionEnd) {\n //do not cut-copy if no selection\n return;\n }\n\n fabric.copiedText = this.getSelectedText();\n\n if (!fabric.disableStyleCopyPaste) {\n fabric.copiedTextStyle = this.getSelectionStyles(this.selectionStart, this.selectionEnd, true);\n } else {\n fabric.copiedTextStyle = null;\n }\n\n this._copyDone = true;\n },\n\n /**\n * Pastes text\n * @param {Event} e Event object\n */\n paste: function paste() {\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 _getClipboardData(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 _getWidthBeforeCursor(lineIndex, charIndex) {\n var widthBeforeCursor = this._getLineLeftOffset(lineIndex),\n bound;\n\n if (charIndex > 0) {\n bound = this.__charBounds[lineIndex][charIndex - 1];\n widthBeforeCursor += bound.left + bound.width;\n }\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 getDownCursorOffset(e, isRight) {\n var selectionProp = this._getSelectionForOffset(e, isRight),\n cursorLocation = this.get2DCursorLocation(selectionProp),\n lineIndex = cursorLocation.lineIndex; // if on last line, down cursor goes to end of line\n\n\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\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\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 _getSelectionForOffset(e, isRight) {\n if (e.shiftKey && this.selectionStart !== this.selectionEnd && isRight) {\n return this.selectionEnd;\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 getUpCursorOffset(e, isRight) {\n var selectionProp = this._getSelectionForOffset(e, isRight),\n cursorLocation = this.get2DCursorLocation(selectionProp),\n lineIndex = cursorLocation.lineIndex;\n\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\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); // return a negative offset\n\n\n return -this._textLines[lineIndex - 1].length + indexOnOtherLine - textBeforeCursor.length + (1 - missingNewlineOffset);\n },\n\n /**\n * for a given width it founds the matching character.\n * @private\n */\n _getIndexOnLine: function _getIndexOnLine(lineIndex, width) {\n var line = this._textLines[lineIndex],\n lineLeftOffset = this._getLineLeftOffset(lineIndex),\n widthOfCharsOnLine = lineLeftOffset,\n indexOnLine = 0,\n charWidth,\n foundMatch;\n\n for (var j = 0, jlen = line.length; j < jlen; j++) {\n charWidth = this.__charBounds[lineIndex][j].width;\n widthOfCharsOnLine += charWidth;\n\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 indexOnLine = offsetFromRightEdge < offsetFromLeftEdge ? j : j - 1;\n break;\n }\n } // reached end\n\n\n if (!foundMatch) {\n indexOnLine = line.length - 1;\n }\n\n return indexOnLine;\n },\n\n /**\n * Moves cursor down\n * @param {Event} e Event object\n */\n moveCursorDown: function moveCursorDown(e) {\n if (this.selectionStart >= this._text.length && this.selectionEnd >= this._text.length) {\n return;\n }\n\n this._moveCursorUpOrDown('Down', e);\n },\n\n /**\n * Moves cursor up\n * @param {Event} e Event object\n */\n moveCursorUp: function moveCursorUp(e) {\n if (this.selectionStart === 0 && this.selectionEnd === 0) {\n return;\n }\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 _moveCursorUpOrDown(direction, e) {\n // getUpCursorOffset\n // getDownCursorOffset\n var action = 'get' + direction + 'CursorOffset',\n offset = this[action](e, this._selectionDirection === 'right');\n\n if (e.shiftKey) {\n this.moveCursorWithShift(offset);\n } else {\n this.moveCursorWithoutShift(offset);\n }\n\n if (offset !== 0) {\n this.setSelectionInBoundaries();\n this.abortCursorAnimation();\n this._currentCursorOpacity = 1;\n this.initDelayedCursor();\n\n this._fireSelectionChanged();\n\n this._updateTextarea();\n }\n },\n\n /**\n * Moves cursor with shift\n * @param {Number} offset\n */\n moveCursorWithShift: function moveCursorWithShift(offset) {\n var newSelection = this._selectionDirection === 'left' ? this.selectionStart + offset : 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 moveCursorWithoutShift(offset) {\n if (offset < 0) {\n this.selectionStart += offset;\n this.selectionEnd = this.selectionStart;\n } else {\n this.selectionEnd += offset;\n this.selectionStart = this.selectionEnd;\n }\n\n return offset !== 0;\n },\n\n /**\n * Moves cursor left\n * @param {Event} e Event object\n */\n moveCursorLeft: function moveCursorLeft(e) {\n if (this.selectionStart === 0 && this.selectionEnd === 0) {\n return;\n }\n\n this._moveCursorLeftOrRight('Left', e);\n },\n\n /**\n * @private\n * @return {Boolean} true if a change happened\n */\n _move: function _move(e, prop, direction) {\n var newValue;\n\n if (e.altKey) {\n newValue = this['findWordBoundary' + direction](this[prop]);\n } else if (e.metaKey || e.keyCode === 35 || e.keyCode === 36) {\n newValue = this['findLineBoundary' + direction](this[prop]);\n } else {\n this[prop] += direction === 'Left' ? -1 : 1;\n return true;\n }\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 _moveLeft(e, prop) {\n return this._move(e, prop, 'Left');\n },\n\n /**\n * @private\n */\n _moveRight: function _moveRight(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 moveCursorLeftWithoutShift(e) {\n var change = true;\n this._selectionDirection = 'left'; // only move cursor when there is no selection,\n // otherwise we discard it, and leave cursor on same place\n\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 moveCursorLeftWithShift(e) {\n if (this._selectionDirection === 'right' && this.selectionStart !== this.selectionEnd) {\n return this._moveLeft(e, 'selectionEnd');\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 moveCursorRight(e) {\n if (this.selectionStart >= this._text.length && this.selectionEnd >= this._text.length) {\n return;\n }\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 _moveCursorLeftOrRight(direction, e) {\n var actionName = 'moveCursor' + direction + 'With';\n this._currentCursorOpacity = 1;\n\n if (e.shiftKey) {\n actionName += 'Shift';\n } else {\n actionName += 'outShift';\n }\n\n if (this[actionName](e)) {\n this.abortCursorAnimation();\n this.initDelayedCursor();\n\n this._fireSelectionChanged();\n\n this._updateTextarea();\n }\n },\n\n /**\n * Moves cursor right while keeping selection\n * @param {Event} e\n */\n moveCursorRightWithShift: function moveCursorRightWithShift(e) {\n if (this._selectionDirection === 'left' && this.selectionStart !== this.selectionEnd) {\n return this._moveRight(e, 'selectionStart');\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 moveCursorRightWithoutShift(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 } else {\n this.selectionStart = this.selectionEnd;\n }\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 removeChars(start, end) {\n if (typeof end === 'undefined') {\n end = start + 1;\n }\n\n this.removeStyleFromTo(start, end);\n\n this._text.splice(start, end - start);\n\n this.text = this._text.join('');\n this.set('dirty', true);\n\n if (this._shouldClearDimensionCache()) {\n this.initDimensions();\n this.setCoords();\n }\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 insertChars(text, style, start, end) {\n if (typeof end === 'undefined') {\n end = start;\n }\n\n if (end > start) {\n this.removeStyleFromTo(start, end);\n }\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\n if (this._shouldClearDimensionCache()) {\n this.initDimensions();\n this.setCoords();\n }\n\n this._removeExtraneousStyles();\n }\n});\n/* _TO_SVG_START_ */\n\n(function () {\n var toFixed = fabric.util.toFixed,\n multipleSpacesRegex = / +/g;\n fabric.util.object.extend(fabric.Text.prototype,\n /** @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 _toSVG() {\n var offsets = this._getSVGLeftTopOffsets(),\n textAndBg = this._getSVGTextAndBg(offsets.textTop, offsets.textLeft);\n\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 toSVG(reviver) {\n return this._createBaseSVGMarkup(this._toSVG(), {\n reviver: reviver,\n noStyle: true,\n withShadow: true\n });\n },\n\n /**\n * @private\n */\n _getSVGLeftTopOffsets: function _getSVGLeftTopOffsets() {\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 _wrapSVGTextAndBg(textAndBg) {\n var noShadow = true,\n textDecoration = this.getSvgTextDecoration(this);\n return [textAndBg.textBgRects.join(''), '\\t\\t', textAndBg.textSpans.join(''), '\\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 _getSVGTextAndBg(textTopOffset, textLeftOffset) {\n var textSpans = [],\n textBgRects = [],\n height = textTopOffset,\n lineOffset; // bounding-box background\n\n this._setSVGBg(textBgRects); // text and text-background\n\n\n for (var i = 0, len = this._textLines.length; i < len; i++) {\n lineOffset = this._getLineLeftOffset(i);\n\n if (this.textBackgroundColor || this.styleHas('textBackgroundColor', i)) {\n this._setSVGTextLineBg(textBgRects, i, textLeftOffset + lineOffset, height);\n }\n\n this._setSVGTextLineText(textSpans, i, textLeftOffset + lineOffset, height);\n\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 _createTextCharSpan(_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,\n dySpan = '',\n NUM_FRACTION_DIGITS = fabric.Object.NUM_FRACTION_DIGITS;\n\n if (dy) {\n dySpan = ' dy=\"' + toFixed(dy, NUM_FRACTION_DIGITS) + '\" ';\n }\n\n return ['', fabric.util.string.escapeXml(_char), ''].join('');\n },\n _setSVGTextLineText: function _setSVGTextLineText(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,\n style,\n boxWidth = 0,\n line = this._textLines[lineIndex],\n timeToRender;\n textTopOffset += lineHeight * (1 - this._fontSizeFraction) / this.lineHeight;\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\n if (boxWidth === 0) {\n textLeftOffset += charBox.kernedWidth - charBox.width;\n boxWidth += charBox.width;\n } else {\n boxWidth += charBox.kernedWidth;\n }\n\n if (isJustify && !timeToRender) {\n if (this._reSpaceAndTab.test(line[i])) {\n timeToRender = true;\n }\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\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 _pushTextBgRect: function _pushTextBgRect(textBgRects, color, left, top, width, height) {\n var NUM_FRACTION_DIGITS = fabric.Object.NUM_FRACTION_DIGITS;\n textBgRects.push('\\t\\t\\n');\n },\n _setSVGTextLineBg: function _setSVGTextLineBg(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,\n currentColor,\n lastColor = this.getValueOfPropertyAt(i, 0, 'textBackgroundColor');\n\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\n if (currentColor !== lastColor) {\n lastColor && this._pushTextBgRect(textBgRects, lastColor, leftOffset + boxStart, textTopOffset, boxWidth, heightOfLine);\n boxStart = charBox.left;\n boxWidth = charBox.width;\n lastColor = currentColor;\n } else {\n boxWidth += charBox.kernedWidth;\n }\n }\n\n currentColor && this._pushTextBgRect(textBgRects, currentColor, leftOffset + boxStart, 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 _getFillAttributes(value) {\n var fillColor = value && typeof value === 'string' ? new fabric.Color(value) : '';\n\n if (!fillColor || !fillColor.getSource() || fillColor.getAlpha() === 1) {\n return 'fill=\"' + value + '\"';\n }\n\n return 'opacity=\"' + fillColor.getAlpha() + '\" fill=\"' + fillColor.setAlpha(1).toRgb() + '\"';\n },\n\n /**\n * @private\n */\n _getSVGLineTopOffset: function _getSVGLineTopOffset(lineIndex) {\n var lineTopOffset = 0,\n lastHeight = 0;\n\n for (var j = 0; j < lineIndex; j++) {\n lineTopOffset += this.getHeightOfLine(j);\n }\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 getSvgStyles(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 'use strict';\n\n var fabric = global.fabric || (global.fabric = {});\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\n fabric.Textbox = fabric.util.createClass(fabric.IText, fabric.Observable, {\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 initDimensions() {\n if (this.__skipDimension) {\n return;\n }\n\n this.isEditing && this.initDelayedCursor();\n this.clearContextTop();\n\n this._clearCache(); // clear dynamicMinWidth as it will be different after we re-wrap line\n\n\n this.dynamicMinWidth = 0; // wrap lines\n\n this._styleMap = this._generateStyleMap(this._splitText()); // if after wrapping, the width is smaller than dynamicMinWidth, change the width and re-wrap\n\n if (this.dynamicMinWidth > this.width) {\n this._set('width', this.dynamicMinWidth);\n }\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 } // clear cache and re-calculate height\n\n\n this.height = this.calcTextHeight();\n this.saveState({\n propertySet: '_dimensionAffectingProps'\n });\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 _generateStyleMap(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 } 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] = {\n line: realLineCount,\n 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 styleHas(property, lineIndex) {\n if (this._styleMap && !this.isWrapping) {\n var map = this._styleMap[lineIndex];\n\n if (map) {\n lineIndex = map.line;\n }\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 isEmptyStyles(lineIndex) {\n if (!this.styles) {\n return true;\n }\n\n var offset = 0,\n nextLineIndex = lineIndex + 1,\n nextOffset,\n obj,\n shouldLimit = false,\n map = this._styleMap[lineIndex],\n mapNextLine = this._styleMap[lineIndex + 1];\n\n if (map) {\n lineIndex = map.line;\n offset = map.offset;\n }\n\n if (mapNextLine) {\n nextLineIndex = mapNextLine.line;\n shouldLimit = nextLineIndex === lineIndex;\n nextOffset = mapNextLine.offset;\n }\n\n obj = typeof lineIndex === 'undefined' ? this.styles : {\n line: this.styles[lineIndex]\n };\n\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\n return true;\n },\n\n /**\n * @param {Number} lineIndex\n * @param {Number} charIndex\n * @private\n */\n _getStyleDeclaration: function _getStyleDeclaration(lineIndex, charIndex) {\n if (this._styleMap && !this.isWrapping) {\n var map = this._styleMap[lineIndex];\n\n if (!map) {\n return null;\n }\n\n lineIndex = map.line;\n charIndex = map.offset + charIndex;\n }\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 _setStyleDeclaration(lineIndex, charIndex, style) {\n var map = this._styleMap[lineIndex];\n lineIndex = map.line;\n charIndex = map.offset + charIndex;\n this.styles[lineIndex][charIndex] = style;\n },\n\n /**\n * @param {Number} lineIndex\n * @param {Number} charIndex\n * @private\n */\n _deleteStyleDeclaration: function _deleteStyleDeclaration(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 _getLineStyle(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 _setLineStyle(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 _wrapText(lines, desiredWidth) {\n var wrapped = [],\n i;\n this.isWrapping = true;\n\n for (i = 0; i < lines.length; i++) {\n wrapped = wrapped.concat(this._wrapLine(lines[i], i, desiredWidth));\n }\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 _measureWord(word, lineIndex, charOffset) {\n var width = 0,\n prevGrapheme,\n skipLeft = true;\n charOffset = charOffset || 0;\n\n for (var i = 0, len = word.length; i < len; i++) {\n var box = this._getGraphemeBox(word[i], lineIndex, i + charOffset, prevGrapheme, skipLeft);\n\n width += box.kernedWidth;\n prevGrapheme = word[i];\n }\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 _wrapLine(_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 = this._getWidthOfCharSpacing(),\n reservedSpace = reservedSpace || 0; // fix a difference between split and graphemeSplit\n\n\n if (words.length === 0) {\n words.push([]);\n }\n\n desiredWidth -= reservedSpace;\n\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 lineWidth += infixWidth + wordWidth - additionalSpace;\n\n if (lineWidth >= desiredWidth && !lineJustStarted) {\n graphemeLines.push(line);\n line = [];\n lineWidth = wordWidth;\n lineJustStarted = true;\n } else {\n lineWidth += additionalSpace;\n }\n\n if (!lineJustStarted && !splitByGrapheme) {\n line.push(infix);\n }\n\n line = line.concat(word);\n infixWidth = splitByGrapheme ? 0 : this._measureWord([infix], lineIndex, offset);\n offset++;\n lineJustStarted = false; // keep track of largest word\n\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 isEndOfWrapping(lineIndex) {\n if (!this._styleMap[lineIndex + 1]) {\n // is last line, return true;\n return true;\n }\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\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 missingNewlineOffset(lineIndex) {\n if (this.splitByGrapheme) {\n return this.isEndOfWrapping(lineIndex) ? 1 : 0;\n }\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 _splitTextIntoLines(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\n for (var i = 0; i < graphemeLines.length; i++) {\n lines[i] = graphemeLines[i].join('');\n }\n\n newText.lines = lines;\n newText.graphemeLines = graphemeLines;\n return newText;\n },\n getMinWidth: function getMinWidth() {\n return Math.max(this.minWidth, this.dynamicMinWidth);\n },\n _removeExtraneousStyles: function _removeExtraneousStyles() {\n var linesToKeep = {};\n\n for (var prop in this._styleMap) {\n if (this._textLines[prop]) {\n linesToKeep[this._styleMap[prop].line] = 1;\n }\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 toObject(propertiesToInclude) {\n return this.callSuper('toObject', ['minWidth', 'splitByGrapheme'].concat(propertiesToInclude));\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\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(function () {\n var controlsUtils = fabric.controlsUtils,\n scaleSkewStyleHandler = controlsUtils.scaleSkewCursorStyleHandler,\n scaleStyleHandler = controlsUtils.scaleCursorStyleHandler,\n scalingEqually = controlsUtils.scalingEqually,\n scalingYOrSkewingX = controlsUtils.scalingYOrSkewingX,\n scalingXOrSkewingY = controlsUtils.scalingXOrSkewingY,\n scaleOrSkewActionName = controlsUtils.scaleOrSkewActionName,\n objectControls = fabric.Object.prototype.controls;\n objectControls.ml = new fabric.Control({\n x: -0.5,\n y: 0,\n cursorStyleHandler: scaleSkewStyleHandler,\n actionHandler: scalingXOrSkewingY,\n getActionName: scaleOrSkewActionName\n });\n objectControls.mr = new fabric.Control({\n x: 0.5,\n y: 0,\n cursorStyleHandler: scaleSkewStyleHandler,\n actionHandler: scalingXOrSkewingY,\n getActionName: scaleOrSkewActionName\n });\n objectControls.mb = new fabric.Control({\n x: 0,\n y: 0.5,\n cursorStyleHandler: scaleSkewStyleHandler,\n actionHandler: scalingYOrSkewingX,\n getActionName: scaleOrSkewActionName\n });\n objectControls.mt = new fabric.Control({\n x: 0,\n y: -0.5,\n cursorStyleHandler: scaleSkewStyleHandler,\n actionHandler: scalingYOrSkewingX,\n getActionName: scaleOrSkewActionName\n });\n objectControls.tl = new fabric.Control({\n x: -0.5,\n y: -0.5,\n cursorStyleHandler: scaleStyleHandler,\n actionHandler: scalingEqually\n });\n objectControls.tr = new fabric.Control({\n x: 0.5,\n y: -0.5,\n cursorStyleHandler: scaleStyleHandler,\n actionHandler: scalingEqually\n });\n objectControls.bl = new fabric.Control({\n x: -0.5,\n y: 0.5,\n cursorStyleHandler: scaleStyleHandler,\n actionHandler: scalingEqually\n });\n objectControls.br = new fabric.Control({\n x: 0.5,\n y: 0.5,\n cursorStyleHandler: scaleStyleHandler,\n actionHandler: scalingEqually\n });\n objectControls.mtr = new fabric.Control({\n x: 0,\n y: -0.5,\n actionHandler: controlsUtils.rotationWithSnapping,\n cursorStyleHandler: controlsUtils.rotationStyleHandler,\n offsetY: -40,\n withConnection: true,\n actionName: 'rotate'\n });\n\n if (fabric.Textbox) {\n // this is breaking the prototype inheritance, no time / ideas to fix it.\n // is important to document that if you want to have all objects to have a\n // specific custom control, you have to add it to Object prototype and to Textbox\n // prototype. The controls are shared as references. So changes to control `tr`\n // can still apply to all objects if needed.\n var textBoxControls = fabric.Textbox.prototype.controls = {};\n textBoxControls.mtr = objectControls.mtr;\n textBoxControls.tr = objectControls.tr;\n textBoxControls.br = objectControls.br;\n textBoxControls.tl = objectControls.tl;\n textBoxControls.bl = objectControls.bl;\n textBoxControls.mt = objectControls.mt;\n textBoxControls.mb = objectControls.mb;\n textBoxControls.mr = new fabric.Control({\n x: 0.5,\n y: 0,\n actionHandler: controlsUtils.changeWidth,\n cursorStyleHandler: scaleSkewStyleHandler,\n actionName: 'resizing'\n });\n textBoxControls.ml = new fabric.Control({\n x: -0.5,\n y: 0,\n actionHandler: controlsUtils.changeWidth,\n cursorStyleHandler: scaleSkewStyleHandler,\n actionName: 'resizing'\n });\n }\n})();"],"sourceRoot":""}