{"version":3,"sources":["../node_modules/process/browser.js","../node_modules/jquery/dist/jquery.js","../node_modules/jquery.fancytree/dist/modules/jquery.fancytree.ui-deps.js","../node_modules/jquery.fancytree/dist/modules/jquery.fancytree.js","../node_modules/jquery.fancytree/dist/modules/jquery.fancytree.edit.js","../node_modules/jquery.fancytree/dist/modules/jquery.fancytree.filter.js","../node_modules/base64-js/index.js","../node_modules/ieee754/index.js","../node_modules/isarray/index.js","../node_modules/buffer/index.js","../node_modules/fabric/dist/fabric.js","../node_modules/hotkeys-js/dist/hotkeys.esm.js","../node_modules/lodash/lodash.js","models/palace.tsx","tools/quickpreview.tsx","../node_modules/path-browserify/index.js","../node_modules/dotenv/lib/main.js","online.tsx"],"names":["cachedSetTimeout","cachedClearTimeout","process","module","exports","defaultSetTimout","Error","defaultClearTimeout","runTimeout","fun","setTimeout","e","call","runClearTimeout","marker","clearTimeout","currentQueue","queue","draining","queueIndex","cleanUpNextTick","length","concat","drainQueue","timeout","len","run","Item","array","noop","nextTick","args","Array","arguments","i","push","prototype","apply","title","browser","env","argv","version","versions","on","addListener","once","off","removeListener","removeAllListeners","emit","prependListener","prependOnceListener","listeners","name","binding","cwd","chdir","dir","umask","fabric","resizeCanvasIfNeeded","pipelineState","targetCanvas","width","height","dWidth","destinationWidth","dHeight","destinationHeight","copyGLTo2DDrawImage","gl","glCanvas","canvas","ctx","getContext","translate","scale","sourceY","drawImage","copyGLTo2DPutImageData","numBytes","u8","Uint8Array","imageBuffer","u8Clamped","Uint8ClampedArray","readPixels","RGBA","UNSIGNED_BYTE","imgData","ImageData","putImageData","define","amd","document","window","require","jsdom","decodeURIComponent","features","FetchExternalResources","jsdomImplForWrapper","implForWrapper","nodeCanvas","Canvas","defaultView","DOMParser","isTouchSupported","isLikelyNode","Buffer","SHARED_ATTRIBUTES","DPI","reNum","fontPaths","iMatrix","canvasModule","perfLimitSizeTotal","maxCacheSideLimit","minCacheSideLimit","charWidthsCache","textureSize","enableGLFiltering","devicePixelRatio","webkitDevicePixelRatio","mozDevicePixelRatio","browserShadowBlurConstant","arcToSegmentsCache","boundsOfCurveCache","cachesBoundsOfCurve","initFilterBackend","isWebglSupported","console","log","maxTextureSize","WebglFilterBackend","tileSize","Canvas2dFilterBackend","_removeEventListener","eventName","handler","__eventListeners","eventListener","indexOf","util","fill","observe","prop","stopObserving","fire","options","listenersForEvent","filter","value","Observable","trigger","Collection","_objects","add","_onObjectAdded","renderOnAddRemove","requestRenderAll","insertAt","object","index","nonSplicing","objects","splice","remove","somethingRemoved","_onObjectRemoved","forEachObject","callback","context","getObjects","type","o","item","isEmpty","size","contains","complexity","reduce","memo","current","CommonMethods","_setOptions","set","_initGradient","filler","property","colorStops","Gradient","_initPattern","source","Pattern","_initClipping","clipTo","functionBody","getFunctionBody","Function","_setObject","obj","_set","key","get","toggle","global","sqrt","Math","atan2","pow","abs","PiBy180","PI","PiBy2","cos","angle","angleSlice","sin","sign","removeFromArray","idx","getRandomInt","min","max","floor","random","degreesToRadians","degrees","radiansToDegrees","radians","rotatePoint","point","origin","subtractEquals","v","rotateVector","Point","x","y","addEquals","vector","transformPoint","p","t","ignoreOffset","makeBoundingBoxFromPoints","points","xPoints","minX","yPoints","minY","left","top","invertTransform","a","r","toFixed","number","fractionDigits","parseFloat","Number","parseUnit","fontSize","unit","exec","Text","DEFAULT_SVG_FONT_SIZE","falseFunction","getKlass","namespace","string","camelize","charAt","toUpperCase","slice","resolveNamespace","getSvgAttributes","attributes","parts","split","loadImage","url","crossOrigin","img","createImage","onLoadCallback","onload","onerror","src","substring","loadImageInDom","div","createElement","style","position","appendChild","querySelector","parentNode","removeChild","enlivenObjects","reviver","onLoaded","numLoadedObjects","numTotalObjects","enlivenedObjects","forEach","fromObject","error","enlivenPatterns","patterns","numLoadedPatterns","numPatterns","enlivenedPatterns","pattern","groupSVGElements","elements","path","centerPoint","Group","sourcePath","populateWithProperties","destination","properties","Object","toString","drawDashedLine","x2","y2","da","dx","dy","rot","dc","di","draw","save","moveTo","rotate","restore","createCanvasElement","copyCanvasElement","newCanvas","clipContext","receiver","beginPath","clip","multiplyTransformMatrices","b","is2x2","qrDecompose","denom","scaleX","scaleY","skewX","skewY","translateX","translateY","customTransformMatrix","skewMatrixX","tan","scaleMatrix","resetObjectTransform","target","flipX","flipY","saveObjectTransform","fn","String","match","isTransparent","tolerance","_isTransparent","imageData","getImageData","l","data","parsePreserveAspectRatioAttribute","attribute","meetOrSlice","align","aspectRatioAttrs","pop","alignX","alignY","clearFabricFontCache","fontFamily","toLowerCase","limitDimsByArea","ar","maximumArea","roughWidth","perfLimitSizeY","capValue","findScaleToFit","findScaleToCover","_join","join","arcToSegments","toX","toY","rx","ry","large","sweep","rotateX","argsString","th","sinTh","cosTh","fromX","fromY","px","py","rx2","ry2","py2","px2","pl","root","s","cx","cy","cx1","cy1","mTheta","calcVectorAngle","dtheta","segments","ceil","result","mDelta","mT","th3","segmentToBezier","th2","costh2","sinth2","costh3","sinth3","ux","uy","vx","vy","ta","tb","getBoundsOfCurve","x0","y0","x1","y1","x3","y3","c","t1","t2","b2ac","sqrtb2ac","tvalues","bounds","j","mt","jlen","drawArc","fx","fy","coords","segs","segsNorm","bezierCurveTo","getBoundsOfArc","tx","ty","bound","find","byProperty","condition","k","invoke","method","value1","value2","extend","deep","Element","hasOwnProperty","clone","getWholeChar","str","code","charCodeAt","isNaN","next","prev","replace","character","capitalize","firstLetterOnly","escapeXml","graphemeSplit","textstring","chr","graphemes","emptyFunction","IS_DONTENUM_BUGGY","addMethods","klass","parent","superclass","constructor","returnValue","valueOf","Subclass","callSuper","methodName","_this","parentMethod","superClassMethod","createClass","initialize","shift","subclasses","unknown","areHostMethods","methodNames","test","getElement","setElement","uid","getUniqueId","element","__uniqueID","createListener","wrappedHandler","createWrappedHandler","event","shouldUseAddListenerRemoveListener","documentElement","shouldUseAttachEventDetachEvent","handlers","addEventListener","removeEventListener","listener","attachEvent","detachEvent","existingHandler","createDispatcher","handlersForEvent","pointerX","clientX","pointerY","clientY","_getPointer","pageProp","clientProp","touchProp","pointer","eventTouchProp","getPointer","srcElement","scroll","getScrollLeftTop","parseEl","supportsOpacity","opacity","supportsFilters","reOpacity","setOpacity","es","currentStyle","hasLayout","zoom","setStyle","styles","elementStyle","cssText","styleFloat","_slice","sliceCanConvertNodelists","getElementStyle","toArray","arrayLike","childNodes","err","makeElement","tagName","el","className","htmlFor","setAttribute","docElement","body","scrollLeft","scrollTop","host","nodeType","arr","getComputedStyle","attr","undefined","selectProp","makeElementUnselectable","onselectstart","unselectable","makeElementSelectable","getScript","headEl","getElementsByTagName","scriptEl","loading","onreadystatechange","readyState","getById","id","getElementById","addClass","wrapElement","wrapper","replaceChild","getElementOffset","docElem","scrollLeftTop","doc","ownerDocument","box","offset","offsetAttributes","borderLeftWidth","borderTopWidth","paddingLeft","paddingTop","parseInt","getBoundingClientRect","clientLeft","clientTop","getNodeCanvas","impl","_canvas","_image","cleanUpJsdomNode","_currentSrc","_attributes","_classList","emptyFn","request","onComplete","xhr","XMLHttpRequest","parameters","addParamToUrl","param","open","setRequestHeader","send","warn","_requestAnimFrame","requestAnimationFrame","webkitRequestAnimationFrame","mozRequestAnimationFrame","oRequestAnimationFrame","msRequestAnimationFrame","_cancelAnimFrame","cancelAnimationFrame","requestAnimFrame","animate","timestamp","start","time","Date","duration","finish","onChange","abort","easing","d","startValue","endValue","byValue","onStart","tick","ticktime","currentTime","timePerc","valuePerc","cancelAnimFrame","animateColor","fromColor","toColor","startColor","Color","getSource","endColor","posValue","begin","end","pos","color","colorEasing","calculateColor","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","transform","colorAttributes","stroke","normalizeAttr","normalizeValue","parentAttributes","isArray","parsed","map","n","transformMatrix","parseTransformAttribute","visible","fillIndex","strokeIndex","getSvgRegex","RegExp","_getMultipleNodes","nodeNames","nodeName","nodeList","nodeArray","elementMatchesRule","selectors","firstMatching","parentMatching","selectorMatches","doesSomeParentMatch","selector","matcher","classNames","getAttribute","elementById","node","nodelist","svgValidTagNamesRegEx","svgViewBoxElementsRegEx","svgInvalidAncestorsRegEx","svgValidParentsRegEx","cssRules","gradientDefs","clipPaths","skewMatrix","matrix","commaWsp","reTransformList","reTransform","attributeValue","matrices","m","operation","translateMatrix","rotateMatrix","multiplierX","multiplierY","combinedMatrix","reViewBoxAttrValue","applyViewboxTransform","viewBoxAttr","viewBoxWidth","viewBoxHeight","widthAttr","heightAttr","preserveAspectRatio","missingViewBox","missingDimAttr","toBeParsed","parsedDim","widthDiff","heightDiff","viewboxTransform","firstChild","parseSVGDocument","parsingOptions","parseUseDirectives","attrs","xlink","substr","el2","cloneNode","currentTrans","oldLength","el3","nodeValue","removeAttribute","svgUid","__uid","descendants","selectNodes","hasAncestorWithNodeName","getGradientDefs","getCSSRules","parseElements","instances","reFontDeclaration","parseFontDeclaration","oStyle","fontStyle","fontWeight","lineHeight","tagArray","elList","idsToXlinkMap","parseAttributes","ownAttributes","getGlobalStylesForElement","rule","parseStyleAttribute","normalizedAttr","normalizedValue","normalizedStyle","font","mergedAttrs","_setStrokeFillOpacity","setAlpha","getAlpha","toRgba","ElementsParser","parse","parseStyleString","chunk","pair","trim","parseStyleObject","parsePointsAttribute","parsedPoints","allRules","styleContents","textContent","text","ruleObj","propertyValuePairs","_rule","loadSVGFromURL","xml","responseXML","ActiveXObject","responseText","async","loadXML","results","_options","allElements","loadSVGFromString","parser","parseFromString","regexUrl","proto","numElements","createObjects","createObject","findTag","fromElement","createCallback","checkIfDone","resolveGradient","Image","_removeTransformMatrix","resolveClipPath","extractPropertyDefinition","storage","lastIndex","gradientDef","createClipPathCallback","container","_newObj","fillRule","clipRule","clipPath","objTransformInv","gTransform","calcTransformMatrix","setPositionByOrigin","that","scalarAdd","scalar","scalarAddEquals","subtract","scalarSubtract","scalarSubtractEquals","multiply","multiplyEquals","divide","divideEquals","eq","lt","lte","gt","gte","lerp","distanceFrom","midPointFrom","setXY","setX","setY","setFromPoint","swap","Intersection","status","appendPoint","appendPoints","intersectLineLine","a1","a2","b1","b2","uaT","ubT","uB","ua","ub","intersectLinePolygon","inter","intersectPolygonPolygon","points1","points2","intersectPolygonRectangle","r1","r2","topRight","bottomLeft","inter1","inter2","inter3","inter4","_tryParsingColor","setSource","hue2rgb","q","colorNameMap","sourceFromHex","sourceFromRgb","sourceFromHsl","_rgbToHsl","g","h","round","_source","toRgb","toHsl","hsl","toHsla","toHex","toHexa","alpha","toGrayscale","average","currentAlpha","toBlackWhite","threshold","overlayWith","otherColor","otherSource","reRGBa","reHSLa","reHex","aliceblue","antiquewhite","aqua","aquamarine","azure","beige","bisque","black","blanchedalmond","blue","blueviolet","brown","burlywood","cadetblue","chartreuse","chocolate","coral","cornflowerblue","cornsilk","crimson","cyan","darkblue","darkcyan","darkgoldenrod","darkgray","darkgrey","darkgreen","darkkhaki","darkmagenta","darkolivegreen","darkorange","darkorchid","darkred","darksalmon","darkseagreen","darkslateblue","darkslategray","darkslategrey","darkturquoise","darkviolet","deeppink","deepskyblue","dimgray","dimgrey","dodgerblue","firebrick","floralwhite","forestgreen","fuchsia","gainsboro","ghostwhite","gold","goldenrod","gray","grey","green","greenyellow","honeydew","hotpink","indianred","indigo","ivory","khaki","lavender","lavenderblush","lawngreen","lemonchiffon","lightblue","lightcoral","lightcyan","lightgoldenrodyellow","lightgray","lightgrey","lightgreen","lightpink","lightsalmon","lightseagreen","lightskyblue","lightslategray","lightslategrey","lightsteelblue","lightyellow","lime","limegreen","linen","magenta","maroon","mediumaquamarine","mediumblue","mediumorchid","mediumpurple","mediumseagreen","mediumslateblue","mediumspringgreen","mediumturquoise","mediumvioletred","midnightblue","mintcream","mistyrose","moccasin","navajowhite","navy","oldlace","olive","olivedrab","orange","orangered","orchid","palegoldenrod","palegreen","paleturquoise","palevioletred","papayawhip","peachpuff","peru","pink","plum","powderblue","purple","rebeccapurple","red","rosybrown","royalblue","saddlebrown","salmon","sandybrown","seagreen","seashell","sienna","silver","skyblue","slateblue","slategray","slategrey","snow","springgreen","steelblue","teal","thistle","tomato","turquoise","violet","wheat","white","whitesmoke","yellow","yellowgreen","fromRgb","fromSource","fromRgba","fromHsl","fromHsla","fromHex","isShortNotation","isRGBa","oColor","getColorStop","colorAlpha","keyValuePairs","_convertPercentUnitsToValues","gradientUnits","propValue","addFactor","multFactor","ellipseMatrix","scaleFactor","offsetX","offsetY","gradientTransform","addColorStop","toObject","propertiesToInclude","toSVG","markup","commonAttributes","needsSwap","sort","pathOffset","reverse","minRadius","maxRadius","percentageShift","colorStop","toLive","gradient","createLinearGradient","createRadialGradient","instance","colorStopEls","getLinearCoords","getRadialCoords","forObject","repeat","patternTransform","setOptions","NUM_FRACTION_DIGITS","toDataURL","patternSource","patternWidth","patternHeight","patternOffsetX","patternOffsetY","patternImgSrc","complete","naturalWidth","naturalHeight","createPattern","Shadow","blur","affectStroke","includeDefaultValues","_parseShadow","shadow","shadowStr","offsetsAndBlur","reOffsetsAndBlur","fBoxX","fBoxY","StaticCanvas","CANVAS_INIT_ERROR","renderAndResetBound","renderAndReset","bind","requestRenderAllBound","_initStatic","backgroundColor","backgroundImage","overlayColor","overlayImage","stateful","controlsAboveOverlay","allowTouchScrolling","imageSmoothingEnabled","viewportTransform","backgroundVpt","overlayVpt","onBeforeScaleRotate","enableRetinaScaling","vptCoords","skipOffscreen","cb","_createLowerCanvas","_initOptions","_setImageSmoothing","interactive","_initRetinaScaling","setOverlayImage","setBackgroundImage","setBackgroundColor","setOverlayColor","calcOffset","_isRetinaScaling","getRetinaScaling","lowerCanvasEl","contextContainer","_offset","image","__setBgOverlayImage","__setBgOverlayColor","webkitImageSmoothingEnabled","mozImageSmoothingEnabled","msImageSmoothingEnabled","oImageSmoothingEnabled","_createCanvasElement","canvasEl","_applyCanvasStyle","getWidth","getHeight","setWidth","setDimensions","setHeight","dimensions","cssValue","cssOnly","_setBackstoreDimension","hasLostContext","backstoreOnly","_setCssDimension","_isCurrentlyDrawing","freeDrawingBrush","_setBrushStyles","upperCanvasEl","cacheCanvasEl","wrapperEl","getZoom","setViewportTransform","vpt","activeObject","_activeObject","group","setCoords","calcViewportBoundaries","zoomToPoint","before","after","setZoom","absolutePan","relativePan","setupState","clearContext","clearRect","clear","_hasITextHandlers","_mouseUpITextHandler","_iTextInstances","renderAll","canvasToDrawOn","renderCanvas","isRendering","iVpt","tl","br","tr","bl","cancelRequestedRender","_renderBackground","_renderObjects","drawControls","shouldCache","_transformDone","renderCache","forClipping","drawClipPathOnCanvas","_renderOverlay","globalCompositeOperation","zoomX","zoomY","_cacheCanvas","cacheTranslationX","cacheTranslationY","render","_renderBackgroundOrOverlay","fillStyle","fillRect","getCenter","centerObjectH","_centerObject","getCenterPoint","centerObjectV","centerObject","center","viewportCenterObject","vpCenter","getVpCenter","viewportCenterObjectH","viewportCenterObjectV","toDatalessJSON","toDatalessObject","_toObjectMethod","_toObjects","__serializeBgOverlay","excludeFromExport","_toObject","originalValue","bgImage","overlay","background","svgViewportTransformation","_setSVGPreamble","_setSVGHeader","_setSVGBgOverlayColor","_setSVGBgOverlayImage","clipPathId","_setSVGObjects","suppressPreamble","encoding","viewBox","createSVGFontFacesMarkup","createSVGRefElementsMarkup","createSVGClipPathMarkup","toClipPathSVG","row","rowIndex","charIndex","fontList","_setSVGObject","finalWidth","finalHeight","sendToBack","activeSelection","objs","unshift","bringToFront","sendBackwards","intersecting","newIdx","objsMoved","_findNewLowerIndex","isIntersecting","intersectsWithObject","isContainedWithinObject","bringForward","_findNewUpperIndex","dispose","DataURLExporter","EMPTY_JSON","supports","setLineDash","toJSON","createPNGStream","createJPEGStream","BaseBrush","strokeLineCap","strokeLineJoin","strokeMiterLimit","strokeDashArray","setShadow","contextTop","strokeStyle","lineWidth","lineCap","miterLimit","lineJoin","_saveAndTransform","_setShadow","shadowColor","shadowBlur","shadowOffsetX","shadowOffsetY","_resetShadow","PencilBrush","_points","_drawSegment","p1","p2","midPoint","quadraticCurveTo","onMouseDown","_prepareForDrawing","_captureDrawingPath","_render","onMouseMove","needsFullRender","oldEnd","onMouseUp","_finalizeAndAddPath","_reset","_addPoint","pointerPoint","lineTo","convertPointsToSVGPath","multSignX","multSignY","manyPoints","createPath","pathData","Path","strokeWidth","translateToGivenOrigin","originX","originY","closePath","CircleBrush","drawDot","addPoint","arc","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","PatternBrush","getPatternSrc","patternCanvas","patternCtx","getPatternSrcFunction","getPattern","topLeft","_getLeftTopCoords","supportLineDash","_initInteractive","_createCacheCanvas","uniScaleTransform","uniScaleKey","centeredScaling","centeredRotation","centeredKey","altActionKey","selection","selectionKey","altSelectionKey","selectionColor","selectionDashArray","selectionBorderColor","selectionLineWidth","selectionFullyContained","hoverCursor","moveCursor","defaultCursor","freeDrawingCursor","rotationCursor","notAllowedCursor","containerClass","perPixelTargetFind","targetFindTolerance","skipTargetFind","isDrawingMode","preserveObjectStacking","snapAngle","snapThreshold","stopContextMenu","fireRightClick","fireMiddleClick","_currentTransform","_groupSelector","_initWrapperElement","_createUpperCanvas","_initEventListeners","_chooseObjectsToRender","activeObjects","objsToRender","activeGroupObjects","getActiveObjects","contextTopDirty","renderTopLayer","_drawSelection","renderTop","_resetCurrentTransform","original","_shouldCenterTransform","mouseXSign","mouseYSign","containsPoint","ignoreZoom","xy","_normalizePointer","_findTargetCorner","invertedM","vptPointer","restorePointerVpt","isTargetTransparent","normalizedPointer","targetRelativeX","targetRelativeY","_cacheContext","contextCache","originalColor","selectionBackgroundColor","_renderControls","hasBorders","transparentCorners","_isSelectionKeyPressed","selectionKeyPressed","_shouldClearSelection","evented","selectable","centerTransform","action","altKey","_getOriginFromCorner","corner","_getActionFromCorner","_setupCurrentTransform","ex","ey","lastX","lastY","theta","shiftKey","_beforeTransform","_translateObject","newLeft","newTop","moveX","moveY","_changeSkewTransformOrigin","mouseMove","by","origins","skew","originA","originB","flipSign","skewSign","_skewObject","skewed","lockSkewingX","lockSkewingY","actualMouseByOrigin","constraintPosition","actualMouseByCenter","toLocalPoint","lastMouseByCenter","dim","_getTransformedDimensions","translateToOriginPoint","_setObjectSkew","localMouse","_dim","newValue","newDim","dimNoSkew","otherBy","_otherBy","_by","newDimMouse","atan","_scaleObject","lockScalingX","lockScalingY","lockScalingFlip","scaled","_setLocalMouse","_setObjectScale","changeX","changeY","forbidScalingX","forbidScalingY","_scaleObjectEqually","newScaleX","newScaleY","_flipObject","dist","lastDist","signX","signY","padding","_rotateObject","lockRotation","lastAngle","curAngle","hasRotated","rightAngleLocked","leftAngleLocked","setCursor","cursor","groupSelector","aleft","atop","_setLineDash","strokeRect","findTarget","skipGroup","activeTarget","activeTargetSubs","aObjects","targets","_searchPossibleTargets","_checkTarget","globalPointer","isEditing","subTarget","objToCheck","pointerToUse","subTargetCheck","_absolutePointer","_pointer","cssScale","boundsWidth","boundsHeight","bottom","right","lowerCanvasClass","_copyCanvasStyle","fromEl","toEl","getSelectionContext","getSelectionElement","getActiveObject","active","_discardActiveObject","_hoveredTarget","_fireSelectionEvents","oldObjects","somethingChanged","added","removed","opt","oldObject","selected","deselected","updated","setActiveObject","currentActives","_setActiveObject","onSelect","onDeselect","discardActiveObject","removeListeners","originalProperties","_realizeGroupTransformOnObject","_unwindGroupTransformOnObject","layoutProps","originalValues","realizeTransform","clearContextTop","_setCursorFromEvent","cursorOffset","mr","mb","ml","addEventOptions","passive","checkClick","which","button","cursorMap","_bindEvents","addOrRemove","functor","eventjsFunctor","_onResize","_onMouseDown","_onMouseMove","_onMouseOut","_onMouseEnter","_onMouseWheel","_onContextMenu","_onDoubleClick","_onDragOver","_onDragEnter","_onDragLeave","_onDrop","eventjs","_onGesture","_onDrag","_onOrientationChange","_onShake","_onLongPress","_onMouseUp","eventsBound","_simpleEventHandler","self","__onTransformGesture","__onDrag","__onMouseWheel","hiddenTextarea","focus","__onOrientationChange","__onShake","__onLongPress","preventDefault","_fireEnterLeaveEvents","stopPropagation","_cacheTransformEventData","_handleEvent","_resetTransformEventData","__onMouseDown","__onMouseUp","__onMouseMove","_shouldRender","shouldRender","isClick","_target","_onMouseUpInDrawingMode","_finalizeCurrentTransform","actionPerformed","_maybeGroupObjects","isMoving","__corner","eventType","subTargets","absolutePointer","_scaling","hasStateChanged","_addEventOptions","_fire","_onMouseDownInDrawingMode","_onMouseMoveInDrawingMode","_previousPointer","shouldGroup","_shouldGroup","_handleGrouping","saveState","touches","_transformObject","_fireOverOutEvents","fireSynteticInOutEvents","targetName","canvasEvtOut","evtOut","canvasEvtIn","evtIn","config","inOpt","outOpt","inFires","oldTarget","targetChanged","previousTarget","nextTarget","reset","_beforeScaleTransform","_performTransformAction","_onScale","_isUniscalePossible","currentAction","getCornerCursor","actionIsDisabled","_getRotatedCornerCursor","hasRotatingPoint","_updateActiveSelection","_createActiveSelection","currentActiveObjects","removeWithUpdate","addWithUpdate","_createGroup","groupObjects","exitEditing","ActiveSelection","_groupSelectedObjects","aGroup","_collectObjects","currentObject","selectionX1Y1","selectionX2Y2","allowIntersect","intersectsWithRect","isContainedWithinRect","supportQuality","format","quality","multiplier","cropping","__toDataURLWithMultiplier","origWidth","origHeight","scaledWidth","scaledHeight","newZoom","vp","newVp","originalInteractive","originalSkipOffScreen","needsResize","__toDataURL","loadFromDatalessJSON","json","loadFromJSON","serialized","JSON","_enlivenObjects","_setBgOverlay","loaded","cbIfLoaded","__setBgOverlay","enlivedObject","_toDataURL","_toDataURLWithMultiplier","toDataURLWithMultiplier","stringify","cloneWithoutData","backgroundImageOpacity","backgroundImageStretch","supportsLineDash","objectCaching","cornerSize","borderColor","borderDashArray","cornerColor","cornerStrokeColor","cornerStyle","cornerDashArray","borderOpacityWhenMoving","borderScaleFactor","minScaleLimit","hasControls","rotatingPointOffset","lockMovementX","lockMovementY","lockUniScaling","statefullCache","noScaleCache","dirty","paintFirst","stateProperties","cacheProperties","inverted","absolutePositioned","_cacheProperties","_updateCacheCanvas","_limitCacheSize","dims","limitedDims","capped","_getCacheCanvasDimensions","objectScale","getTotalObjectScaling","_getNonTransformedDimensions","drawingWidth","drawingHeight","minCacheSize","dimensionsChanged","cacheWidth","cacheHeight","zoomChanged","shouldRedraw","additionalWidth","additionalHeight","shouldResizeCanvas","canvasWidth","canvasHeight","sizeGrowing","setTransform","calcOwnMatrix","_removeDefaultValues","getObjectScaling","scaling","retina","getObjectOpacity","shouldConstrainValue","isChanged","groupNeedsUpdate","_constrainScale","isOnACache","setOnGroup","getViewportTransform","isNotVisible","isOnScreen","_setupCompositeOperation","drawSelectionBackground","_setOpacity","drawCacheOnCanvas","_removeCacheCanvas","drawObject","propertySet","isCacheDirty","needsItsOwnCache","ownCaching","willDrawShadow","drawClipPathOnCache","_setClippingProperties","_setStrokeStyles","_setFillStyles","_drawClipPath","skipCanvas","_removeShadow","decl","dashArray","alternative","styleOverride","drawBorders","forActiveSelection","drawBordersInGroup","multX","multY","_applyPatternGradientTransform","_renderPaintInOrder","_renderStroke","_renderFill","_renderDashedStroke","_findCenterFromElement","_assignTransformMatrixProps","preserveAspectRatioOptions","cropX","cropY","offsetLeft","offsetTop","objectForm","_fromObject","cloneAsImage","dataUrl","utils","origParams","originalShadow","withoutTransform","withoutShadow","boundingRect","getBoundingRect","shadowOffset","originalCanvas","isType","setGradient","setPatternFill","setColor","shouldCenterOrigin","_setOriginToCenter","_resetOrigin","centerH","viewportCenterH","centerV","viewportCenterV","viewportCenter","getLocalPointer","pClicked","objectLeftTop","createAccessors","extraParam","enlivedProps","originXOffset","originYOffset","fromOriginX","fromOriginY","toOriginX","toOriginY","translateToCenterPoint","leftTop","getPointByOrigin","adjustPosition","to","offsetFrom","offsetTo","hypotFull","getScaledWidth","xFull","yFull","_originalOriginX","_originalOriginY","originPoint","multiplyMatrices","oCoords","aCoords","ownMatrixCache","matrixCache","getCoords","absolute","calculate","calcCoords","pointTL","pointBR","intersection","other","lines","_getImageLines","_findCrossPoints","_containsCenterOfCanvas","isPartiallyOnScreen","topline","rightline","bottomline","leftline","xi","iLine","xcount","lineKey","getScaledHeight","scaleToWidth","boundingRectFactor","scaleToHeight","_calcRotateMatrix","_calcTranslateMatrix","startMatrix","finalMatrix","w","cosP","sinP","cosPSinP","cosPMinusSinP","mtr","skipAbsolute","_setCornerCoords","transformMatrixKey","sep","prefix","cache","dimensionMatrix","_calcDimensionsTransformMatrix","flipping","dimX","bbox","dimY","_calculateCurrentDimensions","getSvgColorString","getSvgStyles","skipShadow","getSvgFilter","getSvgSpanStyles","useWhiteSpace","term","textDecoration","getSvgTextDecoration","deltaY","overline","underline","linethrough","getSvgCommons","getSvgTransform","full","additionalTransform","getSvgTransformMatrix","_setSVGBg","textBgRects","_getFillAttributes","_createBaseSVGMarkup","_toSVG","_createBaseClipPathSVGMarkup","objectMarkup","commonPieces","noStyle","clipPathMarkup","withShadow","styleInfo","shadowInfo","absoluteClipPath","addPaintOrder","saveProps","props","tmpObj","dashedPropertySet","keys","_isEqual","origValue","currentValue","firstPass","_controlsVisibility","isControlVisible","newTheta","cornerHypotenuse","cosHalfOffset","sinHalfOffset","wh","drawRotatingPoint","rotateHeight","scaleOffset","_drawControl","control","controlName","_getControlsVisibility","setControlVisible","setControlsVisibility","FX_DURATION","fxCenterObjectH","callbacks","empty","fxCenterObjectV","fxRemove","propsToAnimate","skipCallbacks","_animate","propPair","from","valueProgress","timeProgress","coordProps","makeEdgeToOriginGetter","propertyNames","originValues","axis1","axis2","dimension","nearest","farthest","Line","_setWidthHeight","_getLeftToOriginX","_getTopToOriginY","calcLinePoints","origStrokeStyle","xMult","yMult","ATTRIBUTE_NAMES","parsedAttributes","_callback","pi","startAngle","endAngle","setRadius","svgString","startX","startY","endX","endY","largeFlag","getRadiusX","getRadiusY","Triangle","widthBy2","heightBy2","piBy2","Ellipse","getRx","getRy","_initRxRy","isRounded","Polyline","calcDim","_calcDimensions","diffX","diffY","commonRender","Polygon","_toString","commandLengths","repeatedCommands","M","fromArray","_parsePath","_setPositionDimensions","_parseDimensions","_renderPathCommands","tempX","tempY","previous","subpathStartX","subpathStartY","controlX","controlY","specificTransform","_getOffsetTransform","digits","currentPath","coordsStr","coordsParsed","re","command","commandLength","repeatedCommand","klen","aX","aY","pathUrl","useSetOnGroup","isAlreadyGrouped","_updateObjectsACoords","_calcBounds","_updateObjectsCoords","_updateObjectCoords","objectLeft","objectTop","_restoreObjectsState","_includeDefaultValues","objsToObject","originalDefaults","_obj","ownCache","_restoreObjectState","destroy","toActiveSelection","ungroupOnCanvas","setObjectsCoords","onlyWidthHeight","iLen","jLen","_getBounds","minXY","maxXY","enlivedClipPath","toGroup","newGroup","childrenOverride","_lastScaleX","_lastScaleY","_filterScalingX","_filterScalingY","minimumScaleTrigger","cacheKey","filters","_initElement","_element","removeTexture","_originalElement","_initConfig","applyFilters","resizeFilter","applyResizeFilters","backend","filterBackend","evictCachesForKey","setCrossOrigin","getOriginalSize","_stroke","filterObj","getSrc","hasCrop","strokeSvg","imageMarkup","getSvgSrc","origFill","filtered","setSrc","minimumScale","elementToFilter","_filteredEl","sourceWidth","sourceHeight","isNeutralState","imgElement","_needsResize","sW","sH","elementToDraw","_resetWidthHeight","CSS_CANVAS","_initFilters","pAR","rWidth","rHeight","pWidth","pHeight","_object","resizeFilters","fromURL","imgOptions","_getAngleValueForStraighten","straighten","fxStraighten","straightenObject","fxStraightenObject","testPrecision","precision","fragmentSource","fragmentShader","createShader","FRAGMENT_SHADER","shaderSource","compileShader","getShaderParameter","COMPILE_STATUS","setupGLContext","captureGPUInfo","isSupported","getParameter","MAX_TEXTURE_SIZE","precisions","webGlPrecision","resources","createWebGLCanvas","aPosition","Float32Array","chooseFastestCopyGLTo2DMethod","canMeasurePerf","canUseImageData","performance","canUseArrayBuffer","ArrayBuffer","canUseUint8Clamped","startTime","drawImageTime","testContext","now","copyGLTo2D","glOptions","premultipliedAlpha","depth","stencil","antialias","clearColor","cachedTexture","getCachedTexture","originalWidth","originalHeight","sourceTexture","createTexture","targetTexture","originalTexture","passes","webgl","programCache","pass","tempFbo","createFramebuffer","bindFramebuffer","FRAMEBUFFER","applyTo","bindTexture","TEXTURE_2D","deleteTexture","deleteFramebuffer","applyFiltersDebug","ret","glError","getError","NO_ERROR","errorString","glErrorToString","glErrorCode","errorCode","INVALID_ENUM","INVALID_VALUE","INVALID_OPERATION","INVALID_FRAMEBUFFER_OPERATION","OUT_OF_MEMORY","CONTEXT_LOST_WEBGL","clearWebGLCaches","textureCache","textureImageSource","texture","texParameteri","TEXTURE_MAG_FILTER","NEAREST","TEXTURE_MIN_FILTER","TEXTURE_WRAP_S","CLAMP_TO_EDGE","TEXTURE_WRAP_T","texImage2D","uniqueId","gpuInfo","ext","getExtension","renderer","vendor","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","_class","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","distance","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","oW","newData","oH","sliceByTwo","hermiteFastResize","bilinearFiltering","lanczosResize","tmpCanvas","doneW","doneH","stepW","stepH","sX","sY","dX","dY","srcData","destImg","destData","lanczos","ratioX","ratioY","rcpRatioX","rcpRatioY","range2X","range2Y","cacheLanc","icenter","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","ctx1","percent","ctx2","newImageData","delta","chooseRightDelta","blurScale","Gamma","gamma","rInv","gInv","bInv","rVals","gVals","bVals","uGamma","uniform3fv","Composed","subFilters","some","HueRotation","rotation","rad","aThirdSqtSin","OneMinusCos","_dimensionAffectingProps","_reNewline","_reSpacesAndTabs","_reSpaceAndTab","_reWords","textAlign","superscript","baseline","subscript","textBackgroundColor","_fontSizeFraction","_fontSizeMult","charSpacing","_measuringContext","_styleProperties","__charBounds","CACHE_FONT_SIZE","MIN_TEXT_WIDTH","__skipDimension","initDimensions","getMeasuringContext","_splitText","newLines","_splitTextIntoLines","textLines","_textLines","graphemeLines","_unwrappedTextLines","_unwrappedLines","_text","graphemeText","_clearCache","calcTextWidth","cursorWidth","enlargeSpaces","calcTextHeight","diffSpace","currentLineWidth","numberOfSpaces","accumulatedSpace","line","charBound","spaces","isEndOfWrapping","getLineWidth","kernedWidth","lineIndex","_setTextStyles","_renderTextLinesBackground","_renderTextDecoration","_renderText","_renderTextStroke","_renderTextFill","charStyle","forMeasuring","textBaseline","_getFontDeclaration","maxWidth","_renderTextLine","_renderChars","styleHas","lineTopOffset","heightOfLine","lineLeftOffset","lastColor","charBox","currentColor","originalFill","leftOffset","_getLeftOffset","topOffset","_getTopOffset","boxStart","boxWidth","getHeightOfLine","_getLineLeftOffset","getValueOfPropertyAt","getFontCache","cacheProp","_applyCharStyles","styleDeclaration","_measureChar","_char","previousChar","prevCharStyle","fontCache","coupleWidth","previousWidth","couple","stylesAreEqual","fontMultiplier","measureText","getHeightOfChar","char","measureLine","lineInfo","_measureLine","_getWidthOfCharSpacing","grapheme","prevGrapheme","graphemeInfo","lineBounds","_getGraphemeBox","numOfSpaces","skipLeft","getCompleteStyleDeclaration","prevStyle","info","previousBox","__lineHeights","maxHeight","_renderTextCommon","lineHeights","isEmptyStyles","actualStyle","nextStyle","timeToRender","isJustify","charsToRender","shortCut","_renderChar","_hasStyleChanged","_getStyleDeclaration","fullDecl","shouldFill","shouldStroke","fillText","strokeText","setSuperscript","_setScript","setSubscript","schema","loc","get2DCursorLocation","setSelectionStyles","thisStyle","_hasStyleChangedForSvg","__lineWidths","_shouldClearDimensionCache","shouldClear","_forceClearCache","_size","_dy","lastDecoration","currentDecoration","currentFill","lastFill","styleObject","family","fontIsGeneric","genericFonts","newLine","newText","additionalProperties","needsDims","_key","parsedAnchor","textAnchor","originalStrokeWidth","textHeightScaleFactor","scaledDiff","textHeight","offX","p3","cleanStyle","letterCount","stylePropertyValue","stylesCount","allStyleObjectPropertiesMatch","graphemeCount","removeStyle","lineNum","charNum","_extendStyles","_getLineStyle","_setLineStyle","_setStyleDeclaration","selectionStart","skipWrapping","getSelectionStyles","startIndex","endIndex","selectionEnd","getStyleAtPosition","lineStyle","_deleteStyleDeclaration","_deleteLineStyle","parseDecoration","IText","editable","editingBorderColor","cursorColor","cursorDelay","cursorDuration","caching","_reSpace","_currentCursorOpacity","_selectionDirection","_abortCursorAnimation","__widthOfSpace","inCompositionMode","initBehavior","setSelectionStart","_updateAndFire","setSelectionEnd","_fireSelectionChanged","_updateTextarea","initDelayedCursor","cursorOffsetCache","renderCursorOrSelection","skipRestore","_clearTextArea","boundaries","_getCursorBoundaries","renderCursor","renderSelection","_getCursorBoundariesOffsets","cursorPosition","cursorLocation","charHeight","__isMousedown","startLine","endLine","startChar","endChar","lineOffset","realLineHeight","boxEnd","compositionColor","getCurrentCharFontSize","cp","_getCurrentCharIndex","getCurrentCharColor","initAddedHandler","initRemovedHandler","initCursorSelectionHandlers","initDoubleClickSimulation","mouseMoveHandler","_initCanvasHandlers","_removeCanvasHandlers","_tick","_currentTickState","_animateCursor","targetOpacity","completeMethod","tickState","isAborted","_onTickComplete","_cursorTimeout1","_currentTickCompleteState","restart","delay","abortCursorAnimation","_cursorTimeout2","selectAll","getSelectedText","findWordBoundaryLeft","startFrom","findWordBoundaryRight","findLineBoundaryLeft","findLineBoundaryRight","searchWordBoundary","direction","reNonWord","selectWord","newSelectionStart","newSelectionEnd","selectLine","enterEditing","exitEditingOnOthers","initHiddenTextarea","_saveEditingProps","_setEditingProps","_textBeforeEdit","initMouseMoveHandler","getSelectionStartFromPointer","currentStart","currentEnd","__selectionStartOnMouseDown","restartCursorIfNeeded","fromStringToGraphemeSelection","smallerTextStart","graphemeStart","smallerTextEnd","fromGraphemeToStringSelection","newSelection","updateTextareaPosition","updateFromTextArea","_calcTextareaPosition","desiredPostion","compositionStart","upperCanvas","upperCanvasWidth","upperCanvasHeight","clientWidth","clientHeight","_savedProps","_restoreEditingProps","isTextChanged","_removeExtraneousStyles","removeStyleFromTo","cursorStart","styleObj","cursorEnd","lineStart","charStart","lineEnd","charEnd","shiftLineStyles","numericChar","clonedStyles","numericLine","insertNewlineStyleObject","qty","copiedStyle","currentCharStyle","newLineStyles","somethingAdded","numIndex","insertCharStyleObject","quantity","currentLineStyles","currentLineStylesCloned","numericIndex","newStyle","insertNewStyleBlock","insertedText","cursorLoc","addedLines","linesLenght","setSelectionStartEndWithShift","setSelectionInBoundaries","__lastClickTime","__lastLastClickTime","__lastPointer","__newClickTime","newPointer","isTripleClick","_stopEvent","__lastIsEditing","__lastSelected","initMousedownHandler","initMouseupHandler","initClicks","_mouseDownHandler","setCursorByClick","_mouseDownHandlerBefore","mouseUpHandler","currentActive","mouseOffset","prevWidth","_getNewSelectionStartFromOffset","distanceBtwLastCharAndCursor","distanceBtwNextCharAndCursor","onKeyDown","onKeyUp","onInput","copy","paste","onCompositionStart","onCompositionUpdate","onCompositionEnd","_clickHandlerInitialized","onClick","keysMap","ctrlKeysMapUp","ctrlKeysMapDown","keyCode","ctrlKey","metaKey","stopImmediatePropagation","_copyDone","fromPaste","nextText","removedText","charCount","nextCharCount","charDiff","textareaSelection","backDelete","copiedText","copiedTextStyle","compositionEnd","_getClipboardData","clipboardData","_getWidthBeforeCursor","widthBeforeCursor","getDownCursorOffset","isRight","selectionProp","_getSelectionForOffset","indexOnOtherLine","_getIndexOnLine","textAfterCursor","getUpCursorOffset","textBeforeCursor","charWidth","foundMatch","widthOfCharsOnLine","indexOnLine","leftEdge","rightEdge","offsetFromLeftEdge","moveCursorDown","_moveCursorUpOrDown","moveCursorUp","moveCursorWithShift","moveCursorWithoutShift","moveCursorLeft","_moveCursorLeftOrRight","_move","_moveLeft","_moveRight","moveCursorLeftWithoutShift","change","moveCursorLeftWithShift","moveCursorRight","actionName","moveCursorRightWithShift","moveCursorRightWithoutShift","changed","removeChars","insertChars","multipleSpacesRegex","_getSVGLeftTopOffsets","textAndBg","_getSVGTextAndBg","textTop","textLeft","internalMarkup","_wrapSVGTextAndBg","lineTop","noShadow","textSpans","textTopOffset","textLeftOffset","_setSVGTextLineBg","_setSVGTextLineText","_createTextCharSpan","styleDecl","shouldUseWhitespace","styleProps","fillStyles","dySpan","_pushTextBgRect","fillColor","_getSVGLineTopOffset","lastHeight","svgStyle","Textbox","minWidth","dynamicMinWidth","__cachedLines","_styleMap","_generateStyleMap","textInfo","realLineCount","realLineCharCount","isWrapping","nextOffset","shouldLimit","mapNextLine","_wrapText","desiredWidth","wrapped","_wrapLine","_measureWord","word","charOffset","_line","reservedSpace","words","wordWidth","infixWidth","largestWordWidth","lineJustStarted","additionalSpace","getMinWidth","setObjectScaleOverridden","tw","hotkeys","isff","navigator","userAgent","addEvent","getMods","modifier","mods","getKeys","lastIndexOf","compareArray","arr1","arr2","isIndex","_keyMap","backspace","tab","enter","return","esc","escape","space","up","down","del","delete","ins","insert","home","pageup","pagedown","capslock","_modifier","alt","option","ctrl","cmd","_downKeys","modifierMap","_mods","_handlers","_scope","isBindElement","setScope","scope","getScope","getPressedKeyCodes","isContentEditable","isPressed","deleteScope","newScope","clearModifier","charCode","unbind","multipleKeys","eventHandler","modifiersMatch","shortcut","cancelBubble","dispatch","asterisk","_api","_hotkeys","noConflict","fs","message","debug","Boolean","keyValueArr","dotenvPath","resolve","readFileSync","load"],"mappings":"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","file":"online.def598ed.map","sourceRoot":"../src","sourcesContent":["// shim for using process in browser\nvar process = module.exports = {};\n\n// cached from whatever global is present so that test runners that stub it\n// don't break things.  But we need to wrap it in a try catch in case it is\n// wrapped in strict mode code which doesn't define any globals.  It's inside a\n// function because try/catches deoptimize in certain engines.\n\nvar cachedSetTimeout;\nvar cachedClearTimeout;\n\nfunction defaultSetTimout() {\n    throw new Error('setTimeout has not been defined');\n}\nfunction defaultClearTimeout () {\n    throw new Error('clearTimeout has not been defined');\n}\n(function () {\n    try {\n        if (typeof setTimeout === 'function') {\n            cachedSetTimeout = setTimeout;\n        } else {\n            cachedSetTimeout = defaultSetTimout;\n        }\n    } catch (e) {\n        cachedSetTimeout = defaultSetTimout;\n    }\n    try {\n        if (typeof clearTimeout === 'function') {\n            cachedClearTimeout = clearTimeout;\n        } else {\n            cachedClearTimeout = defaultClearTimeout;\n        }\n    } catch (e) {\n        cachedClearTimeout = defaultClearTimeout;\n    }\n} ())\nfunction runTimeout(fun) {\n    if (cachedSetTimeout === setTimeout) {\n        //normal enviroments in sane situations\n        return setTimeout(fun, 0);\n    }\n    // if setTimeout wasn't available but was latter defined\n    if ((cachedSetTimeout === defaultSetTimout || !cachedSetTimeout) && setTimeout) {\n        cachedSetTimeout = setTimeout;\n        return setTimeout(fun, 0);\n    }\n    try {\n        // when when somebody has screwed with setTimeout but no I.E. maddness\n        return cachedSetTimeout(fun, 0);\n    } catch(e){\n        try {\n            // When we are in I.E. but the script has been evaled so I.E. doesn't trust the global object when called normally\n            return cachedSetTimeout.call(null, fun, 0);\n        } catch(e){\n            // same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error\n            return cachedSetTimeout.call(this, fun, 0);\n        }\n    }\n\n\n}\nfunction runClearTimeout(marker) {\n    if (cachedClearTimeout === clearTimeout) {\n        //normal enviroments in sane situations\n        return clearTimeout(marker);\n    }\n    // if clearTimeout wasn't available but was latter defined\n    if ((cachedClearTimeout === defaultClearTimeout || !cachedClearTimeout) && clearTimeout) {\n        cachedClearTimeout = clearTimeout;\n        return clearTimeout(marker);\n    }\n    try {\n        // when when somebody has screwed with setTimeout but no I.E. maddness\n        return cachedClearTimeout(marker);\n    } catch (e){\n        try {\n            // When we are in I.E. but the script has been evaled so I.E. doesn't  trust the global object when called normally\n            return cachedClearTimeout.call(null, marker);\n        } catch (e){\n            // same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error.\n            // Some versions of I.E. have different rules for clearTimeout vs setTimeout\n            return cachedClearTimeout.call(this, marker);\n        }\n    }\n\n\n\n}\nvar queue = [];\nvar draining = false;\nvar currentQueue;\nvar queueIndex = -1;\n\nfunction cleanUpNextTick() {\n    if (!draining || !currentQueue) {\n        return;\n    }\n    draining = false;\n    if (currentQueue.length) {\n        queue = currentQueue.concat(queue);\n    } else {\n        queueIndex = -1;\n    }\n    if (queue.length) {\n        drainQueue();\n    }\n}\n\nfunction drainQueue() {\n    if (draining) {\n        return;\n    }\n    var timeout = runTimeout(cleanUpNextTick);\n    draining = true;\n\n    var len = queue.length;\n    while(len) {\n        currentQueue = queue;\n        queue = [];\n        while (++queueIndex < len) {\n            if (currentQueue) {\n                currentQueue[queueIndex].run();\n            }\n        }\n        queueIndex = -1;\n        len = queue.length;\n    }\n    currentQueue = null;\n    draining = false;\n    runClearTimeout(timeout);\n}\n\nprocess.nextTick = function (fun) {\n    var args = new Array(arguments.length - 1);\n    if (arguments.length > 1) {\n        for (var i = 1; i < arguments.length; i++) {\n            args[i - 1] = arguments[i];\n        }\n    }\n    queue.push(new Item(fun, args));\n    if (queue.length === 1 && !draining) {\n        runTimeout(drainQueue);\n    }\n};\n\n// v8 likes predictible objects\nfunction Item(fun, array) {\n    this.fun = fun;\n    this.array = array;\n}\nItem.prototype.run = function () {\n    this.fun.apply(null, this.array);\n};\nprocess.title = 'browser';\nprocess.browser = true;\nprocess.env = {};\nprocess.argv = [];\nprocess.version = ''; // empty string to avoid regexp issues\nprocess.versions = {};\n\nfunction noop() {}\n\nprocess.on = noop;\nprocess.addListener = noop;\nprocess.once = noop;\nprocess.off = noop;\nprocess.removeListener = noop;\nprocess.removeAllListeners = noop;\nprocess.emit = noop;\nprocess.prependListener = noop;\nprocess.prependOnceListener = noop;\n\nprocess.listeners = function (name) { return [] }\n\nprocess.binding = function (name) {\n    throw new Error('process.binding is not supported');\n};\n\nprocess.cwd = function () { return '/' };\nprocess.chdir = function (dir) {\n    throw new Error('process.chdir is not supported');\n};\nprocess.umask = function() { return 0; };\n","/*!\n * jQuery JavaScript Library v3.3.1\n * https://jquery.com/\n *\n * Includes Sizzle.js\n * https://sizzlejs.com/\n *\n * Copyright JS Foundation and other contributors\n * Released under the MIT license\n * https://jquery.org/license\n *\n * Date: 2018-01-20T17:24Z\n */\n( function( global, factory ) {\n\n\t\"use strict\";\n\n\tif ( typeof module === \"object\" && typeof module.exports === \"object\" ) {\n\n\t\t// For CommonJS and CommonJS-like environments where a proper `window`\n\t\t// is present, execute the factory and get jQuery.\n\t\t// For environments that do not have a `window` with a `document`\n\t\t// (such as Node.js), expose a factory as module.exports.\n\t\t// This accentuates the need for the creation of a real `window`.\n\t\t// e.g. var jQuery = require(\"jquery\")(window);\n\t\t// See ticket #14549 for more info.\n\t\tmodule.exports = global.document ?\n\t\t\tfactory( global, true ) :\n\t\t\tfunction( w ) {\n\t\t\t\tif ( !w.document ) {\n\t\t\t\t\tthrow new Error( \"jQuery requires a window with a document\" );\n\t\t\t\t}\n\t\t\t\treturn factory( w );\n\t\t\t};\n\t} else {\n\t\tfactory( global );\n\t}\n\n// Pass this if window is not defined yet\n} )( typeof window !== \"undefined\" ? window : this, function( window, noGlobal ) {\n\n// Edge <= 12 - 13+, Firefox <=18 - 45+, IE 10 - 11, Safari 5.1 - 9+, iOS 6 - 9.1\n// throw exceptions when non-strict code (e.g., ASP.NET 4.5) accesses strict mode\n// arguments.callee.caller (trac-13335). But as of jQuery 3.0 (2016), strict mode should be common\n// enough that all such attempts are guarded in a try block.\n\"use strict\";\n\nvar arr = [];\n\nvar document = window.document;\n\nvar getProto = Object.getPrototypeOf;\n\nvar slice = arr.slice;\n\nvar concat = arr.concat;\n\nvar push = arr.push;\n\nvar indexOf = arr.indexOf;\n\nvar class2type = {};\n\nvar toString = class2type.toString;\n\nvar hasOwn = class2type.hasOwnProperty;\n\nvar fnToString = hasOwn.toString;\n\nvar ObjectFunctionString = fnToString.call( Object );\n\nvar support = {};\n\nvar isFunction = function isFunction( obj ) {\n\n      // Support: Chrome <=57, Firefox <=52\n      // In some browsers, typeof returns \"function\" for HTML <object> elements\n      // (i.e., `typeof document.createElement( \"object\" ) === \"function\"`).\n      // We don't want to classify *any* DOM node as a function.\n      return typeof obj === \"function\" && typeof obj.nodeType !== \"number\";\n  };\n\n\nvar isWindow = function isWindow( obj ) {\n\t\treturn obj != null && obj === obj.window;\n\t};\n\n\n\n\n\tvar preservedScriptAttributes = {\n\t\ttype: true,\n\t\tsrc: true,\n\t\tnoModule: true\n\t};\n\n\tfunction DOMEval( code, doc, node ) {\n\t\tdoc = doc || document;\n\n\t\tvar i,\n\t\t\tscript = doc.createElement( \"script\" );\n\n\t\tscript.text = code;\n\t\tif ( node ) {\n\t\t\tfor ( i in preservedScriptAttributes ) {\n\t\t\t\tif ( node[ i ] ) {\n\t\t\t\t\tscript[ i ] = node[ i ];\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tdoc.head.appendChild( script ).parentNode.removeChild( script );\n\t}\n\n\nfunction toType( obj ) {\n\tif ( obj == null ) {\n\t\treturn obj + \"\";\n\t}\n\n\t// Support: Android <=2.3 only (functionish RegExp)\n\treturn typeof obj === \"object\" || typeof obj === \"function\" ?\n\t\tclass2type[ toString.call( obj ) ] || \"object\" :\n\t\ttypeof obj;\n}\n/* global Symbol */\n// Defining this global in .eslintrc.json would create a danger of using the global\n// unguarded in another place, it seems safer to define global only for this module\n\n\n\nvar\n\tversion = \"3.3.1\",\n\n\t// Define a local copy of jQuery\n\tjQuery = function( selector, context ) {\n\n\t\t// The jQuery object is actually just the init constructor 'enhanced'\n\t\t// Need init if jQuery is called (just allow error to be thrown if not included)\n\t\treturn new jQuery.fn.init( selector, context );\n\t},\n\n\t// Support: Android <=4.0 only\n\t// Make sure we trim BOM and NBSP\n\trtrim = /^[\\s\\uFEFF\\xA0]+|[\\s\\uFEFF\\xA0]+$/g;\n\njQuery.fn = jQuery.prototype = {\n\n\t// The current version of jQuery being used\n\tjquery: version,\n\n\tconstructor: jQuery,\n\n\t// The default length of a jQuery object is 0\n\tlength: 0,\n\n\ttoArray: function() {\n\t\treturn slice.call( this );\n\t},\n\n\t// Get the Nth element in the matched element set OR\n\t// Get the whole matched element set as a clean array\n\tget: function( num ) {\n\n\t\t// Return all the elements in a clean array\n\t\tif ( num == null ) {\n\t\t\treturn slice.call( this );\n\t\t}\n\n\t\t// Return just the one element from the set\n\t\treturn num < 0 ? this[ num + this.length ] : this[ num ];\n\t},\n\n\t// Take an array of elements and push it onto the stack\n\t// (returning the new matched element set)\n\tpushStack: function( elems ) {\n\n\t\t// Build a new jQuery matched element set\n\t\tvar ret = jQuery.merge( this.constructor(), elems );\n\n\t\t// Add the old object onto the stack (as a reference)\n\t\tret.prevObject = this;\n\n\t\t// Return the newly-formed element set\n\t\treturn ret;\n\t},\n\n\t// Execute a callback for every element in the matched set.\n\teach: function( callback ) {\n\t\treturn jQuery.each( this, callback );\n\t},\n\n\tmap: function( callback ) {\n\t\treturn this.pushStack( jQuery.map( this, function( elem, i ) {\n\t\t\treturn callback.call( elem, i, elem );\n\t\t} ) );\n\t},\n\n\tslice: function() {\n\t\treturn this.pushStack( slice.apply( this, arguments ) );\n\t},\n\n\tfirst: function() {\n\t\treturn this.eq( 0 );\n\t},\n\n\tlast: function() {\n\t\treturn this.eq( -1 );\n\t},\n\n\teq: function( i ) {\n\t\tvar len = this.length,\n\t\t\tj = +i + ( i < 0 ? len : 0 );\n\t\treturn this.pushStack( j >= 0 && j < len ? [ this[ j ] ] : [] );\n\t},\n\n\tend: function() {\n\t\treturn this.prevObject || this.constructor();\n\t},\n\n\t// For internal use only.\n\t// Behaves like an Array's method, not like a jQuery method.\n\tpush: push,\n\tsort: arr.sort,\n\tsplice: arr.splice\n};\n\njQuery.extend = jQuery.fn.extend = function() {\n\tvar options, name, src, copy, copyIsArray, clone,\n\t\ttarget = arguments[ 0 ] || {},\n\t\ti = 1,\n\t\tlength = arguments.length,\n\t\tdeep = false;\n\n\t// Handle a deep copy situation\n\tif ( typeof target === \"boolean\" ) {\n\t\tdeep = target;\n\n\t\t// Skip the boolean and the target\n\t\ttarget = arguments[ i ] || {};\n\t\ti++;\n\t}\n\n\t// Handle case when target is a string or something (possible in deep copy)\n\tif ( typeof target !== \"object\" && !isFunction( target ) ) {\n\t\ttarget = {};\n\t}\n\n\t// Extend jQuery itself if only one argument is passed\n\tif ( i === length ) {\n\t\ttarget = this;\n\t\ti--;\n\t}\n\n\tfor ( ; i < length; i++ ) {\n\n\t\t// Only deal with non-null/undefined values\n\t\tif ( ( options = arguments[ i ] ) != null ) {\n\n\t\t\t// Extend the base object\n\t\t\tfor ( name in options ) {\n\t\t\t\tsrc = target[ name ];\n\t\t\t\tcopy = options[ name ];\n\n\t\t\t\t// Prevent never-ending loop\n\t\t\t\tif ( target === copy ) {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\t// Recurse if we're merging plain objects or arrays\n\t\t\t\tif ( deep && copy && ( jQuery.isPlainObject( copy ) ||\n\t\t\t\t\t( copyIsArray = Array.isArray( copy ) ) ) ) {\n\n\t\t\t\t\tif ( copyIsArray ) {\n\t\t\t\t\t\tcopyIsArray = false;\n\t\t\t\t\t\tclone = src && Array.isArray( src ) ? src : [];\n\n\t\t\t\t\t} else {\n\t\t\t\t\t\tclone = src && jQuery.isPlainObject( src ) ? src : {};\n\t\t\t\t\t}\n\n\t\t\t\t\t// Never move original objects, clone them\n\t\t\t\t\ttarget[ name ] = jQuery.extend( deep, clone, copy );\n\n\t\t\t\t// Don't bring in undefined values\n\t\t\t\t} else if ( copy !== undefined ) {\n\t\t\t\t\ttarget[ name ] = copy;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t// Return the modified object\n\treturn target;\n};\n\njQuery.extend( {\n\n\t// Unique for each copy of jQuery on the page\n\texpando: \"jQuery\" + ( version + Math.random() ).replace( /\\D/g, \"\" ),\n\n\t// Assume jQuery is ready without the ready module\n\tisReady: true,\n\n\terror: function( msg ) {\n\t\tthrow new Error( msg );\n\t},\n\n\tnoop: function() {},\n\n\tisPlainObject: function( obj ) {\n\t\tvar proto, Ctor;\n\n\t\t// Detect obvious negatives\n\t\t// Use toString instead of jQuery.type to catch host objects\n\t\tif ( !obj || toString.call( obj ) !== \"[object Object]\" ) {\n\t\t\treturn false;\n\t\t}\n\n\t\tproto = getProto( obj );\n\n\t\t// Objects with no prototype (e.g., `Object.create( null )`) are plain\n\t\tif ( !proto ) {\n\t\t\treturn true;\n\t\t}\n\n\t\t// Objects with prototype are plain iff they were constructed by a global Object function\n\t\tCtor = hasOwn.call( proto, \"constructor\" ) && proto.constructor;\n\t\treturn typeof Ctor === \"function\" && fnToString.call( Ctor ) === ObjectFunctionString;\n\t},\n\n\tisEmptyObject: function( obj ) {\n\n\t\t/* eslint-disable no-unused-vars */\n\t\t// See https://github.com/eslint/eslint/issues/6125\n\t\tvar name;\n\n\t\tfor ( name in obj ) {\n\t\t\treturn false;\n\t\t}\n\t\treturn true;\n\t},\n\n\t// Evaluates a script in a global context\n\tglobalEval: function( code ) {\n\t\tDOMEval( code );\n\t},\n\n\teach: function( obj, callback ) {\n\t\tvar length, i = 0;\n\n\t\tif ( isArrayLike( obj ) ) {\n\t\t\tlength = obj.length;\n\t\t\tfor ( ; i < length; i++ ) {\n\t\t\t\tif ( callback.call( obj[ i ], i, obj[ i ] ) === false ) {\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\tfor ( i in obj ) {\n\t\t\t\tif ( callback.call( obj[ i ], i, obj[ i ] ) === false ) {\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn obj;\n\t},\n\n\t// Support: Android <=4.0 only\n\ttrim: function( text ) {\n\t\treturn text == null ?\n\t\t\t\"\" :\n\t\t\t( text + \"\" ).replace( rtrim, \"\" );\n\t},\n\n\t// results is for internal usage only\n\tmakeArray: function( arr, results ) {\n\t\tvar ret = results || [];\n\n\t\tif ( arr != null ) {\n\t\t\tif ( isArrayLike( Object( arr ) ) ) {\n\t\t\t\tjQuery.merge( ret,\n\t\t\t\t\ttypeof arr === \"string\" ?\n\t\t\t\t\t[ arr ] : arr\n\t\t\t\t);\n\t\t\t} else {\n\t\t\t\tpush.call( ret, arr );\n\t\t\t}\n\t\t}\n\n\t\treturn ret;\n\t},\n\n\tinArray: function( elem, arr, i ) {\n\t\treturn arr == null ? -1 : indexOf.call( arr, elem, i );\n\t},\n\n\t// Support: Android <=4.0 only, PhantomJS 1 only\n\t// push.apply(_, arraylike) throws on ancient WebKit\n\tmerge: function( first, second ) {\n\t\tvar len = +second.length,\n\t\t\tj = 0,\n\t\t\ti = first.length;\n\n\t\tfor ( ; j < len; j++ ) {\n\t\t\tfirst[ i++ ] = second[ j ];\n\t\t}\n\n\t\tfirst.length = i;\n\n\t\treturn first;\n\t},\n\n\tgrep: function( elems, callback, invert ) {\n\t\tvar callbackInverse,\n\t\t\tmatches = [],\n\t\t\ti = 0,\n\t\t\tlength = elems.length,\n\t\t\tcallbackExpect = !invert;\n\n\t\t// Go through the array, only saving the items\n\t\t// that pass the validator function\n\t\tfor ( ; i < length; i++ ) {\n\t\t\tcallbackInverse = !callback( elems[ i ], i );\n\t\t\tif ( callbackInverse !== callbackExpect ) {\n\t\t\t\tmatches.push( elems[ i ] );\n\t\t\t}\n\t\t}\n\n\t\treturn matches;\n\t},\n\n\t// arg is for internal usage only\n\tmap: function( elems, callback, arg ) {\n\t\tvar length, value,\n\t\t\ti = 0,\n\t\t\tret = [];\n\n\t\t// Go through the array, translating each of the items to their new values\n\t\tif ( isArrayLike( elems ) ) {\n\t\t\tlength = elems.length;\n\t\t\tfor ( ; i < length; i++ ) {\n\t\t\t\tvalue = callback( elems[ i ], i, arg );\n\n\t\t\t\tif ( value != null ) {\n\t\t\t\t\tret.push( value );\n\t\t\t\t}\n\t\t\t}\n\n\t\t// Go through every key on the object,\n\t\t} else {\n\t\t\tfor ( i in elems ) {\n\t\t\t\tvalue = callback( elems[ i ], i, arg );\n\n\t\t\t\tif ( value != null ) {\n\t\t\t\t\tret.push( value );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Flatten any nested arrays\n\t\treturn concat.apply( [], ret );\n\t},\n\n\t// A global GUID counter for objects\n\tguid: 1,\n\n\t// jQuery.support is not used in Core but other projects attach their\n\t// properties to it so it needs to exist.\n\tsupport: support\n} );\n\nif ( typeof Symbol === \"function\" ) {\n\tjQuery.fn[ Symbol.iterator ] = arr[ Symbol.iterator ];\n}\n\n// Populate the class2type map\njQuery.each( \"Boolean Number String Function Array Date RegExp Object Error Symbol\".split( \" \" ),\nfunction( i, name ) {\n\tclass2type[ \"[object \" + name + \"]\" ] = name.toLowerCase();\n} );\n\nfunction isArrayLike( obj ) {\n\n\t// Support: real iOS 8.2 only (not reproducible in simulator)\n\t// `in` check used to prevent JIT error (gh-2145)\n\t// hasOwn isn't used here due to false negatives\n\t// regarding Nodelist length in IE\n\tvar length = !!obj && \"length\" in obj && obj.length,\n\t\ttype = toType( obj );\n\n\tif ( isFunction( obj ) || isWindow( obj ) ) {\n\t\treturn false;\n\t}\n\n\treturn type === \"array\" || length === 0 ||\n\t\ttypeof length === \"number\" && length > 0 && ( length - 1 ) in obj;\n}\nvar Sizzle =\n/*!\n * Sizzle CSS Selector Engine v2.3.3\n * https://sizzlejs.com/\n *\n * Copyright jQuery Foundation and other contributors\n * Released under the MIT license\n * http://jquery.org/license\n *\n * Date: 2016-08-08\n */\n(function( window ) {\n\nvar i,\n\tsupport,\n\tExpr,\n\tgetText,\n\tisXML,\n\ttokenize,\n\tcompile,\n\tselect,\n\toutermostContext,\n\tsortInput,\n\thasDuplicate,\n\n\t// Local document vars\n\tsetDocument,\n\tdocument,\n\tdocElem,\n\tdocumentIsHTML,\n\trbuggyQSA,\n\trbuggyMatches,\n\tmatches,\n\tcontains,\n\n\t// Instance-specific data\n\texpando = \"sizzle\" + 1 * new Date(),\n\tpreferredDoc = window.document,\n\tdirruns = 0,\n\tdone = 0,\n\tclassCache = createCache(),\n\ttokenCache = createCache(),\n\tcompilerCache = createCache(),\n\tsortOrder = function( a, b ) {\n\t\tif ( a === b ) {\n\t\t\thasDuplicate = true;\n\t\t}\n\t\treturn 0;\n\t},\n\n\t// Instance methods\n\thasOwn = ({}).hasOwnProperty,\n\tarr = [],\n\tpop = arr.pop,\n\tpush_native = arr.push,\n\tpush = arr.push,\n\tslice = arr.slice,\n\t// Use a stripped-down indexOf as it's faster than native\n\t// https://jsperf.com/thor-indexof-vs-for/5\n\tindexOf = function( list, elem ) {\n\t\tvar i = 0,\n\t\t\tlen = list.length;\n\t\tfor ( ; i < len; i++ ) {\n\t\t\tif ( list[i] === elem ) {\n\t\t\t\treturn i;\n\t\t\t}\n\t\t}\n\t\treturn -1;\n\t},\n\n\tbooleans = \"checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped\",\n\n\t// Regular expressions\n\n\t// http://www.w3.org/TR/css3-selectors/#whitespace\n\twhitespace = \"[\\\\x20\\\\t\\\\r\\\\n\\\\f]\",\n\n\t// http://www.w3.org/TR/CSS21/syndata.html#value-def-identifier\n\tidentifier = \"(?:\\\\\\\\.|[\\\\w-]|[^\\0-\\\\xa0])+\",\n\n\t// Attribute selectors: http://www.w3.org/TR/selectors/#attribute-selectors\n\tattributes = \"\\\\[\" + whitespace + \"*(\" + identifier + \")(?:\" + whitespace +\n\t\t// Operator (capture 2)\n\t\t\"*([*^$|!~]?=)\" + whitespace +\n\t\t// \"Attribute values must be CSS identifiers [capture 5] or strings [capture 3 or capture 4]\"\n\t\t\"*(?:'((?:\\\\\\\\.|[^\\\\\\\\'])*)'|\\\"((?:\\\\\\\\.|[^\\\\\\\\\\\"])*)\\\"|(\" + identifier + \"))|)\" + whitespace +\n\t\t\"*\\\\]\",\n\n\tpseudos = \":(\" + identifier + \")(?:\\\\((\" +\n\t\t// To reduce the number of selectors needing tokenize in the preFilter, prefer arguments:\n\t\t// 1. quoted (capture 3; capture 4 or capture 5)\n\t\t\"('((?:\\\\\\\\.|[^\\\\\\\\'])*)'|\\\"((?:\\\\\\\\.|[^\\\\\\\\\\\"])*)\\\")|\" +\n\t\t// 2. simple (capture 6)\n\t\t\"((?:\\\\\\\\.|[^\\\\\\\\()[\\\\]]|\" + attributes + \")*)|\" +\n\t\t// 3. anything else (capture 2)\n\t\t\".*\" +\n\t\t\")\\\\)|)\",\n\n\t// Leading and non-escaped trailing whitespace, capturing some non-whitespace characters preceding the latter\n\trwhitespace = new RegExp( whitespace + \"+\", \"g\" ),\n\trtrim = new RegExp( \"^\" + whitespace + \"+|((?:^|[^\\\\\\\\])(?:\\\\\\\\.)*)\" + whitespace + \"+$\", \"g\" ),\n\n\trcomma = new RegExp( \"^\" + whitespace + \"*,\" + whitespace + \"*\" ),\n\trcombinators = new RegExp( \"^\" + whitespace + \"*([>+~]|\" + whitespace + \")\" + whitespace + \"*\" ),\n\n\trattributeQuotes = new RegExp( \"=\" + whitespace + \"*([^\\\\]'\\\"]*?)\" + whitespace + \"*\\\\]\", \"g\" ),\n\n\trpseudo = new RegExp( pseudos ),\n\tridentifier = new RegExp( \"^\" + identifier + \"$\" ),\n\n\tmatchExpr = {\n\t\t\"ID\": new RegExp( \"^#(\" + identifier + \")\" ),\n\t\t\"CLASS\": new RegExp( \"^\\\\.(\" + identifier + \")\" ),\n\t\t\"TAG\": new RegExp( \"^(\" + identifier + \"|[*])\" ),\n\t\t\"ATTR\": new RegExp( \"^\" + attributes ),\n\t\t\"PSEUDO\": new RegExp( \"^\" + pseudos ),\n\t\t\"CHILD\": new RegExp( \"^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\\\(\" + whitespace +\n\t\t\t\"*(even|odd|(([+-]|)(\\\\d*)n|)\" + whitespace + \"*(?:([+-]|)\" + whitespace +\n\t\t\t\"*(\\\\d+)|))\" + whitespace + \"*\\\\)|)\", \"i\" ),\n\t\t\"bool\": new RegExp( \"^(?:\" + booleans + \")$\", \"i\" ),\n\t\t// For use in libraries implementing .is()\n\t\t// We use this for POS matching in `select`\n\t\t\"needsContext\": new RegExp( \"^\" + whitespace + \"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\\\(\" +\n\t\t\twhitespace + \"*((?:-\\\\d)?\\\\d*)\" + whitespace + \"*\\\\)|)(?=[^-]|$)\", \"i\" )\n\t},\n\n\trinputs = /^(?:input|select|textarea|button)$/i,\n\trheader = /^h\\d$/i,\n\n\trnative = /^[^{]+\\{\\s*\\[native \\w/,\n\n\t// Easily-parseable/retrievable ID or TAG or CLASS selectors\n\trquickExpr = /^(?:#([\\w-]+)|(\\w+)|\\.([\\w-]+))$/,\n\n\trsibling = /[+~]/,\n\n\t// CSS escapes\n\t// http://www.w3.org/TR/CSS21/syndata.html#escaped-characters\n\trunescape = new RegExp( \"\\\\\\\\([\\\\da-f]{1,6}\" + whitespace + \"?|(\" + whitespace + \")|.)\", \"ig\" ),\n\tfunescape = function( _, escaped, escapedWhitespace ) {\n\t\tvar high = \"0x\" + escaped - 0x10000;\n\t\t// NaN means non-codepoint\n\t\t// Support: Firefox<24\n\t\t// Workaround erroneous numeric interpretation of +\"0x\"\n\t\treturn high !== high || escapedWhitespace ?\n\t\t\tescaped :\n\t\t\thigh < 0 ?\n\t\t\t\t// BMP codepoint\n\t\t\t\tString.fromCharCode( high + 0x10000 ) :\n\t\t\t\t// Supplemental Plane codepoint (surrogate pair)\n\t\t\t\tString.fromCharCode( high >> 10 | 0xD800, high & 0x3FF | 0xDC00 );\n\t},\n\n\t// CSS string/identifier serialization\n\t// https://drafts.csswg.org/cssom/#common-serializing-idioms\n\trcssescape = /([\\0-\\x1f\\x7f]|^-?\\d)|^-$|[^\\0-\\x1f\\x7f-\\uFFFF\\w-]/g,\n\tfcssescape = function( ch, asCodePoint ) {\n\t\tif ( asCodePoint ) {\n\n\t\t\t// U+0000 NULL becomes U+FFFD REPLACEMENT CHARACTER\n\t\t\tif ( ch === \"\\0\" ) {\n\t\t\t\treturn \"\\uFFFD\";\n\t\t\t}\n\n\t\t\t// Control characters and (dependent upon position) numbers get escaped as code points\n\t\t\treturn ch.slice( 0, -1 ) + \"\\\\\" + ch.charCodeAt( ch.length - 1 ).toString( 16 ) + \" \";\n\t\t}\n\n\t\t// Other potentially-special ASCII characters get backslash-escaped\n\t\treturn \"\\\\\" + ch;\n\t},\n\n\t// Used for iframes\n\t// See setDocument()\n\t// Removing the function wrapper causes a \"Permission Denied\"\n\t// error in IE\n\tunloadHandler = function() {\n\t\tsetDocument();\n\t},\n\n\tdisabledAncestor = addCombinator(\n\t\tfunction( elem ) {\n\t\t\treturn elem.disabled === true && (\"form\" in elem || \"label\" in elem);\n\t\t},\n\t\t{ dir: \"parentNode\", next: \"legend\" }\n\t);\n\n// Optimize for push.apply( _, NodeList )\ntry {\n\tpush.apply(\n\t\t(arr = slice.call( preferredDoc.childNodes )),\n\t\tpreferredDoc.childNodes\n\t);\n\t// Support: Android<4.0\n\t// Detect silently failing push.apply\n\tarr[ preferredDoc.childNodes.length ].nodeType;\n} catch ( e ) {\n\tpush = { apply: arr.length ?\n\n\t\t// Leverage slice if possible\n\t\tfunction( target, els ) {\n\t\t\tpush_native.apply( target, slice.call(els) );\n\t\t} :\n\n\t\t// Support: IE<9\n\t\t// Otherwise append directly\n\t\tfunction( target, els ) {\n\t\t\tvar j = target.length,\n\t\t\t\ti = 0;\n\t\t\t// Can't trust NodeList.length\n\t\t\twhile ( (target[j++] = els[i++]) ) {}\n\t\t\ttarget.length = j - 1;\n\t\t}\n\t};\n}\n\nfunction Sizzle( selector, context, results, seed ) {\n\tvar m, i, elem, nid, match, groups, newSelector,\n\t\tnewContext = context && context.ownerDocument,\n\n\t\t// nodeType defaults to 9, since context defaults to document\n\t\tnodeType = context ? context.nodeType : 9;\n\n\tresults = results || [];\n\n\t// Return early from calls with invalid selector or context\n\tif ( typeof selector !== \"string\" || !selector ||\n\t\tnodeType !== 1 && nodeType !== 9 && nodeType !== 11 ) {\n\n\t\treturn results;\n\t}\n\n\t// Try to shortcut find operations (as opposed to filters) in HTML documents\n\tif ( !seed ) {\n\n\t\tif ( ( context ? context.ownerDocument || context : preferredDoc ) !== document ) {\n\t\t\tsetDocument( context );\n\t\t}\n\t\tcontext = context || document;\n\n\t\tif ( documentIsHTML ) {\n\n\t\t\t// If the selector is sufficiently simple, try using a \"get*By*\" DOM method\n\t\t\t// (excepting DocumentFragment context, where the methods don't exist)\n\t\t\tif ( nodeType !== 11 && (match = rquickExpr.exec( selector )) ) {\n\n\t\t\t\t// ID selector\n\t\t\t\tif ( (m = match[1]) ) {\n\n\t\t\t\t\t// Document context\n\t\t\t\t\tif ( nodeType === 9 ) {\n\t\t\t\t\t\tif ( (elem = context.getElementById( m )) ) {\n\n\t\t\t\t\t\t\t// Support: IE, Opera, Webkit\n\t\t\t\t\t\t\t// TODO: identify versions\n\t\t\t\t\t\t\t// getElementById can match elements by name instead of ID\n\t\t\t\t\t\t\tif ( elem.id === m ) {\n\t\t\t\t\t\t\t\tresults.push( elem );\n\t\t\t\t\t\t\t\treturn results;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\treturn results;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t// Element context\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\t// Support: IE, Opera, Webkit\n\t\t\t\t\t\t// TODO: identify versions\n\t\t\t\t\t\t// getElementById can match elements by name instead of ID\n\t\t\t\t\t\tif ( newContext && (elem = newContext.getElementById( m )) &&\n\t\t\t\t\t\t\tcontains( context, elem ) &&\n\t\t\t\t\t\t\telem.id === m ) {\n\n\t\t\t\t\t\t\tresults.push( elem );\n\t\t\t\t\t\t\treturn results;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t// Type selector\n\t\t\t\t} else if ( match[2] ) {\n\t\t\t\t\tpush.apply( results, context.getElementsByTagName( selector ) );\n\t\t\t\t\treturn results;\n\n\t\t\t\t// Class selector\n\t\t\t\t} else if ( (m = match[3]) && support.getElementsByClassName &&\n\t\t\t\t\tcontext.getElementsByClassName ) {\n\n\t\t\t\t\tpush.apply( results, context.getElementsByClassName( m ) );\n\t\t\t\t\treturn results;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Take advantage of querySelectorAll\n\t\t\tif ( support.qsa &&\n\t\t\t\t!compilerCache[ selector + \" \" ] &&\n\t\t\t\t(!rbuggyQSA || !rbuggyQSA.test( selector )) ) {\n\n\t\t\t\tif ( nodeType !== 1 ) {\n\t\t\t\t\tnewContext = context;\n\t\t\t\t\tnewSelector = selector;\n\n\t\t\t\t// qSA looks outside Element context, which is not what we want\n\t\t\t\t// Thanks to Andrew Dupont for this workaround technique\n\t\t\t\t// Support: IE <=8\n\t\t\t\t// Exclude object elements\n\t\t\t\t} else if ( context.nodeName.toLowerCase() !== \"object\" ) {\n\n\t\t\t\t\t// Capture the context ID, setting it first if necessary\n\t\t\t\t\tif ( (nid = context.getAttribute( \"id\" )) ) {\n\t\t\t\t\t\tnid = nid.replace( rcssescape, fcssescape );\n\t\t\t\t\t} else {\n\t\t\t\t\t\tcontext.setAttribute( \"id\", (nid = expando) );\n\t\t\t\t\t}\n\n\t\t\t\t\t// Prefix every selector in the list\n\t\t\t\t\tgroups = tokenize( selector );\n\t\t\t\t\ti = groups.length;\n\t\t\t\t\twhile ( i-- ) {\n\t\t\t\t\t\tgroups[i] = \"#\" + nid + \" \" + toSelector( groups[i] );\n\t\t\t\t\t}\n\t\t\t\t\tnewSelector = groups.join( \",\" );\n\n\t\t\t\t\t// Expand context for sibling selectors\n\t\t\t\t\tnewContext = rsibling.test( selector ) && testContext( context.parentNode ) ||\n\t\t\t\t\t\tcontext;\n\t\t\t\t}\n\n\t\t\t\tif ( newSelector ) {\n\t\t\t\t\ttry {\n\t\t\t\t\t\tpush.apply( results,\n\t\t\t\t\t\t\tnewContext.querySelectorAll( newSelector )\n\t\t\t\t\t\t);\n\t\t\t\t\t\treturn results;\n\t\t\t\t\t} catch ( qsaError ) {\n\t\t\t\t\t} finally {\n\t\t\t\t\t\tif ( nid === expando ) {\n\t\t\t\t\t\t\tcontext.removeAttribute( \"id\" );\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t// All others\n\treturn select( selector.replace( rtrim, \"$1\" ), context, results, seed );\n}\n\n/**\n * Create key-value caches of limited size\n * @returns {function(string, object)} Returns the Object data after storing it on itself with\n *\tproperty name the (space-suffixed) string and (if the cache is larger than Expr.cacheLength)\n *\tdeleting the oldest entry\n */\nfunction createCache() {\n\tvar keys = [];\n\n\tfunction cache( key, value ) {\n\t\t// Use (key + \" \") to avoid collision with native prototype properties (see Issue #157)\n\t\tif ( keys.push( key + \" \" ) > Expr.cacheLength ) {\n\t\t\t// Only keep the most recent entries\n\t\t\tdelete cache[ keys.shift() ];\n\t\t}\n\t\treturn (cache[ key + \" \" ] = value);\n\t}\n\treturn cache;\n}\n\n/**\n * Mark a function for special use by Sizzle\n * @param {Function} fn The function to mark\n */\nfunction markFunction( fn ) {\n\tfn[ expando ] = true;\n\treturn fn;\n}\n\n/**\n * Support testing using an element\n * @param {Function} fn Passed the created element and returns a boolean result\n */\nfunction assert( fn ) {\n\tvar el = document.createElement(\"fieldset\");\n\n\ttry {\n\t\treturn !!fn( el );\n\t} catch (e) {\n\t\treturn false;\n\t} finally {\n\t\t// Remove from its parent by default\n\t\tif ( el.parentNode ) {\n\t\t\tel.parentNode.removeChild( el );\n\t\t}\n\t\t// release memory in IE\n\t\tel = null;\n\t}\n}\n\n/**\n * Adds the same handler for all of the specified attrs\n * @param {String} attrs Pipe-separated list of attributes\n * @param {Function} handler The method that will be applied\n */\nfunction addHandle( attrs, handler ) {\n\tvar arr = attrs.split(\"|\"),\n\t\ti = arr.length;\n\n\twhile ( i-- ) {\n\t\tExpr.attrHandle[ arr[i] ] = handler;\n\t}\n}\n\n/**\n * Checks document order of two siblings\n * @param {Element} a\n * @param {Element} b\n * @returns {Number} Returns less than 0 if a precedes b, greater than 0 if a follows b\n */\nfunction siblingCheck( a, b ) {\n\tvar cur = b && a,\n\t\tdiff = cur && a.nodeType === 1 && b.nodeType === 1 &&\n\t\t\ta.sourceIndex - b.sourceIndex;\n\n\t// Use IE sourceIndex if available on both nodes\n\tif ( diff ) {\n\t\treturn diff;\n\t}\n\n\t// Check if b follows a\n\tif ( cur ) {\n\t\twhile ( (cur = cur.nextSibling) ) {\n\t\t\tif ( cur === b ) {\n\t\t\t\treturn -1;\n\t\t\t}\n\t\t}\n\t}\n\n\treturn a ? 1 : -1;\n}\n\n/**\n * Returns a function to use in pseudos for input types\n * @param {String} type\n */\nfunction createInputPseudo( type ) {\n\treturn function( elem ) {\n\t\tvar name = elem.nodeName.toLowerCase();\n\t\treturn name === \"input\" && elem.type === type;\n\t};\n}\n\n/**\n * Returns a function to use in pseudos for buttons\n * @param {String} type\n */\nfunction createButtonPseudo( type ) {\n\treturn function( elem ) {\n\t\tvar name = elem.nodeName.toLowerCase();\n\t\treturn (name === \"input\" || name === \"button\") && elem.type === type;\n\t};\n}\n\n/**\n * Returns a function to use in pseudos for :enabled/:disabled\n * @param {Boolean} disabled true for :disabled; false for :enabled\n */\nfunction createDisabledPseudo( disabled ) {\n\n\t// Known :disabled false positives: fieldset[disabled] > legend:nth-of-type(n+2) :can-disable\n\treturn function( elem ) {\n\n\t\t// Only certain elements can match :enabled or :disabled\n\t\t// https://html.spec.whatwg.org/multipage/scripting.html#selector-enabled\n\t\t// https://html.spec.whatwg.org/multipage/scripting.html#selector-disabled\n\t\tif ( \"form\" in elem ) {\n\n\t\t\t// Check for inherited disabledness on relevant non-disabled elements:\n\t\t\t// * listed form-associated elements in a disabled fieldset\n\t\t\t//   https://html.spec.whatwg.org/multipage/forms.html#category-listed\n\t\t\t//   https://html.spec.whatwg.org/multipage/forms.html#concept-fe-disabled\n\t\t\t// * option elements in a disabled optgroup\n\t\t\t//   https://html.spec.whatwg.org/multipage/forms.html#concept-option-disabled\n\t\t\t// All such elements have a \"form\" property.\n\t\t\tif ( elem.parentNode && elem.disabled === false ) {\n\n\t\t\t\t// Option elements defer to a parent optgroup if present\n\t\t\t\tif ( \"label\" in elem ) {\n\t\t\t\t\tif ( \"label\" in elem.parentNode ) {\n\t\t\t\t\t\treturn elem.parentNode.disabled === disabled;\n\t\t\t\t\t} else {\n\t\t\t\t\t\treturn elem.disabled === disabled;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// Support: IE 6 - 11\n\t\t\t\t// Use the isDisabled shortcut property to check for disabled fieldset ancestors\n\t\t\t\treturn elem.isDisabled === disabled ||\n\n\t\t\t\t\t// Where there is no isDisabled, check manually\n\t\t\t\t\t/* jshint -W018 */\n\t\t\t\t\telem.isDisabled !== !disabled &&\n\t\t\t\t\t\tdisabledAncestor( elem ) === disabled;\n\t\t\t}\n\n\t\t\treturn elem.disabled === disabled;\n\n\t\t// Try to winnow out elements that can't be disabled before trusting the disabled property.\n\t\t// Some victims get caught in our net (label, legend, menu, track), but it shouldn't\n\t\t// even exist on them, let alone have a boolean value.\n\t\t} else if ( \"label\" in elem ) {\n\t\t\treturn elem.disabled === disabled;\n\t\t}\n\n\t\t// Remaining elements are neither :enabled nor :disabled\n\t\treturn false;\n\t};\n}\n\n/**\n * Returns a function to use in pseudos for positionals\n * @param {Function} fn\n */\nfunction createPositionalPseudo( fn ) {\n\treturn markFunction(function( argument ) {\n\t\targument = +argument;\n\t\treturn markFunction(function( seed, matches ) {\n\t\t\tvar j,\n\t\t\t\tmatchIndexes = fn( [], seed.length, argument ),\n\t\t\t\ti = matchIndexes.length;\n\n\t\t\t// Match elements found at the specified indexes\n\t\t\twhile ( i-- ) {\n\t\t\t\tif ( seed[ (j = matchIndexes[i]) ] ) {\n\t\t\t\t\tseed[j] = !(matches[j] = seed[j]);\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\t});\n}\n\n/**\n * Checks a node for validity as a Sizzle context\n * @param {Element|Object=} context\n * @returns {Element|Object|Boolean} The input node if acceptable, otherwise a falsy value\n */\nfunction testContext( context ) {\n\treturn context && typeof context.getElementsByTagName !== \"undefined\" && context;\n}\n\n// Expose support vars for convenience\nsupport = Sizzle.support = {};\n\n/**\n * Detects XML nodes\n * @param {Element|Object} elem An element or a document\n * @returns {Boolean} True iff elem is a non-HTML XML node\n */\nisXML = Sizzle.isXML = function( elem ) {\n\t// documentElement is verified for cases where it doesn't yet exist\n\t// (such as loading iframes in IE - #4833)\n\tvar documentElement = elem && (elem.ownerDocument || elem).documentElement;\n\treturn documentElement ? documentElement.nodeName !== \"HTML\" : false;\n};\n\n/**\n * Sets document-related variables once based on the current document\n * @param {Element|Object} [doc] An element or document object to use to set the document\n * @returns {Object} Returns the current document\n */\nsetDocument = Sizzle.setDocument = function( node ) {\n\tvar hasCompare, subWindow,\n\t\tdoc = node ? node.ownerDocument || node : preferredDoc;\n\n\t// Return early if doc is invalid or already selected\n\tif ( doc === document || doc.nodeType !== 9 || !doc.documentElement ) {\n\t\treturn document;\n\t}\n\n\t// Update global variables\n\tdocument = doc;\n\tdocElem = document.documentElement;\n\tdocumentIsHTML = !isXML( document );\n\n\t// Support: IE 9-11, Edge\n\t// Accessing iframe documents after unload throws \"permission denied\" errors (jQuery #13936)\n\tif ( preferredDoc !== document &&\n\t\t(subWindow = document.defaultView) && subWindow.top !== subWindow ) {\n\n\t\t// Support: IE 11, Edge\n\t\tif ( subWindow.addEventListener ) {\n\t\t\tsubWindow.addEventListener( \"unload\", unloadHandler, false );\n\n\t\t// Support: IE 9 - 10 only\n\t\t} else if ( subWindow.attachEvent ) {\n\t\t\tsubWindow.attachEvent( \"onunload\", unloadHandler );\n\t\t}\n\t}\n\n\t/* Attributes\n\t---------------------------------------------------------------------- */\n\n\t// Support: IE<8\n\t// Verify that getAttribute really returns attributes and not properties\n\t// (excepting IE8 booleans)\n\tsupport.attributes = assert(function( el ) {\n\t\tel.className = \"i\";\n\t\treturn !el.getAttribute(\"className\");\n\t});\n\n\t/* getElement(s)By*\n\t---------------------------------------------------------------------- */\n\n\t// Check if getElementsByTagName(\"*\") returns only elements\n\tsupport.getElementsByTagName = assert(function( el ) {\n\t\tel.appendChild( document.createComment(\"\") );\n\t\treturn !el.getElementsByTagName(\"*\").length;\n\t});\n\n\t// Support: IE<9\n\tsupport.getElementsByClassName = rnative.test( document.getElementsByClassName );\n\n\t// Support: IE<10\n\t// Check if getElementById returns elements by name\n\t// The broken getElementById methods don't pick up programmatically-set names,\n\t// so use a roundabout getElementsByName test\n\tsupport.getById = assert(function( el ) {\n\t\tdocElem.appendChild( el ).id = expando;\n\t\treturn !document.getElementsByName || !document.getElementsByName( expando ).length;\n\t});\n\n\t// ID filter and find\n\tif ( support.getById ) {\n\t\tExpr.filter[\"ID\"] = function( id ) {\n\t\t\tvar attrId = id.replace( runescape, funescape );\n\t\t\treturn function( elem ) {\n\t\t\t\treturn elem.getAttribute(\"id\") === attrId;\n\t\t\t};\n\t\t};\n\t\tExpr.find[\"ID\"] = function( id, context ) {\n\t\t\tif ( typeof context.getElementById !== \"undefined\" && documentIsHTML ) {\n\t\t\t\tvar elem = context.getElementById( id );\n\t\t\t\treturn elem ? [ elem ] : [];\n\t\t\t}\n\t\t};\n\t} else {\n\t\tExpr.filter[\"ID\"] =  function( id ) {\n\t\t\tvar attrId = id.replace( runescape, funescape );\n\t\t\treturn function( elem ) {\n\t\t\t\tvar node = typeof elem.getAttributeNode !== \"undefined\" &&\n\t\t\t\t\telem.getAttributeNode(\"id\");\n\t\t\t\treturn node && node.value === attrId;\n\t\t\t};\n\t\t};\n\n\t\t// Support: IE 6 - 7 only\n\t\t// getElementById is not reliable as a find shortcut\n\t\tExpr.find[\"ID\"] = function( id, context ) {\n\t\t\tif ( typeof context.getElementById !== \"undefined\" && documentIsHTML ) {\n\t\t\t\tvar node, i, elems,\n\t\t\t\t\telem = context.getElementById( id );\n\n\t\t\t\tif ( elem ) {\n\n\t\t\t\t\t// Verify the id attribute\n\t\t\t\t\tnode = elem.getAttributeNode(\"id\");\n\t\t\t\t\tif ( node && node.value === id ) {\n\t\t\t\t\t\treturn [ elem ];\n\t\t\t\t\t}\n\n\t\t\t\t\t// Fall back on getElementsByName\n\t\t\t\t\telems = context.getElementsByName( id );\n\t\t\t\t\ti = 0;\n\t\t\t\t\twhile ( (elem = elems[i++]) ) {\n\t\t\t\t\t\tnode = elem.getAttributeNode(\"id\");\n\t\t\t\t\t\tif ( node && node.value === id ) {\n\t\t\t\t\t\t\treturn [ elem ];\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\treturn [];\n\t\t\t}\n\t\t};\n\t}\n\n\t// Tag\n\tExpr.find[\"TAG\"] = support.getElementsByTagName ?\n\t\tfunction( tag, context ) {\n\t\t\tif ( typeof context.getElementsByTagName !== \"undefined\" ) {\n\t\t\t\treturn context.getElementsByTagName( tag );\n\n\t\t\t// DocumentFragment nodes don't have gEBTN\n\t\t\t} else if ( support.qsa ) {\n\t\t\t\treturn context.querySelectorAll( tag );\n\t\t\t}\n\t\t} :\n\n\t\tfunction( tag, context ) {\n\t\t\tvar elem,\n\t\t\t\ttmp = [],\n\t\t\t\ti = 0,\n\t\t\t\t// By happy coincidence, a (broken) gEBTN appears on DocumentFragment nodes too\n\t\t\t\tresults = context.getElementsByTagName( tag );\n\n\t\t\t// Filter out possible comments\n\t\t\tif ( tag === \"*\" ) {\n\t\t\t\twhile ( (elem = results[i++]) ) {\n\t\t\t\t\tif ( elem.nodeType === 1 ) {\n\t\t\t\t\t\ttmp.push( elem );\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\treturn tmp;\n\t\t\t}\n\t\t\treturn results;\n\t\t};\n\n\t// Class\n\tExpr.find[\"CLASS\"] = support.getElementsByClassName && function( className, context ) {\n\t\tif ( typeof context.getElementsByClassName !== \"undefined\" && documentIsHTML ) {\n\t\t\treturn context.getElementsByClassName( className );\n\t\t}\n\t};\n\n\t/* QSA/matchesSelector\n\t---------------------------------------------------------------------- */\n\n\t// QSA and matchesSelector support\n\n\t// matchesSelector(:active) reports false when true (IE9/Opera 11.5)\n\trbuggyMatches = [];\n\n\t// qSa(:focus) reports false when true (Chrome 21)\n\t// We allow this because of a bug in IE8/9 that throws an error\n\t// whenever `document.activeElement` is accessed on an iframe\n\t// So, we allow :focus to pass through QSA all the time to avoid the IE error\n\t// See https://bugs.jquery.com/ticket/13378\n\trbuggyQSA = [];\n\n\tif ( (support.qsa = rnative.test( document.querySelectorAll )) ) {\n\t\t// Build QSA regex\n\t\t// Regex strategy adopted from Diego Perini\n\t\tassert(function( el ) {\n\t\t\t// Select is set to empty string on purpose\n\t\t\t// This is to test IE's treatment of not explicitly\n\t\t\t// setting a boolean content attribute,\n\t\t\t// since its presence should be enough\n\t\t\t// https://bugs.jquery.com/ticket/12359\n\t\t\tdocElem.appendChild( el ).innerHTML = \"<a id='\" + expando + \"'></a>\" +\n\t\t\t\t\"<select id='\" + expando + \"-\\r\\\\' msallowcapture=''>\" +\n\t\t\t\t\"<option selected=''></option></select>\";\n\n\t\t\t// Support: IE8, Opera 11-12.16\n\t\t\t// Nothing should be selected when empty strings follow ^= or $= or *=\n\t\t\t// The test attribute must be unknown in Opera but \"safe\" for WinRT\n\t\t\t// https://msdn.microsoft.com/en-us/library/ie/hh465388.aspx#attribute_section\n\t\t\tif ( el.querySelectorAll(\"[msallowcapture^='']\").length ) {\n\t\t\t\trbuggyQSA.push( \"[*^$]=\" + whitespace + \"*(?:''|\\\"\\\")\" );\n\t\t\t}\n\n\t\t\t// Support: IE8\n\t\t\t// Boolean attributes and \"value\" are not treated correctly\n\t\t\tif ( !el.querySelectorAll(\"[selected]\").length ) {\n\t\t\t\trbuggyQSA.push( \"\\\\[\" + whitespace + \"*(?:value|\" + booleans + \")\" );\n\t\t\t}\n\n\t\t\t// Support: Chrome<29, Android<4.4, Safari<7.0+, iOS<7.0+, PhantomJS<1.9.8+\n\t\t\tif ( !el.querySelectorAll( \"[id~=\" + expando + \"-]\" ).length ) {\n\t\t\t\trbuggyQSA.push(\"~=\");\n\t\t\t}\n\n\t\t\t// Webkit/Opera - :checked should return selected option elements\n\t\t\t// http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked\n\t\t\t// IE8 throws error here and will not see later tests\n\t\t\tif ( !el.querySelectorAll(\":checked\").length ) {\n\t\t\t\trbuggyQSA.push(\":checked\");\n\t\t\t}\n\n\t\t\t// Support: Safari 8+, iOS 8+\n\t\t\t// https://bugs.webkit.org/show_bug.cgi?id=136851\n\t\t\t// In-page `selector#id sibling-combinator selector` fails\n\t\t\tif ( !el.querySelectorAll( \"a#\" + expando + \"+*\" ).length ) {\n\t\t\t\trbuggyQSA.push(\".#.+[+~]\");\n\t\t\t}\n\t\t});\n\n\t\tassert(function( el ) {\n\t\t\tel.innerHTML = \"<a href='' disabled='disabled'></a>\" +\n\t\t\t\t\"<select disabled='disabled'><option/></select>\";\n\n\t\t\t// Support: Windows 8 Native Apps\n\t\t\t// The type and name attributes are restricted during .innerHTML assignment\n\t\t\tvar input = document.createElement(\"input\");\n\t\t\tinput.setAttribute( \"type\", \"hidden\" );\n\t\t\tel.appendChild( input ).setAttribute( \"name\", \"D\" );\n\n\t\t\t// Support: IE8\n\t\t\t// Enforce case-sensitivity of name attribute\n\t\t\tif ( el.querySelectorAll(\"[name=d]\").length ) {\n\t\t\t\trbuggyQSA.push( \"name\" + whitespace + \"*[*^$|!~]?=\" );\n\t\t\t}\n\n\t\t\t// FF 3.5 - :enabled/:disabled and hidden elements (hidden elements are still enabled)\n\t\t\t// IE8 throws error here and will not see later tests\n\t\t\tif ( el.querySelectorAll(\":enabled\").length !== 2 ) {\n\t\t\t\trbuggyQSA.push( \":enabled\", \":disabled\" );\n\t\t\t}\n\n\t\t\t// Support: IE9-11+\n\t\t\t// IE's :disabled selector does not pick up the children of disabled fieldsets\n\t\t\tdocElem.appendChild( el ).disabled = true;\n\t\t\tif ( el.querySelectorAll(\":disabled\").length !== 2 ) {\n\t\t\t\trbuggyQSA.push( \":enabled\", \":disabled\" );\n\t\t\t}\n\n\t\t\t// Opera 10-11 does not throw on post-comma invalid pseudos\n\t\t\tel.querySelectorAll(\"*,:x\");\n\t\t\trbuggyQSA.push(\",.*:\");\n\t\t});\n\t}\n\n\tif ( (support.matchesSelector = rnative.test( (matches = docElem.matches ||\n\t\tdocElem.webkitMatchesSelector ||\n\t\tdocElem.mozMatchesSelector ||\n\t\tdocElem.oMatchesSelector ||\n\t\tdocElem.msMatchesSelector) )) ) {\n\n\t\tassert(function( el ) {\n\t\t\t// Check to see if it's possible to do matchesSelector\n\t\t\t// on a disconnected node (IE 9)\n\t\t\tsupport.disconnectedMatch = matches.call( el, \"*\" );\n\n\t\t\t// This should fail with an exception\n\t\t\t// Gecko does not error, returns false instead\n\t\t\tmatches.call( el, \"[s!='']:x\" );\n\t\t\trbuggyMatches.push( \"!=\", pseudos );\n\t\t});\n\t}\n\n\trbuggyQSA = rbuggyQSA.length && new RegExp( rbuggyQSA.join(\"|\") );\n\trbuggyMatches = rbuggyMatches.length && new RegExp( rbuggyMatches.join(\"|\") );\n\n\t/* Contains\n\t---------------------------------------------------------------------- */\n\thasCompare = rnative.test( docElem.compareDocumentPosition );\n\n\t// Element contains another\n\t// Purposefully self-exclusive\n\t// As in, an element does not contain itself\n\tcontains = hasCompare || rnative.test( docElem.contains ) ?\n\t\tfunction( a, b ) {\n\t\t\tvar adown = a.nodeType === 9 ? a.documentElement : a,\n\t\t\t\tbup = b && b.parentNode;\n\t\t\treturn a === bup || !!( bup && bup.nodeType === 1 && (\n\t\t\t\tadown.contains ?\n\t\t\t\t\tadown.contains( bup ) :\n\t\t\t\t\ta.compareDocumentPosition && a.compareDocumentPosition( bup ) & 16\n\t\t\t));\n\t\t} :\n\t\tfunction( a, b ) {\n\t\t\tif ( b ) {\n\t\t\t\twhile ( (b = b.parentNode) ) {\n\t\t\t\t\tif ( b === a ) {\n\t\t\t\t\t\treturn true;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn false;\n\t\t};\n\n\t/* Sorting\n\t---------------------------------------------------------------------- */\n\n\t// Document order sorting\n\tsortOrder = hasCompare ?\n\tfunction( a, b ) {\n\n\t\t// Flag for duplicate removal\n\t\tif ( a === b ) {\n\t\t\thasDuplicate = true;\n\t\t\treturn 0;\n\t\t}\n\n\t\t// Sort on method existence if only one input has compareDocumentPosition\n\t\tvar compare = !a.compareDocumentPosition - !b.compareDocumentPosition;\n\t\tif ( compare ) {\n\t\t\treturn compare;\n\t\t}\n\n\t\t// Calculate position if both inputs belong to the same document\n\t\tcompare = ( a.ownerDocument || a ) === ( b.ownerDocument || b ) ?\n\t\t\ta.compareDocumentPosition( b ) :\n\n\t\t\t// Otherwise we know they are disconnected\n\t\t\t1;\n\n\t\t// Disconnected nodes\n\t\tif ( compare & 1 ||\n\t\t\t(!support.sortDetached && b.compareDocumentPosition( a ) === compare) ) {\n\n\t\t\t// Choose the first element that is related to our preferred document\n\t\t\tif ( a === document || a.ownerDocument === preferredDoc && contains(preferredDoc, a) ) {\n\t\t\t\treturn -1;\n\t\t\t}\n\t\t\tif ( b === document || b.ownerDocument === preferredDoc && contains(preferredDoc, b) ) {\n\t\t\t\treturn 1;\n\t\t\t}\n\n\t\t\t// Maintain original order\n\t\t\treturn sortInput ?\n\t\t\t\t( indexOf( sortInput, a ) - indexOf( sortInput, b ) ) :\n\t\t\t\t0;\n\t\t}\n\n\t\treturn compare & 4 ? -1 : 1;\n\t} :\n\tfunction( a, b ) {\n\t\t// Exit early if the nodes are identical\n\t\tif ( a === b ) {\n\t\t\thasDuplicate = true;\n\t\t\treturn 0;\n\t\t}\n\n\t\tvar cur,\n\t\t\ti = 0,\n\t\t\taup = a.parentNode,\n\t\t\tbup = b.parentNode,\n\t\t\tap = [ a ],\n\t\t\tbp = [ b ];\n\n\t\t// Parentless nodes are either documents or disconnected\n\t\tif ( !aup || !bup ) {\n\t\t\treturn a === document ? -1 :\n\t\t\t\tb === document ? 1 :\n\t\t\t\taup ? -1 :\n\t\t\t\tbup ? 1 :\n\t\t\t\tsortInput ?\n\t\t\t\t( indexOf( sortInput, a ) - indexOf( sortInput, b ) ) :\n\t\t\t\t0;\n\n\t\t// If the nodes are siblings, we can do a quick check\n\t\t} else if ( aup === bup ) {\n\t\t\treturn siblingCheck( a, b );\n\t\t}\n\n\t\t// Otherwise we need full lists of their ancestors for comparison\n\t\tcur = a;\n\t\twhile ( (cur = cur.parentNode) ) {\n\t\t\tap.unshift( cur );\n\t\t}\n\t\tcur = b;\n\t\twhile ( (cur = cur.parentNode) ) {\n\t\t\tbp.unshift( cur );\n\t\t}\n\n\t\t// Walk down the tree looking for a discrepancy\n\t\twhile ( ap[i] === bp[i] ) {\n\t\t\ti++;\n\t\t}\n\n\t\treturn i ?\n\t\t\t// Do a sibling check if the nodes have a common ancestor\n\t\t\tsiblingCheck( ap[i], bp[i] ) :\n\n\t\t\t// Otherwise nodes in our document sort first\n\t\t\tap[i] === preferredDoc ? -1 :\n\t\t\tbp[i] === preferredDoc ? 1 :\n\t\t\t0;\n\t};\n\n\treturn document;\n};\n\nSizzle.matches = function( expr, elements ) {\n\treturn Sizzle( expr, null, null, elements );\n};\n\nSizzle.matchesSelector = function( elem, expr ) {\n\t// Set document vars if needed\n\tif ( ( elem.ownerDocument || elem ) !== document ) {\n\t\tsetDocument( elem );\n\t}\n\n\t// Make sure that attribute selectors are quoted\n\texpr = expr.replace( rattributeQuotes, \"='$1']\" );\n\n\tif ( support.matchesSelector && documentIsHTML &&\n\t\t!compilerCache[ expr + \" \" ] &&\n\t\t( !rbuggyMatches || !rbuggyMatches.test( expr ) ) &&\n\t\t( !rbuggyQSA     || !rbuggyQSA.test( expr ) ) ) {\n\n\t\ttry {\n\t\t\tvar ret = matches.call( elem, expr );\n\n\t\t\t// IE 9's matchesSelector returns false on disconnected nodes\n\t\t\tif ( ret || support.disconnectedMatch ||\n\t\t\t\t\t// As well, disconnected nodes are said to be in a document\n\t\t\t\t\t// fragment in IE 9\n\t\t\t\t\telem.document && elem.document.nodeType !== 11 ) {\n\t\t\t\treturn ret;\n\t\t\t}\n\t\t} catch (e) {}\n\t}\n\n\treturn Sizzle( expr, document, null, [ elem ] ).length > 0;\n};\n\nSizzle.contains = function( context, elem ) {\n\t// Set document vars if needed\n\tif ( ( context.ownerDocument || context ) !== document ) {\n\t\tsetDocument( context );\n\t}\n\treturn contains( context, elem );\n};\n\nSizzle.attr = function( elem, name ) {\n\t// Set document vars if needed\n\tif ( ( elem.ownerDocument || elem ) !== document ) {\n\t\tsetDocument( elem );\n\t}\n\n\tvar fn = Expr.attrHandle[ name.toLowerCase() ],\n\t\t// Don't get fooled by Object.prototype properties (jQuery #13807)\n\t\tval = fn && hasOwn.call( Expr.attrHandle, name.toLowerCase() ) ?\n\t\t\tfn( elem, name, !documentIsHTML ) :\n\t\t\tundefined;\n\n\treturn val !== undefined ?\n\t\tval :\n\t\tsupport.attributes || !documentIsHTML ?\n\t\t\telem.getAttribute( name ) :\n\t\t\t(val = elem.getAttributeNode(name)) && val.specified ?\n\t\t\t\tval.value :\n\t\t\t\tnull;\n};\n\nSizzle.escape = function( sel ) {\n\treturn (sel + \"\").replace( rcssescape, fcssescape );\n};\n\nSizzle.error = function( msg ) {\n\tthrow new Error( \"Syntax error, unrecognized expression: \" + msg );\n};\n\n/**\n * Document sorting and removing duplicates\n * @param {ArrayLike} results\n */\nSizzle.uniqueSort = function( results ) {\n\tvar elem,\n\t\tduplicates = [],\n\t\tj = 0,\n\t\ti = 0;\n\n\t// Unless we *know* we can detect duplicates, assume their presence\n\thasDuplicate = !support.detectDuplicates;\n\tsortInput = !support.sortStable && results.slice( 0 );\n\tresults.sort( sortOrder );\n\n\tif ( hasDuplicate ) {\n\t\twhile ( (elem = results[i++]) ) {\n\t\t\tif ( elem === results[ i ] ) {\n\t\t\t\tj = duplicates.push( i );\n\t\t\t}\n\t\t}\n\t\twhile ( j-- ) {\n\t\t\tresults.splice( duplicates[ j ], 1 );\n\t\t}\n\t}\n\n\t// Clear input after sorting to release objects\n\t// See https://github.com/jquery/sizzle/pull/225\n\tsortInput = null;\n\n\treturn results;\n};\n\n/**\n * Utility function for retrieving the text value of an array of DOM nodes\n * @param {Array|Element} elem\n */\ngetText = Sizzle.getText = function( elem ) {\n\tvar node,\n\t\tret = \"\",\n\t\ti = 0,\n\t\tnodeType = elem.nodeType;\n\n\tif ( !nodeType ) {\n\t\t// If no nodeType, this is expected to be an array\n\t\twhile ( (node = elem[i++]) ) {\n\t\t\t// Do not traverse comment nodes\n\t\t\tret += getText( node );\n\t\t}\n\t} else if ( nodeType === 1 || nodeType === 9 || nodeType === 11 ) {\n\t\t// Use textContent for elements\n\t\t// innerText usage removed for consistency of new lines (jQuery #11153)\n\t\tif ( typeof elem.textContent === \"string\" ) {\n\t\t\treturn elem.textContent;\n\t\t} else {\n\t\t\t// Traverse its children\n\t\t\tfor ( elem = elem.firstChild; elem; elem = elem.nextSibling ) {\n\t\t\t\tret += getText( elem );\n\t\t\t}\n\t\t}\n\t} else if ( nodeType === 3 || nodeType === 4 ) {\n\t\treturn elem.nodeValue;\n\t}\n\t// Do not include comment or processing instruction nodes\n\n\treturn ret;\n};\n\nExpr = Sizzle.selectors = {\n\n\t// Can be adjusted by the user\n\tcacheLength: 50,\n\n\tcreatePseudo: markFunction,\n\n\tmatch: matchExpr,\n\n\tattrHandle: {},\n\n\tfind: {},\n\n\trelative: {\n\t\t\">\": { dir: \"parentNode\", first: true },\n\t\t\" \": { dir: \"parentNode\" },\n\t\t\"+\": { dir: \"previousSibling\", first: true },\n\t\t\"~\": { dir: \"previousSibling\" }\n\t},\n\n\tpreFilter: {\n\t\t\"ATTR\": function( match ) {\n\t\t\tmatch[1] = match[1].replace( runescape, funescape );\n\n\t\t\t// Move the given value to match[3] whether quoted or unquoted\n\t\t\tmatch[3] = ( match[3] || match[4] || match[5] || \"\" ).replace( runescape, funescape );\n\n\t\t\tif ( match[2] === \"~=\" ) {\n\t\t\t\tmatch[3] = \" \" + match[3] + \" \";\n\t\t\t}\n\n\t\t\treturn match.slice( 0, 4 );\n\t\t},\n\n\t\t\"CHILD\": function( match ) {\n\t\t\t/* matches from matchExpr[\"CHILD\"]\n\t\t\t\t1 type (only|nth|...)\n\t\t\t\t2 what (child|of-type)\n\t\t\t\t3 argument (even|odd|\\d*|\\d*n([+-]\\d+)?|...)\n\t\t\t\t4 xn-component of xn+y argument ([+-]?\\d*n|)\n\t\t\t\t5 sign of xn-component\n\t\t\t\t6 x of xn-component\n\t\t\t\t7 sign of y-component\n\t\t\t\t8 y of y-component\n\t\t\t*/\n\t\t\tmatch[1] = match[1].toLowerCase();\n\n\t\t\tif ( match[1].slice( 0, 3 ) === \"nth\" ) {\n\t\t\t\t// nth-* requires argument\n\t\t\t\tif ( !match[3] ) {\n\t\t\t\t\tSizzle.error( match[0] );\n\t\t\t\t}\n\n\t\t\t\t// numeric x and y parameters for Expr.filter.CHILD\n\t\t\t\t// remember that false/true cast respectively to 0/1\n\t\t\t\tmatch[4] = +( match[4] ? match[5] + (match[6] || 1) : 2 * ( match[3] === \"even\" || match[3] === \"odd\" ) );\n\t\t\t\tmatch[5] = +( ( match[7] + match[8] ) || match[3] === \"odd\" );\n\n\t\t\t// other types prohibit arguments\n\t\t\t} else if ( match[3] ) {\n\t\t\t\tSizzle.error( match[0] );\n\t\t\t}\n\n\t\t\treturn match;\n\t\t},\n\n\t\t\"PSEUDO\": function( match ) {\n\t\t\tvar excess,\n\t\t\t\tunquoted = !match[6] && match[2];\n\n\t\t\tif ( matchExpr[\"CHILD\"].test( match[0] ) ) {\n\t\t\t\treturn null;\n\t\t\t}\n\n\t\t\t// Accept quoted arguments as-is\n\t\t\tif ( match[3] ) {\n\t\t\t\tmatch[2] = match[4] || match[5] || \"\";\n\n\t\t\t// Strip excess characters from unquoted arguments\n\t\t\t} else if ( unquoted && rpseudo.test( unquoted ) &&\n\t\t\t\t// Get excess from tokenize (recursively)\n\t\t\t\t(excess = tokenize( unquoted, true )) &&\n\t\t\t\t// advance to the next closing parenthesis\n\t\t\t\t(excess = unquoted.indexOf( \")\", unquoted.length - excess ) - unquoted.length) ) {\n\n\t\t\t\t// excess is a negative index\n\t\t\t\tmatch[0] = match[0].slice( 0, excess );\n\t\t\t\tmatch[2] = unquoted.slice( 0, excess );\n\t\t\t}\n\n\t\t\t// Return only captures needed by the pseudo filter method (type and argument)\n\t\t\treturn match.slice( 0, 3 );\n\t\t}\n\t},\n\n\tfilter: {\n\n\t\t\"TAG\": function( nodeNameSelector ) {\n\t\t\tvar nodeName = nodeNameSelector.replace( runescape, funescape ).toLowerCase();\n\t\t\treturn nodeNameSelector === \"*\" ?\n\t\t\t\tfunction() { return true; } :\n\t\t\t\tfunction( elem ) {\n\t\t\t\t\treturn elem.nodeName && elem.nodeName.toLowerCase() === nodeName;\n\t\t\t\t};\n\t\t},\n\n\t\t\"CLASS\": function( className ) {\n\t\t\tvar pattern = classCache[ className + \" \" ];\n\n\t\t\treturn pattern ||\n\t\t\t\t(pattern = new RegExp( \"(^|\" + whitespace + \")\" + className + \"(\" + whitespace + \"|$)\" )) &&\n\t\t\t\tclassCache( className, function( elem ) {\n\t\t\t\t\treturn pattern.test( typeof elem.className === \"string\" && elem.className || typeof elem.getAttribute !== \"undefined\" && elem.getAttribute(\"class\") || \"\" );\n\t\t\t\t});\n\t\t},\n\n\t\t\"ATTR\": function( name, operator, check ) {\n\t\t\treturn function( elem ) {\n\t\t\t\tvar result = Sizzle.attr( elem, name );\n\n\t\t\t\tif ( result == null ) {\n\t\t\t\t\treturn operator === \"!=\";\n\t\t\t\t}\n\t\t\t\tif ( !operator ) {\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\n\t\t\t\tresult += \"\";\n\n\t\t\t\treturn operator === \"=\" ? result === check :\n\t\t\t\t\toperator === \"!=\" ? result !== check :\n\t\t\t\t\toperator === \"^=\" ? check && result.indexOf( check ) === 0 :\n\t\t\t\t\toperator === \"*=\" ? check && result.indexOf( check ) > -1 :\n\t\t\t\t\toperator === \"$=\" ? check && result.slice( -check.length ) === check :\n\t\t\t\t\toperator === \"~=\" ? ( \" \" + result.replace( rwhitespace, \" \" ) + \" \" ).indexOf( check ) > -1 :\n\t\t\t\t\toperator === \"|=\" ? result === check || result.slice( 0, check.length + 1 ) === check + \"-\" :\n\t\t\t\t\tfalse;\n\t\t\t};\n\t\t},\n\n\t\t\"CHILD\": function( type, what, argument, first, last ) {\n\t\t\tvar simple = type.slice( 0, 3 ) !== \"nth\",\n\t\t\t\tforward = type.slice( -4 ) !== \"last\",\n\t\t\t\tofType = what === \"of-type\";\n\n\t\t\treturn first === 1 && last === 0 ?\n\n\t\t\t\t// Shortcut for :nth-*(n)\n\t\t\t\tfunction( elem ) {\n\t\t\t\t\treturn !!elem.parentNode;\n\t\t\t\t} :\n\n\t\t\t\tfunction( elem, context, xml ) {\n\t\t\t\t\tvar cache, uniqueCache, outerCache, node, nodeIndex, start,\n\t\t\t\t\t\tdir = simple !== forward ? \"nextSibling\" : \"previousSibling\",\n\t\t\t\t\t\tparent = elem.parentNode,\n\t\t\t\t\t\tname = ofType && elem.nodeName.toLowerCase(),\n\t\t\t\t\t\tuseCache = !xml && !ofType,\n\t\t\t\t\t\tdiff = false;\n\n\t\t\t\t\tif ( parent ) {\n\n\t\t\t\t\t\t// :(first|last|only)-(child|of-type)\n\t\t\t\t\t\tif ( simple ) {\n\t\t\t\t\t\t\twhile ( dir ) {\n\t\t\t\t\t\t\t\tnode = elem;\n\t\t\t\t\t\t\t\twhile ( (node = node[ dir ]) ) {\n\t\t\t\t\t\t\t\t\tif ( ofType ?\n\t\t\t\t\t\t\t\t\t\tnode.nodeName.toLowerCase() === name :\n\t\t\t\t\t\t\t\t\t\tnode.nodeType === 1 ) {\n\n\t\t\t\t\t\t\t\t\t\treturn false;\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t// Reverse direction for :only-* (if we haven't yet done so)\n\t\t\t\t\t\t\t\tstart = dir = type === \"only\" && !start && \"nextSibling\";\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\treturn true;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tstart = [ forward ? parent.firstChild : parent.lastChild ];\n\n\t\t\t\t\t\t// non-xml :nth-child(...) stores cache data on `parent`\n\t\t\t\t\t\tif ( forward && useCache ) {\n\n\t\t\t\t\t\t\t// Seek `elem` from a previously-cached index\n\n\t\t\t\t\t\t\t// ...in a gzip-friendly way\n\t\t\t\t\t\t\tnode = parent;\n\t\t\t\t\t\t\touterCache = node[ expando ] || (node[ expando ] = {});\n\n\t\t\t\t\t\t\t// Support: IE <9 only\n\t\t\t\t\t\t\t// Defend against cloned attroperties (jQuery gh-1709)\n\t\t\t\t\t\t\tuniqueCache = outerCache[ node.uniqueID ] ||\n\t\t\t\t\t\t\t\t(outerCache[ node.uniqueID ] = {});\n\n\t\t\t\t\t\t\tcache = uniqueCache[ type ] || [];\n\t\t\t\t\t\t\tnodeIndex = cache[ 0 ] === dirruns && cache[ 1 ];\n\t\t\t\t\t\t\tdiff = nodeIndex && cache[ 2 ];\n\t\t\t\t\t\t\tnode = nodeIndex && parent.childNodes[ nodeIndex ];\n\n\t\t\t\t\t\t\twhile ( (node = ++nodeIndex && node && node[ dir ] ||\n\n\t\t\t\t\t\t\t\t// Fallback to seeking `elem` from the start\n\t\t\t\t\t\t\t\t(diff = nodeIndex = 0) || start.pop()) ) {\n\n\t\t\t\t\t\t\t\t// When found, cache indexes on `parent` and break\n\t\t\t\t\t\t\t\tif ( node.nodeType === 1 && ++diff && node === elem ) {\n\t\t\t\t\t\t\t\t\tuniqueCache[ type ] = [ dirruns, nodeIndex, diff ];\n\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t// Use previously-cached element index if available\n\t\t\t\t\t\t\tif ( useCache ) {\n\t\t\t\t\t\t\t\t// ...in a gzip-friendly way\n\t\t\t\t\t\t\t\tnode = elem;\n\t\t\t\t\t\t\t\touterCache = node[ expando ] || (node[ expando ] = {});\n\n\t\t\t\t\t\t\t\t// Support: IE <9 only\n\t\t\t\t\t\t\t\t// Defend against cloned attroperties (jQuery gh-1709)\n\t\t\t\t\t\t\t\tuniqueCache = outerCache[ node.uniqueID ] ||\n\t\t\t\t\t\t\t\t\t(outerCache[ node.uniqueID ] = {});\n\n\t\t\t\t\t\t\t\tcache = uniqueCache[ type ] || [];\n\t\t\t\t\t\t\t\tnodeIndex = cache[ 0 ] === dirruns && cache[ 1 ];\n\t\t\t\t\t\t\t\tdiff = nodeIndex;\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t// xml :nth-child(...)\n\t\t\t\t\t\t\t// or :nth-last-child(...) or :nth(-last)?-of-type(...)\n\t\t\t\t\t\t\tif ( diff === false ) {\n\t\t\t\t\t\t\t\t// Use the same loop as above to seek `elem` from the start\n\t\t\t\t\t\t\t\twhile ( (node = ++nodeIndex && node && node[ dir ] ||\n\t\t\t\t\t\t\t\t\t(diff = nodeIndex = 0) || start.pop()) ) {\n\n\t\t\t\t\t\t\t\t\tif ( ( ofType ?\n\t\t\t\t\t\t\t\t\t\tnode.nodeName.toLowerCase() === name :\n\t\t\t\t\t\t\t\t\t\tnode.nodeType === 1 ) &&\n\t\t\t\t\t\t\t\t\t\t++diff ) {\n\n\t\t\t\t\t\t\t\t\t\t// Cache the index of each encountered element\n\t\t\t\t\t\t\t\t\t\tif ( useCache ) {\n\t\t\t\t\t\t\t\t\t\t\touterCache = node[ expando ] || (node[ expando ] = {});\n\n\t\t\t\t\t\t\t\t\t\t\t// Support: IE <9 only\n\t\t\t\t\t\t\t\t\t\t\t// Defend against cloned attroperties (jQuery gh-1709)\n\t\t\t\t\t\t\t\t\t\t\tuniqueCache = outerCache[ node.uniqueID ] ||\n\t\t\t\t\t\t\t\t\t\t\t\t(outerCache[ node.uniqueID ] = {});\n\n\t\t\t\t\t\t\t\t\t\t\tuniqueCache[ type ] = [ dirruns, diff ];\n\t\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t\t\tif ( node === elem ) {\n\t\t\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// Incorporate the offset, then check against cycle size\n\t\t\t\t\t\tdiff -= last;\n\t\t\t\t\t\treturn diff === first || ( diff % first === 0 && diff / first >= 0 );\n\t\t\t\t\t}\n\t\t\t\t};\n\t\t},\n\n\t\t\"PSEUDO\": function( pseudo, argument ) {\n\t\t\t// pseudo-class names are case-insensitive\n\t\t\t// http://www.w3.org/TR/selectors/#pseudo-classes\n\t\t\t// Prioritize by case sensitivity in case custom pseudos are added with uppercase letters\n\t\t\t// Remember that setFilters inherits from pseudos\n\t\t\tvar args,\n\t\t\t\tfn = Expr.pseudos[ pseudo ] || Expr.setFilters[ pseudo.toLowerCase() ] ||\n\t\t\t\t\tSizzle.error( \"unsupported pseudo: \" + pseudo );\n\n\t\t\t// The user may use createPseudo to indicate that\n\t\t\t// arguments are needed to create the filter function\n\t\t\t// just as Sizzle does\n\t\t\tif ( fn[ expando ] ) {\n\t\t\t\treturn fn( argument );\n\t\t\t}\n\n\t\t\t// But maintain support for old signatures\n\t\t\tif ( fn.length > 1 ) {\n\t\t\t\targs = [ pseudo, pseudo, \"\", argument ];\n\t\t\t\treturn Expr.setFilters.hasOwnProperty( pseudo.toLowerCase() ) ?\n\t\t\t\t\tmarkFunction(function( seed, matches ) {\n\t\t\t\t\t\tvar idx,\n\t\t\t\t\t\t\tmatched = fn( seed, argument ),\n\t\t\t\t\t\t\ti = matched.length;\n\t\t\t\t\t\twhile ( i-- ) {\n\t\t\t\t\t\t\tidx = indexOf( seed, matched[i] );\n\t\t\t\t\t\t\tseed[ idx ] = !( matches[ idx ] = matched[i] );\n\t\t\t\t\t\t}\n\t\t\t\t\t}) :\n\t\t\t\t\tfunction( elem ) {\n\t\t\t\t\t\treturn fn( elem, 0, args );\n\t\t\t\t\t};\n\t\t\t}\n\n\t\t\treturn fn;\n\t\t}\n\t},\n\n\tpseudos: {\n\t\t// Potentially complex pseudos\n\t\t\"not\": markFunction(function( selector ) {\n\t\t\t// Trim the selector passed to compile\n\t\t\t// to avoid treating leading and trailing\n\t\t\t// spaces as combinators\n\t\t\tvar input = [],\n\t\t\t\tresults = [],\n\t\t\t\tmatcher = compile( selector.replace( rtrim, \"$1\" ) );\n\n\t\t\treturn matcher[ expando ] ?\n\t\t\t\tmarkFunction(function( seed, matches, context, xml ) {\n\t\t\t\t\tvar elem,\n\t\t\t\t\t\tunmatched = matcher( seed, null, xml, [] ),\n\t\t\t\t\t\ti = seed.length;\n\n\t\t\t\t\t// Match elements unmatched by `matcher`\n\t\t\t\t\twhile ( i-- ) {\n\t\t\t\t\t\tif ( (elem = unmatched[i]) ) {\n\t\t\t\t\t\t\tseed[i] = !(matches[i] = elem);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}) :\n\t\t\t\tfunction( elem, context, xml ) {\n\t\t\t\t\tinput[0] = elem;\n\t\t\t\t\tmatcher( input, null, xml, results );\n\t\t\t\t\t// Don't keep the element (issue #299)\n\t\t\t\t\tinput[0] = null;\n\t\t\t\t\treturn !results.pop();\n\t\t\t\t};\n\t\t}),\n\n\t\t\"has\": markFunction(function( selector ) {\n\t\t\treturn function( elem ) {\n\t\t\t\treturn Sizzle( selector, elem ).length > 0;\n\t\t\t};\n\t\t}),\n\n\t\t\"contains\": markFunction(function( text ) {\n\t\t\ttext = text.replace( runescape, funescape );\n\t\t\treturn function( elem ) {\n\t\t\t\treturn ( elem.textContent || elem.innerText || getText( elem ) ).indexOf( text ) > -1;\n\t\t\t};\n\t\t}),\n\n\t\t// \"Whether an element is represented by a :lang() selector\n\t\t// is based solely on the element's language value\n\t\t// being equal to the identifier C,\n\t\t// or beginning with the identifier C immediately followed by \"-\".\n\t\t// The matching of C against the element's language value is performed case-insensitively.\n\t\t// The identifier C does not have to be a valid language name.\"\n\t\t// http://www.w3.org/TR/selectors/#lang-pseudo\n\t\t\"lang\": markFunction( function( lang ) {\n\t\t\t// lang value must be a valid identifier\n\t\t\tif ( !ridentifier.test(lang || \"\") ) {\n\t\t\t\tSizzle.error( \"unsupported lang: \" + lang );\n\t\t\t}\n\t\t\tlang = lang.replace( runescape, funescape ).toLowerCase();\n\t\t\treturn function( elem ) {\n\t\t\t\tvar elemLang;\n\t\t\t\tdo {\n\t\t\t\t\tif ( (elemLang = documentIsHTML ?\n\t\t\t\t\t\telem.lang :\n\t\t\t\t\t\telem.getAttribute(\"xml:lang\") || elem.getAttribute(\"lang\")) ) {\n\n\t\t\t\t\t\telemLang = elemLang.toLowerCase();\n\t\t\t\t\t\treturn elemLang === lang || elemLang.indexOf( lang + \"-\" ) === 0;\n\t\t\t\t\t}\n\t\t\t\t} while ( (elem = elem.parentNode) && elem.nodeType === 1 );\n\t\t\t\treturn false;\n\t\t\t};\n\t\t}),\n\n\t\t// Miscellaneous\n\t\t\"target\": function( elem ) {\n\t\t\tvar hash = window.location && window.location.hash;\n\t\t\treturn hash && hash.slice( 1 ) === elem.id;\n\t\t},\n\n\t\t\"root\": function( elem ) {\n\t\t\treturn elem === docElem;\n\t\t},\n\n\t\t\"focus\": function( elem ) {\n\t\t\treturn elem === document.activeElement && (!document.hasFocus || document.hasFocus()) && !!(elem.type || elem.href || ~elem.tabIndex);\n\t\t},\n\n\t\t// Boolean properties\n\t\t\"enabled\": createDisabledPseudo( false ),\n\t\t\"disabled\": createDisabledPseudo( true ),\n\n\t\t\"checked\": function( elem ) {\n\t\t\t// In CSS3, :checked should return both checked and selected elements\n\t\t\t// http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked\n\t\t\tvar nodeName = elem.nodeName.toLowerCase();\n\t\t\treturn (nodeName === \"input\" && !!elem.checked) || (nodeName === \"option\" && !!elem.selected);\n\t\t},\n\n\t\t\"selected\": function( elem ) {\n\t\t\t// Accessing this property makes selected-by-default\n\t\t\t// options in Safari work properly\n\t\t\tif ( elem.parentNode ) {\n\t\t\t\telem.parentNode.selectedIndex;\n\t\t\t}\n\n\t\t\treturn elem.selected === true;\n\t\t},\n\n\t\t// Contents\n\t\t\"empty\": function( elem ) {\n\t\t\t// http://www.w3.org/TR/selectors/#empty-pseudo\n\t\t\t// :empty is negated by element (1) or content nodes (text: 3; cdata: 4; entity ref: 5),\n\t\t\t//   but not by others (comment: 8; processing instruction: 7; etc.)\n\t\t\t// nodeType < 6 works because attributes (2) do not appear as children\n\t\t\tfor ( elem = elem.firstChild; elem; elem = elem.nextSibling ) {\n\t\t\t\tif ( elem.nodeType < 6 ) {\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn true;\n\t\t},\n\n\t\t\"parent\": function( elem ) {\n\t\t\treturn !Expr.pseudos[\"empty\"]( elem );\n\t\t},\n\n\t\t// Element/input types\n\t\t\"header\": function( elem ) {\n\t\t\treturn rheader.test( elem.nodeName );\n\t\t},\n\n\t\t\"input\": function( elem ) {\n\t\t\treturn rinputs.test( elem.nodeName );\n\t\t},\n\n\t\t\"button\": function( elem ) {\n\t\t\tvar name = elem.nodeName.toLowerCase();\n\t\t\treturn name === \"input\" && elem.type === \"button\" || name === \"button\";\n\t\t},\n\n\t\t\"text\": function( elem ) {\n\t\t\tvar attr;\n\t\t\treturn elem.nodeName.toLowerCase() === \"input\" &&\n\t\t\t\telem.type === \"text\" &&\n\n\t\t\t\t// Support: IE<8\n\t\t\t\t// New HTML5 attribute values (e.g., \"search\") appear with elem.type === \"text\"\n\t\t\t\t( (attr = elem.getAttribute(\"type\")) == null || attr.toLowerCase() === \"text\" );\n\t\t},\n\n\t\t// Position-in-collection\n\t\t\"first\": createPositionalPseudo(function() {\n\t\t\treturn [ 0 ];\n\t\t}),\n\n\t\t\"last\": createPositionalPseudo(function( matchIndexes, length ) {\n\t\t\treturn [ length - 1 ];\n\t\t}),\n\n\t\t\"eq\": createPositionalPseudo(function( matchIndexes, length, argument ) {\n\t\t\treturn [ argument < 0 ? argument + length : argument ];\n\t\t}),\n\n\t\t\"even\": createPositionalPseudo(function( matchIndexes, length ) {\n\t\t\tvar i = 0;\n\t\t\tfor ( ; i < length; i += 2 ) {\n\t\t\t\tmatchIndexes.push( i );\n\t\t\t}\n\t\t\treturn matchIndexes;\n\t\t}),\n\n\t\t\"odd\": createPositionalPseudo(function( matchIndexes, length ) {\n\t\t\tvar i = 1;\n\t\t\tfor ( ; i < length; i += 2 ) {\n\t\t\t\tmatchIndexes.push( i );\n\t\t\t}\n\t\t\treturn matchIndexes;\n\t\t}),\n\n\t\t\"lt\": createPositionalPseudo(function( matchIndexes, length, argument ) {\n\t\t\tvar i = argument < 0 ? argument + length : argument;\n\t\t\tfor ( ; --i >= 0; ) {\n\t\t\t\tmatchIndexes.push( i );\n\t\t\t}\n\t\t\treturn matchIndexes;\n\t\t}),\n\n\t\t\"gt\": createPositionalPseudo(function( matchIndexes, length, argument ) {\n\t\t\tvar i = argument < 0 ? argument + length : argument;\n\t\t\tfor ( ; ++i < length; ) {\n\t\t\t\tmatchIndexes.push( i );\n\t\t\t}\n\t\t\treturn matchIndexes;\n\t\t})\n\t}\n};\n\nExpr.pseudos[\"nth\"] = Expr.pseudos[\"eq\"];\n\n// Add button/input type pseudos\nfor ( i in { radio: true, checkbox: true, file: true, password: true, image: true } ) {\n\tExpr.pseudos[ i ] = createInputPseudo( i );\n}\nfor ( i in { submit: true, reset: true } ) {\n\tExpr.pseudos[ i ] = createButtonPseudo( i );\n}\n\n// Easy API for creating new setFilters\nfunction setFilters() {}\nsetFilters.prototype = Expr.filters = Expr.pseudos;\nExpr.setFilters = new setFilters();\n\ntokenize = Sizzle.tokenize = function( selector, parseOnly ) {\n\tvar matched, match, tokens, type,\n\t\tsoFar, groups, preFilters,\n\t\tcached = tokenCache[ selector + \" \" ];\n\n\tif ( cached ) {\n\t\treturn parseOnly ? 0 : cached.slice( 0 );\n\t}\n\n\tsoFar = selector;\n\tgroups = [];\n\tpreFilters = Expr.preFilter;\n\n\twhile ( soFar ) {\n\n\t\t// Comma and first run\n\t\tif ( !matched || (match = rcomma.exec( soFar )) ) {\n\t\t\tif ( match ) {\n\t\t\t\t// Don't consume trailing commas as valid\n\t\t\t\tsoFar = soFar.slice( match[0].length ) || soFar;\n\t\t\t}\n\t\t\tgroups.push( (tokens = []) );\n\t\t}\n\n\t\tmatched = false;\n\n\t\t// Combinators\n\t\tif ( (match = rcombinators.exec( soFar )) ) {\n\t\t\tmatched = match.shift();\n\t\t\ttokens.push({\n\t\t\t\tvalue: matched,\n\t\t\t\t// Cast descendant combinators to space\n\t\t\t\ttype: match[0].replace( rtrim, \" \" )\n\t\t\t});\n\t\t\tsoFar = soFar.slice( matched.length );\n\t\t}\n\n\t\t// Filters\n\t\tfor ( type in Expr.filter ) {\n\t\t\tif ( (match = matchExpr[ type ].exec( soFar )) && (!preFilters[ type ] ||\n\t\t\t\t(match = preFilters[ type ]( match ))) ) {\n\t\t\t\tmatched = match.shift();\n\t\t\t\ttokens.push({\n\t\t\t\t\tvalue: matched,\n\t\t\t\t\ttype: type,\n\t\t\t\t\tmatches: match\n\t\t\t\t});\n\t\t\t\tsoFar = soFar.slice( matched.length );\n\t\t\t}\n\t\t}\n\n\t\tif ( !matched ) {\n\t\t\tbreak;\n\t\t}\n\t}\n\n\t// Return the length of the invalid excess\n\t// if we're just parsing\n\t// Otherwise, throw an error or return tokens\n\treturn parseOnly ?\n\t\tsoFar.length :\n\t\tsoFar ?\n\t\t\tSizzle.error( selector ) :\n\t\t\t// Cache the tokens\n\t\t\ttokenCache( selector, groups ).slice( 0 );\n};\n\nfunction toSelector( tokens ) {\n\tvar i = 0,\n\t\tlen = tokens.length,\n\t\tselector = \"\";\n\tfor ( ; i < len; i++ ) {\n\t\tselector += tokens[i].value;\n\t}\n\treturn selector;\n}\n\nfunction addCombinator( matcher, combinator, base ) {\n\tvar dir = combinator.dir,\n\t\tskip = combinator.next,\n\t\tkey = skip || dir,\n\t\tcheckNonElements = base && key === \"parentNode\",\n\t\tdoneName = done++;\n\n\treturn combinator.first ?\n\t\t// Check against closest ancestor/preceding element\n\t\tfunction( elem, context, xml ) {\n\t\t\twhile ( (elem = elem[ dir ]) ) {\n\t\t\t\tif ( elem.nodeType === 1 || checkNonElements ) {\n\t\t\t\t\treturn matcher( elem, context, xml );\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn false;\n\t\t} :\n\n\t\t// Check against all ancestor/preceding elements\n\t\tfunction( elem, context, xml ) {\n\t\t\tvar oldCache, uniqueCache, outerCache,\n\t\t\t\tnewCache = [ dirruns, doneName ];\n\n\t\t\t// We can't set arbitrary data on XML nodes, so they don't benefit from combinator caching\n\t\t\tif ( xml ) {\n\t\t\t\twhile ( (elem = elem[ dir ]) ) {\n\t\t\t\t\tif ( elem.nodeType === 1 || checkNonElements ) {\n\t\t\t\t\t\tif ( matcher( elem, context, xml ) ) {\n\t\t\t\t\t\t\treturn true;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\twhile ( (elem = elem[ dir ]) ) {\n\t\t\t\t\tif ( elem.nodeType === 1 || checkNonElements ) {\n\t\t\t\t\t\touterCache = elem[ expando ] || (elem[ expando ] = {});\n\n\t\t\t\t\t\t// Support: IE <9 only\n\t\t\t\t\t\t// Defend against cloned attroperties (jQuery gh-1709)\n\t\t\t\t\t\tuniqueCache = outerCache[ elem.uniqueID ] || (outerCache[ elem.uniqueID ] = {});\n\n\t\t\t\t\t\tif ( skip && skip === elem.nodeName.toLowerCase() ) {\n\t\t\t\t\t\t\telem = elem[ dir ] || elem;\n\t\t\t\t\t\t} else if ( (oldCache = uniqueCache[ key ]) &&\n\t\t\t\t\t\t\toldCache[ 0 ] === dirruns && oldCache[ 1 ] === doneName ) {\n\n\t\t\t\t\t\t\t// Assign to newCache so results back-propagate to previous elements\n\t\t\t\t\t\t\treturn (newCache[ 2 ] = oldCache[ 2 ]);\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t// Reuse newcache so results back-propagate to previous elements\n\t\t\t\t\t\t\tuniqueCache[ key ] = newCache;\n\n\t\t\t\t\t\t\t// A match means we're done; a fail means we have to keep checking\n\t\t\t\t\t\t\tif ( (newCache[ 2 ] = matcher( elem, context, xml )) ) {\n\t\t\t\t\t\t\t\treturn true;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn false;\n\t\t};\n}\n\nfunction elementMatcher( matchers ) {\n\treturn matchers.length > 1 ?\n\t\tfunction( elem, context, xml ) {\n\t\t\tvar i = matchers.length;\n\t\t\twhile ( i-- ) {\n\t\t\t\tif ( !matchers[i]( elem, context, xml ) ) {\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn true;\n\t\t} :\n\t\tmatchers[0];\n}\n\nfunction multipleContexts( selector, contexts, results ) {\n\tvar i = 0,\n\t\tlen = contexts.length;\n\tfor ( ; i < len; i++ ) {\n\t\tSizzle( selector, contexts[i], results );\n\t}\n\treturn results;\n}\n\nfunction condense( unmatched, map, filter, context, xml ) {\n\tvar elem,\n\t\tnewUnmatched = [],\n\t\ti = 0,\n\t\tlen = unmatched.length,\n\t\tmapped = map != null;\n\n\tfor ( ; i < len; i++ ) {\n\t\tif ( (elem = unmatched[i]) ) {\n\t\t\tif ( !filter || filter( elem, context, xml ) ) {\n\t\t\t\tnewUnmatched.push( elem );\n\t\t\t\tif ( mapped ) {\n\t\t\t\t\tmap.push( i );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\treturn newUnmatched;\n}\n\nfunction setMatcher( preFilter, selector, matcher, postFilter, postFinder, postSelector ) {\n\tif ( postFilter && !postFilter[ expando ] ) {\n\t\tpostFilter = setMatcher( postFilter );\n\t}\n\tif ( postFinder && !postFinder[ expando ] ) {\n\t\tpostFinder = setMatcher( postFinder, postSelector );\n\t}\n\treturn markFunction(function( seed, results, context, xml ) {\n\t\tvar temp, i, elem,\n\t\t\tpreMap = [],\n\t\t\tpostMap = [],\n\t\t\tpreexisting = results.length,\n\n\t\t\t// Get initial elements from seed or context\n\t\t\telems = seed || multipleContexts( selector || \"*\", context.nodeType ? [ context ] : context, [] ),\n\n\t\t\t// Prefilter to get matcher input, preserving a map for seed-results synchronization\n\t\t\tmatcherIn = preFilter && ( seed || !selector ) ?\n\t\t\t\tcondense( elems, preMap, preFilter, context, xml ) :\n\t\t\t\telems,\n\n\t\t\tmatcherOut = matcher ?\n\t\t\t\t// If we have a postFinder, or filtered seed, or non-seed postFilter or preexisting results,\n\t\t\t\tpostFinder || ( seed ? preFilter : preexisting || postFilter ) ?\n\n\t\t\t\t\t// ...intermediate processing is necessary\n\t\t\t\t\t[] :\n\n\t\t\t\t\t// ...otherwise use results directly\n\t\t\t\t\tresults :\n\t\t\t\tmatcherIn;\n\n\t\t// Find primary matches\n\t\tif ( matcher ) {\n\t\t\tmatcher( matcherIn, matcherOut, context, xml );\n\t\t}\n\n\t\t// Apply postFilter\n\t\tif ( postFilter ) {\n\t\t\ttemp = condense( matcherOut, postMap );\n\t\t\tpostFilter( temp, [], context, xml );\n\n\t\t\t// Un-match failing elements by moving them back to matcherIn\n\t\t\ti = temp.length;\n\t\t\twhile ( i-- ) {\n\t\t\t\tif ( (elem = temp[i]) ) {\n\t\t\t\t\tmatcherOut[ postMap[i] ] = !(matcherIn[ postMap[i] ] = elem);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif ( seed ) {\n\t\t\tif ( postFinder || preFilter ) {\n\t\t\t\tif ( postFinder ) {\n\t\t\t\t\t// Get the final matcherOut by condensing this intermediate into postFinder contexts\n\t\t\t\t\ttemp = [];\n\t\t\t\t\ti = matcherOut.length;\n\t\t\t\t\twhile ( i-- ) {\n\t\t\t\t\t\tif ( (elem = matcherOut[i]) ) {\n\t\t\t\t\t\t\t// Restore matcherIn since elem is not yet a final match\n\t\t\t\t\t\t\ttemp.push( (matcherIn[i] = elem) );\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tpostFinder( null, (matcherOut = []), temp, xml );\n\t\t\t\t}\n\n\t\t\t\t// Move matched elements from seed to results to keep them synchronized\n\t\t\t\ti = matcherOut.length;\n\t\t\t\twhile ( i-- ) {\n\t\t\t\t\tif ( (elem = matcherOut[i]) &&\n\t\t\t\t\t\t(temp = postFinder ? indexOf( seed, elem ) : preMap[i]) > -1 ) {\n\n\t\t\t\t\t\tseed[temp] = !(results[temp] = elem);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t// Add elements to results, through postFinder if defined\n\t\t} else {\n\t\t\tmatcherOut = condense(\n\t\t\t\tmatcherOut === results ?\n\t\t\t\t\tmatcherOut.splice( preexisting, matcherOut.length ) :\n\t\t\t\t\tmatcherOut\n\t\t\t);\n\t\t\tif ( postFinder ) {\n\t\t\t\tpostFinder( null, results, matcherOut, xml );\n\t\t\t} else {\n\t\t\t\tpush.apply( results, matcherOut );\n\t\t\t}\n\t\t}\n\t});\n}\n\nfunction matcherFromTokens( tokens ) {\n\tvar checkContext, matcher, j,\n\t\tlen = tokens.length,\n\t\tleadingRelative = Expr.relative[ tokens[0].type ],\n\t\timplicitRelative = leadingRelative || Expr.relative[\" \"],\n\t\ti = leadingRelative ? 1 : 0,\n\n\t\t// The foundational matcher ensures that elements are reachable from top-level context(s)\n\t\tmatchContext = addCombinator( function( elem ) {\n\t\t\treturn elem === checkContext;\n\t\t}, implicitRelative, true ),\n\t\tmatchAnyContext = addCombinator( function( elem ) {\n\t\t\treturn indexOf( checkContext, elem ) > -1;\n\t\t}, implicitRelative, true ),\n\t\tmatchers = [ function( elem, context, xml ) {\n\t\t\tvar ret = ( !leadingRelative && ( xml || context !== outermostContext ) ) || (\n\t\t\t\t(checkContext = context).nodeType ?\n\t\t\t\t\tmatchContext( elem, context, xml ) :\n\t\t\t\t\tmatchAnyContext( elem, context, xml ) );\n\t\t\t// Avoid hanging onto element (issue #299)\n\t\t\tcheckContext = null;\n\t\t\treturn ret;\n\t\t} ];\n\n\tfor ( ; i < len; i++ ) {\n\t\tif ( (matcher = Expr.relative[ tokens[i].type ]) ) {\n\t\t\tmatchers = [ addCombinator(elementMatcher( matchers ), matcher) ];\n\t\t} else {\n\t\t\tmatcher = Expr.filter[ tokens[i].type ].apply( null, tokens[i].matches );\n\n\t\t\t// Return special upon seeing a positional matcher\n\t\t\tif ( matcher[ expando ] ) {\n\t\t\t\t// Find the next relative operator (if any) for proper handling\n\t\t\t\tj = ++i;\n\t\t\t\tfor ( ; j < len; j++ ) {\n\t\t\t\t\tif ( Expr.relative[ tokens[j].type ] ) {\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn setMatcher(\n\t\t\t\t\ti > 1 && elementMatcher( matchers ),\n\t\t\t\t\ti > 1 && toSelector(\n\t\t\t\t\t\t// If the preceding token was a descendant combinator, insert an implicit any-element `*`\n\t\t\t\t\t\ttokens.slice( 0, i - 1 ).concat({ value: tokens[ i - 2 ].type === \" \" ? \"*\" : \"\" })\n\t\t\t\t\t).replace( rtrim, \"$1\" ),\n\t\t\t\t\tmatcher,\n\t\t\t\t\ti < j && matcherFromTokens( tokens.slice( i, j ) ),\n\t\t\t\t\tj < len && matcherFromTokens( (tokens = tokens.slice( j )) ),\n\t\t\t\t\tj < len && toSelector( tokens )\n\t\t\t\t);\n\t\t\t}\n\t\t\tmatchers.push( matcher );\n\t\t}\n\t}\n\n\treturn elementMatcher( matchers );\n}\n\nfunction matcherFromGroupMatchers( elementMatchers, setMatchers ) {\n\tvar bySet = setMatchers.length > 0,\n\t\tbyElement = elementMatchers.length > 0,\n\t\tsuperMatcher = function( seed, context, xml, results, outermost ) {\n\t\t\tvar elem, j, matcher,\n\t\t\t\tmatchedCount = 0,\n\t\t\t\ti = \"0\",\n\t\t\t\tunmatched = seed && [],\n\t\t\t\tsetMatched = [],\n\t\t\t\tcontextBackup = outermostContext,\n\t\t\t\t// We must always have either seed elements or outermost context\n\t\t\t\telems = seed || byElement && Expr.find[\"TAG\"]( \"*\", outermost ),\n\t\t\t\t// Use integer dirruns iff this is the outermost matcher\n\t\t\t\tdirrunsUnique = (dirruns += contextBackup == null ? 1 : Math.random() || 0.1),\n\t\t\t\tlen = elems.length;\n\n\t\t\tif ( outermost ) {\n\t\t\t\toutermostContext = context === document || context || outermost;\n\t\t\t}\n\n\t\t\t// Add elements passing elementMatchers directly to results\n\t\t\t// Support: IE<9, Safari\n\t\t\t// Tolerate NodeList properties (IE: \"length\"; Safari: <number>) matching elements by id\n\t\t\tfor ( ; i !== len && (elem = elems[i]) != null; i++ ) {\n\t\t\t\tif ( byElement && elem ) {\n\t\t\t\t\tj = 0;\n\t\t\t\t\tif ( !context && elem.ownerDocument !== document ) {\n\t\t\t\t\t\tsetDocument( elem );\n\t\t\t\t\t\txml = !documentIsHTML;\n\t\t\t\t\t}\n\t\t\t\t\twhile ( (matcher = elementMatchers[j++]) ) {\n\t\t\t\t\t\tif ( matcher( elem, context || document, xml) ) {\n\t\t\t\t\t\t\tresults.push( elem );\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tif ( outermost ) {\n\t\t\t\t\t\tdirruns = dirrunsUnique;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// Track unmatched elements for set filters\n\t\t\t\tif ( bySet ) {\n\t\t\t\t\t// They will have gone through all possible matchers\n\t\t\t\t\tif ( (elem = !matcher && elem) ) {\n\t\t\t\t\t\tmatchedCount--;\n\t\t\t\t\t}\n\n\t\t\t\t\t// Lengthen the array for every element, matched or not\n\t\t\t\t\tif ( seed ) {\n\t\t\t\t\t\tunmatched.push( elem );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// `i` is now the count of elements visited above, and adding it to `matchedCount`\n\t\t\t// makes the latter nonnegative.\n\t\t\tmatchedCount += i;\n\n\t\t\t// Apply set filters to unmatched elements\n\t\t\t// NOTE: This can be skipped if there are no unmatched elements (i.e., `matchedCount`\n\t\t\t// equals `i`), unless we didn't visit _any_ elements in the above loop because we have\n\t\t\t// no element matchers and no seed.\n\t\t\t// Incrementing an initially-string \"0\" `i` allows `i` to remain a string only in that\n\t\t\t// case, which will result in a \"00\" `matchedCount` that differs from `i` but is also\n\t\t\t// numerically zero.\n\t\t\tif ( bySet && i !== matchedCount ) {\n\t\t\t\tj = 0;\n\t\t\t\twhile ( (matcher = setMatchers[j++]) ) {\n\t\t\t\t\tmatcher( unmatched, setMatched, context, xml );\n\t\t\t\t}\n\n\t\t\t\tif ( seed ) {\n\t\t\t\t\t// Reintegrate element matches to eliminate the need for sorting\n\t\t\t\t\tif ( matchedCount > 0 ) {\n\t\t\t\t\t\twhile ( i-- ) {\n\t\t\t\t\t\t\tif ( !(unmatched[i] || setMatched[i]) ) {\n\t\t\t\t\t\t\t\tsetMatched[i] = pop.call( results );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\t// Discard index placeholder values to get only actual matches\n\t\t\t\t\tsetMatched = condense( setMatched );\n\t\t\t\t}\n\n\t\t\t\t// Add matches to results\n\t\t\t\tpush.apply( results, setMatched );\n\n\t\t\t\t// Seedless set matches succeeding multiple successful matchers stipulate sorting\n\t\t\t\tif ( outermost && !seed && setMatched.length > 0 &&\n\t\t\t\t\t( matchedCount + setMatchers.length ) > 1 ) {\n\n\t\t\t\t\tSizzle.uniqueSort( results );\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Override manipulation of globals by nested matchers\n\t\t\tif ( outermost ) {\n\t\t\t\tdirruns = dirrunsUnique;\n\t\t\t\toutermostContext = contextBackup;\n\t\t\t}\n\n\t\t\treturn unmatched;\n\t\t};\n\n\treturn bySet ?\n\t\tmarkFunction( superMatcher ) :\n\t\tsuperMatcher;\n}\n\ncompile = Sizzle.compile = function( selector, match /* Internal Use Only */ ) {\n\tvar i,\n\t\tsetMatchers = [],\n\t\telementMatchers = [],\n\t\tcached = compilerCache[ selector + \" \" ];\n\n\tif ( !cached ) {\n\t\t// Generate a function of recursive functions that can be used to check each element\n\t\tif ( !match ) {\n\t\t\tmatch = tokenize( selector );\n\t\t}\n\t\ti = match.length;\n\t\twhile ( i-- ) {\n\t\t\tcached = matcherFromTokens( match[i] );\n\t\t\tif ( cached[ expando ] ) {\n\t\t\t\tsetMatchers.push( cached );\n\t\t\t} else {\n\t\t\t\telementMatchers.push( cached );\n\t\t\t}\n\t\t}\n\n\t\t// Cache the compiled function\n\t\tcached = compilerCache( selector, matcherFromGroupMatchers( elementMatchers, setMatchers ) );\n\n\t\t// Save selector and tokenization\n\t\tcached.selector = selector;\n\t}\n\treturn cached;\n};\n\n/**\n * A low-level selection function that works with Sizzle's compiled\n *  selector functions\n * @param {String|Function} selector A selector or a pre-compiled\n *  selector function built with Sizzle.compile\n * @param {Element} context\n * @param {Array} [results]\n * @param {Array} [seed] A set of elements to match against\n */\nselect = Sizzle.select = function( selector, context, results, seed ) {\n\tvar i, tokens, token, type, find,\n\t\tcompiled = typeof selector === \"function\" && selector,\n\t\tmatch = !seed && tokenize( (selector = compiled.selector || selector) );\n\n\tresults = results || [];\n\n\t// Try to minimize operations if there is only one selector in the list and no seed\n\t// (the latter of which guarantees us context)\n\tif ( match.length === 1 ) {\n\n\t\t// Reduce context if the leading compound selector is an ID\n\t\ttokens = match[0] = match[0].slice( 0 );\n\t\tif ( tokens.length > 2 && (token = tokens[0]).type === \"ID\" &&\n\t\t\t\tcontext.nodeType === 9 && documentIsHTML && Expr.relative[ tokens[1].type ] ) {\n\n\t\t\tcontext = ( Expr.find[\"ID\"]( token.matches[0].replace(runescape, funescape), context ) || [] )[0];\n\t\t\tif ( !context ) {\n\t\t\t\treturn results;\n\n\t\t\t// Precompiled matchers will still verify ancestry, so step up a level\n\t\t\t} else if ( compiled ) {\n\t\t\t\tcontext = context.parentNode;\n\t\t\t}\n\n\t\t\tselector = selector.slice( tokens.shift().value.length );\n\t\t}\n\n\t\t// Fetch a seed set for right-to-left matching\n\t\ti = matchExpr[\"needsContext\"].test( selector ) ? 0 : tokens.length;\n\t\twhile ( i-- ) {\n\t\t\ttoken = tokens[i];\n\n\t\t\t// Abort if we hit a combinator\n\t\t\tif ( Expr.relative[ (type = token.type) ] ) {\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tif ( (find = Expr.find[ type ]) ) {\n\t\t\t\t// Search, expanding context for leading sibling combinators\n\t\t\t\tif ( (seed = find(\n\t\t\t\t\ttoken.matches[0].replace( runescape, funescape ),\n\t\t\t\t\trsibling.test( tokens[0].type ) && testContext( context.parentNode ) || context\n\t\t\t\t)) ) {\n\n\t\t\t\t\t// If seed is empty or no tokens remain, we can return early\n\t\t\t\t\ttokens.splice( i, 1 );\n\t\t\t\t\tselector = seed.length && toSelector( tokens );\n\t\t\t\t\tif ( !selector ) {\n\t\t\t\t\t\tpush.apply( results, seed );\n\t\t\t\t\t\treturn results;\n\t\t\t\t\t}\n\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t// Compile and execute a filtering function if one is not provided\n\t// Provide `match` to avoid retokenization if we modified the selector above\n\t( compiled || compile( selector, match ) )(\n\t\tseed,\n\t\tcontext,\n\t\t!documentIsHTML,\n\t\tresults,\n\t\t!context || rsibling.test( selector ) && testContext( context.parentNode ) || context\n\t);\n\treturn results;\n};\n\n// One-time assignments\n\n// Sort stability\nsupport.sortStable = expando.split(\"\").sort( sortOrder ).join(\"\") === expando;\n\n// Support: Chrome 14-35+\n// Always assume duplicates if they aren't passed to the comparison function\nsupport.detectDuplicates = !!hasDuplicate;\n\n// Initialize against the default document\nsetDocument();\n\n// Support: Webkit<537.32 - Safari 6.0.3/Chrome 25 (fixed in Chrome 27)\n// Detached nodes confoundingly follow *each other*\nsupport.sortDetached = assert(function( el ) {\n\t// Should return 1, but returns 4 (following)\n\treturn el.compareDocumentPosition( document.createElement(\"fieldset\") ) & 1;\n});\n\n// Support: IE<8\n// Prevent attribute/property \"interpolation\"\n// https://msdn.microsoft.com/en-us/library/ms536429%28VS.85%29.aspx\nif ( !assert(function( el ) {\n\tel.innerHTML = \"<a href='#'></a>\";\n\treturn el.firstChild.getAttribute(\"href\") === \"#\" ;\n}) ) {\n\taddHandle( \"type|href|height|width\", function( elem, name, isXML ) {\n\t\tif ( !isXML ) {\n\t\t\treturn elem.getAttribute( name, name.toLowerCase() === \"type\" ? 1 : 2 );\n\t\t}\n\t});\n}\n\n// Support: IE<9\n// Use defaultValue in place of getAttribute(\"value\")\nif ( !support.attributes || !assert(function( el ) {\n\tel.innerHTML = \"<input/>\";\n\tel.firstChild.setAttribute( \"value\", \"\" );\n\treturn el.firstChild.getAttribute( \"value\" ) === \"\";\n}) ) {\n\taddHandle( \"value\", function( elem, name, isXML ) {\n\t\tif ( !isXML && elem.nodeName.toLowerCase() === \"input\" ) {\n\t\t\treturn elem.defaultValue;\n\t\t}\n\t});\n}\n\n// Support: IE<9\n// Use getAttributeNode to fetch booleans when getAttribute lies\nif ( !assert(function( el ) {\n\treturn el.getAttribute(\"disabled\") == null;\n}) ) {\n\taddHandle( booleans, function( elem, name, isXML ) {\n\t\tvar val;\n\t\tif ( !isXML ) {\n\t\t\treturn elem[ name ] === true ? name.toLowerCase() :\n\t\t\t\t\t(val = elem.getAttributeNode( name )) && val.specified ?\n\t\t\t\t\tval.value :\n\t\t\t\tnull;\n\t\t}\n\t});\n}\n\nreturn Sizzle;\n\n})( window );\n\n\n\njQuery.find = Sizzle;\njQuery.expr = Sizzle.selectors;\n\n// Deprecated\njQuery.expr[ \":\" ] = jQuery.expr.pseudos;\njQuery.uniqueSort = jQuery.unique = Sizzle.uniqueSort;\njQuery.text = Sizzle.getText;\njQuery.isXMLDoc = Sizzle.isXML;\njQuery.contains = Sizzle.contains;\njQuery.escapeSelector = Sizzle.escape;\n\n\n\n\nvar dir = function( elem, dir, until ) {\n\tvar matched = [],\n\t\ttruncate = until !== undefined;\n\n\twhile ( ( elem = elem[ dir ] ) && elem.nodeType !== 9 ) {\n\t\tif ( elem.nodeType === 1 ) {\n\t\t\tif ( truncate && jQuery( elem ).is( until ) ) {\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tmatched.push( elem );\n\t\t}\n\t}\n\treturn matched;\n};\n\n\nvar siblings = function( n, elem ) {\n\tvar matched = [];\n\n\tfor ( ; n; n = n.nextSibling ) {\n\t\tif ( n.nodeType === 1 && n !== elem ) {\n\t\t\tmatched.push( n );\n\t\t}\n\t}\n\n\treturn matched;\n};\n\n\nvar rneedsContext = jQuery.expr.match.needsContext;\n\n\n\nfunction nodeName( elem, name ) {\n\n  return elem.nodeName && elem.nodeName.toLowerCase() === name.toLowerCase();\n\n};\nvar rsingleTag = ( /^<([a-z][^\\/\\0>:\\x20\\t\\r\\n\\f]*)[\\x20\\t\\r\\n\\f]*\\/?>(?:<\\/\\1>|)$/i );\n\n\n\n// Implement the identical functionality for filter and not\nfunction winnow( elements, qualifier, not ) {\n\tif ( isFunction( qualifier ) ) {\n\t\treturn jQuery.grep( elements, function( elem, i ) {\n\t\t\treturn !!qualifier.call( elem, i, elem ) !== not;\n\t\t} );\n\t}\n\n\t// Single element\n\tif ( qualifier.nodeType ) {\n\t\treturn jQuery.grep( elements, function( elem ) {\n\t\t\treturn ( elem === qualifier ) !== not;\n\t\t} );\n\t}\n\n\t// Arraylike of elements (jQuery, arguments, Array)\n\tif ( typeof qualifier !== \"string\" ) {\n\t\treturn jQuery.grep( elements, function( elem ) {\n\t\t\treturn ( indexOf.call( qualifier, elem ) > -1 ) !== not;\n\t\t} );\n\t}\n\n\t// Filtered directly for both simple and complex selectors\n\treturn jQuery.filter( qualifier, elements, not );\n}\n\njQuery.filter = function( expr, elems, not ) {\n\tvar elem = elems[ 0 ];\n\n\tif ( not ) {\n\t\texpr = \":not(\" + expr + \")\";\n\t}\n\n\tif ( elems.length === 1 && elem.nodeType === 1 ) {\n\t\treturn jQuery.find.matchesSelector( elem, expr ) ? [ elem ] : [];\n\t}\n\n\treturn jQuery.find.matches( expr, jQuery.grep( elems, function( elem ) {\n\t\treturn elem.nodeType === 1;\n\t} ) );\n};\n\njQuery.fn.extend( {\n\tfind: function( selector ) {\n\t\tvar i, ret,\n\t\t\tlen = this.length,\n\t\t\tself = this;\n\n\t\tif ( typeof selector !== \"string\" ) {\n\t\t\treturn this.pushStack( jQuery( selector ).filter( function() {\n\t\t\t\tfor ( i = 0; i < len; i++ ) {\n\t\t\t\t\tif ( jQuery.contains( self[ i ], this ) ) {\n\t\t\t\t\t\treturn true;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} ) );\n\t\t}\n\n\t\tret = this.pushStack( [] );\n\n\t\tfor ( i = 0; i < len; i++ ) {\n\t\t\tjQuery.find( selector, self[ i ], ret );\n\t\t}\n\n\t\treturn len > 1 ? jQuery.uniqueSort( ret ) : ret;\n\t},\n\tfilter: function( selector ) {\n\t\treturn this.pushStack( winnow( this, selector || [], false ) );\n\t},\n\tnot: function( selector ) {\n\t\treturn this.pushStack( winnow( this, selector || [], true ) );\n\t},\n\tis: function( selector ) {\n\t\treturn !!winnow(\n\t\t\tthis,\n\n\t\t\t// If this is a positional/relative selector, check membership in the returned set\n\t\t\t// so $(\"p:first\").is(\"p:last\") won't return true for a doc with two \"p\".\n\t\t\ttypeof selector === \"string\" && rneedsContext.test( selector ) ?\n\t\t\t\tjQuery( selector ) :\n\t\t\t\tselector || [],\n\t\t\tfalse\n\t\t).length;\n\t}\n} );\n\n\n// Initialize a jQuery object\n\n\n// A central reference to the root jQuery(document)\nvar rootjQuery,\n\n\t// A simple way to check for HTML strings\n\t// Prioritize #id over <tag> to avoid XSS via location.hash (#9521)\n\t// Strict HTML recognition (#11290: must start with <)\n\t// Shortcut simple #id case for speed\n\trquickExpr = /^(?:\\s*(<[\\w\\W]+>)[^>]*|#([\\w-]+))$/,\n\n\tinit = jQuery.fn.init = function( selector, context, root ) {\n\t\tvar match, elem;\n\n\t\t// HANDLE: $(\"\"), $(null), $(undefined), $(false)\n\t\tif ( !selector ) {\n\t\t\treturn this;\n\t\t}\n\n\t\t// Method init() accepts an alternate rootjQuery\n\t\t// so migrate can support jQuery.sub (gh-2101)\n\t\troot = root || rootjQuery;\n\n\t\t// Handle HTML strings\n\t\tif ( typeof selector === \"string\" ) {\n\t\t\tif ( selector[ 0 ] === \"<\" &&\n\t\t\t\tselector[ selector.length - 1 ] === \">\" &&\n\t\t\t\tselector.length >= 3 ) {\n\n\t\t\t\t// Assume that strings that start and end with <> are HTML and skip the regex check\n\t\t\t\tmatch = [ null, selector, null ];\n\n\t\t\t} else {\n\t\t\t\tmatch = rquickExpr.exec( selector );\n\t\t\t}\n\n\t\t\t// Match html or make sure no context is specified for #id\n\t\t\tif ( match && ( match[ 1 ] || !context ) ) {\n\n\t\t\t\t// HANDLE: $(html) -> $(array)\n\t\t\t\tif ( match[ 1 ] ) {\n\t\t\t\t\tcontext = context instanceof jQuery ? context[ 0 ] : context;\n\n\t\t\t\t\t// Option to run scripts is true for back-compat\n\t\t\t\t\t// Intentionally let the error be thrown if parseHTML is not present\n\t\t\t\t\tjQuery.merge( this, jQuery.parseHTML(\n\t\t\t\t\t\tmatch[ 1 ],\n\t\t\t\t\t\tcontext && context.nodeType ? context.ownerDocument || context : document,\n\t\t\t\t\t\ttrue\n\t\t\t\t\t) );\n\n\t\t\t\t\t// HANDLE: $(html, props)\n\t\t\t\t\tif ( rsingleTag.test( match[ 1 ] ) && jQuery.isPlainObject( context ) ) {\n\t\t\t\t\t\tfor ( match in context ) {\n\n\t\t\t\t\t\t\t// Properties of context are called as methods if possible\n\t\t\t\t\t\t\tif ( isFunction( this[ match ] ) ) {\n\t\t\t\t\t\t\t\tthis[ match ]( context[ match ] );\n\n\t\t\t\t\t\t\t// ...and otherwise set as attributes\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tthis.attr( match, context[ match ] );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\treturn this;\n\n\t\t\t\t// HANDLE: $(#id)\n\t\t\t\t} else {\n\t\t\t\t\telem = document.getElementById( match[ 2 ] );\n\n\t\t\t\t\tif ( elem ) {\n\n\t\t\t\t\t\t// Inject the element directly into the jQuery object\n\t\t\t\t\t\tthis[ 0 ] = elem;\n\t\t\t\t\t\tthis.length = 1;\n\t\t\t\t\t}\n\t\t\t\t\treturn this;\n\t\t\t\t}\n\n\t\t\t// HANDLE: $(expr, $(...))\n\t\t\t} else if ( !context || context.jquery ) {\n\t\t\t\treturn ( context || root ).find( selector );\n\n\t\t\t// HANDLE: $(expr, context)\n\t\t\t// (which is just equivalent to: $(context).find(expr)\n\t\t\t} else {\n\t\t\t\treturn this.constructor( context ).find( selector );\n\t\t\t}\n\n\t\t// HANDLE: $(DOMElement)\n\t\t} else if ( selector.nodeType ) {\n\t\t\tthis[ 0 ] = selector;\n\t\t\tthis.length = 1;\n\t\t\treturn this;\n\n\t\t// HANDLE: $(function)\n\t\t// Shortcut for document ready\n\t\t} else if ( isFunction( selector ) ) {\n\t\t\treturn root.ready !== undefined ?\n\t\t\t\troot.ready( selector ) :\n\n\t\t\t\t// Execute immediately if ready is not present\n\t\t\t\tselector( jQuery );\n\t\t}\n\n\t\treturn jQuery.makeArray( selector, this );\n\t};\n\n// Give the init function the jQuery prototype for later instantiation\ninit.prototype = jQuery.fn;\n\n// Initialize central reference\nrootjQuery = jQuery( document );\n\n\nvar rparentsprev = /^(?:parents|prev(?:Until|All))/,\n\n\t// Methods guaranteed to produce a unique set when starting from a unique set\n\tguaranteedUnique = {\n\t\tchildren: true,\n\t\tcontents: true,\n\t\tnext: true,\n\t\tprev: true\n\t};\n\njQuery.fn.extend( {\n\thas: function( target ) {\n\t\tvar targets = jQuery( target, this ),\n\t\t\tl = targets.length;\n\n\t\treturn this.filter( function() {\n\t\t\tvar i = 0;\n\t\t\tfor ( ; i < l; i++ ) {\n\t\t\t\tif ( jQuery.contains( this, targets[ i ] ) ) {\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t}\n\t\t} );\n\t},\n\n\tclosest: function( selectors, context ) {\n\t\tvar cur,\n\t\t\ti = 0,\n\t\t\tl = this.length,\n\t\t\tmatched = [],\n\t\t\ttargets = typeof selectors !== \"string\" && jQuery( selectors );\n\n\t\t// Positional selectors never match, since there's no _selection_ context\n\t\tif ( !rneedsContext.test( selectors ) ) {\n\t\t\tfor ( ; i < l; i++ ) {\n\t\t\t\tfor ( cur = this[ i ]; cur && cur !== context; cur = cur.parentNode ) {\n\n\t\t\t\t\t// Always skip document fragments\n\t\t\t\t\tif ( cur.nodeType < 11 && ( targets ?\n\t\t\t\t\t\ttargets.index( cur ) > -1 :\n\n\t\t\t\t\t\t// Don't pass non-elements to Sizzle\n\t\t\t\t\t\tcur.nodeType === 1 &&\n\t\t\t\t\t\t\tjQuery.find.matchesSelector( cur, selectors ) ) ) {\n\n\t\t\t\t\t\tmatched.push( cur );\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn this.pushStack( matched.length > 1 ? jQuery.uniqueSort( matched ) : matched );\n\t},\n\n\t// Determine the position of an element within the set\n\tindex: function( elem ) {\n\n\t\t// No argument, return index in parent\n\t\tif ( !elem ) {\n\t\t\treturn ( this[ 0 ] && this[ 0 ].parentNode ) ? this.first().prevAll().length : -1;\n\t\t}\n\n\t\t// Index in selector\n\t\tif ( typeof elem === \"string\" ) {\n\t\t\treturn indexOf.call( jQuery( elem ), this[ 0 ] );\n\t\t}\n\n\t\t// Locate the position of the desired element\n\t\treturn indexOf.call( this,\n\n\t\t\t// If it receives a jQuery object, the first element is used\n\t\t\telem.jquery ? elem[ 0 ] : elem\n\t\t);\n\t},\n\n\tadd: function( selector, context ) {\n\t\treturn this.pushStack(\n\t\t\tjQuery.uniqueSort(\n\t\t\t\tjQuery.merge( this.get(), jQuery( selector, context ) )\n\t\t\t)\n\t\t);\n\t},\n\n\taddBack: function( selector ) {\n\t\treturn this.add( selector == null ?\n\t\t\tthis.prevObject : this.prevObject.filter( selector )\n\t\t);\n\t}\n} );\n\nfunction sibling( cur, dir ) {\n\twhile ( ( cur = cur[ dir ] ) && cur.nodeType !== 1 ) {}\n\treturn cur;\n}\n\njQuery.each( {\n\tparent: function( elem ) {\n\t\tvar parent = elem.parentNode;\n\t\treturn parent && parent.nodeType !== 11 ? parent : null;\n\t},\n\tparents: function( elem ) {\n\t\treturn dir( elem, \"parentNode\" );\n\t},\n\tparentsUntil: function( elem, i, until ) {\n\t\treturn dir( elem, \"parentNode\", until );\n\t},\n\tnext: function( elem ) {\n\t\treturn sibling( elem, \"nextSibling\" );\n\t},\n\tprev: function( elem ) {\n\t\treturn sibling( elem, \"previousSibling\" );\n\t},\n\tnextAll: function( elem ) {\n\t\treturn dir( elem, \"nextSibling\" );\n\t},\n\tprevAll: function( elem ) {\n\t\treturn dir( elem, \"previousSibling\" );\n\t},\n\tnextUntil: function( elem, i, until ) {\n\t\treturn dir( elem, \"nextSibling\", until );\n\t},\n\tprevUntil: function( elem, i, until ) {\n\t\treturn dir( elem, \"previousSibling\", until );\n\t},\n\tsiblings: function( elem ) {\n\t\treturn siblings( ( elem.parentNode || {} ).firstChild, elem );\n\t},\n\tchildren: function( elem ) {\n\t\treturn siblings( elem.firstChild );\n\t},\n\tcontents: function( elem ) {\n        if ( nodeName( elem, \"iframe\" ) ) {\n            return elem.contentDocument;\n        }\n\n        // Support: IE 9 - 11 only, iOS 7 only, Android Browser <=4.3 only\n        // Treat the template element as a regular one in browsers that\n        // don't support it.\n        if ( nodeName( elem, \"template\" ) ) {\n            elem = elem.content || elem;\n        }\n\n        return jQuery.merge( [], elem.childNodes );\n\t}\n}, function( name, fn ) {\n\tjQuery.fn[ name ] = function( until, selector ) {\n\t\tvar matched = jQuery.map( this, fn, until );\n\n\t\tif ( name.slice( -5 ) !== \"Until\" ) {\n\t\t\tselector = until;\n\t\t}\n\n\t\tif ( selector && typeof selector === \"string\" ) {\n\t\t\tmatched = jQuery.filter( selector, matched );\n\t\t}\n\n\t\tif ( this.length > 1 ) {\n\n\t\t\t// Remove duplicates\n\t\t\tif ( !guaranteedUnique[ name ] ) {\n\t\t\t\tjQuery.uniqueSort( matched );\n\t\t\t}\n\n\t\t\t// Reverse order for parents* and prev-derivatives\n\t\t\tif ( rparentsprev.test( name ) ) {\n\t\t\t\tmatched.reverse();\n\t\t\t}\n\t\t}\n\n\t\treturn this.pushStack( matched );\n\t};\n} );\nvar rnothtmlwhite = ( /[^\\x20\\t\\r\\n\\f]+/g );\n\n\n\n// Convert String-formatted options into Object-formatted ones\nfunction createOptions( options ) {\n\tvar object = {};\n\tjQuery.each( options.match( rnothtmlwhite ) || [], function( _, flag ) {\n\t\tobject[ flag ] = true;\n\t} );\n\treturn object;\n}\n\n/*\n * Create a callback list using the following parameters:\n *\n *\toptions: an optional list of space-separated options that will change how\n *\t\t\tthe callback list behaves or a more traditional option object\n *\n * By default a callback list will act like an event callback list and can be\n * \"fired\" multiple times.\n *\n * Possible options:\n *\n *\tonce:\t\t\twill ensure the callback list can only be fired once (like a Deferred)\n *\n *\tmemory:\t\t\twill keep track of previous values and will call any callback added\n *\t\t\t\t\tafter the list has been fired right away with the latest \"memorized\"\n *\t\t\t\t\tvalues (like a Deferred)\n *\n *\tunique:\t\t\twill ensure a callback can only be added once (no duplicate in the list)\n *\n *\tstopOnFalse:\tinterrupt callings when a callback returns false\n *\n */\njQuery.Callbacks = function( options ) {\n\n\t// Convert options from String-formatted to Object-formatted if needed\n\t// (we check in cache first)\n\toptions = typeof options === \"string\" ?\n\t\tcreateOptions( options ) :\n\t\tjQuery.extend( {}, options );\n\n\tvar // Flag to know if list is currently firing\n\t\tfiring,\n\n\t\t// Last fire value for non-forgettable lists\n\t\tmemory,\n\n\t\t// Flag to know if list was already fired\n\t\tfired,\n\n\t\t// Flag to prevent firing\n\t\tlocked,\n\n\t\t// Actual callback list\n\t\tlist = [],\n\n\t\t// Queue of execution data for repeatable lists\n\t\tqueue = [],\n\n\t\t// Index of currently firing callback (modified by add/remove as needed)\n\t\tfiringIndex = -1,\n\n\t\t// Fire callbacks\n\t\tfire = function() {\n\n\t\t\t// Enforce single-firing\n\t\t\tlocked = locked || options.once;\n\n\t\t\t// Execute callbacks for all pending executions,\n\t\t\t// respecting firingIndex overrides and runtime changes\n\t\t\tfired = firing = true;\n\t\t\tfor ( ; queue.length; firingIndex = -1 ) {\n\t\t\t\tmemory = queue.shift();\n\t\t\t\twhile ( ++firingIndex < list.length ) {\n\n\t\t\t\t\t// Run callback and check for early termination\n\t\t\t\t\tif ( list[ firingIndex ].apply( memory[ 0 ], memory[ 1 ] ) === false &&\n\t\t\t\t\t\toptions.stopOnFalse ) {\n\n\t\t\t\t\t\t// Jump to end and forget the data so .add doesn't re-fire\n\t\t\t\t\t\tfiringIndex = list.length;\n\t\t\t\t\t\tmemory = false;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Forget the data if we're done with it\n\t\t\tif ( !options.memory ) {\n\t\t\t\tmemory = false;\n\t\t\t}\n\n\t\t\tfiring = false;\n\n\t\t\t// Clean up if we're done firing for good\n\t\t\tif ( locked ) {\n\n\t\t\t\t// Keep an empty list if we have data for future add calls\n\t\t\t\tif ( memory ) {\n\t\t\t\t\tlist = [];\n\n\t\t\t\t// Otherwise, this object is spent\n\t\t\t\t} else {\n\t\t\t\t\tlist = \"\";\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\n\t\t// Actual Callbacks object\n\t\tself = {\n\n\t\t\t// Add a callback or a collection of callbacks to the list\n\t\t\tadd: function() {\n\t\t\t\tif ( list ) {\n\n\t\t\t\t\t// If we have memory from a past run, we should fire after adding\n\t\t\t\t\tif ( memory && !firing ) {\n\t\t\t\t\t\tfiringIndex = list.length - 1;\n\t\t\t\t\t\tqueue.push( memory );\n\t\t\t\t\t}\n\n\t\t\t\t\t( function add( args ) {\n\t\t\t\t\t\tjQuery.each( args, function( _, arg ) {\n\t\t\t\t\t\t\tif ( isFunction( arg ) ) {\n\t\t\t\t\t\t\t\tif ( !options.unique || !self.has( arg ) ) {\n\t\t\t\t\t\t\t\t\tlist.push( arg );\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t} else if ( arg && arg.length && toType( arg ) !== \"string\" ) {\n\n\t\t\t\t\t\t\t\t// Inspect recursively\n\t\t\t\t\t\t\t\tadd( arg );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} );\n\t\t\t\t\t} )( arguments );\n\n\t\t\t\t\tif ( memory && !firing ) {\n\t\t\t\t\t\tfire();\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn this;\n\t\t\t},\n\n\t\t\t// Remove a callback from the list\n\t\t\tremove: function() {\n\t\t\t\tjQuery.each( arguments, function( _, arg ) {\n\t\t\t\t\tvar index;\n\t\t\t\t\twhile ( ( index = jQuery.inArray( arg, list, index ) ) > -1 ) {\n\t\t\t\t\t\tlist.splice( index, 1 );\n\n\t\t\t\t\t\t// Handle firing indexes\n\t\t\t\t\t\tif ( index <= firingIndex ) {\n\t\t\t\t\t\t\tfiringIndex--;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t} );\n\t\t\t\treturn this;\n\t\t\t},\n\n\t\t\t// Check if a given callback is in the list.\n\t\t\t// If no argument is given, return whether or not list has callbacks attached.\n\t\t\thas: function( fn ) {\n\t\t\t\treturn fn ?\n\t\t\t\t\tjQuery.inArray( fn, list ) > -1 :\n\t\t\t\t\tlist.length > 0;\n\t\t\t},\n\n\t\t\t// Remove all callbacks from the list\n\t\t\tempty: function() {\n\t\t\t\tif ( list ) {\n\t\t\t\t\tlist = [];\n\t\t\t\t}\n\t\t\t\treturn this;\n\t\t\t},\n\n\t\t\t// Disable .fire and .add\n\t\t\t// Abort any current/pending executions\n\t\t\t// Clear all callbacks and values\n\t\t\tdisable: function() {\n\t\t\t\tlocked = queue = [];\n\t\t\t\tlist = memory = \"\";\n\t\t\t\treturn this;\n\t\t\t},\n\t\t\tdisabled: function() {\n\t\t\t\treturn !list;\n\t\t\t},\n\n\t\t\t// Disable .fire\n\t\t\t// Also disable .add unless we have memory (since it would have no effect)\n\t\t\t// Abort any pending executions\n\t\t\tlock: function() {\n\t\t\t\tlocked = queue = [];\n\t\t\t\tif ( !memory && !firing ) {\n\t\t\t\t\tlist = memory = \"\";\n\t\t\t\t}\n\t\t\t\treturn this;\n\t\t\t},\n\t\t\tlocked: function() {\n\t\t\t\treturn !!locked;\n\t\t\t},\n\n\t\t\t// Call all callbacks with the given context and arguments\n\t\t\tfireWith: function( context, args ) {\n\t\t\t\tif ( !locked ) {\n\t\t\t\t\targs = args || [];\n\t\t\t\t\targs = [ context, args.slice ? args.slice() : args ];\n\t\t\t\t\tqueue.push( args );\n\t\t\t\t\tif ( !firing ) {\n\t\t\t\t\t\tfire();\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn this;\n\t\t\t},\n\n\t\t\t// Call all the callbacks with the given arguments\n\t\t\tfire: function() {\n\t\t\t\tself.fireWith( this, arguments );\n\t\t\t\treturn this;\n\t\t\t},\n\n\t\t\t// To know if the callbacks have already been called at least once\n\t\t\tfired: function() {\n\t\t\t\treturn !!fired;\n\t\t\t}\n\t\t};\n\n\treturn self;\n};\n\n\nfunction Identity( v ) {\n\treturn v;\n}\nfunction Thrower( ex ) {\n\tthrow ex;\n}\n\nfunction adoptValue( value, resolve, reject, noValue ) {\n\tvar method;\n\n\ttry {\n\n\t\t// Check for promise aspect first to privilege synchronous behavior\n\t\tif ( value && isFunction( ( method = value.promise ) ) ) {\n\t\t\tmethod.call( value ).done( resolve ).fail( reject );\n\n\t\t// Other thenables\n\t\t} else if ( value && isFunction( ( method = value.then ) ) ) {\n\t\t\tmethod.call( value, resolve, reject );\n\n\t\t// Other non-thenables\n\t\t} else {\n\n\t\t\t// Control `resolve` arguments by letting Array#slice cast boolean `noValue` to integer:\n\t\t\t// * false: [ value ].slice( 0 ) => resolve( value )\n\t\t\t// * true: [ value ].slice( 1 ) => resolve()\n\t\t\tresolve.apply( undefined, [ value ].slice( noValue ) );\n\t\t}\n\n\t// For Promises/A+, convert exceptions into rejections\n\t// Since jQuery.when doesn't unwrap thenables, we can skip the extra checks appearing in\n\t// Deferred#then to conditionally suppress rejection.\n\t} catch ( value ) {\n\n\t\t// Support: Android 4.0 only\n\t\t// Strict mode functions invoked without .call/.apply get global-object context\n\t\treject.apply( undefined, [ value ] );\n\t}\n}\n\njQuery.extend( {\n\n\tDeferred: function( func ) {\n\t\tvar tuples = [\n\n\t\t\t\t// action, add listener, callbacks,\n\t\t\t\t// ... .then handlers, argument index, [final state]\n\t\t\t\t[ \"notify\", \"progress\", jQuery.Callbacks( \"memory\" ),\n\t\t\t\t\tjQuery.Callbacks( \"memory\" ), 2 ],\n\t\t\t\t[ \"resolve\", \"done\", jQuery.Callbacks( \"once memory\" ),\n\t\t\t\t\tjQuery.Callbacks( \"once memory\" ), 0, \"resolved\" ],\n\t\t\t\t[ \"reject\", \"fail\", jQuery.Callbacks( \"once memory\" ),\n\t\t\t\t\tjQuery.Callbacks( \"once memory\" ), 1, \"rejected\" ]\n\t\t\t],\n\t\t\tstate = \"pending\",\n\t\t\tpromise = {\n\t\t\t\tstate: function() {\n\t\t\t\t\treturn state;\n\t\t\t\t},\n\t\t\t\talways: function() {\n\t\t\t\t\tdeferred.done( arguments ).fail( arguments );\n\t\t\t\t\treturn this;\n\t\t\t\t},\n\t\t\t\t\"catch\": function( fn ) {\n\t\t\t\t\treturn promise.then( null, fn );\n\t\t\t\t},\n\n\t\t\t\t// Keep pipe for back-compat\n\t\t\t\tpipe: function( /* fnDone, fnFail, fnProgress */ ) {\n\t\t\t\t\tvar fns = arguments;\n\n\t\t\t\t\treturn jQuery.Deferred( function( newDefer ) {\n\t\t\t\t\t\tjQuery.each( tuples, function( i, tuple ) {\n\n\t\t\t\t\t\t\t// Map tuples (progress, done, fail) to arguments (done, fail, progress)\n\t\t\t\t\t\t\tvar fn = isFunction( fns[ tuple[ 4 ] ] ) && fns[ tuple[ 4 ] ];\n\n\t\t\t\t\t\t\t// deferred.progress(function() { bind to newDefer or newDefer.notify })\n\t\t\t\t\t\t\t// deferred.done(function() { bind to newDefer or newDefer.resolve })\n\t\t\t\t\t\t\t// deferred.fail(function() { bind to newDefer or newDefer.reject })\n\t\t\t\t\t\t\tdeferred[ tuple[ 1 ] ]( function() {\n\t\t\t\t\t\t\t\tvar returned = fn && fn.apply( this, arguments );\n\t\t\t\t\t\t\t\tif ( returned && isFunction( returned.promise ) ) {\n\t\t\t\t\t\t\t\t\treturned.promise()\n\t\t\t\t\t\t\t\t\t\t.progress( newDefer.notify )\n\t\t\t\t\t\t\t\t\t\t.done( newDefer.resolve )\n\t\t\t\t\t\t\t\t\t\t.fail( newDefer.reject );\n\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\tnewDefer[ tuple[ 0 ] + \"With\" ](\n\t\t\t\t\t\t\t\t\t\tthis,\n\t\t\t\t\t\t\t\t\t\tfn ? [ returned ] : arguments\n\t\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t} );\n\t\t\t\t\t\t} );\n\t\t\t\t\t\tfns = null;\n\t\t\t\t\t} ).promise();\n\t\t\t\t},\n\t\t\t\tthen: function( onFulfilled, onRejected, onProgress ) {\n\t\t\t\t\tvar maxDepth = 0;\n\t\t\t\t\tfunction resolve( depth, deferred, handler, special ) {\n\t\t\t\t\t\treturn function() {\n\t\t\t\t\t\t\tvar that = this,\n\t\t\t\t\t\t\t\targs = arguments,\n\t\t\t\t\t\t\t\tmightThrow = function() {\n\t\t\t\t\t\t\t\t\tvar returned, then;\n\n\t\t\t\t\t\t\t\t\t// Support: Promises/A+ section 2.3.3.3.3\n\t\t\t\t\t\t\t\t\t// https://promisesaplus.com/#point-59\n\t\t\t\t\t\t\t\t\t// Ignore double-resolution attempts\n\t\t\t\t\t\t\t\t\tif ( depth < maxDepth ) {\n\t\t\t\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t\treturned = handler.apply( that, args );\n\n\t\t\t\t\t\t\t\t\t// Support: Promises/A+ section 2.3.1\n\t\t\t\t\t\t\t\t\t// https://promisesaplus.com/#point-48\n\t\t\t\t\t\t\t\t\tif ( returned === deferred.promise() ) {\n\t\t\t\t\t\t\t\t\t\tthrow new TypeError( \"Thenable self-resolution\" );\n\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t\t// Support: Promises/A+ sections 2.3.3.1, 3.5\n\t\t\t\t\t\t\t\t\t// https://promisesaplus.com/#point-54\n\t\t\t\t\t\t\t\t\t// https://promisesaplus.com/#point-75\n\t\t\t\t\t\t\t\t\t// Retrieve `then` only once\n\t\t\t\t\t\t\t\t\tthen = returned &&\n\n\t\t\t\t\t\t\t\t\t\t// Support: Promises/A+ section 2.3.4\n\t\t\t\t\t\t\t\t\t\t// https://promisesaplus.com/#point-64\n\t\t\t\t\t\t\t\t\t\t// Only check objects and functions for thenability\n\t\t\t\t\t\t\t\t\t\t( typeof returned === \"object\" ||\n\t\t\t\t\t\t\t\t\t\t\ttypeof returned === \"function\" ) &&\n\t\t\t\t\t\t\t\t\t\treturned.then;\n\n\t\t\t\t\t\t\t\t\t// Handle a returned thenable\n\t\t\t\t\t\t\t\t\tif ( isFunction( then ) ) {\n\n\t\t\t\t\t\t\t\t\t\t// Special processors (notify) just wait for resolution\n\t\t\t\t\t\t\t\t\t\tif ( special ) {\n\t\t\t\t\t\t\t\t\t\t\tthen.call(\n\t\t\t\t\t\t\t\t\t\t\t\treturned,\n\t\t\t\t\t\t\t\t\t\t\t\tresolve( maxDepth, deferred, Identity, special ),\n\t\t\t\t\t\t\t\t\t\t\t\tresolve( maxDepth, deferred, Thrower, special )\n\t\t\t\t\t\t\t\t\t\t\t);\n\n\t\t\t\t\t\t\t\t\t\t// Normal processors (resolve) also hook into progress\n\t\t\t\t\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\t\t\t\t\t// ...and disregard older resolution values\n\t\t\t\t\t\t\t\t\t\t\tmaxDepth++;\n\n\t\t\t\t\t\t\t\t\t\t\tthen.call(\n\t\t\t\t\t\t\t\t\t\t\t\treturned,\n\t\t\t\t\t\t\t\t\t\t\t\tresolve( maxDepth, deferred, Identity, special ),\n\t\t\t\t\t\t\t\t\t\t\t\tresolve( maxDepth, deferred, Thrower, special ),\n\t\t\t\t\t\t\t\t\t\t\t\tresolve( maxDepth, deferred, Identity,\n\t\t\t\t\t\t\t\t\t\t\t\t\tdeferred.notifyWith )\n\t\t\t\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t\t// Handle all other returned values\n\t\t\t\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\t\t\t\t// Only substitute handlers pass on context\n\t\t\t\t\t\t\t\t\t\t// and multiple values (non-spec behavior)\n\t\t\t\t\t\t\t\t\t\tif ( handler !== Identity ) {\n\t\t\t\t\t\t\t\t\t\t\tthat = undefined;\n\t\t\t\t\t\t\t\t\t\t\targs = [ returned ];\n\t\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t\t\t// Process the value(s)\n\t\t\t\t\t\t\t\t\t\t// Default process is resolve\n\t\t\t\t\t\t\t\t\t\t( special || deferred.resolveWith )( that, args );\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t},\n\n\t\t\t\t\t\t\t\t// Only normal processors (resolve) catch and reject exceptions\n\t\t\t\t\t\t\t\tprocess = special ?\n\t\t\t\t\t\t\t\t\tmightThrow :\n\t\t\t\t\t\t\t\t\tfunction() {\n\t\t\t\t\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\t\t\t\t\tmightThrow();\n\t\t\t\t\t\t\t\t\t\t} catch ( e ) {\n\n\t\t\t\t\t\t\t\t\t\t\tif ( jQuery.Deferred.exceptionHook ) {\n\t\t\t\t\t\t\t\t\t\t\t\tjQuery.Deferred.exceptionHook( e,\n\t\t\t\t\t\t\t\t\t\t\t\t\tprocess.stackTrace );\n\t\t\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t\t\t\t// Support: Promises/A+ section 2.3.3.3.4.1\n\t\t\t\t\t\t\t\t\t\t\t// https://promisesaplus.com/#point-61\n\t\t\t\t\t\t\t\t\t\t\t// Ignore post-resolution exceptions\n\t\t\t\t\t\t\t\t\t\t\tif ( depth + 1 >= maxDepth ) {\n\n\t\t\t\t\t\t\t\t\t\t\t\t// Only substitute handlers pass on context\n\t\t\t\t\t\t\t\t\t\t\t\t// and multiple values (non-spec behavior)\n\t\t\t\t\t\t\t\t\t\t\t\tif ( handler !== Thrower ) {\n\t\t\t\t\t\t\t\t\t\t\t\t\tthat = undefined;\n\t\t\t\t\t\t\t\t\t\t\t\t\targs = [ e ];\n\t\t\t\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t\t\t\t\tdeferred.rejectWith( that, args );\n\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t};\n\n\t\t\t\t\t\t\t// Support: Promises/A+ section 2.3.3.3.1\n\t\t\t\t\t\t\t// https://promisesaplus.com/#point-57\n\t\t\t\t\t\t\t// Re-resolve promises immediately to dodge false rejection from\n\t\t\t\t\t\t\t// subsequent errors\n\t\t\t\t\t\t\tif ( depth ) {\n\t\t\t\t\t\t\t\tprocess();\n\t\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\t\t// Call an optional hook to record the stack, in case of exception\n\t\t\t\t\t\t\t\t// since it's otherwise lost when execution goes async\n\t\t\t\t\t\t\t\tif ( jQuery.Deferred.getStackHook ) {\n\t\t\t\t\t\t\t\t\tprocess.stackTrace = jQuery.Deferred.getStackHook();\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\twindow.setTimeout( process );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t};\n\t\t\t\t\t}\n\n\t\t\t\t\treturn jQuery.Deferred( function( newDefer ) {\n\n\t\t\t\t\t\t// progress_handlers.add( ... )\n\t\t\t\t\t\ttuples[ 0 ][ 3 ].add(\n\t\t\t\t\t\t\tresolve(\n\t\t\t\t\t\t\t\t0,\n\t\t\t\t\t\t\t\tnewDefer,\n\t\t\t\t\t\t\t\tisFunction( onProgress ) ?\n\t\t\t\t\t\t\t\t\tonProgress :\n\t\t\t\t\t\t\t\t\tIdentity,\n\t\t\t\t\t\t\t\tnewDefer.notifyWith\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t);\n\n\t\t\t\t\t\t// fulfilled_handlers.add( ... )\n\t\t\t\t\t\ttuples[ 1 ][ 3 ].add(\n\t\t\t\t\t\t\tresolve(\n\t\t\t\t\t\t\t\t0,\n\t\t\t\t\t\t\t\tnewDefer,\n\t\t\t\t\t\t\t\tisFunction( onFulfilled ) ?\n\t\t\t\t\t\t\t\t\tonFulfilled :\n\t\t\t\t\t\t\t\t\tIdentity\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t);\n\n\t\t\t\t\t\t// rejected_handlers.add( ... )\n\t\t\t\t\t\ttuples[ 2 ][ 3 ].add(\n\t\t\t\t\t\t\tresolve(\n\t\t\t\t\t\t\t\t0,\n\t\t\t\t\t\t\t\tnewDefer,\n\t\t\t\t\t\t\t\tisFunction( onRejected ) ?\n\t\t\t\t\t\t\t\t\tonRejected :\n\t\t\t\t\t\t\t\t\tThrower\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t);\n\t\t\t\t\t} ).promise();\n\t\t\t\t},\n\n\t\t\t\t// Get a promise for this deferred\n\t\t\t\t// If obj is provided, the promise aspect is added to the object\n\t\t\t\tpromise: function( obj ) {\n\t\t\t\t\treturn obj != null ? jQuery.extend( obj, promise ) : promise;\n\t\t\t\t}\n\t\t\t},\n\t\t\tdeferred = {};\n\n\t\t// Add list-specific methods\n\t\tjQuery.each( tuples, function( i, tuple ) {\n\t\t\tvar list = tuple[ 2 ],\n\t\t\t\tstateString = tuple[ 5 ];\n\n\t\t\t// promise.progress = list.add\n\t\t\t// promise.done = list.add\n\t\t\t// promise.fail = list.add\n\t\t\tpromise[ tuple[ 1 ] ] = list.add;\n\n\t\t\t// Handle state\n\t\t\tif ( stateString ) {\n\t\t\t\tlist.add(\n\t\t\t\t\tfunction() {\n\n\t\t\t\t\t\t// state = \"resolved\" (i.e., fulfilled)\n\t\t\t\t\t\t// state = \"rejected\"\n\t\t\t\t\t\tstate = stateString;\n\t\t\t\t\t},\n\n\t\t\t\t\t// rejected_callbacks.disable\n\t\t\t\t\t// fulfilled_callbacks.disable\n\t\t\t\t\ttuples[ 3 - i ][ 2 ].disable,\n\n\t\t\t\t\t// rejected_handlers.disable\n\t\t\t\t\t// fulfilled_handlers.disable\n\t\t\t\t\ttuples[ 3 - i ][ 3 ].disable,\n\n\t\t\t\t\t// progress_callbacks.lock\n\t\t\t\t\ttuples[ 0 ][ 2 ].lock,\n\n\t\t\t\t\t// progress_handlers.lock\n\t\t\t\t\ttuples[ 0 ][ 3 ].lock\n\t\t\t\t);\n\t\t\t}\n\n\t\t\t// progress_handlers.fire\n\t\t\t// fulfilled_handlers.fire\n\t\t\t// rejected_handlers.fire\n\t\t\tlist.add( tuple[ 3 ].fire );\n\n\t\t\t// deferred.notify = function() { deferred.notifyWith(...) }\n\t\t\t// deferred.resolve = function() { deferred.resolveWith(...) }\n\t\t\t// deferred.reject = function() { deferred.rejectWith(...) }\n\t\t\tdeferred[ tuple[ 0 ] ] = function() {\n\t\t\t\tdeferred[ tuple[ 0 ] + \"With\" ]( this === deferred ? undefined : this, arguments );\n\t\t\t\treturn this;\n\t\t\t};\n\n\t\t\t// deferred.notifyWith = list.fireWith\n\t\t\t// deferred.resolveWith = list.fireWith\n\t\t\t// deferred.rejectWith = list.fireWith\n\t\t\tdeferred[ tuple[ 0 ] + \"With\" ] = list.fireWith;\n\t\t} );\n\n\t\t// Make the deferred a promise\n\t\tpromise.promise( deferred );\n\n\t\t// Call given func if any\n\t\tif ( func ) {\n\t\t\tfunc.call( deferred, deferred );\n\t\t}\n\n\t\t// All done!\n\t\treturn deferred;\n\t},\n\n\t// Deferred helper\n\twhen: function( singleValue ) {\n\t\tvar\n\n\t\t\t// count of uncompleted subordinates\n\t\t\tremaining = arguments.length,\n\n\t\t\t// count of unprocessed arguments\n\t\t\ti = remaining,\n\n\t\t\t// subordinate fulfillment data\n\t\t\tresolveContexts = Array( i ),\n\t\t\tresolveValues = slice.call( arguments ),\n\n\t\t\t// the master Deferred\n\t\t\tmaster = jQuery.Deferred(),\n\n\t\t\t// subordinate callback factory\n\t\t\tupdateFunc = function( i ) {\n\t\t\t\treturn function( value ) {\n\t\t\t\t\tresolveContexts[ i ] = this;\n\t\t\t\t\tresolveValues[ i ] = arguments.length > 1 ? slice.call( arguments ) : value;\n\t\t\t\t\tif ( !( --remaining ) ) {\n\t\t\t\t\t\tmaster.resolveWith( resolveContexts, resolveValues );\n\t\t\t\t\t}\n\t\t\t\t};\n\t\t\t};\n\n\t\t// Single- and empty arguments are adopted like Promise.resolve\n\t\tif ( remaining <= 1 ) {\n\t\t\tadoptValue( singleValue, master.done( updateFunc( i ) ).resolve, master.reject,\n\t\t\t\t!remaining );\n\n\t\t\t// Use .then() to unwrap secondary thenables (cf. gh-3000)\n\t\t\tif ( master.state() === \"pending\" ||\n\t\t\t\tisFunction( resolveValues[ i ] && resolveValues[ i ].then ) ) {\n\n\t\t\t\treturn master.then();\n\t\t\t}\n\t\t}\n\n\t\t// Multiple arguments are aggregated like Promise.all array elements\n\t\twhile ( i-- ) {\n\t\t\tadoptValue( resolveValues[ i ], updateFunc( i ), master.reject );\n\t\t}\n\n\t\treturn master.promise();\n\t}\n} );\n\n\n// These usually indicate a programmer mistake during development,\n// warn about them ASAP rather than swallowing them by default.\nvar rerrorNames = /^(Eval|Internal|Range|Reference|Syntax|Type|URI)Error$/;\n\njQuery.Deferred.exceptionHook = function( error, stack ) {\n\n\t// Support: IE 8 - 9 only\n\t// Console exists when dev tools are open, which can happen at any time\n\tif ( window.console && window.console.warn && error && rerrorNames.test( error.name ) ) {\n\t\twindow.console.warn( \"jQuery.Deferred exception: \" + error.message, error.stack, stack );\n\t}\n};\n\n\n\n\njQuery.readyException = function( error ) {\n\twindow.setTimeout( function() {\n\t\tthrow error;\n\t} );\n};\n\n\n\n\n// The deferred used on DOM ready\nvar readyList = jQuery.Deferred();\n\njQuery.fn.ready = function( fn ) {\n\n\treadyList\n\t\t.then( fn )\n\n\t\t// Wrap jQuery.readyException in a function so that the lookup\n\t\t// happens at the time of error handling instead of callback\n\t\t// registration.\n\t\t.catch( function( error ) {\n\t\t\tjQuery.readyException( error );\n\t\t} );\n\n\treturn this;\n};\n\njQuery.extend( {\n\n\t// Is the DOM ready to be used? Set to true once it occurs.\n\tisReady: false,\n\n\t// A counter to track how many items to wait for before\n\t// the ready event fires. See #6781\n\treadyWait: 1,\n\n\t// Handle when the DOM is ready\n\tready: function( wait ) {\n\n\t\t// Abort if there are pending holds or we're already ready\n\t\tif ( wait === true ? --jQuery.readyWait : jQuery.isReady ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Remember that the DOM is ready\n\t\tjQuery.isReady = true;\n\n\t\t// If a normal DOM Ready event fired, decrement, and wait if need be\n\t\tif ( wait !== true && --jQuery.readyWait > 0 ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// If there are functions bound, to execute\n\t\treadyList.resolveWith( document, [ jQuery ] );\n\t}\n} );\n\njQuery.ready.then = readyList.then;\n\n// The ready event handler and self cleanup method\nfunction completed() {\n\tdocument.removeEventListener( \"DOMContentLoaded\", completed );\n\twindow.removeEventListener( \"load\", completed );\n\tjQuery.ready();\n}\n\n// Catch cases where $(document).ready() is called\n// after the browser event has already occurred.\n// Support: IE <=9 - 10 only\n// Older IE sometimes signals \"interactive\" too soon\nif ( document.readyState === \"complete\" ||\n\t( document.readyState !== \"loading\" && !document.documentElement.doScroll ) ) {\n\n\t// Handle it asynchronously to allow scripts the opportunity to delay ready\n\twindow.setTimeout( jQuery.ready );\n\n} else {\n\n\t// Use the handy event callback\n\tdocument.addEventListener( \"DOMContentLoaded\", completed );\n\n\t// A fallback to window.onload, that will always work\n\twindow.addEventListener( \"load\", completed );\n}\n\n\n\n\n// Multifunctional method to get and set values of a collection\n// The value/s can optionally be executed if it's a function\nvar access = function( elems, fn, key, value, chainable, emptyGet, raw ) {\n\tvar i = 0,\n\t\tlen = elems.length,\n\t\tbulk = key == null;\n\n\t// Sets many values\n\tif ( toType( key ) === \"object\" ) {\n\t\tchainable = true;\n\t\tfor ( i in key ) {\n\t\t\taccess( elems, fn, i, key[ i ], true, emptyGet, raw );\n\t\t}\n\n\t// Sets one value\n\t} else if ( value !== undefined ) {\n\t\tchainable = true;\n\n\t\tif ( !isFunction( value ) ) {\n\t\t\traw = true;\n\t\t}\n\n\t\tif ( bulk ) {\n\n\t\t\t// Bulk operations run against the entire set\n\t\t\tif ( raw ) {\n\t\t\t\tfn.call( elems, value );\n\t\t\t\tfn = null;\n\n\t\t\t// ...except when executing function values\n\t\t\t} else {\n\t\t\t\tbulk = fn;\n\t\t\t\tfn = function( elem, key, value ) {\n\t\t\t\t\treturn bulk.call( jQuery( elem ), value );\n\t\t\t\t};\n\t\t\t}\n\t\t}\n\n\t\tif ( fn ) {\n\t\t\tfor ( ; i < len; i++ ) {\n\t\t\t\tfn(\n\t\t\t\t\telems[ i ], key, raw ?\n\t\t\t\t\tvalue :\n\t\t\t\t\tvalue.call( elems[ i ], i, fn( elems[ i ], key ) )\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\t}\n\n\tif ( chainable ) {\n\t\treturn elems;\n\t}\n\n\t// Gets\n\tif ( bulk ) {\n\t\treturn fn.call( elems );\n\t}\n\n\treturn len ? fn( elems[ 0 ], key ) : emptyGet;\n};\n\n\n// Matches dashed string for camelizing\nvar rmsPrefix = /^-ms-/,\n\trdashAlpha = /-([a-z])/g;\n\n// Used by camelCase as callback to replace()\nfunction fcamelCase( all, letter ) {\n\treturn letter.toUpperCase();\n}\n\n// Convert dashed to camelCase; used by the css and data modules\n// Support: IE <=9 - 11, Edge 12 - 15\n// Microsoft forgot to hump their vendor prefix (#9572)\nfunction camelCase( string ) {\n\treturn string.replace( rmsPrefix, \"ms-\" ).replace( rdashAlpha, fcamelCase );\n}\nvar acceptData = function( owner ) {\n\n\t// Accepts only:\n\t//  - Node\n\t//    - Node.ELEMENT_NODE\n\t//    - Node.DOCUMENT_NODE\n\t//  - Object\n\t//    - Any\n\treturn owner.nodeType === 1 || owner.nodeType === 9 || !( +owner.nodeType );\n};\n\n\n\n\nfunction Data() {\n\tthis.expando = jQuery.expando + Data.uid++;\n}\n\nData.uid = 1;\n\nData.prototype = {\n\n\tcache: function( owner ) {\n\n\t\t// Check if the owner object already has a cache\n\t\tvar value = owner[ this.expando ];\n\n\t\t// If not, create one\n\t\tif ( !value ) {\n\t\t\tvalue = {};\n\n\t\t\t// We can accept data for non-element nodes in modern browsers,\n\t\t\t// but we should not, see #8335.\n\t\t\t// Always return an empty object.\n\t\t\tif ( acceptData( owner ) ) {\n\n\t\t\t\t// If it is a node unlikely to be stringify-ed or looped over\n\t\t\t\t// use plain assignment\n\t\t\t\tif ( owner.nodeType ) {\n\t\t\t\t\towner[ this.expando ] = value;\n\n\t\t\t\t// Otherwise secure it in a non-enumerable property\n\t\t\t\t// configurable must be true to allow the property to be\n\t\t\t\t// deleted when data is removed\n\t\t\t\t} else {\n\t\t\t\t\tObject.defineProperty( owner, this.expando, {\n\t\t\t\t\t\tvalue: value,\n\t\t\t\t\t\tconfigurable: true\n\t\t\t\t\t} );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn value;\n\t},\n\tset: function( owner, data, value ) {\n\t\tvar prop,\n\t\t\tcache = this.cache( owner );\n\n\t\t// Handle: [ owner, key, value ] args\n\t\t// Always use camelCase key (gh-2257)\n\t\tif ( typeof data === \"string\" ) {\n\t\t\tcache[ camelCase( data ) ] = value;\n\n\t\t// Handle: [ owner, { properties } ] args\n\t\t} else {\n\n\t\t\t// Copy the properties one-by-one to the cache object\n\t\t\tfor ( prop in data ) {\n\t\t\t\tcache[ camelCase( prop ) ] = data[ prop ];\n\t\t\t}\n\t\t}\n\t\treturn cache;\n\t},\n\tget: function( owner, key ) {\n\t\treturn key === undefined ?\n\t\t\tthis.cache( owner ) :\n\n\t\t\t// Always use camelCase key (gh-2257)\n\t\t\towner[ this.expando ] && owner[ this.expando ][ camelCase( key ) ];\n\t},\n\taccess: function( owner, key, value ) {\n\n\t\t// In cases where either:\n\t\t//\n\t\t//   1. No key was specified\n\t\t//   2. A string key was specified, but no value provided\n\t\t//\n\t\t// Take the \"read\" path and allow the get method to determine\n\t\t// which value to return, respectively either:\n\t\t//\n\t\t//   1. The entire cache object\n\t\t//   2. The data stored at the key\n\t\t//\n\t\tif ( key === undefined ||\n\t\t\t\t( ( key && typeof key === \"string\" ) && value === undefined ) ) {\n\n\t\t\treturn this.get( owner, key );\n\t\t}\n\n\t\t// When the key is not a string, or both a key and value\n\t\t// are specified, set or extend (existing objects) with either:\n\t\t//\n\t\t//   1. An object of properties\n\t\t//   2. A key and value\n\t\t//\n\t\tthis.set( owner, key, value );\n\n\t\t// Since the \"set\" path can have two possible entry points\n\t\t// return the expected data based on which path was taken[*]\n\t\treturn value !== undefined ? value : key;\n\t},\n\tremove: function( owner, key ) {\n\t\tvar i,\n\t\t\tcache = owner[ this.expando ];\n\n\t\tif ( cache === undefined ) {\n\t\t\treturn;\n\t\t}\n\n\t\tif ( key !== undefined ) {\n\n\t\t\t// Support array or space separated string of keys\n\t\t\tif ( Array.isArray( key ) ) {\n\n\t\t\t\t// If key is an array of keys...\n\t\t\t\t// We always set camelCase keys, so remove that.\n\t\t\t\tkey = key.map( camelCase );\n\t\t\t} else {\n\t\t\t\tkey = camelCase( key );\n\n\t\t\t\t// If a key with the spaces exists, use it.\n\t\t\t\t// Otherwise, create an array by matching non-whitespace\n\t\t\t\tkey = key in cache ?\n\t\t\t\t\t[ key ] :\n\t\t\t\t\t( key.match( rnothtmlwhite ) || [] );\n\t\t\t}\n\n\t\t\ti = key.length;\n\n\t\t\twhile ( i-- ) {\n\t\t\t\tdelete cache[ key[ i ] ];\n\t\t\t}\n\t\t}\n\n\t\t// Remove the expando if there's no more data\n\t\tif ( key === undefined || jQuery.isEmptyObject( cache ) ) {\n\n\t\t\t// Support: Chrome <=35 - 45\n\t\t\t// Webkit & Blink performance suffers when deleting properties\n\t\t\t// from DOM nodes, so set to undefined instead\n\t\t\t// https://bugs.chromium.org/p/chromium/issues/detail?id=378607 (bug restricted)\n\t\t\tif ( owner.nodeType ) {\n\t\t\t\towner[ this.expando ] = undefined;\n\t\t\t} else {\n\t\t\t\tdelete owner[ this.expando ];\n\t\t\t}\n\t\t}\n\t},\n\thasData: function( owner ) {\n\t\tvar cache = owner[ this.expando ];\n\t\treturn cache !== undefined && !jQuery.isEmptyObject( cache );\n\t}\n};\nvar dataPriv = new Data();\n\nvar dataUser = new Data();\n\n\n\n//\tImplementation Summary\n//\n//\t1. Enforce API surface and semantic compatibility with 1.9.x branch\n//\t2. Improve the module's maintainability by reducing the storage\n//\t\tpaths to a single mechanism.\n//\t3. Use the same single mechanism to support \"private\" and \"user\" data.\n//\t4. _Never_ expose \"private\" data to user code (TODO: Drop _data, _removeData)\n//\t5. Avoid exposing implementation details on user objects (eg. expando properties)\n//\t6. Provide a clear path for implementation upgrade to WeakMap in 2014\n\nvar rbrace = /^(?:\\{[\\w\\W]*\\}|\\[[\\w\\W]*\\])$/,\n\trmultiDash = /[A-Z]/g;\n\nfunction getData( data ) {\n\tif ( data === \"true\" ) {\n\t\treturn true;\n\t}\n\n\tif ( data === \"false\" ) {\n\t\treturn false;\n\t}\n\n\tif ( data === \"null\" ) {\n\t\treturn null;\n\t}\n\n\t// Only convert to a number if it doesn't change the string\n\tif ( data === +data + \"\" ) {\n\t\treturn +data;\n\t}\n\n\tif ( rbrace.test( data ) ) {\n\t\treturn JSON.parse( data );\n\t}\n\n\treturn data;\n}\n\nfunction dataAttr( elem, key, data ) {\n\tvar name;\n\n\t// If nothing was found internally, try to fetch any\n\t// data from the HTML5 data-* attribute\n\tif ( data === undefined && elem.nodeType === 1 ) {\n\t\tname = \"data-\" + key.replace( rmultiDash, \"-$&\" ).toLowerCase();\n\t\tdata = elem.getAttribute( name );\n\n\t\tif ( typeof data === \"string\" ) {\n\t\t\ttry {\n\t\t\t\tdata = getData( data );\n\t\t\t} catch ( e ) {}\n\n\t\t\t// Make sure we set the data so it isn't changed later\n\t\t\tdataUser.set( elem, key, data );\n\t\t} else {\n\t\t\tdata = undefined;\n\t\t}\n\t}\n\treturn data;\n}\n\njQuery.extend( {\n\thasData: function( elem ) {\n\t\treturn dataUser.hasData( elem ) || dataPriv.hasData( elem );\n\t},\n\n\tdata: function( elem, name, data ) {\n\t\treturn dataUser.access( elem, name, data );\n\t},\n\n\tremoveData: function( elem, name ) {\n\t\tdataUser.remove( elem, name );\n\t},\n\n\t// TODO: Now that all calls to _data and _removeData have been replaced\n\t// with direct calls to dataPriv methods, these can be deprecated.\n\t_data: function( elem, name, data ) {\n\t\treturn dataPriv.access( elem, name, data );\n\t},\n\n\t_removeData: function( elem, name ) {\n\t\tdataPriv.remove( elem, name );\n\t}\n} );\n\njQuery.fn.extend( {\n\tdata: function( key, value ) {\n\t\tvar i, name, data,\n\t\t\telem = this[ 0 ],\n\t\t\tattrs = elem && elem.attributes;\n\n\t\t// Gets all values\n\t\tif ( key === undefined ) {\n\t\t\tif ( this.length ) {\n\t\t\t\tdata = dataUser.get( elem );\n\n\t\t\t\tif ( elem.nodeType === 1 && !dataPriv.get( elem, \"hasDataAttrs\" ) ) {\n\t\t\t\t\ti = attrs.length;\n\t\t\t\t\twhile ( i-- ) {\n\n\t\t\t\t\t\t// Support: IE 11 only\n\t\t\t\t\t\t// The attrs elements can be null (#14894)\n\t\t\t\t\t\tif ( attrs[ i ] ) {\n\t\t\t\t\t\t\tname = attrs[ i ].name;\n\t\t\t\t\t\t\tif ( name.indexOf( \"data-\" ) === 0 ) {\n\t\t\t\t\t\t\t\tname = camelCase( name.slice( 5 ) );\n\t\t\t\t\t\t\t\tdataAttr( elem, name, data[ name ] );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tdataPriv.set( elem, \"hasDataAttrs\", true );\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn data;\n\t\t}\n\n\t\t// Sets multiple values\n\t\tif ( typeof key === \"object\" ) {\n\t\t\treturn this.each( function() {\n\t\t\t\tdataUser.set( this, key );\n\t\t\t} );\n\t\t}\n\n\t\treturn access( this, function( value ) {\n\t\t\tvar data;\n\n\t\t\t// The calling jQuery object (element matches) is not empty\n\t\t\t// (and therefore has an element appears at this[ 0 ]) and the\n\t\t\t// `value` parameter was not undefined. An empty jQuery object\n\t\t\t// will result in `undefined` for elem = this[ 0 ] which will\n\t\t\t// throw an exception if an attempt to read a data cache is made.\n\t\t\tif ( elem && value === undefined ) {\n\n\t\t\t\t// Attempt to get data from the cache\n\t\t\t\t// The key will always be camelCased in Data\n\t\t\t\tdata = dataUser.get( elem, key );\n\t\t\t\tif ( data !== undefined ) {\n\t\t\t\t\treturn data;\n\t\t\t\t}\n\n\t\t\t\t// Attempt to \"discover\" the data in\n\t\t\t\t// HTML5 custom data-* attrs\n\t\t\t\tdata = dataAttr( elem, key );\n\t\t\t\tif ( data !== undefined ) {\n\t\t\t\t\treturn data;\n\t\t\t\t}\n\n\t\t\t\t// We tried really hard, but the data doesn't exist.\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// Set the data...\n\t\t\tthis.each( function() {\n\n\t\t\t\t// We always store the camelCased key\n\t\t\t\tdataUser.set( this, key, value );\n\t\t\t} );\n\t\t}, null, value, arguments.length > 1, null, true );\n\t},\n\n\tremoveData: function( key ) {\n\t\treturn this.each( function() {\n\t\t\tdataUser.remove( this, key );\n\t\t} );\n\t}\n} );\n\n\njQuery.extend( {\n\tqueue: function( elem, type, data ) {\n\t\tvar queue;\n\n\t\tif ( elem ) {\n\t\t\ttype = ( type || \"fx\" ) + \"queue\";\n\t\t\tqueue = dataPriv.get( elem, type );\n\n\t\t\t// Speed up dequeue by getting out quickly if this is just a lookup\n\t\t\tif ( data ) {\n\t\t\t\tif ( !queue || Array.isArray( data ) ) {\n\t\t\t\t\tqueue = dataPriv.access( elem, type, jQuery.makeArray( data ) );\n\t\t\t\t} else {\n\t\t\t\t\tqueue.push( data );\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn queue || [];\n\t\t}\n\t},\n\n\tdequeue: function( elem, type ) {\n\t\ttype = type || \"fx\";\n\n\t\tvar queue = jQuery.queue( elem, type ),\n\t\t\tstartLength = queue.length,\n\t\t\tfn = queue.shift(),\n\t\t\thooks = jQuery._queueHooks( elem, type ),\n\t\t\tnext = function() {\n\t\t\t\tjQuery.dequeue( elem, type );\n\t\t\t};\n\n\t\t// If the fx queue is dequeued, always remove the progress sentinel\n\t\tif ( fn === \"inprogress\" ) {\n\t\t\tfn = queue.shift();\n\t\t\tstartLength--;\n\t\t}\n\n\t\tif ( fn ) {\n\n\t\t\t// Add a progress sentinel to prevent the fx queue from being\n\t\t\t// automatically dequeued\n\t\t\tif ( type === \"fx\" ) {\n\t\t\t\tqueue.unshift( \"inprogress\" );\n\t\t\t}\n\n\t\t\t// Clear up the last queue stop function\n\t\t\tdelete hooks.stop;\n\t\t\tfn.call( elem, next, hooks );\n\t\t}\n\n\t\tif ( !startLength && hooks ) {\n\t\t\thooks.empty.fire();\n\t\t}\n\t},\n\n\t// Not public - generate a queueHooks object, or return the current one\n\t_queueHooks: function( elem, type ) {\n\t\tvar key = type + \"queueHooks\";\n\t\treturn dataPriv.get( elem, key ) || dataPriv.access( elem, key, {\n\t\t\tempty: jQuery.Callbacks( \"once memory\" ).add( function() {\n\t\t\t\tdataPriv.remove( elem, [ type + \"queue\", key ] );\n\t\t\t} )\n\t\t} );\n\t}\n} );\n\njQuery.fn.extend( {\n\tqueue: function( type, data ) {\n\t\tvar setter = 2;\n\n\t\tif ( typeof type !== \"string\" ) {\n\t\t\tdata = type;\n\t\t\ttype = \"fx\";\n\t\t\tsetter--;\n\t\t}\n\n\t\tif ( arguments.length < setter ) {\n\t\t\treturn jQuery.queue( this[ 0 ], type );\n\t\t}\n\n\t\treturn data === undefined ?\n\t\t\tthis :\n\t\t\tthis.each( function() {\n\t\t\t\tvar queue = jQuery.queue( this, type, data );\n\n\t\t\t\t// Ensure a hooks for this queue\n\t\t\t\tjQuery._queueHooks( this, type );\n\n\t\t\t\tif ( type === \"fx\" && queue[ 0 ] !== \"inprogress\" ) {\n\t\t\t\t\tjQuery.dequeue( this, type );\n\t\t\t\t}\n\t\t\t} );\n\t},\n\tdequeue: function( type ) {\n\t\treturn this.each( function() {\n\t\t\tjQuery.dequeue( this, type );\n\t\t} );\n\t},\n\tclearQueue: function( type ) {\n\t\treturn this.queue( type || \"fx\", [] );\n\t},\n\n\t// Get a promise resolved when queues of a certain type\n\t// are emptied (fx is the type by default)\n\tpromise: function( type, obj ) {\n\t\tvar tmp,\n\t\t\tcount = 1,\n\t\t\tdefer = jQuery.Deferred(),\n\t\t\telements = this,\n\t\t\ti = this.length,\n\t\t\tresolve = function() {\n\t\t\t\tif ( !( --count ) ) {\n\t\t\t\t\tdefer.resolveWith( elements, [ elements ] );\n\t\t\t\t}\n\t\t\t};\n\n\t\tif ( typeof type !== \"string\" ) {\n\t\t\tobj = type;\n\t\t\ttype = undefined;\n\t\t}\n\t\ttype = type || \"fx\";\n\n\t\twhile ( i-- ) {\n\t\t\ttmp = dataPriv.get( elements[ i ], type + \"queueHooks\" );\n\t\t\tif ( tmp && tmp.empty ) {\n\t\t\t\tcount++;\n\t\t\t\ttmp.empty.add( resolve );\n\t\t\t}\n\t\t}\n\t\tresolve();\n\t\treturn defer.promise( obj );\n\t}\n} );\nvar pnum = ( /[+-]?(?:\\d*\\.|)\\d+(?:[eE][+-]?\\d+|)/ ).source;\n\nvar rcssNum = new RegExp( \"^(?:([+-])=|)(\" + pnum + \")([a-z%]*)$\", \"i\" );\n\n\nvar cssExpand = [ \"Top\", \"Right\", \"Bottom\", \"Left\" ];\n\nvar isHiddenWithinTree = function( elem, el ) {\n\n\t\t// isHiddenWithinTree might be called from jQuery#filter function;\n\t\t// in that case, element will be second argument\n\t\telem = el || elem;\n\n\t\t// Inline style trumps all\n\t\treturn elem.style.display === \"none\" ||\n\t\t\telem.style.display === \"\" &&\n\n\t\t\t// Otherwise, check computed style\n\t\t\t// Support: Firefox <=43 - 45\n\t\t\t// Disconnected elements can have computed display: none, so first confirm that elem is\n\t\t\t// in the document.\n\t\t\tjQuery.contains( elem.ownerDocument, elem ) &&\n\n\t\t\tjQuery.css( elem, \"display\" ) === \"none\";\n\t};\n\nvar swap = function( elem, options, callback, args ) {\n\tvar ret, name,\n\t\told = {};\n\n\t// Remember the old values, and insert the new ones\n\tfor ( name in options ) {\n\t\told[ name ] = elem.style[ name ];\n\t\telem.style[ name ] = options[ name ];\n\t}\n\n\tret = callback.apply( elem, args || [] );\n\n\t// Revert the old values\n\tfor ( name in options ) {\n\t\telem.style[ name ] = old[ name ];\n\t}\n\n\treturn ret;\n};\n\n\n\n\nfunction adjustCSS( elem, prop, valueParts, tween ) {\n\tvar adjusted, scale,\n\t\tmaxIterations = 20,\n\t\tcurrentValue = tween ?\n\t\t\tfunction() {\n\t\t\t\treturn tween.cur();\n\t\t\t} :\n\t\t\tfunction() {\n\t\t\t\treturn jQuery.css( elem, prop, \"\" );\n\t\t\t},\n\t\tinitial = currentValue(),\n\t\tunit = valueParts && valueParts[ 3 ] || ( jQuery.cssNumber[ prop ] ? \"\" : \"px\" ),\n\n\t\t// Starting value computation is required for potential unit mismatches\n\t\tinitialInUnit = ( jQuery.cssNumber[ prop ] || unit !== \"px\" && +initial ) &&\n\t\t\trcssNum.exec( jQuery.css( elem, prop ) );\n\n\tif ( initialInUnit && initialInUnit[ 3 ] !== unit ) {\n\n\t\t// Support: Firefox <=54\n\t\t// Halve the iteration target value to prevent interference from CSS upper bounds (gh-2144)\n\t\tinitial = initial / 2;\n\n\t\t// Trust units reported by jQuery.css\n\t\tunit = unit || initialInUnit[ 3 ];\n\n\t\t// Iteratively approximate from a nonzero starting point\n\t\tinitialInUnit = +initial || 1;\n\n\t\twhile ( maxIterations-- ) {\n\n\t\t\t// Evaluate and update our best guess (doubling guesses that zero out).\n\t\t\t// Finish if the scale equals or crosses 1 (making the old*new product non-positive).\n\t\t\tjQuery.style( elem, prop, initialInUnit + unit );\n\t\t\tif ( ( 1 - scale ) * ( 1 - ( scale = currentValue() / initial || 0.5 ) ) <= 0 ) {\n\t\t\t\tmaxIterations = 0;\n\t\t\t}\n\t\t\tinitialInUnit = initialInUnit / scale;\n\n\t\t}\n\n\t\tinitialInUnit = initialInUnit * 2;\n\t\tjQuery.style( elem, prop, initialInUnit + unit );\n\n\t\t// Make sure we update the tween properties later on\n\t\tvalueParts = valueParts || [];\n\t}\n\n\tif ( valueParts ) {\n\t\tinitialInUnit = +initialInUnit || +initial || 0;\n\n\t\t// Apply relative offset (+=/-=) if specified\n\t\tadjusted = valueParts[ 1 ] ?\n\t\t\tinitialInUnit + ( valueParts[ 1 ] + 1 ) * valueParts[ 2 ] :\n\t\t\t+valueParts[ 2 ];\n\t\tif ( tween ) {\n\t\t\ttween.unit = unit;\n\t\t\ttween.start = initialInUnit;\n\t\t\ttween.end = adjusted;\n\t\t}\n\t}\n\treturn adjusted;\n}\n\n\nvar defaultDisplayMap = {};\n\nfunction getDefaultDisplay( elem ) {\n\tvar temp,\n\t\tdoc = elem.ownerDocument,\n\t\tnodeName = elem.nodeName,\n\t\tdisplay = defaultDisplayMap[ nodeName ];\n\n\tif ( display ) {\n\t\treturn display;\n\t}\n\n\ttemp = doc.body.appendChild( doc.createElement( nodeName ) );\n\tdisplay = jQuery.css( temp, \"display\" );\n\n\ttemp.parentNode.removeChild( temp );\n\n\tif ( display === \"none\" ) {\n\t\tdisplay = \"block\";\n\t}\n\tdefaultDisplayMap[ nodeName ] = display;\n\n\treturn display;\n}\n\nfunction showHide( elements, show ) {\n\tvar display, elem,\n\t\tvalues = [],\n\t\tindex = 0,\n\t\tlength = elements.length;\n\n\t// Determine new display value for elements that need to change\n\tfor ( ; index < length; index++ ) {\n\t\telem = elements[ index ];\n\t\tif ( !elem.style ) {\n\t\t\tcontinue;\n\t\t}\n\n\t\tdisplay = elem.style.display;\n\t\tif ( show ) {\n\n\t\t\t// Since we force visibility upon cascade-hidden elements, an immediate (and slow)\n\t\t\t// check is required in this first loop unless we have a nonempty display value (either\n\t\t\t// inline or about-to-be-restored)\n\t\t\tif ( display === \"none\" ) {\n\t\t\t\tvalues[ index ] = dataPriv.get( elem, \"display\" ) || null;\n\t\t\t\tif ( !values[ index ] ) {\n\t\t\t\t\telem.style.display = \"\";\n\t\t\t\t}\n\t\t\t}\n\t\t\tif ( elem.style.display === \"\" && isHiddenWithinTree( elem ) ) {\n\t\t\t\tvalues[ index ] = getDefaultDisplay( elem );\n\t\t\t}\n\t\t} else {\n\t\t\tif ( display !== \"none\" ) {\n\t\t\t\tvalues[ index ] = \"none\";\n\n\t\t\t\t// Remember what we're overwriting\n\t\t\t\tdataPriv.set( elem, \"display\", display );\n\t\t\t}\n\t\t}\n\t}\n\n\t// Set the display of the elements in a second loop to avoid constant reflow\n\tfor ( index = 0; index < length; index++ ) {\n\t\tif ( values[ index ] != null ) {\n\t\t\telements[ index ].style.display = values[ index ];\n\t\t}\n\t}\n\n\treturn elements;\n}\n\njQuery.fn.extend( {\n\tshow: function() {\n\t\treturn showHide( this, true );\n\t},\n\thide: function() {\n\t\treturn showHide( this );\n\t},\n\ttoggle: function( state ) {\n\t\tif ( typeof state === \"boolean\" ) {\n\t\t\treturn state ? this.show() : this.hide();\n\t\t}\n\n\t\treturn this.each( function() {\n\t\t\tif ( isHiddenWithinTree( this ) ) {\n\t\t\t\tjQuery( this ).show();\n\t\t\t} else {\n\t\t\t\tjQuery( this ).hide();\n\t\t\t}\n\t\t} );\n\t}\n} );\nvar rcheckableType = ( /^(?:checkbox|radio)$/i );\n\nvar rtagName = ( /<([a-z][^\\/\\0>\\x20\\t\\r\\n\\f]+)/i );\n\nvar rscriptType = ( /^$|^module$|\\/(?:java|ecma)script/i );\n\n\n\n// We have to close these tags to support XHTML (#13200)\nvar wrapMap = {\n\n\t// Support: IE <=9 only\n\toption: [ 1, \"<select multiple='multiple'>\", \"</select>\" ],\n\n\t// XHTML parsers do not magically insert elements in the\n\t// same way that tag soup parsers do. So we cannot shorten\n\t// this by omitting <tbody> or other required elements.\n\tthead: [ 1, \"<table>\", \"</table>\" ],\n\tcol: [ 2, \"<table><colgroup>\", \"</colgroup></table>\" ],\n\ttr: [ 2, \"<table><tbody>\", \"</tbody></table>\" ],\n\ttd: [ 3, \"<table><tbody><tr>\", \"</tr></tbody></table>\" ],\n\n\t_default: [ 0, \"\", \"\" ]\n};\n\n// Support: IE <=9 only\nwrapMap.optgroup = wrapMap.option;\n\nwrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead;\nwrapMap.th = wrapMap.td;\n\n\nfunction getAll( context, tag ) {\n\n\t// Support: IE <=9 - 11 only\n\t// Use typeof to avoid zero-argument method invocation on host objects (#15151)\n\tvar ret;\n\n\tif ( typeof context.getElementsByTagName !== \"undefined\" ) {\n\t\tret = context.getElementsByTagName( tag || \"*\" );\n\n\t} else if ( typeof context.querySelectorAll !== \"undefined\" ) {\n\t\tret = context.querySelectorAll( tag || \"*\" );\n\n\t} else {\n\t\tret = [];\n\t}\n\n\tif ( tag === undefined || tag && nodeName( context, tag ) ) {\n\t\treturn jQuery.merge( [ context ], ret );\n\t}\n\n\treturn ret;\n}\n\n\n// Mark scripts as having already been evaluated\nfunction setGlobalEval( elems, refElements ) {\n\tvar i = 0,\n\t\tl = elems.length;\n\n\tfor ( ; i < l; i++ ) {\n\t\tdataPriv.set(\n\t\t\telems[ i ],\n\t\t\t\"globalEval\",\n\t\t\t!refElements || dataPriv.get( refElements[ i ], \"globalEval\" )\n\t\t);\n\t}\n}\n\n\nvar rhtml = /<|&#?\\w+;/;\n\nfunction buildFragment( elems, context, scripts, selection, ignored ) {\n\tvar elem, tmp, tag, wrap, contains, j,\n\t\tfragment = context.createDocumentFragment(),\n\t\tnodes = [],\n\t\ti = 0,\n\t\tl = elems.length;\n\n\tfor ( ; i < l; i++ ) {\n\t\telem = elems[ i ];\n\n\t\tif ( elem || elem === 0 ) {\n\n\t\t\t// Add nodes directly\n\t\t\tif ( toType( elem ) === \"object\" ) {\n\n\t\t\t\t// Support: Android <=4.0 only, PhantomJS 1 only\n\t\t\t\t// push.apply(_, arraylike) throws on ancient WebKit\n\t\t\t\tjQuery.merge( nodes, elem.nodeType ? [ elem ] : elem );\n\n\t\t\t// Convert non-html into a text node\n\t\t\t} else if ( !rhtml.test( elem ) ) {\n\t\t\t\tnodes.push( context.createTextNode( elem ) );\n\n\t\t\t// Convert html into DOM nodes\n\t\t\t} else {\n\t\t\t\ttmp = tmp || fragment.appendChild( context.createElement( \"div\" ) );\n\n\t\t\t\t// Deserialize a standard representation\n\t\t\t\ttag = ( rtagName.exec( elem ) || [ \"\", \"\" ] )[ 1 ].toLowerCase();\n\t\t\t\twrap = wrapMap[ tag ] || wrapMap._default;\n\t\t\t\ttmp.innerHTML = wrap[ 1 ] + jQuery.htmlPrefilter( elem ) + wrap[ 2 ];\n\n\t\t\t\t// Descend through wrappers to the right content\n\t\t\t\tj = wrap[ 0 ];\n\t\t\t\twhile ( j-- ) {\n\t\t\t\t\ttmp = tmp.lastChild;\n\t\t\t\t}\n\n\t\t\t\t// Support: Android <=4.0 only, PhantomJS 1 only\n\t\t\t\t// push.apply(_, arraylike) throws on ancient WebKit\n\t\t\t\tjQuery.merge( nodes, tmp.childNodes );\n\n\t\t\t\t// Remember the top-level container\n\t\t\t\ttmp = fragment.firstChild;\n\n\t\t\t\t// Ensure the created nodes are orphaned (#12392)\n\t\t\t\ttmp.textContent = \"\";\n\t\t\t}\n\t\t}\n\t}\n\n\t// Remove wrapper from fragment\n\tfragment.textContent = \"\";\n\n\ti = 0;\n\twhile ( ( elem = nodes[ i++ ] ) ) {\n\n\t\t// Skip elements already in the context collection (trac-4087)\n\t\tif ( selection && jQuery.inArray( elem, selection ) > -1 ) {\n\t\t\tif ( ignored ) {\n\t\t\t\tignored.push( elem );\n\t\t\t}\n\t\t\tcontinue;\n\t\t}\n\n\t\tcontains = jQuery.contains( elem.ownerDocument, elem );\n\n\t\t// Append to fragment\n\t\ttmp = getAll( fragment.appendChild( elem ), \"script\" );\n\n\t\t// Preserve script evaluation history\n\t\tif ( contains ) {\n\t\t\tsetGlobalEval( tmp );\n\t\t}\n\n\t\t// Capture executables\n\t\tif ( scripts ) {\n\t\t\tj = 0;\n\t\t\twhile ( ( elem = tmp[ j++ ] ) ) {\n\t\t\t\tif ( rscriptType.test( elem.type || \"\" ) ) {\n\t\t\t\t\tscripts.push( elem );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\treturn fragment;\n}\n\n\n( function() {\n\tvar fragment = document.createDocumentFragment(),\n\t\tdiv = fragment.appendChild( document.createElement( \"div\" ) ),\n\t\tinput = document.createElement( \"input\" );\n\n\t// Support: Android 4.0 - 4.3 only\n\t// Check state lost if the name is set (#11217)\n\t// Support: Windows Web Apps (WWA)\n\t// `name` and `type` must use .setAttribute for WWA (#14901)\n\tinput.setAttribute( \"type\", \"radio\" );\n\tinput.setAttribute( \"checked\", \"checked\" );\n\tinput.setAttribute( \"name\", \"t\" );\n\n\tdiv.appendChild( input );\n\n\t// Support: Android <=4.1 only\n\t// Older WebKit doesn't clone checked state correctly in fragments\n\tsupport.checkClone = div.cloneNode( true ).cloneNode( true ).lastChild.checked;\n\n\t// Support: IE <=11 only\n\t// Make sure textarea (and checkbox) defaultValue is properly cloned\n\tdiv.innerHTML = \"<textarea>x</textarea>\";\n\tsupport.noCloneChecked = !!div.cloneNode( true ).lastChild.defaultValue;\n} )();\nvar documentElement = document.documentElement;\n\n\n\nvar\n\trkeyEvent = /^key/,\n\trmouseEvent = /^(?:mouse|pointer|contextmenu|drag|drop)|click/,\n\trtypenamespace = /^([^.]*)(?:\\.(.+)|)/;\n\nfunction returnTrue() {\n\treturn true;\n}\n\nfunction returnFalse() {\n\treturn false;\n}\n\n// Support: IE <=9 only\n// See #13393 for more info\nfunction safeActiveElement() {\n\ttry {\n\t\treturn document.activeElement;\n\t} catch ( err ) { }\n}\n\nfunction on( elem, types, selector, data, fn, one ) {\n\tvar origFn, type;\n\n\t// Types can be a map of types/handlers\n\tif ( typeof types === \"object\" ) {\n\n\t\t// ( types-Object, selector, data )\n\t\tif ( typeof selector !== \"string\" ) {\n\n\t\t\t// ( types-Object, data )\n\t\t\tdata = data || selector;\n\t\t\tselector = undefined;\n\t\t}\n\t\tfor ( type in types ) {\n\t\t\ton( elem, type, selector, data, types[ type ], one );\n\t\t}\n\t\treturn elem;\n\t}\n\n\tif ( data == null && fn == null ) {\n\n\t\t// ( types, fn )\n\t\tfn = selector;\n\t\tdata = selector = undefined;\n\t} else if ( fn == null ) {\n\t\tif ( typeof selector === \"string\" ) {\n\n\t\t\t// ( types, selector, fn )\n\t\t\tfn = data;\n\t\t\tdata = undefined;\n\t\t} else {\n\n\t\t\t// ( types, data, fn )\n\t\t\tfn = data;\n\t\t\tdata = selector;\n\t\t\tselector = undefined;\n\t\t}\n\t}\n\tif ( fn === false ) {\n\t\tfn = returnFalse;\n\t} else if ( !fn ) {\n\t\treturn elem;\n\t}\n\n\tif ( one === 1 ) {\n\t\torigFn = fn;\n\t\tfn = function( event ) {\n\n\t\t\t// Can use an empty set, since event contains the info\n\t\t\tjQuery().off( event );\n\t\t\treturn origFn.apply( this, arguments );\n\t\t};\n\n\t\t// Use same guid so caller can remove using origFn\n\t\tfn.guid = origFn.guid || ( origFn.guid = jQuery.guid++ );\n\t}\n\treturn elem.each( function() {\n\t\tjQuery.event.add( this, types, fn, data, selector );\n\t} );\n}\n\n/*\n * Helper functions for managing events -- not part of the public interface.\n * Props to Dean Edwards' addEvent library for many of the ideas.\n */\njQuery.event = {\n\n\tglobal: {},\n\n\tadd: function( elem, types, handler, data, selector ) {\n\n\t\tvar handleObjIn, eventHandle, tmp,\n\t\t\tevents, t, handleObj,\n\t\t\tspecial, handlers, type, namespaces, origType,\n\t\t\telemData = dataPriv.get( elem );\n\n\t\t// Don't attach events to noData or text/comment nodes (but allow plain objects)\n\t\tif ( !elemData ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Caller can pass in an object of custom data in lieu of the handler\n\t\tif ( handler.handler ) {\n\t\t\thandleObjIn = handler;\n\t\t\thandler = handleObjIn.handler;\n\t\t\tselector = handleObjIn.selector;\n\t\t}\n\n\t\t// Ensure that invalid selectors throw exceptions at attach time\n\t\t// Evaluate against documentElement in case elem is a non-element node (e.g., document)\n\t\tif ( selector ) {\n\t\t\tjQuery.find.matchesSelector( documentElement, selector );\n\t\t}\n\n\t\t// Make sure that the handler has a unique ID, used to find/remove it later\n\t\tif ( !handler.guid ) {\n\t\t\thandler.guid = jQuery.guid++;\n\t\t}\n\n\t\t// Init the element's event structure and main handler, if this is the first\n\t\tif ( !( events = elemData.events ) ) {\n\t\t\tevents = elemData.events = {};\n\t\t}\n\t\tif ( !( eventHandle = elemData.handle ) ) {\n\t\t\teventHandle = elemData.handle = function( e ) {\n\n\t\t\t\t// Discard the second event of a jQuery.event.trigger() and\n\t\t\t\t// when an event is called after a page has unloaded\n\t\t\t\treturn typeof jQuery !== \"undefined\" && jQuery.event.triggered !== e.type ?\n\t\t\t\t\tjQuery.event.dispatch.apply( elem, arguments ) : undefined;\n\t\t\t};\n\t\t}\n\n\t\t// Handle multiple events separated by a space\n\t\ttypes = ( types || \"\" ).match( rnothtmlwhite ) || [ \"\" ];\n\t\tt = types.length;\n\t\twhile ( t-- ) {\n\t\t\ttmp = rtypenamespace.exec( types[ t ] ) || [];\n\t\t\ttype = origType = tmp[ 1 ];\n\t\t\tnamespaces = ( tmp[ 2 ] || \"\" ).split( \".\" ).sort();\n\n\t\t\t// There *must* be a type, no attaching namespace-only handlers\n\t\t\tif ( !type ) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\t// If event changes its type, use the special event handlers for the changed type\n\t\t\tspecial = jQuery.event.special[ type ] || {};\n\n\t\t\t// If selector defined, determine special event api type, otherwise given type\n\t\t\ttype = ( selector ? special.delegateType : special.bindType ) || type;\n\n\t\t\t// Update special based on newly reset type\n\t\t\tspecial = jQuery.event.special[ type ] || {};\n\n\t\t\t// handleObj is passed to all event handlers\n\t\t\thandleObj = jQuery.extend( {\n\t\t\t\ttype: type,\n\t\t\t\torigType: origType,\n\t\t\t\tdata: data,\n\t\t\t\thandler: handler,\n\t\t\t\tguid: handler.guid,\n\t\t\t\tselector: selector,\n\t\t\t\tneedsContext: selector && jQuery.expr.match.needsContext.test( selector ),\n\t\t\t\tnamespace: namespaces.join( \".\" )\n\t\t\t}, handleObjIn );\n\n\t\t\t// Init the event handler queue if we're the first\n\t\t\tif ( !( handlers = events[ type ] ) ) {\n\t\t\t\thandlers = events[ type ] = [];\n\t\t\t\thandlers.delegateCount = 0;\n\n\t\t\t\t// Only use addEventListener if the special events handler returns false\n\t\t\t\tif ( !special.setup ||\n\t\t\t\t\tspecial.setup.call( elem, data, namespaces, eventHandle ) === false ) {\n\n\t\t\t\t\tif ( elem.addEventListener ) {\n\t\t\t\t\t\telem.addEventListener( type, eventHandle );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif ( special.add ) {\n\t\t\t\tspecial.add.call( elem, handleObj );\n\n\t\t\t\tif ( !handleObj.handler.guid ) {\n\t\t\t\t\thandleObj.handler.guid = handler.guid;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Add to the element's handler list, delegates in front\n\t\t\tif ( selector ) {\n\t\t\t\thandlers.splice( handlers.delegateCount++, 0, handleObj );\n\t\t\t} else {\n\t\t\t\thandlers.push( handleObj );\n\t\t\t}\n\n\t\t\t// Keep track of which events have ever been used, for event optimization\n\t\t\tjQuery.event.global[ type ] = true;\n\t\t}\n\n\t},\n\n\t// Detach an event or set of events from an element\n\tremove: function( elem, types, handler, selector, mappedTypes ) {\n\n\t\tvar j, origCount, tmp,\n\t\t\tevents, t, handleObj,\n\t\t\tspecial, handlers, type, namespaces, origType,\n\t\t\telemData = dataPriv.hasData( elem ) && dataPriv.get( elem );\n\n\t\tif ( !elemData || !( events = elemData.events ) ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Once for each type.namespace in types; type may be omitted\n\t\ttypes = ( types || \"\" ).match( rnothtmlwhite ) || [ \"\" ];\n\t\tt = types.length;\n\t\twhile ( t-- ) {\n\t\t\ttmp = rtypenamespace.exec( types[ t ] ) || [];\n\t\t\ttype = origType = tmp[ 1 ];\n\t\t\tnamespaces = ( tmp[ 2 ] || \"\" ).split( \".\" ).sort();\n\n\t\t\t// Unbind all events (on this namespace, if provided) for the element\n\t\t\tif ( !type ) {\n\t\t\t\tfor ( type in events ) {\n\t\t\t\t\tjQuery.event.remove( elem, type + types[ t ], handler, selector, true );\n\t\t\t\t}\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tspecial = jQuery.event.special[ type ] || {};\n\t\t\ttype = ( selector ? special.delegateType : special.bindType ) || type;\n\t\t\thandlers = events[ type ] || [];\n\t\t\ttmp = tmp[ 2 ] &&\n\t\t\t\tnew RegExp( \"(^|\\\\.)\" + namespaces.join( \"\\\\.(?:.*\\\\.|)\" ) + \"(\\\\.|$)\" );\n\n\t\t\t// Remove matching events\n\t\t\torigCount = j = handlers.length;\n\t\t\twhile ( j-- ) {\n\t\t\t\thandleObj = handlers[ j ];\n\n\t\t\t\tif ( ( mappedTypes || origType === handleObj.origType ) &&\n\t\t\t\t\t( !handler || handler.guid === handleObj.guid ) &&\n\t\t\t\t\t( !tmp || tmp.test( handleObj.namespace ) ) &&\n\t\t\t\t\t( !selector || selector === handleObj.selector ||\n\t\t\t\t\t\tselector === \"**\" && handleObj.selector ) ) {\n\t\t\t\t\thandlers.splice( j, 1 );\n\n\t\t\t\t\tif ( handleObj.selector ) {\n\t\t\t\t\t\thandlers.delegateCount--;\n\t\t\t\t\t}\n\t\t\t\t\tif ( special.remove ) {\n\t\t\t\t\t\tspecial.remove.call( elem, handleObj );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Remove generic event handler if we removed something and no more handlers exist\n\t\t\t// (avoids potential for endless recursion during removal of special event handlers)\n\t\t\tif ( origCount && !handlers.length ) {\n\t\t\t\tif ( !special.teardown ||\n\t\t\t\t\tspecial.teardown.call( elem, namespaces, elemData.handle ) === false ) {\n\n\t\t\t\t\tjQuery.removeEvent( elem, type, elemData.handle );\n\t\t\t\t}\n\n\t\t\t\tdelete events[ type ];\n\t\t\t}\n\t\t}\n\n\t\t// Remove data and the expando if it's no longer used\n\t\tif ( jQuery.isEmptyObject( events ) ) {\n\t\t\tdataPriv.remove( elem, \"handle events\" );\n\t\t}\n\t},\n\n\tdispatch: function( nativeEvent ) {\n\n\t\t// Make a writable jQuery.Event from the native event object\n\t\tvar event = jQuery.event.fix( nativeEvent );\n\n\t\tvar i, j, ret, matched, handleObj, handlerQueue,\n\t\t\targs = new Array( arguments.length ),\n\t\t\thandlers = ( dataPriv.get( this, \"events\" ) || {} )[ event.type ] || [],\n\t\t\tspecial = jQuery.event.special[ event.type ] || {};\n\n\t\t// Use the fix-ed jQuery.Event rather than the (read-only) native event\n\t\targs[ 0 ] = event;\n\n\t\tfor ( i = 1; i < arguments.length; i++ ) {\n\t\t\targs[ i ] = arguments[ i ];\n\t\t}\n\n\t\tevent.delegateTarget = this;\n\n\t\t// Call the preDispatch hook for the mapped type, and let it bail if desired\n\t\tif ( special.preDispatch && special.preDispatch.call( this, event ) === false ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Determine handlers\n\t\thandlerQueue = jQuery.event.handlers.call( this, event, handlers );\n\n\t\t// Run delegates first; they may want to stop propagation beneath us\n\t\ti = 0;\n\t\twhile ( ( matched = handlerQueue[ i++ ] ) && !event.isPropagationStopped() ) {\n\t\t\tevent.currentTarget = matched.elem;\n\n\t\t\tj = 0;\n\t\t\twhile ( ( handleObj = matched.handlers[ j++ ] ) &&\n\t\t\t\t!event.isImmediatePropagationStopped() ) {\n\n\t\t\t\t// Triggered event must either 1) have no namespace, or 2) have namespace(s)\n\t\t\t\t// a subset or equal to those in the bound event (both can have no namespace).\n\t\t\t\tif ( !event.rnamespace || event.rnamespace.test( handleObj.namespace ) ) {\n\n\t\t\t\t\tevent.handleObj = handleObj;\n\t\t\t\t\tevent.data = handleObj.data;\n\n\t\t\t\t\tret = ( ( jQuery.event.special[ handleObj.origType ] || {} ).handle ||\n\t\t\t\t\t\thandleObj.handler ).apply( matched.elem, args );\n\n\t\t\t\t\tif ( ret !== undefined ) {\n\t\t\t\t\t\tif ( ( event.result = ret ) === false ) {\n\t\t\t\t\t\t\tevent.preventDefault();\n\t\t\t\t\t\t\tevent.stopPropagation();\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Call the postDispatch hook for the mapped type\n\t\tif ( special.postDispatch ) {\n\t\t\tspecial.postDispatch.call( this, event );\n\t\t}\n\n\t\treturn event.result;\n\t},\n\n\thandlers: function( event, handlers ) {\n\t\tvar i, handleObj, sel, matchedHandlers, matchedSelectors,\n\t\t\thandlerQueue = [],\n\t\t\tdelegateCount = handlers.delegateCount,\n\t\t\tcur = event.target;\n\n\t\t// Find delegate handlers\n\t\tif ( delegateCount &&\n\n\t\t\t// Support: IE <=9\n\t\t\t// Black-hole SVG <use> instance trees (trac-13180)\n\t\t\tcur.nodeType &&\n\n\t\t\t// Support: Firefox <=42\n\t\t\t// Suppress spec-violating clicks indicating a non-primary pointer button (trac-3861)\n\t\t\t// https://www.w3.org/TR/DOM-Level-3-Events/#event-type-click\n\t\t\t// Support: IE 11 only\n\t\t\t// ...but not arrow key \"clicks\" of radio inputs, which can have `button` -1 (gh-2343)\n\t\t\t!( event.type === \"click\" && event.button >= 1 ) ) {\n\n\t\t\tfor ( ; cur !== this; cur = cur.parentNode || this ) {\n\n\t\t\t\t// Don't check non-elements (#13208)\n\t\t\t\t// Don't process clicks on disabled elements (#6911, #8165, #11382, #11764)\n\t\t\t\tif ( cur.nodeType === 1 && !( event.type === \"click\" && cur.disabled === true ) ) {\n\t\t\t\t\tmatchedHandlers = [];\n\t\t\t\t\tmatchedSelectors = {};\n\t\t\t\t\tfor ( i = 0; i < delegateCount; i++ ) {\n\t\t\t\t\t\thandleObj = handlers[ i ];\n\n\t\t\t\t\t\t// Don't conflict with Object.prototype properties (#13203)\n\t\t\t\t\t\tsel = handleObj.selector + \" \";\n\n\t\t\t\t\t\tif ( matchedSelectors[ sel ] === undefined ) {\n\t\t\t\t\t\t\tmatchedSelectors[ sel ] = handleObj.needsContext ?\n\t\t\t\t\t\t\t\tjQuery( sel, this ).index( cur ) > -1 :\n\t\t\t\t\t\t\t\tjQuery.find( sel, this, null, [ cur ] ).length;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif ( matchedSelectors[ sel ] ) {\n\t\t\t\t\t\t\tmatchedHandlers.push( handleObj );\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tif ( matchedHandlers.length ) {\n\t\t\t\t\t\thandlerQueue.push( { elem: cur, handlers: matchedHandlers } );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Add the remaining (directly-bound) handlers\n\t\tcur = this;\n\t\tif ( delegateCount < handlers.length ) {\n\t\t\thandlerQueue.push( { elem: cur, handlers: handlers.slice( delegateCount ) } );\n\t\t}\n\n\t\treturn handlerQueue;\n\t},\n\n\taddProp: function( name, hook ) {\n\t\tObject.defineProperty( jQuery.Event.prototype, name, {\n\t\t\tenumerable: true,\n\t\t\tconfigurable: true,\n\n\t\t\tget: isFunction( hook ) ?\n\t\t\t\tfunction() {\n\t\t\t\t\tif ( this.originalEvent ) {\n\t\t\t\t\t\t\treturn hook( this.originalEvent );\n\t\t\t\t\t}\n\t\t\t\t} :\n\t\t\t\tfunction() {\n\t\t\t\t\tif ( this.originalEvent ) {\n\t\t\t\t\t\t\treturn this.originalEvent[ name ];\n\t\t\t\t\t}\n\t\t\t\t},\n\n\t\t\tset: function( value ) {\n\t\t\t\tObject.defineProperty( this, name, {\n\t\t\t\t\tenumerable: true,\n\t\t\t\t\tconfigurable: true,\n\t\t\t\t\twritable: true,\n\t\t\t\t\tvalue: value\n\t\t\t\t} );\n\t\t\t}\n\t\t} );\n\t},\n\n\tfix: function( originalEvent ) {\n\t\treturn originalEvent[ jQuery.expando ] ?\n\t\t\toriginalEvent :\n\t\t\tnew jQuery.Event( originalEvent );\n\t},\n\n\tspecial: {\n\t\tload: {\n\n\t\t\t// Prevent triggered image.load events from bubbling to window.load\n\t\t\tnoBubble: true\n\t\t},\n\t\tfocus: {\n\n\t\t\t// Fire native event if possible so blur/focus sequence is correct\n\t\t\ttrigger: function() {\n\t\t\t\tif ( this !== safeActiveElement() && this.focus ) {\n\t\t\t\t\tthis.focus();\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t},\n\t\t\tdelegateType: \"focusin\"\n\t\t},\n\t\tblur: {\n\t\t\ttrigger: function() {\n\t\t\t\tif ( this === safeActiveElement() && this.blur ) {\n\t\t\t\t\tthis.blur();\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t},\n\t\t\tdelegateType: \"focusout\"\n\t\t},\n\t\tclick: {\n\n\t\t\t// For checkbox, fire native event so checked state will be right\n\t\t\ttrigger: function() {\n\t\t\t\tif ( this.type === \"checkbox\" && this.click && nodeName( this, \"input\" ) ) {\n\t\t\t\t\tthis.click();\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t},\n\n\t\t\t// For cross-browser consistency, don't fire native .click() on links\n\t\t\t_default: function( event ) {\n\t\t\t\treturn nodeName( event.target, \"a\" );\n\t\t\t}\n\t\t},\n\n\t\tbeforeunload: {\n\t\t\tpostDispatch: function( event ) {\n\n\t\t\t\t// Support: Firefox 20+\n\t\t\t\t// Firefox doesn't alert if the returnValue field is not set.\n\t\t\t\tif ( event.result !== undefined && event.originalEvent ) {\n\t\t\t\t\tevent.originalEvent.returnValue = event.result;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n};\n\njQuery.removeEvent = function( elem, type, handle ) {\n\n\t// This \"if\" is needed for plain objects\n\tif ( elem.removeEventListener ) {\n\t\telem.removeEventListener( type, handle );\n\t}\n};\n\njQuery.Event = function( src, props ) {\n\n\t// Allow instantiation without the 'new' keyword\n\tif ( !( this instanceof jQuery.Event ) ) {\n\t\treturn new jQuery.Event( src, props );\n\t}\n\n\t// Event object\n\tif ( src && src.type ) {\n\t\tthis.originalEvent = src;\n\t\tthis.type = src.type;\n\n\t\t// Events bubbling up the document may have been marked as prevented\n\t\t// by a handler lower down the tree; reflect the correct value.\n\t\tthis.isDefaultPrevented = src.defaultPrevented ||\n\t\t\t\tsrc.defaultPrevented === undefined &&\n\n\t\t\t\t// Support: Android <=2.3 only\n\t\t\t\tsrc.returnValue === false ?\n\t\t\treturnTrue :\n\t\t\treturnFalse;\n\n\t\t// Create target properties\n\t\t// Support: Safari <=6 - 7 only\n\t\t// Target should not be a text node (#504, #13143)\n\t\tthis.target = ( src.target && src.target.nodeType === 3 ) ?\n\t\t\tsrc.target.parentNode :\n\t\t\tsrc.target;\n\n\t\tthis.currentTarget = src.currentTarget;\n\t\tthis.relatedTarget = src.relatedTarget;\n\n\t// Event type\n\t} else {\n\t\tthis.type = src;\n\t}\n\n\t// Put explicitly provided properties onto the event object\n\tif ( props ) {\n\t\tjQuery.extend( this, props );\n\t}\n\n\t// Create a timestamp if incoming event doesn't have one\n\tthis.timeStamp = src && src.timeStamp || Date.now();\n\n\t// Mark it as fixed\n\tthis[ jQuery.expando ] = true;\n};\n\n// jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding\n// https://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html\njQuery.Event.prototype = {\n\tconstructor: jQuery.Event,\n\tisDefaultPrevented: returnFalse,\n\tisPropagationStopped: returnFalse,\n\tisImmediatePropagationStopped: returnFalse,\n\tisSimulated: false,\n\n\tpreventDefault: function() {\n\t\tvar e = this.originalEvent;\n\n\t\tthis.isDefaultPrevented = returnTrue;\n\n\t\tif ( e && !this.isSimulated ) {\n\t\t\te.preventDefault();\n\t\t}\n\t},\n\tstopPropagation: function() {\n\t\tvar e = this.originalEvent;\n\n\t\tthis.isPropagationStopped = returnTrue;\n\n\t\tif ( e && !this.isSimulated ) {\n\t\t\te.stopPropagation();\n\t\t}\n\t},\n\tstopImmediatePropagation: function() {\n\t\tvar e = this.originalEvent;\n\n\t\tthis.isImmediatePropagationStopped = returnTrue;\n\n\t\tif ( e && !this.isSimulated ) {\n\t\t\te.stopImmediatePropagation();\n\t\t}\n\n\t\tthis.stopPropagation();\n\t}\n};\n\n// Includes all common event props including KeyEvent and MouseEvent specific props\njQuery.each( {\n\taltKey: true,\n\tbubbles: true,\n\tcancelable: true,\n\tchangedTouches: true,\n\tctrlKey: true,\n\tdetail: true,\n\teventPhase: true,\n\tmetaKey: true,\n\tpageX: true,\n\tpageY: true,\n\tshiftKey: true,\n\tview: true,\n\t\"char\": true,\n\tcharCode: true,\n\tkey: true,\n\tkeyCode: true,\n\tbutton: true,\n\tbuttons: true,\n\tclientX: true,\n\tclientY: true,\n\toffsetX: true,\n\toffsetY: true,\n\tpointerId: true,\n\tpointerType: true,\n\tscreenX: true,\n\tscreenY: true,\n\ttargetTouches: true,\n\ttoElement: true,\n\ttouches: true,\n\n\twhich: function( event ) {\n\t\tvar button = event.button;\n\n\t\t// Add which for key events\n\t\tif ( event.which == null && rkeyEvent.test( event.type ) ) {\n\t\t\treturn event.charCode != null ? event.charCode : event.keyCode;\n\t\t}\n\n\t\t// Add which for click: 1 === left; 2 === middle; 3 === right\n\t\tif ( !event.which && button !== undefined && rmouseEvent.test( event.type ) ) {\n\t\t\tif ( button & 1 ) {\n\t\t\t\treturn 1;\n\t\t\t}\n\n\t\t\tif ( button & 2 ) {\n\t\t\t\treturn 3;\n\t\t\t}\n\n\t\t\tif ( button & 4 ) {\n\t\t\t\treturn 2;\n\t\t\t}\n\n\t\t\treturn 0;\n\t\t}\n\n\t\treturn event.which;\n\t}\n}, jQuery.event.addProp );\n\n// Create mouseenter/leave events using mouseover/out and event-time checks\n// so that event delegation works in jQuery.\n// Do the same for pointerenter/pointerleave and pointerover/pointerout\n//\n// Support: Safari 7 only\n// Safari sends mouseenter too often; see:\n// https://bugs.chromium.org/p/chromium/issues/detail?id=470258\n// for the description of the bug (it existed in older Chrome versions as well).\njQuery.each( {\n\tmouseenter: \"mouseover\",\n\tmouseleave: \"mouseout\",\n\tpointerenter: \"pointerover\",\n\tpointerleave: \"pointerout\"\n}, function( orig, fix ) {\n\tjQuery.event.special[ orig ] = {\n\t\tdelegateType: fix,\n\t\tbindType: fix,\n\n\t\thandle: function( event ) {\n\t\t\tvar ret,\n\t\t\t\ttarget = this,\n\t\t\t\trelated = event.relatedTarget,\n\t\t\t\thandleObj = event.handleObj;\n\n\t\t\t// For mouseenter/leave call the handler if related is outside the target.\n\t\t\t// NB: No relatedTarget if the mouse left/entered the browser window\n\t\t\tif ( !related || ( related !== target && !jQuery.contains( target, related ) ) ) {\n\t\t\t\tevent.type = handleObj.origType;\n\t\t\t\tret = handleObj.handler.apply( this, arguments );\n\t\t\t\tevent.type = fix;\n\t\t\t}\n\t\t\treturn ret;\n\t\t}\n\t};\n} );\n\njQuery.fn.extend( {\n\n\ton: function( types, selector, data, fn ) {\n\t\treturn on( this, types, selector, data, fn );\n\t},\n\tone: function( types, selector, data, fn ) {\n\t\treturn on( this, types, selector, data, fn, 1 );\n\t},\n\toff: function( types, selector, fn ) {\n\t\tvar handleObj, type;\n\t\tif ( types && types.preventDefault && types.handleObj ) {\n\n\t\t\t// ( event )  dispatched jQuery.Event\n\t\t\thandleObj = types.handleObj;\n\t\t\tjQuery( types.delegateTarget ).off(\n\t\t\t\thandleObj.namespace ?\n\t\t\t\t\thandleObj.origType + \".\" + handleObj.namespace :\n\t\t\t\t\thandleObj.origType,\n\t\t\t\thandleObj.selector,\n\t\t\t\thandleObj.handler\n\t\t\t);\n\t\t\treturn this;\n\t\t}\n\t\tif ( typeof types === \"object\" ) {\n\n\t\t\t// ( types-object [, selector] )\n\t\t\tfor ( type in types ) {\n\t\t\t\tthis.off( type, selector, types[ type ] );\n\t\t\t}\n\t\t\treturn this;\n\t\t}\n\t\tif ( selector === false || typeof selector === \"function\" ) {\n\n\t\t\t// ( types [, fn] )\n\t\t\tfn = selector;\n\t\t\tselector = undefined;\n\t\t}\n\t\tif ( fn === false ) {\n\t\t\tfn = returnFalse;\n\t\t}\n\t\treturn this.each( function() {\n\t\t\tjQuery.event.remove( this, types, fn, selector );\n\t\t} );\n\t}\n} );\n\n\nvar\n\n\t/* eslint-disable max-len */\n\n\t// See https://github.com/eslint/eslint/issues/3229\n\trxhtmlTag = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([a-z][^\\/\\0>\\x20\\t\\r\\n\\f]*)[^>]*)\\/>/gi,\n\n\t/* eslint-enable */\n\n\t// Support: IE <=10 - 11, Edge 12 - 13 only\n\t// In IE/Edge using regex groups here causes severe slowdowns.\n\t// See https://connect.microsoft.com/IE/feedback/details/1736512/\n\trnoInnerhtml = /<script|<style|<link/i,\n\n\t// checked=\"checked\" or checked\n\trchecked = /checked\\s*(?:[^=]|=\\s*.checked.)/i,\n\trcleanScript = /^\\s*<!(?:\\[CDATA\\[|--)|(?:\\]\\]|--)>\\s*$/g;\n\n// Prefer a tbody over its parent table for containing new rows\nfunction manipulationTarget( elem, content ) {\n\tif ( nodeName( elem, \"table\" ) &&\n\t\tnodeName( content.nodeType !== 11 ? content : content.firstChild, \"tr\" ) ) {\n\n\t\treturn jQuery( elem ).children( \"tbody\" )[ 0 ] || elem;\n\t}\n\n\treturn elem;\n}\n\n// Replace/restore the type attribute of script elements for safe DOM manipulation\nfunction disableScript( elem ) {\n\telem.type = ( elem.getAttribute( \"type\" ) !== null ) + \"/\" + elem.type;\n\treturn elem;\n}\nfunction restoreScript( elem ) {\n\tif ( ( elem.type || \"\" ).slice( 0, 5 ) === \"true/\" ) {\n\t\telem.type = elem.type.slice( 5 );\n\t} else {\n\t\telem.removeAttribute( \"type\" );\n\t}\n\n\treturn elem;\n}\n\nfunction cloneCopyEvent( src, dest ) {\n\tvar i, l, type, pdataOld, pdataCur, udataOld, udataCur, events;\n\n\tif ( dest.nodeType !== 1 ) {\n\t\treturn;\n\t}\n\n\t// 1. Copy private data: events, handlers, etc.\n\tif ( dataPriv.hasData( src ) ) {\n\t\tpdataOld = dataPriv.access( src );\n\t\tpdataCur = dataPriv.set( dest, pdataOld );\n\t\tevents = pdataOld.events;\n\n\t\tif ( events ) {\n\t\t\tdelete pdataCur.handle;\n\t\t\tpdataCur.events = {};\n\n\t\t\tfor ( type in events ) {\n\t\t\t\tfor ( i = 0, l = events[ type ].length; i < l; i++ ) {\n\t\t\t\t\tjQuery.event.add( dest, type, events[ type ][ i ] );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t// 2. Copy user data\n\tif ( dataUser.hasData( src ) ) {\n\t\tudataOld = dataUser.access( src );\n\t\tudataCur = jQuery.extend( {}, udataOld );\n\n\t\tdataUser.set( dest, udataCur );\n\t}\n}\n\n// Fix IE bugs, see support tests\nfunction fixInput( src, dest ) {\n\tvar nodeName = dest.nodeName.toLowerCase();\n\n\t// Fails to persist the checked state of a cloned checkbox or radio button.\n\tif ( nodeName === \"input\" && rcheckableType.test( src.type ) ) {\n\t\tdest.checked = src.checked;\n\n\t// Fails to return the selected option to the default selected state when cloning options\n\t} else if ( nodeName === \"input\" || nodeName === \"textarea\" ) {\n\t\tdest.defaultValue = src.defaultValue;\n\t}\n}\n\nfunction domManip( collection, args, callback, ignored ) {\n\n\t// Flatten any nested arrays\n\targs = concat.apply( [], args );\n\n\tvar fragment, first, scripts, hasScripts, node, doc,\n\t\ti = 0,\n\t\tl = collection.length,\n\t\tiNoClone = l - 1,\n\t\tvalue = args[ 0 ],\n\t\tvalueIsFunction = isFunction( value );\n\n\t// We can't cloneNode fragments that contain checked, in WebKit\n\tif ( valueIsFunction ||\n\t\t\t( l > 1 && typeof value === \"string\" &&\n\t\t\t\t!support.checkClone && rchecked.test( value ) ) ) {\n\t\treturn collection.each( function( index ) {\n\t\t\tvar self = collection.eq( index );\n\t\t\tif ( valueIsFunction ) {\n\t\t\t\targs[ 0 ] = value.call( this, index, self.html() );\n\t\t\t}\n\t\t\tdomManip( self, args, callback, ignored );\n\t\t} );\n\t}\n\n\tif ( l ) {\n\t\tfragment = buildFragment( args, collection[ 0 ].ownerDocument, false, collection, ignored );\n\t\tfirst = fragment.firstChild;\n\n\t\tif ( fragment.childNodes.length === 1 ) {\n\t\t\tfragment = first;\n\t\t}\n\n\t\t// Require either new content or an interest in ignored elements to invoke the callback\n\t\tif ( first || ignored ) {\n\t\t\tscripts = jQuery.map( getAll( fragment, \"script\" ), disableScript );\n\t\t\thasScripts = scripts.length;\n\n\t\t\t// Use the original fragment for the last item\n\t\t\t// instead of the first because it can end up\n\t\t\t// being emptied incorrectly in certain situations (#8070).\n\t\t\tfor ( ; i < l; i++ ) {\n\t\t\t\tnode = fragment;\n\n\t\t\t\tif ( i !== iNoClone ) {\n\t\t\t\t\tnode = jQuery.clone( node, true, true );\n\n\t\t\t\t\t// Keep references to cloned scripts for later restoration\n\t\t\t\t\tif ( hasScripts ) {\n\n\t\t\t\t\t\t// Support: Android <=4.0 only, PhantomJS 1 only\n\t\t\t\t\t\t// push.apply(_, arraylike) throws on ancient WebKit\n\t\t\t\t\t\tjQuery.merge( scripts, getAll( node, \"script\" ) );\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tcallback.call( collection[ i ], node, i );\n\t\t\t}\n\n\t\t\tif ( hasScripts ) {\n\t\t\t\tdoc = scripts[ scripts.length - 1 ].ownerDocument;\n\n\t\t\t\t// Reenable scripts\n\t\t\t\tjQuery.map( scripts, restoreScript );\n\n\t\t\t\t// Evaluate executable scripts on first document insertion\n\t\t\t\tfor ( i = 0; i < hasScripts; i++ ) {\n\t\t\t\t\tnode = scripts[ i ];\n\t\t\t\t\tif ( rscriptType.test( node.type || \"\" ) &&\n\t\t\t\t\t\t!dataPriv.access( node, \"globalEval\" ) &&\n\t\t\t\t\t\tjQuery.contains( doc, node ) ) {\n\n\t\t\t\t\t\tif ( node.src && ( node.type || \"\" ).toLowerCase()  !== \"module\" ) {\n\n\t\t\t\t\t\t\t// Optional AJAX dependency, but won't run scripts if not present\n\t\t\t\t\t\t\tif ( jQuery._evalUrl ) {\n\t\t\t\t\t\t\t\tjQuery._evalUrl( node.src );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tDOMEval( node.textContent.replace( rcleanScript, \"\" ), doc, node );\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\treturn collection;\n}\n\nfunction remove( elem, selector, keepData ) {\n\tvar node,\n\t\tnodes = selector ? jQuery.filter( selector, elem ) : elem,\n\t\ti = 0;\n\n\tfor ( ; ( node = nodes[ i ] ) != null; i++ ) {\n\t\tif ( !keepData && node.nodeType === 1 ) {\n\t\t\tjQuery.cleanData( getAll( node ) );\n\t\t}\n\n\t\tif ( node.parentNode ) {\n\t\t\tif ( keepData && jQuery.contains( node.ownerDocument, node ) ) {\n\t\t\t\tsetGlobalEval( getAll( node, \"script\" ) );\n\t\t\t}\n\t\t\tnode.parentNode.removeChild( node );\n\t\t}\n\t}\n\n\treturn elem;\n}\n\njQuery.extend( {\n\thtmlPrefilter: function( html ) {\n\t\treturn html.replace( rxhtmlTag, \"<$1></$2>\" );\n\t},\n\n\tclone: function( elem, dataAndEvents, deepDataAndEvents ) {\n\t\tvar i, l, srcElements, destElements,\n\t\t\tclone = elem.cloneNode( true ),\n\t\t\tinPage = jQuery.contains( elem.ownerDocument, elem );\n\n\t\t// Fix IE cloning issues\n\t\tif ( !support.noCloneChecked && ( elem.nodeType === 1 || elem.nodeType === 11 ) &&\n\t\t\t\t!jQuery.isXMLDoc( elem ) ) {\n\n\t\t\t// We eschew Sizzle here for performance reasons: https://jsperf.com/getall-vs-sizzle/2\n\t\t\tdestElements = getAll( clone );\n\t\t\tsrcElements = getAll( elem );\n\n\t\t\tfor ( i = 0, l = srcElements.length; i < l; i++ ) {\n\t\t\t\tfixInput( srcElements[ i ], destElements[ i ] );\n\t\t\t}\n\t\t}\n\n\t\t// Copy the events from the original to the clone\n\t\tif ( dataAndEvents ) {\n\t\t\tif ( deepDataAndEvents ) {\n\t\t\t\tsrcElements = srcElements || getAll( elem );\n\t\t\t\tdestElements = destElements || getAll( clone );\n\n\t\t\t\tfor ( i = 0, l = srcElements.length; i < l; i++ ) {\n\t\t\t\t\tcloneCopyEvent( srcElements[ i ], destElements[ i ] );\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tcloneCopyEvent( elem, clone );\n\t\t\t}\n\t\t}\n\n\t\t// Preserve script evaluation history\n\t\tdestElements = getAll( clone, \"script\" );\n\t\tif ( destElements.length > 0 ) {\n\t\t\tsetGlobalEval( destElements, !inPage && getAll( elem, \"script\" ) );\n\t\t}\n\n\t\t// Return the cloned set\n\t\treturn clone;\n\t},\n\n\tcleanData: function( elems ) {\n\t\tvar data, elem, type,\n\t\t\tspecial = jQuery.event.special,\n\t\t\ti = 0;\n\n\t\tfor ( ; ( elem = elems[ i ] ) !== undefined; i++ ) {\n\t\t\tif ( acceptData( elem ) ) {\n\t\t\t\tif ( ( data = elem[ dataPriv.expando ] ) ) {\n\t\t\t\t\tif ( data.events ) {\n\t\t\t\t\t\tfor ( type in data.events ) {\n\t\t\t\t\t\t\tif ( special[ type ] ) {\n\t\t\t\t\t\t\t\tjQuery.event.remove( elem, type );\n\n\t\t\t\t\t\t\t// This is a shortcut to avoid jQuery.event.remove's overhead\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tjQuery.removeEvent( elem, type, data.handle );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\t// Support: Chrome <=35 - 45+\n\t\t\t\t\t// Assign undefined instead of using delete, see Data#remove\n\t\t\t\t\telem[ dataPriv.expando ] = undefined;\n\t\t\t\t}\n\t\t\t\tif ( elem[ dataUser.expando ] ) {\n\n\t\t\t\t\t// Support: Chrome <=35 - 45+\n\t\t\t\t\t// Assign undefined instead of using delete, see Data#remove\n\t\t\t\t\telem[ dataUser.expando ] = undefined;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n} );\n\njQuery.fn.extend( {\n\tdetach: function( selector ) {\n\t\treturn remove( this, selector, true );\n\t},\n\n\tremove: function( selector ) {\n\t\treturn remove( this, selector );\n\t},\n\n\ttext: function( value ) {\n\t\treturn access( this, function( value ) {\n\t\t\treturn value === undefined ?\n\t\t\t\tjQuery.text( this ) :\n\t\t\t\tthis.empty().each( function() {\n\t\t\t\t\tif ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) {\n\t\t\t\t\t\tthis.textContent = value;\n\t\t\t\t\t}\n\t\t\t\t} );\n\t\t}, null, value, arguments.length );\n\t},\n\n\tappend: function() {\n\t\treturn domManip( this, arguments, function( elem ) {\n\t\t\tif ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) {\n\t\t\t\tvar target = manipulationTarget( this, elem );\n\t\t\t\ttarget.appendChild( elem );\n\t\t\t}\n\t\t} );\n\t},\n\n\tprepend: function() {\n\t\treturn domManip( this, arguments, function( elem ) {\n\t\t\tif ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) {\n\t\t\t\tvar target = manipulationTarget( this, elem );\n\t\t\t\ttarget.insertBefore( elem, target.firstChild );\n\t\t\t}\n\t\t} );\n\t},\n\n\tbefore: function() {\n\t\treturn domManip( this, arguments, function( elem ) {\n\t\t\tif ( this.parentNode ) {\n\t\t\t\tthis.parentNode.insertBefore( elem, this );\n\t\t\t}\n\t\t} );\n\t},\n\n\tafter: function() {\n\t\treturn domManip( this, arguments, function( elem ) {\n\t\t\tif ( this.parentNode ) {\n\t\t\t\tthis.parentNode.insertBefore( elem, this.nextSibling );\n\t\t\t}\n\t\t} );\n\t},\n\n\tempty: function() {\n\t\tvar elem,\n\t\t\ti = 0;\n\n\t\tfor ( ; ( elem = this[ i ] ) != null; i++ ) {\n\t\t\tif ( elem.nodeType === 1 ) {\n\n\t\t\t\t// Prevent memory leaks\n\t\t\t\tjQuery.cleanData( getAll( elem, false ) );\n\n\t\t\t\t// Remove any remaining nodes\n\t\t\t\telem.textContent = \"\";\n\t\t\t}\n\t\t}\n\n\t\treturn this;\n\t},\n\n\tclone: function( dataAndEvents, deepDataAndEvents ) {\n\t\tdataAndEvents = dataAndEvents == null ? false : dataAndEvents;\n\t\tdeepDataAndEvents = deepDataAndEvents == null ? dataAndEvents : deepDataAndEvents;\n\n\t\treturn this.map( function() {\n\t\t\treturn jQuery.clone( this, dataAndEvents, deepDataAndEvents );\n\t\t} );\n\t},\n\n\thtml: function( value ) {\n\t\treturn access( this, function( value ) {\n\t\t\tvar elem = this[ 0 ] || {},\n\t\t\t\ti = 0,\n\t\t\t\tl = this.length;\n\n\t\t\tif ( value === undefined && elem.nodeType === 1 ) {\n\t\t\t\treturn elem.innerHTML;\n\t\t\t}\n\n\t\t\t// See if we can take a shortcut and just use innerHTML\n\t\t\tif ( typeof value === \"string\" && !rnoInnerhtml.test( value ) &&\n\t\t\t\t!wrapMap[ ( rtagName.exec( value ) || [ \"\", \"\" ] )[ 1 ].toLowerCase() ] ) {\n\n\t\t\t\tvalue = jQuery.htmlPrefilter( value );\n\n\t\t\t\ttry {\n\t\t\t\t\tfor ( ; i < l; i++ ) {\n\t\t\t\t\t\telem = this[ i ] || {};\n\n\t\t\t\t\t\t// Remove element nodes and prevent memory leaks\n\t\t\t\t\t\tif ( elem.nodeType === 1 ) {\n\t\t\t\t\t\t\tjQuery.cleanData( getAll( elem, false ) );\n\t\t\t\t\t\t\telem.innerHTML = value;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\telem = 0;\n\n\t\t\t\t// If using innerHTML throws an exception, use the fallback method\n\t\t\t\t} catch ( e ) {}\n\t\t\t}\n\n\t\t\tif ( elem ) {\n\t\t\t\tthis.empty().append( value );\n\t\t\t}\n\t\t}, null, value, arguments.length );\n\t},\n\n\treplaceWith: function() {\n\t\tvar ignored = [];\n\n\t\t// Make the changes, replacing each non-ignored context element with the new content\n\t\treturn domManip( this, arguments, function( elem ) {\n\t\t\tvar parent = this.parentNode;\n\n\t\t\tif ( jQuery.inArray( this, ignored ) < 0 ) {\n\t\t\t\tjQuery.cleanData( getAll( this ) );\n\t\t\t\tif ( parent ) {\n\t\t\t\t\tparent.replaceChild( elem, this );\n\t\t\t\t}\n\t\t\t}\n\n\t\t// Force callback invocation\n\t\t}, ignored );\n\t}\n} );\n\njQuery.each( {\n\tappendTo: \"append\",\n\tprependTo: \"prepend\",\n\tinsertBefore: \"before\",\n\tinsertAfter: \"after\",\n\treplaceAll: \"replaceWith\"\n}, function( name, original ) {\n\tjQuery.fn[ name ] = function( selector ) {\n\t\tvar elems,\n\t\t\tret = [],\n\t\t\tinsert = jQuery( selector ),\n\t\t\tlast = insert.length - 1,\n\t\t\ti = 0;\n\n\t\tfor ( ; i <= last; i++ ) {\n\t\t\telems = i === last ? this : this.clone( true );\n\t\t\tjQuery( insert[ i ] )[ original ]( elems );\n\n\t\t\t// Support: Android <=4.0 only, PhantomJS 1 only\n\t\t\t// .get() because push.apply(_, arraylike) throws on ancient WebKit\n\t\t\tpush.apply( ret, elems.get() );\n\t\t}\n\n\t\treturn this.pushStack( ret );\n\t};\n} );\nvar rnumnonpx = new RegExp( \"^(\" + pnum + \")(?!px)[a-z%]+$\", \"i\" );\n\nvar getStyles = function( elem ) {\n\n\t\t// Support: IE <=11 only, Firefox <=30 (#15098, #14150)\n\t\t// IE throws on elements created in popups\n\t\t// FF meanwhile throws on frame elements through \"defaultView.getComputedStyle\"\n\t\tvar view = elem.ownerDocument.defaultView;\n\n\t\tif ( !view || !view.opener ) {\n\t\t\tview = window;\n\t\t}\n\n\t\treturn view.getComputedStyle( elem );\n\t};\n\nvar rboxStyle = new RegExp( cssExpand.join( \"|\" ), \"i\" );\n\n\n\n( function() {\n\n\t// Executing both pixelPosition & boxSizingReliable tests require only one layout\n\t// so they're executed at the same time to save the second computation.\n\tfunction computeStyleTests() {\n\n\t\t// This is a singleton, we need to execute it only once\n\t\tif ( !div ) {\n\t\t\treturn;\n\t\t}\n\n\t\tcontainer.style.cssText = \"position:absolute;left:-11111px;width:60px;\" +\n\t\t\t\"margin-top:1px;padding:0;border:0\";\n\t\tdiv.style.cssText =\n\t\t\t\"position:relative;display:block;box-sizing:border-box;overflow:scroll;\" +\n\t\t\t\"margin:auto;border:1px;padding:1px;\" +\n\t\t\t\"width:60%;top:1%\";\n\t\tdocumentElement.appendChild( container ).appendChild( div );\n\n\t\tvar divStyle = window.getComputedStyle( div );\n\t\tpixelPositionVal = divStyle.top !== \"1%\";\n\n\t\t// Support: Android 4.0 - 4.3 only, Firefox <=3 - 44\n\t\treliableMarginLeftVal = roundPixelMeasures( divStyle.marginLeft ) === 12;\n\n\t\t// Support: Android 4.0 - 4.3 only, Safari <=9.1 - 10.1, iOS <=7.0 - 9.3\n\t\t// Some styles come back with percentage values, even though they shouldn't\n\t\tdiv.style.right = \"60%\";\n\t\tpixelBoxStylesVal = roundPixelMeasures( divStyle.right ) === 36;\n\n\t\t// Support: IE 9 - 11 only\n\t\t// Detect misreporting of content dimensions for box-sizing:border-box elements\n\t\tboxSizingReliableVal = roundPixelMeasures( divStyle.width ) === 36;\n\n\t\t// Support: IE 9 only\n\t\t// Detect overflow:scroll screwiness (gh-3699)\n\t\tdiv.style.position = \"absolute\";\n\t\tscrollboxSizeVal = div.offsetWidth === 36 || \"absolute\";\n\n\t\tdocumentElement.removeChild( container );\n\n\t\t// Nullify the div so it wouldn't be stored in the memory and\n\t\t// it will also be a sign that checks already performed\n\t\tdiv = null;\n\t}\n\n\tfunction roundPixelMeasures( measure ) {\n\t\treturn Math.round( parseFloat( measure ) );\n\t}\n\n\tvar pixelPositionVal, boxSizingReliableVal, scrollboxSizeVal, pixelBoxStylesVal,\n\t\treliableMarginLeftVal,\n\t\tcontainer = document.createElement( \"div\" ),\n\t\tdiv = document.createElement( \"div\" );\n\n\t// Finish early in limited (non-browser) environments\n\tif ( !div.style ) {\n\t\treturn;\n\t}\n\n\t// Support: IE <=9 - 11 only\n\t// Style of cloned element affects source element cloned (#8908)\n\tdiv.style.backgroundClip = \"content-box\";\n\tdiv.cloneNode( true ).style.backgroundClip = \"\";\n\tsupport.clearCloneStyle = div.style.backgroundClip === \"content-box\";\n\n\tjQuery.extend( support, {\n\t\tboxSizingReliable: function() {\n\t\t\tcomputeStyleTests();\n\t\t\treturn boxSizingReliableVal;\n\t\t},\n\t\tpixelBoxStyles: function() {\n\t\t\tcomputeStyleTests();\n\t\t\treturn pixelBoxStylesVal;\n\t\t},\n\t\tpixelPosition: function() {\n\t\t\tcomputeStyleTests();\n\t\t\treturn pixelPositionVal;\n\t\t},\n\t\treliableMarginLeft: function() {\n\t\t\tcomputeStyleTests();\n\t\t\treturn reliableMarginLeftVal;\n\t\t},\n\t\tscrollboxSize: function() {\n\t\t\tcomputeStyleTests();\n\t\t\treturn scrollboxSizeVal;\n\t\t}\n\t} );\n} )();\n\n\nfunction curCSS( elem, name, computed ) {\n\tvar width, minWidth, maxWidth, ret,\n\n\t\t// Support: Firefox 51+\n\t\t// Retrieving style before computed somehow\n\t\t// fixes an issue with getting wrong values\n\t\t// on detached elements\n\t\tstyle = elem.style;\n\n\tcomputed = computed || getStyles( elem );\n\n\t// getPropertyValue is needed for:\n\t//   .css('filter') (IE 9 only, #12537)\n\t//   .css('--customProperty) (#3144)\n\tif ( computed ) {\n\t\tret = computed.getPropertyValue( name ) || computed[ name ];\n\n\t\tif ( ret === \"\" && !jQuery.contains( elem.ownerDocument, elem ) ) {\n\t\t\tret = jQuery.style( elem, name );\n\t\t}\n\n\t\t// A tribute to the \"awesome hack by Dean Edwards\"\n\t\t// Android Browser returns percentage for some values,\n\t\t// but width seems to be reliably pixels.\n\t\t// This is against the CSSOM draft spec:\n\t\t// https://drafts.csswg.org/cssom/#resolved-values\n\t\tif ( !support.pixelBoxStyles() && rnumnonpx.test( ret ) && rboxStyle.test( name ) ) {\n\n\t\t\t// Remember the original values\n\t\t\twidth = style.width;\n\t\t\tminWidth = style.minWidth;\n\t\t\tmaxWidth = style.maxWidth;\n\n\t\t\t// Put in the new values to get a computed value out\n\t\t\tstyle.minWidth = style.maxWidth = style.width = ret;\n\t\t\tret = computed.width;\n\n\t\t\t// Revert the changed values\n\t\t\tstyle.width = width;\n\t\t\tstyle.minWidth = minWidth;\n\t\t\tstyle.maxWidth = maxWidth;\n\t\t}\n\t}\n\n\treturn ret !== undefined ?\n\n\t\t// Support: IE <=9 - 11 only\n\t\t// IE returns zIndex value as an integer.\n\t\tret + \"\" :\n\t\tret;\n}\n\n\nfunction addGetHookIf( conditionFn, hookFn ) {\n\n\t// Define the hook, we'll check on the first run if it's really needed.\n\treturn {\n\t\tget: function() {\n\t\t\tif ( conditionFn() ) {\n\n\t\t\t\t// Hook not needed (or it's not possible to use it due\n\t\t\t\t// to missing dependency), remove it.\n\t\t\t\tdelete this.get;\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// Hook needed; redefine it so that the support test is not executed again.\n\t\t\treturn ( this.get = hookFn ).apply( this, arguments );\n\t\t}\n\t};\n}\n\n\nvar\n\n\t// Swappable if display is none or starts with table\n\t// except \"table\", \"table-cell\", or \"table-caption\"\n\t// See here for display values: https://developer.mozilla.org/en-US/docs/CSS/display\n\trdisplayswap = /^(none|table(?!-c[ea]).+)/,\n\trcustomProp = /^--/,\n\tcssShow = { position: \"absolute\", visibility: \"hidden\", display: \"block\" },\n\tcssNormalTransform = {\n\t\tletterSpacing: \"0\",\n\t\tfontWeight: \"400\"\n\t},\n\n\tcssPrefixes = [ \"Webkit\", \"Moz\", \"ms\" ],\n\temptyStyle = document.createElement( \"div\" ).style;\n\n// Return a css property mapped to a potentially vendor prefixed property\nfunction vendorPropName( name ) {\n\n\t// Shortcut for names that are not vendor prefixed\n\tif ( name in emptyStyle ) {\n\t\treturn name;\n\t}\n\n\t// Check for vendor prefixed names\n\tvar capName = name[ 0 ].toUpperCase() + name.slice( 1 ),\n\t\ti = cssPrefixes.length;\n\n\twhile ( i-- ) {\n\t\tname = cssPrefixes[ i ] + capName;\n\t\tif ( name in emptyStyle ) {\n\t\t\treturn name;\n\t\t}\n\t}\n}\n\n// Return a property mapped along what jQuery.cssProps suggests or to\n// a vendor prefixed property.\nfunction finalPropName( name ) {\n\tvar ret = jQuery.cssProps[ name ];\n\tif ( !ret ) {\n\t\tret = jQuery.cssProps[ name ] = vendorPropName( name ) || name;\n\t}\n\treturn ret;\n}\n\nfunction setPositiveNumber( elem, value, subtract ) {\n\n\t// Any relative (+/-) values have already been\n\t// normalized at this point\n\tvar matches = rcssNum.exec( value );\n\treturn matches ?\n\n\t\t// Guard against undefined \"subtract\", e.g., when used as in cssHooks\n\t\tMath.max( 0, matches[ 2 ] - ( subtract || 0 ) ) + ( matches[ 3 ] || \"px\" ) :\n\t\tvalue;\n}\n\nfunction boxModelAdjustment( elem, dimension, box, isBorderBox, styles, computedVal ) {\n\tvar i = dimension === \"width\" ? 1 : 0,\n\t\textra = 0,\n\t\tdelta = 0;\n\n\t// Adjustment may not be necessary\n\tif ( box === ( isBorderBox ? \"border\" : \"content\" ) ) {\n\t\treturn 0;\n\t}\n\n\tfor ( ; i < 4; i += 2 ) {\n\n\t\t// Both box models exclude margin\n\t\tif ( box === \"margin\" ) {\n\t\t\tdelta += jQuery.css( elem, box + cssExpand[ i ], true, styles );\n\t\t}\n\n\t\t// If we get here with a content-box, we're seeking \"padding\" or \"border\" or \"margin\"\n\t\tif ( !isBorderBox ) {\n\n\t\t\t// Add padding\n\t\t\tdelta += jQuery.css( elem, \"padding\" + cssExpand[ i ], true, styles );\n\n\t\t\t// For \"border\" or \"margin\", add border\n\t\t\tif ( box !== \"padding\" ) {\n\t\t\t\tdelta += jQuery.css( elem, \"border\" + cssExpand[ i ] + \"Width\", true, styles );\n\n\t\t\t// But still keep track of it otherwise\n\t\t\t} else {\n\t\t\t\textra += jQuery.css( elem, \"border\" + cssExpand[ i ] + \"Width\", true, styles );\n\t\t\t}\n\n\t\t// If we get here with a border-box (content + padding + border), we're seeking \"content\" or\n\t\t// \"padding\" or \"margin\"\n\t\t} else {\n\n\t\t\t// For \"content\", subtract padding\n\t\t\tif ( box === \"content\" ) {\n\t\t\t\tdelta -= jQuery.css( elem, \"padding\" + cssExpand[ i ], true, styles );\n\t\t\t}\n\n\t\t\t// For \"content\" or \"padding\", subtract border\n\t\t\tif ( box !== \"margin\" ) {\n\t\t\t\tdelta -= jQuery.css( elem, \"border\" + cssExpand[ i ] + \"Width\", true, styles );\n\t\t\t}\n\t\t}\n\t}\n\n\t// Account for positive content-box scroll gutter when requested by providing computedVal\n\tif ( !isBorderBox && computedVal >= 0 ) {\n\n\t\t// offsetWidth/offsetHeight is a rounded sum of content, padding, scroll gutter, and border\n\t\t// Assuming integer scroll gutter, subtract the rest and round down\n\t\tdelta += Math.max( 0, Math.ceil(\n\t\t\telem[ \"offset\" + dimension[ 0 ].toUpperCase() + dimension.slice( 1 ) ] -\n\t\t\tcomputedVal -\n\t\t\tdelta -\n\t\t\textra -\n\t\t\t0.5\n\t\t) );\n\t}\n\n\treturn delta;\n}\n\nfunction getWidthOrHeight( elem, dimension, extra ) {\n\n\t// Start with computed style\n\tvar styles = getStyles( elem ),\n\t\tval = curCSS( elem, dimension, styles ),\n\t\tisBorderBox = jQuery.css( elem, \"boxSizing\", false, styles ) === \"border-box\",\n\t\tvalueIsBorderBox = isBorderBox;\n\n\t// Support: Firefox <=54\n\t// Return a confounding non-pixel value or feign ignorance, as appropriate.\n\tif ( rnumnonpx.test( val ) ) {\n\t\tif ( !extra ) {\n\t\t\treturn val;\n\t\t}\n\t\tval = \"auto\";\n\t}\n\n\t// Check for style in case a browser which returns unreliable values\n\t// for getComputedStyle silently falls back to the reliable elem.style\n\tvalueIsBorderBox = valueIsBorderBox &&\n\t\t( support.boxSizingReliable() || val === elem.style[ dimension ] );\n\n\t// Fall back to offsetWidth/offsetHeight when value is \"auto\"\n\t// This happens for inline elements with no explicit setting (gh-3571)\n\t// Support: Android <=4.1 - 4.3 only\n\t// Also use offsetWidth/offsetHeight for misreported inline dimensions (gh-3602)\n\tif ( val === \"auto\" ||\n\t\t!parseFloat( val ) && jQuery.css( elem, \"display\", false, styles ) === \"inline\" ) {\n\n\t\tval = elem[ \"offset\" + dimension[ 0 ].toUpperCase() + dimension.slice( 1 ) ];\n\n\t\t// offsetWidth/offsetHeight provide border-box values\n\t\tvalueIsBorderBox = true;\n\t}\n\n\t// Normalize \"\" and auto\n\tval = parseFloat( val ) || 0;\n\n\t// Adjust for the element's box model\n\treturn ( val +\n\t\tboxModelAdjustment(\n\t\t\telem,\n\t\t\tdimension,\n\t\t\textra || ( isBorderBox ? \"border\" : \"content\" ),\n\t\t\tvalueIsBorderBox,\n\t\t\tstyles,\n\n\t\t\t// Provide the current computed size to request scroll gutter calculation (gh-3589)\n\t\t\tval\n\t\t)\n\t) + \"px\";\n}\n\njQuery.extend( {\n\n\t// Add in style property hooks for overriding the default\n\t// behavior of getting and setting a style property\n\tcssHooks: {\n\t\topacity: {\n\t\t\tget: function( elem, computed ) {\n\t\t\t\tif ( computed ) {\n\n\t\t\t\t\t// We should always get a number back from opacity\n\t\t\t\t\tvar ret = curCSS( elem, \"opacity\" );\n\t\t\t\t\treturn ret === \"\" ? \"1\" : ret;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t},\n\n\t// Don't automatically add \"px\" to these possibly-unitless properties\n\tcssNumber: {\n\t\t\"animationIterationCount\": true,\n\t\t\"columnCount\": true,\n\t\t\"fillOpacity\": true,\n\t\t\"flexGrow\": true,\n\t\t\"flexShrink\": true,\n\t\t\"fontWeight\": true,\n\t\t\"lineHeight\": true,\n\t\t\"opacity\": true,\n\t\t\"order\": true,\n\t\t\"orphans\": true,\n\t\t\"widows\": true,\n\t\t\"zIndex\": true,\n\t\t\"zoom\": true\n\t},\n\n\t// Add in properties whose names you wish to fix before\n\t// setting or getting the value\n\tcssProps: {},\n\n\t// Get and set the style property on a DOM Node\n\tstyle: function( elem, name, value, extra ) {\n\n\t\t// Don't set styles on text and comment nodes\n\t\tif ( !elem || elem.nodeType === 3 || elem.nodeType === 8 || !elem.style ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Make sure that we're working with the right name\n\t\tvar ret, type, hooks,\n\t\t\torigName = camelCase( name ),\n\t\t\tisCustomProp = rcustomProp.test( name ),\n\t\t\tstyle = elem.style;\n\n\t\t// Make sure that we're working with the right name. We don't\n\t\t// want to query the value if it is a CSS custom property\n\t\t// since they are user-defined.\n\t\tif ( !isCustomProp ) {\n\t\t\tname = finalPropName( origName );\n\t\t}\n\n\t\t// Gets hook for the prefixed version, then unprefixed version\n\t\thooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ];\n\n\t\t// Check if we're setting a value\n\t\tif ( value !== undefined ) {\n\t\t\ttype = typeof value;\n\n\t\t\t// Convert \"+=\" or \"-=\" to relative numbers (#7345)\n\t\t\tif ( type === \"string\" && ( ret = rcssNum.exec( value ) ) && ret[ 1 ] ) {\n\t\t\t\tvalue = adjustCSS( elem, name, ret );\n\n\t\t\t\t// Fixes bug #9237\n\t\t\t\ttype = \"number\";\n\t\t\t}\n\n\t\t\t// Make sure that null and NaN values aren't set (#7116)\n\t\t\tif ( value == null || value !== value ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// If a number was passed in, add the unit (except for certain CSS properties)\n\t\t\tif ( type === \"number\" ) {\n\t\t\t\tvalue += ret && ret[ 3 ] || ( jQuery.cssNumber[ origName ] ? \"\" : \"px\" );\n\t\t\t}\n\n\t\t\t// background-* props affect original clone's values\n\t\t\tif ( !support.clearCloneStyle && value === \"\" && name.indexOf( \"background\" ) === 0 ) {\n\t\t\t\tstyle[ name ] = \"inherit\";\n\t\t\t}\n\n\t\t\t// If a hook was provided, use that value, otherwise just set the specified value\n\t\t\tif ( !hooks || !( \"set\" in hooks ) ||\n\t\t\t\t( value = hooks.set( elem, value, extra ) ) !== undefined ) {\n\n\t\t\t\tif ( isCustomProp ) {\n\t\t\t\t\tstyle.setProperty( name, value );\n\t\t\t\t} else {\n\t\t\t\t\tstyle[ name ] = value;\n\t\t\t\t}\n\t\t\t}\n\n\t\t} else {\n\n\t\t\t// If a hook was provided get the non-computed value from there\n\t\t\tif ( hooks && \"get\" in hooks &&\n\t\t\t\t( ret = hooks.get( elem, false, extra ) ) !== undefined ) {\n\n\t\t\t\treturn ret;\n\t\t\t}\n\n\t\t\t// Otherwise just get the value from the style object\n\t\t\treturn style[ name ];\n\t\t}\n\t},\n\n\tcss: function( elem, name, extra, styles ) {\n\t\tvar val, num, hooks,\n\t\t\torigName = camelCase( name ),\n\t\t\tisCustomProp = rcustomProp.test( name );\n\n\t\t// Make sure that we're working with the right name. We don't\n\t\t// want to modify the value if it is a CSS custom property\n\t\t// since they are user-defined.\n\t\tif ( !isCustomProp ) {\n\t\t\tname = finalPropName( origName );\n\t\t}\n\n\t\t// Try prefixed name followed by the unprefixed name\n\t\thooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ];\n\n\t\t// If a hook was provided get the computed value from there\n\t\tif ( hooks && \"get\" in hooks ) {\n\t\t\tval = hooks.get( elem, true, extra );\n\t\t}\n\n\t\t// Otherwise, if a way to get the computed value exists, use that\n\t\tif ( val === undefined ) {\n\t\t\tval = curCSS( elem, name, styles );\n\t\t}\n\n\t\t// Convert \"normal\" to computed value\n\t\tif ( val === \"normal\" && name in cssNormalTransform ) {\n\t\t\tval = cssNormalTransform[ name ];\n\t\t}\n\n\t\t// Make numeric if forced or a qualifier was provided and val looks numeric\n\t\tif ( extra === \"\" || extra ) {\n\t\t\tnum = parseFloat( val );\n\t\t\treturn extra === true || isFinite( num ) ? num || 0 : val;\n\t\t}\n\n\t\treturn val;\n\t}\n} );\n\njQuery.each( [ \"height\", \"width\" ], function( i, dimension ) {\n\tjQuery.cssHooks[ dimension ] = {\n\t\tget: function( elem, computed, extra ) {\n\t\t\tif ( computed ) {\n\n\t\t\t\t// Certain elements can have dimension info if we invisibly show them\n\t\t\t\t// but it must have a current display style that would benefit\n\t\t\t\treturn rdisplayswap.test( jQuery.css( elem, \"display\" ) ) &&\n\n\t\t\t\t\t// Support: Safari 8+\n\t\t\t\t\t// Table columns in Safari have non-zero offsetWidth & zero\n\t\t\t\t\t// getBoundingClientRect().width unless display is changed.\n\t\t\t\t\t// Support: IE <=11 only\n\t\t\t\t\t// Running getBoundingClientRect on a disconnected node\n\t\t\t\t\t// in IE throws an error.\n\t\t\t\t\t( !elem.getClientRects().length || !elem.getBoundingClientRect().width ) ?\n\t\t\t\t\t\tswap( elem, cssShow, function() {\n\t\t\t\t\t\t\treturn getWidthOrHeight( elem, dimension, extra );\n\t\t\t\t\t\t} ) :\n\t\t\t\t\t\tgetWidthOrHeight( elem, dimension, extra );\n\t\t\t}\n\t\t},\n\n\t\tset: function( elem, value, extra ) {\n\t\t\tvar matches,\n\t\t\t\tstyles = getStyles( elem ),\n\t\t\t\tisBorderBox = jQuery.css( elem, \"boxSizing\", false, styles ) === \"border-box\",\n\t\t\t\tsubtract = extra && boxModelAdjustment(\n\t\t\t\t\telem,\n\t\t\t\t\tdimension,\n\t\t\t\t\textra,\n\t\t\t\t\tisBorderBox,\n\t\t\t\t\tstyles\n\t\t\t\t);\n\n\t\t\t// Account for unreliable border-box dimensions by comparing offset* to computed and\n\t\t\t// faking a content-box to get border and padding (gh-3699)\n\t\t\tif ( isBorderBox && support.scrollboxSize() === styles.position ) {\n\t\t\t\tsubtract -= Math.ceil(\n\t\t\t\t\telem[ \"offset\" + dimension[ 0 ].toUpperCase() + dimension.slice( 1 ) ] -\n\t\t\t\t\tparseFloat( styles[ dimension ] ) -\n\t\t\t\t\tboxModelAdjustment( elem, dimension, \"border\", false, styles ) -\n\t\t\t\t\t0.5\n\t\t\t\t);\n\t\t\t}\n\n\t\t\t// Convert to pixels if value adjustment is needed\n\t\t\tif ( subtract && ( matches = rcssNum.exec( value ) ) &&\n\t\t\t\t( matches[ 3 ] || \"px\" ) !== \"px\" ) {\n\n\t\t\t\telem.style[ dimension ] = value;\n\t\t\t\tvalue = jQuery.css( elem, dimension );\n\t\t\t}\n\n\t\t\treturn setPositiveNumber( elem, value, subtract );\n\t\t}\n\t};\n} );\n\njQuery.cssHooks.marginLeft = addGetHookIf( support.reliableMarginLeft,\n\tfunction( elem, computed ) {\n\t\tif ( computed ) {\n\t\t\treturn ( parseFloat( curCSS( elem, \"marginLeft\" ) ) ||\n\t\t\t\telem.getBoundingClientRect().left -\n\t\t\t\t\tswap( elem, { marginLeft: 0 }, function() {\n\t\t\t\t\t\treturn elem.getBoundingClientRect().left;\n\t\t\t\t\t} )\n\t\t\t\t) + \"px\";\n\t\t}\n\t}\n);\n\n// These hooks are used by animate to expand properties\njQuery.each( {\n\tmargin: \"\",\n\tpadding: \"\",\n\tborder: \"Width\"\n}, function( prefix, suffix ) {\n\tjQuery.cssHooks[ prefix + suffix ] = {\n\t\texpand: function( value ) {\n\t\t\tvar i = 0,\n\t\t\t\texpanded = {},\n\n\t\t\t\t// Assumes a single number if not a string\n\t\t\t\tparts = typeof value === \"string\" ? value.split( \" \" ) : [ value ];\n\n\t\t\tfor ( ; i < 4; i++ ) {\n\t\t\t\texpanded[ prefix + cssExpand[ i ] + suffix ] =\n\t\t\t\t\tparts[ i ] || parts[ i - 2 ] || parts[ 0 ];\n\t\t\t}\n\n\t\t\treturn expanded;\n\t\t}\n\t};\n\n\tif ( prefix !== \"margin\" ) {\n\t\tjQuery.cssHooks[ prefix + suffix ].set = setPositiveNumber;\n\t}\n} );\n\njQuery.fn.extend( {\n\tcss: function( name, value ) {\n\t\treturn access( this, function( elem, name, value ) {\n\t\t\tvar styles, len,\n\t\t\t\tmap = {},\n\t\t\t\ti = 0;\n\n\t\t\tif ( Array.isArray( name ) ) {\n\t\t\t\tstyles = getStyles( elem );\n\t\t\t\tlen = name.length;\n\n\t\t\t\tfor ( ; i < len; i++ ) {\n\t\t\t\t\tmap[ name[ i ] ] = jQuery.css( elem, name[ i ], false, styles );\n\t\t\t\t}\n\n\t\t\t\treturn map;\n\t\t\t}\n\n\t\t\treturn value !== undefined ?\n\t\t\t\tjQuery.style( elem, name, value ) :\n\t\t\t\tjQuery.css( elem, name );\n\t\t}, name, value, arguments.length > 1 );\n\t}\n} );\n\n\nfunction Tween( elem, options, prop, end, easing ) {\n\treturn new Tween.prototype.init( elem, options, prop, end, easing );\n}\njQuery.Tween = Tween;\n\nTween.prototype = {\n\tconstructor: Tween,\n\tinit: function( elem, options, prop, end, easing, unit ) {\n\t\tthis.elem = elem;\n\t\tthis.prop = prop;\n\t\tthis.easing = easing || jQuery.easing._default;\n\t\tthis.options = options;\n\t\tthis.start = this.now = this.cur();\n\t\tthis.end = end;\n\t\tthis.unit = unit || ( jQuery.cssNumber[ prop ] ? \"\" : \"px\" );\n\t},\n\tcur: function() {\n\t\tvar hooks = Tween.propHooks[ this.prop ];\n\n\t\treturn hooks && hooks.get ?\n\t\t\thooks.get( this ) :\n\t\t\tTween.propHooks._default.get( this );\n\t},\n\trun: function( percent ) {\n\t\tvar eased,\n\t\t\thooks = Tween.propHooks[ this.prop ];\n\n\t\tif ( this.options.duration ) {\n\t\t\tthis.pos = eased = jQuery.easing[ this.easing ](\n\t\t\t\tpercent, this.options.duration * percent, 0, 1, this.options.duration\n\t\t\t);\n\t\t} else {\n\t\t\tthis.pos = eased = percent;\n\t\t}\n\t\tthis.now = ( this.end - this.start ) * eased + this.start;\n\n\t\tif ( this.options.step ) {\n\t\t\tthis.options.step.call( this.elem, this.now, this );\n\t\t}\n\n\t\tif ( hooks && hooks.set ) {\n\t\t\thooks.set( this );\n\t\t} else {\n\t\t\tTween.propHooks._default.set( this );\n\t\t}\n\t\treturn this;\n\t}\n};\n\nTween.prototype.init.prototype = Tween.prototype;\n\nTween.propHooks = {\n\t_default: {\n\t\tget: function( tween ) {\n\t\t\tvar result;\n\n\t\t\t// Use a property on the element directly when it is not a DOM element,\n\t\t\t// or when there is no matching style property that exists.\n\t\t\tif ( tween.elem.nodeType !== 1 ||\n\t\t\t\ttween.elem[ tween.prop ] != null && tween.elem.style[ tween.prop ] == null ) {\n\t\t\t\treturn tween.elem[ tween.prop ];\n\t\t\t}\n\n\t\t\t// Passing an empty string as a 3rd parameter to .css will automatically\n\t\t\t// attempt a parseFloat and fallback to a string if the parse fails.\n\t\t\t// Simple values such as \"10px\" are parsed to Float;\n\t\t\t// complex values such as \"rotate(1rad)\" are returned as-is.\n\t\t\tresult = jQuery.css( tween.elem, tween.prop, \"\" );\n\n\t\t\t// Empty strings, null, undefined and \"auto\" are converted to 0.\n\t\t\treturn !result || result === \"auto\" ? 0 : result;\n\t\t},\n\t\tset: function( tween ) {\n\n\t\t\t// Use step hook for back compat.\n\t\t\t// Use cssHook if its there.\n\t\t\t// Use .style if available and use plain properties where available.\n\t\t\tif ( jQuery.fx.step[ tween.prop ] ) {\n\t\t\t\tjQuery.fx.step[ tween.prop ]( tween );\n\t\t\t} else if ( tween.elem.nodeType === 1 &&\n\t\t\t\t( tween.elem.style[ jQuery.cssProps[ tween.prop ] ] != null ||\n\t\t\t\t\tjQuery.cssHooks[ tween.prop ] ) ) {\n\t\t\t\tjQuery.style( tween.elem, tween.prop, tween.now + tween.unit );\n\t\t\t} else {\n\t\t\t\ttween.elem[ tween.prop ] = tween.now;\n\t\t\t}\n\t\t}\n\t}\n};\n\n// Support: IE <=9 only\n// Panic based approach to setting things on disconnected nodes\nTween.propHooks.scrollTop = Tween.propHooks.scrollLeft = {\n\tset: function( tween ) {\n\t\tif ( tween.elem.nodeType && tween.elem.parentNode ) {\n\t\t\ttween.elem[ tween.prop ] = tween.now;\n\t\t}\n\t}\n};\n\njQuery.easing = {\n\tlinear: function( p ) {\n\t\treturn p;\n\t},\n\tswing: function( p ) {\n\t\treturn 0.5 - Math.cos( p * Math.PI ) / 2;\n\t},\n\t_default: \"swing\"\n};\n\njQuery.fx = Tween.prototype.init;\n\n// Back compat <1.8 extension point\njQuery.fx.step = {};\n\n\n\n\nvar\n\tfxNow, inProgress,\n\trfxtypes = /^(?:toggle|show|hide)$/,\n\trrun = /queueHooks$/;\n\nfunction schedule() {\n\tif ( inProgress ) {\n\t\tif ( document.hidden === false && window.requestAnimationFrame ) {\n\t\t\twindow.requestAnimationFrame( schedule );\n\t\t} else {\n\t\t\twindow.setTimeout( schedule, jQuery.fx.interval );\n\t\t}\n\n\t\tjQuery.fx.tick();\n\t}\n}\n\n// Animations created synchronously will run synchronously\nfunction createFxNow() {\n\twindow.setTimeout( function() {\n\t\tfxNow = undefined;\n\t} );\n\treturn ( fxNow = Date.now() );\n}\n\n// Generate parameters to create a standard animation\nfunction genFx( type, includeWidth ) {\n\tvar which,\n\t\ti = 0,\n\t\tattrs = { height: type };\n\n\t// If we include width, step value is 1 to do all cssExpand values,\n\t// otherwise step value is 2 to skip over Left and Right\n\tincludeWidth = includeWidth ? 1 : 0;\n\tfor ( ; i < 4; i += 2 - includeWidth ) {\n\t\twhich = cssExpand[ i ];\n\t\tattrs[ \"margin\" + which ] = attrs[ \"padding\" + which ] = type;\n\t}\n\n\tif ( includeWidth ) {\n\t\tattrs.opacity = attrs.width = type;\n\t}\n\n\treturn attrs;\n}\n\nfunction createTween( value, prop, animation ) {\n\tvar tween,\n\t\tcollection = ( Animation.tweeners[ prop ] || [] ).concat( Animation.tweeners[ \"*\" ] ),\n\t\tindex = 0,\n\t\tlength = collection.length;\n\tfor ( ; index < length; index++ ) {\n\t\tif ( ( tween = collection[ index ].call( animation, prop, value ) ) ) {\n\n\t\t\t// We're done with this property\n\t\t\treturn tween;\n\t\t}\n\t}\n}\n\nfunction defaultPrefilter( elem, props, opts ) {\n\tvar prop, value, toggle, hooks, oldfire, propTween, restoreDisplay, display,\n\t\tisBox = \"width\" in props || \"height\" in props,\n\t\tanim = this,\n\t\torig = {},\n\t\tstyle = elem.style,\n\t\thidden = elem.nodeType && isHiddenWithinTree( elem ),\n\t\tdataShow = dataPriv.get( elem, \"fxshow\" );\n\n\t// Queue-skipping animations hijack the fx hooks\n\tif ( !opts.queue ) {\n\t\thooks = jQuery._queueHooks( elem, \"fx\" );\n\t\tif ( hooks.unqueued == null ) {\n\t\t\thooks.unqueued = 0;\n\t\t\toldfire = hooks.empty.fire;\n\t\t\thooks.empty.fire = function() {\n\t\t\t\tif ( !hooks.unqueued ) {\n\t\t\t\t\toldfire();\n\t\t\t\t}\n\t\t\t};\n\t\t}\n\t\thooks.unqueued++;\n\n\t\tanim.always( function() {\n\n\t\t\t// Ensure the complete handler is called before this completes\n\t\t\tanim.always( function() {\n\t\t\t\thooks.unqueued--;\n\t\t\t\tif ( !jQuery.queue( elem, \"fx\" ).length ) {\n\t\t\t\t\thooks.empty.fire();\n\t\t\t\t}\n\t\t\t} );\n\t\t} );\n\t}\n\n\t// Detect show/hide animations\n\tfor ( prop in props ) {\n\t\tvalue = props[ prop ];\n\t\tif ( rfxtypes.test( value ) ) {\n\t\t\tdelete props[ prop ];\n\t\t\ttoggle = toggle || value === \"toggle\";\n\t\t\tif ( value === ( hidden ? \"hide\" : \"show\" ) ) {\n\n\t\t\t\t// Pretend to be hidden if this is a \"show\" and\n\t\t\t\t// there is still data from a stopped show/hide\n\t\t\t\tif ( value === \"show\" && dataShow && dataShow[ prop ] !== undefined ) {\n\t\t\t\t\thidden = true;\n\n\t\t\t\t// Ignore all other no-op show/hide data\n\t\t\t\t} else {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t}\n\t\t\torig[ prop ] = dataShow && dataShow[ prop ] || jQuery.style( elem, prop );\n\t\t}\n\t}\n\n\t// Bail out if this is a no-op like .hide().hide()\n\tpropTween = !jQuery.isEmptyObject( props );\n\tif ( !propTween && jQuery.isEmptyObject( orig ) ) {\n\t\treturn;\n\t}\n\n\t// Restrict \"overflow\" and \"display\" styles during box animations\n\tif ( isBox && elem.nodeType === 1 ) {\n\n\t\t// Support: IE <=9 - 11, Edge 12 - 15\n\t\t// Record all 3 overflow attributes because IE does not infer the shorthand\n\t\t// from identically-valued overflowX and overflowY and Edge just mirrors\n\t\t// the overflowX value there.\n\t\topts.overflow = [ style.overflow, style.overflowX, style.overflowY ];\n\n\t\t// Identify a display type, preferring old show/hide data over the CSS cascade\n\t\trestoreDisplay = dataShow && dataShow.display;\n\t\tif ( restoreDisplay == null ) {\n\t\t\trestoreDisplay = dataPriv.get( elem, \"display\" );\n\t\t}\n\t\tdisplay = jQuery.css( elem, \"display\" );\n\t\tif ( display === \"none\" ) {\n\t\t\tif ( restoreDisplay ) {\n\t\t\t\tdisplay = restoreDisplay;\n\t\t\t} else {\n\n\t\t\t\t// Get nonempty value(s) by temporarily forcing visibility\n\t\t\t\tshowHide( [ elem ], true );\n\t\t\t\trestoreDisplay = elem.style.display || restoreDisplay;\n\t\t\t\tdisplay = jQuery.css( elem, \"display\" );\n\t\t\t\tshowHide( [ elem ] );\n\t\t\t}\n\t\t}\n\n\t\t// Animate inline elements as inline-block\n\t\tif ( display === \"inline\" || display === \"inline-block\" && restoreDisplay != null ) {\n\t\t\tif ( jQuery.css( elem, \"float\" ) === \"none\" ) {\n\n\t\t\t\t// Restore the original display value at the end of pure show/hide animations\n\t\t\t\tif ( !propTween ) {\n\t\t\t\t\tanim.done( function() {\n\t\t\t\t\t\tstyle.display = restoreDisplay;\n\t\t\t\t\t} );\n\t\t\t\t\tif ( restoreDisplay == null ) {\n\t\t\t\t\t\tdisplay = style.display;\n\t\t\t\t\t\trestoreDisplay = display === \"none\" ? \"\" : display;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tstyle.display = \"inline-block\";\n\t\t\t}\n\t\t}\n\t}\n\n\tif ( opts.overflow ) {\n\t\tstyle.overflow = \"hidden\";\n\t\tanim.always( function() {\n\t\t\tstyle.overflow = opts.overflow[ 0 ];\n\t\t\tstyle.overflowX = opts.overflow[ 1 ];\n\t\t\tstyle.overflowY = opts.overflow[ 2 ];\n\t\t} );\n\t}\n\n\t// Implement show/hide animations\n\tpropTween = false;\n\tfor ( prop in orig ) {\n\n\t\t// General show/hide setup for this element animation\n\t\tif ( !propTween ) {\n\t\t\tif ( dataShow ) {\n\t\t\t\tif ( \"hidden\" in dataShow ) {\n\t\t\t\t\thidden = dataShow.hidden;\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tdataShow = dataPriv.access( elem, \"fxshow\", { display: restoreDisplay } );\n\t\t\t}\n\n\t\t\t// Store hidden/visible for toggle so `.stop().toggle()` \"reverses\"\n\t\t\tif ( toggle ) {\n\t\t\t\tdataShow.hidden = !hidden;\n\t\t\t}\n\n\t\t\t// Show elements before animating them\n\t\t\tif ( hidden ) {\n\t\t\t\tshowHide( [ elem ], true );\n\t\t\t}\n\n\t\t\t/* eslint-disable no-loop-func */\n\n\t\t\tanim.done( function() {\n\n\t\t\t/* eslint-enable no-loop-func */\n\n\t\t\t\t// The final step of a \"hide\" animation is actually hiding the element\n\t\t\t\tif ( !hidden ) {\n\t\t\t\t\tshowHide( [ elem ] );\n\t\t\t\t}\n\t\t\t\tdataPriv.remove( elem, \"fxshow\" );\n\t\t\t\tfor ( prop in orig ) {\n\t\t\t\t\tjQuery.style( elem, prop, orig[ prop ] );\n\t\t\t\t}\n\t\t\t} );\n\t\t}\n\n\t\t// Per-property setup\n\t\tpropTween = createTween( hidden ? dataShow[ prop ] : 0, prop, anim );\n\t\tif ( !( prop in dataShow ) ) {\n\t\t\tdataShow[ prop ] = propTween.start;\n\t\t\tif ( hidden ) {\n\t\t\t\tpropTween.end = propTween.start;\n\t\t\t\tpropTween.start = 0;\n\t\t\t}\n\t\t}\n\t}\n}\n\nfunction propFilter( props, specialEasing ) {\n\tvar index, name, easing, value, hooks;\n\n\t// camelCase, specialEasing and expand cssHook pass\n\tfor ( index in props ) {\n\t\tname = camelCase( index );\n\t\teasing = specialEasing[ name ];\n\t\tvalue = props[ index ];\n\t\tif ( Array.isArray( value ) ) {\n\t\t\teasing = value[ 1 ];\n\t\t\tvalue = props[ index ] = value[ 0 ];\n\t\t}\n\n\t\tif ( index !== name ) {\n\t\t\tprops[ name ] = value;\n\t\t\tdelete props[ index ];\n\t\t}\n\n\t\thooks = jQuery.cssHooks[ name ];\n\t\tif ( hooks && \"expand\" in hooks ) {\n\t\t\tvalue = hooks.expand( value );\n\t\t\tdelete props[ name ];\n\n\t\t\t// Not quite $.extend, this won't overwrite existing keys.\n\t\t\t// Reusing 'index' because we have the correct \"name\"\n\t\t\tfor ( index in value ) {\n\t\t\t\tif ( !( index in props ) ) {\n\t\t\t\t\tprops[ index ] = value[ index ];\n\t\t\t\t\tspecialEasing[ index ] = easing;\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\tspecialEasing[ name ] = easing;\n\t\t}\n\t}\n}\n\nfunction Animation( elem, properties, options ) {\n\tvar result,\n\t\tstopped,\n\t\tindex = 0,\n\t\tlength = Animation.prefilters.length,\n\t\tdeferred = jQuery.Deferred().always( function() {\n\n\t\t\t// Don't match elem in the :animated selector\n\t\t\tdelete tick.elem;\n\t\t} ),\n\t\ttick = function() {\n\t\t\tif ( stopped ) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\tvar currentTime = fxNow || createFxNow(),\n\t\t\t\tremaining = Math.max( 0, animation.startTime + animation.duration - currentTime ),\n\n\t\t\t\t// Support: Android 2.3 only\n\t\t\t\t// Archaic crash bug won't allow us to use `1 - ( 0.5 || 0 )` (#12497)\n\t\t\t\ttemp = remaining / animation.duration || 0,\n\t\t\t\tpercent = 1 - temp,\n\t\t\t\tindex = 0,\n\t\t\t\tlength = animation.tweens.length;\n\n\t\t\tfor ( ; index < length; index++ ) {\n\t\t\t\tanimation.tweens[ index ].run( percent );\n\t\t\t}\n\n\t\t\tdeferred.notifyWith( elem, [ animation, percent, remaining ] );\n\n\t\t\t// If there's more to do, yield\n\t\t\tif ( percent < 1 && length ) {\n\t\t\t\treturn remaining;\n\t\t\t}\n\n\t\t\t// If this was an empty animation, synthesize a final progress notification\n\t\t\tif ( !length ) {\n\t\t\t\tdeferred.notifyWith( elem, [ animation, 1, 0 ] );\n\t\t\t}\n\n\t\t\t// Resolve the animation and report its conclusion\n\t\t\tdeferred.resolveWith( elem, [ animation ] );\n\t\t\treturn false;\n\t\t},\n\t\tanimation = deferred.promise( {\n\t\t\telem: elem,\n\t\t\tprops: jQuery.extend( {}, properties ),\n\t\t\topts: jQuery.extend( true, {\n\t\t\t\tspecialEasing: {},\n\t\t\t\teasing: jQuery.easing._default\n\t\t\t}, options ),\n\t\t\toriginalProperties: properties,\n\t\t\toriginalOptions: options,\n\t\t\tstartTime: fxNow || createFxNow(),\n\t\t\tduration: options.duration,\n\t\t\ttweens: [],\n\t\t\tcreateTween: function( prop, end ) {\n\t\t\t\tvar tween = jQuery.Tween( elem, animation.opts, prop, end,\n\t\t\t\t\t\tanimation.opts.specialEasing[ prop ] || animation.opts.easing );\n\t\t\t\tanimation.tweens.push( tween );\n\t\t\t\treturn tween;\n\t\t\t},\n\t\t\tstop: function( gotoEnd ) {\n\t\t\t\tvar index = 0,\n\n\t\t\t\t\t// If we are going to the end, we want to run all the tweens\n\t\t\t\t\t// otherwise we skip this part\n\t\t\t\t\tlength = gotoEnd ? animation.tweens.length : 0;\n\t\t\t\tif ( stopped ) {\n\t\t\t\t\treturn this;\n\t\t\t\t}\n\t\t\t\tstopped = true;\n\t\t\t\tfor ( ; index < length; index++ ) {\n\t\t\t\t\tanimation.tweens[ index ].run( 1 );\n\t\t\t\t}\n\n\t\t\t\t// Resolve when we played the last frame; otherwise, reject\n\t\t\t\tif ( gotoEnd ) {\n\t\t\t\t\tdeferred.notifyWith( elem, [ animation, 1, 0 ] );\n\t\t\t\t\tdeferred.resolveWith( elem, [ animation, gotoEnd ] );\n\t\t\t\t} else {\n\t\t\t\t\tdeferred.rejectWith( elem, [ animation, gotoEnd ] );\n\t\t\t\t}\n\t\t\t\treturn this;\n\t\t\t}\n\t\t} ),\n\t\tprops = animation.props;\n\n\tpropFilter( props, animation.opts.specialEasing );\n\n\tfor ( ; index < length; index++ ) {\n\t\tresult = Animation.prefilters[ index ].call( animation, elem, props, animation.opts );\n\t\tif ( result ) {\n\t\t\tif ( isFunction( result.stop ) ) {\n\t\t\t\tjQuery._queueHooks( animation.elem, animation.opts.queue ).stop =\n\t\t\t\t\tresult.stop.bind( result );\n\t\t\t}\n\t\t\treturn result;\n\t\t}\n\t}\n\n\tjQuery.map( props, createTween, animation );\n\n\tif ( isFunction( animation.opts.start ) ) {\n\t\tanimation.opts.start.call( elem, animation );\n\t}\n\n\t// Attach callbacks from options\n\tanimation\n\t\t.progress( animation.opts.progress )\n\t\t.done( animation.opts.done, animation.opts.complete )\n\t\t.fail( animation.opts.fail )\n\t\t.always( animation.opts.always );\n\n\tjQuery.fx.timer(\n\t\tjQuery.extend( tick, {\n\t\t\telem: elem,\n\t\t\tanim: animation,\n\t\t\tqueue: animation.opts.queue\n\t\t} )\n\t);\n\n\treturn animation;\n}\n\njQuery.Animation = jQuery.extend( Animation, {\n\n\ttweeners: {\n\t\t\"*\": [ function( prop, value ) {\n\t\t\tvar tween = this.createTween( prop, value );\n\t\t\tadjustCSS( tween.elem, prop, rcssNum.exec( value ), tween );\n\t\t\treturn tween;\n\t\t} ]\n\t},\n\n\ttweener: function( props, callback ) {\n\t\tif ( isFunction( props ) ) {\n\t\t\tcallback = props;\n\t\t\tprops = [ \"*\" ];\n\t\t} else {\n\t\t\tprops = props.match( rnothtmlwhite );\n\t\t}\n\n\t\tvar prop,\n\t\t\tindex = 0,\n\t\t\tlength = props.length;\n\n\t\tfor ( ; index < length; index++ ) {\n\t\t\tprop = props[ index ];\n\t\t\tAnimation.tweeners[ prop ] = Animation.tweeners[ prop ] || [];\n\t\t\tAnimation.tweeners[ prop ].unshift( callback );\n\t\t}\n\t},\n\n\tprefilters: [ defaultPrefilter ],\n\n\tprefilter: function( callback, prepend ) {\n\t\tif ( prepend ) {\n\t\t\tAnimation.prefilters.unshift( callback );\n\t\t} else {\n\t\t\tAnimation.prefilters.push( callback );\n\t\t}\n\t}\n} );\n\njQuery.speed = function( speed, easing, fn ) {\n\tvar opt = speed && typeof speed === \"object\" ? jQuery.extend( {}, speed ) : {\n\t\tcomplete: fn || !fn && easing ||\n\t\t\tisFunction( speed ) && speed,\n\t\tduration: speed,\n\t\teasing: fn && easing || easing && !isFunction( easing ) && easing\n\t};\n\n\t// Go to the end state if fx are off\n\tif ( jQuery.fx.off ) {\n\t\topt.duration = 0;\n\n\t} else {\n\t\tif ( typeof opt.duration !== \"number\" ) {\n\t\t\tif ( opt.duration in jQuery.fx.speeds ) {\n\t\t\t\topt.duration = jQuery.fx.speeds[ opt.duration ];\n\n\t\t\t} else {\n\t\t\t\topt.duration = jQuery.fx.speeds._default;\n\t\t\t}\n\t\t}\n\t}\n\n\t// Normalize opt.queue - true/undefined/null -> \"fx\"\n\tif ( opt.queue == null || opt.queue === true ) {\n\t\topt.queue = \"fx\";\n\t}\n\n\t// Queueing\n\topt.old = opt.complete;\n\n\topt.complete = function() {\n\t\tif ( isFunction( opt.old ) ) {\n\t\t\topt.old.call( this );\n\t\t}\n\n\t\tif ( opt.queue ) {\n\t\t\tjQuery.dequeue( this, opt.queue );\n\t\t}\n\t};\n\n\treturn opt;\n};\n\njQuery.fn.extend( {\n\tfadeTo: function( speed, to, easing, callback ) {\n\n\t\t// Show any hidden elements after setting opacity to 0\n\t\treturn this.filter( isHiddenWithinTree ).css( \"opacity\", 0 ).show()\n\n\t\t\t// Animate to the value specified\n\t\t\t.end().animate( { opacity: to }, speed, easing, callback );\n\t},\n\tanimate: function( prop, speed, easing, callback ) {\n\t\tvar empty = jQuery.isEmptyObject( prop ),\n\t\t\toptall = jQuery.speed( speed, easing, callback ),\n\t\t\tdoAnimation = function() {\n\n\t\t\t\t// Operate on a copy of prop so per-property easing won't be lost\n\t\t\t\tvar anim = Animation( this, jQuery.extend( {}, prop ), optall );\n\n\t\t\t\t// Empty animations, or finishing resolves immediately\n\t\t\t\tif ( empty || dataPriv.get( this, \"finish\" ) ) {\n\t\t\t\t\tanim.stop( true );\n\t\t\t\t}\n\t\t\t};\n\t\t\tdoAnimation.finish = doAnimation;\n\n\t\treturn empty || optall.queue === false ?\n\t\t\tthis.each( doAnimation ) :\n\t\t\tthis.queue( optall.queue, doAnimation );\n\t},\n\tstop: function( type, clearQueue, gotoEnd ) {\n\t\tvar stopQueue = function( hooks ) {\n\t\t\tvar stop = hooks.stop;\n\t\t\tdelete hooks.stop;\n\t\t\tstop( gotoEnd );\n\t\t};\n\n\t\tif ( typeof type !== \"string\" ) {\n\t\t\tgotoEnd = clearQueue;\n\t\t\tclearQueue = type;\n\t\t\ttype = undefined;\n\t\t}\n\t\tif ( clearQueue && type !== false ) {\n\t\t\tthis.queue( type || \"fx\", [] );\n\t\t}\n\n\t\treturn this.each( function() {\n\t\t\tvar dequeue = true,\n\t\t\t\tindex = type != null && type + \"queueHooks\",\n\t\t\t\ttimers = jQuery.timers,\n\t\t\t\tdata = dataPriv.get( this );\n\n\t\t\tif ( index ) {\n\t\t\t\tif ( data[ index ] && data[ index ].stop ) {\n\t\t\t\t\tstopQueue( data[ index ] );\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tfor ( index in data ) {\n\t\t\t\t\tif ( data[ index ] && data[ index ].stop && rrun.test( index ) ) {\n\t\t\t\t\t\tstopQueue( data[ index ] );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tfor ( index = timers.length; index--; ) {\n\t\t\t\tif ( timers[ index ].elem === this &&\n\t\t\t\t\t( type == null || timers[ index ].queue === type ) ) {\n\n\t\t\t\t\ttimers[ index ].anim.stop( gotoEnd );\n\t\t\t\t\tdequeue = false;\n\t\t\t\t\ttimers.splice( index, 1 );\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Start the next in the queue if the last step wasn't forced.\n\t\t\t// Timers currently will call their complete callbacks, which\n\t\t\t// will dequeue but only if they were gotoEnd.\n\t\t\tif ( dequeue || !gotoEnd ) {\n\t\t\t\tjQuery.dequeue( this, type );\n\t\t\t}\n\t\t} );\n\t},\n\tfinish: function( type ) {\n\t\tif ( type !== false ) {\n\t\t\ttype = type || \"fx\";\n\t\t}\n\t\treturn this.each( function() {\n\t\t\tvar index,\n\t\t\t\tdata = dataPriv.get( this ),\n\t\t\t\tqueue = data[ type + \"queue\" ],\n\t\t\t\thooks = data[ type + \"queueHooks\" ],\n\t\t\t\ttimers = jQuery.timers,\n\t\t\t\tlength = queue ? queue.length : 0;\n\n\t\t\t// Enable finishing flag on private data\n\t\t\tdata.finish = true;\n\n\t\t\t// Empty the queue first\n\t\t\tjQuery.queue( this, type, [] );\n\n\t\t\tif ( hooks && hooks.stop ) {\n\t\t\t\thooks.stop.call( this, true );\n\t\t\t}\n\n\t\t\t// Look for any active animations, and finish them\n\t\t\tfor ( index = timers.length; index--; ) {\n\t\t\t\tif ( timers[ index ].elem === this && timers[ index ].queue === type ) {\n\t\t\t\t\ttimers[ index ].anim.stop( true );\n\t\t\t\t\ttimers.splice( index, 1 );\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Look for any animations in the old queue and finish them\n\t\t\tfor ( index = 0; index < length; index++ ) {\n\t\t\t\tif ( queue[ index ] && queue[ index ].finish ) {\n\t\t\t\t\tqueue[ index ].finish.call( this );\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Turn off finishing flag\n\t\t\tdelete data.finish;\n\t\t} );\n\t}\n} );\n\njQuery.each( [ \"toggle\", \"show\", \"hide\" ], function( i, name ) {\n\tvar cssFn = jQuery.fn[ name ];\n\tjQuery.fn[ name ] = function( speed, easing, callback ) {\n\t\treturn speed == null || typeof speed === \"boolean\" ?\n\t\t\tcssFn.apply( this, arguments ) :\n\t\t\tthis.animate( genFx( name, true ), speed, easing, callback );\n\t};\n} );\n\n// Generate shortcuts for custom animations\njQuery.each( {\n\tslideDown: genFx( \"show\" ),\n\tslideUp: genFx( \"hide\" ),\n\tslideToggle: genFx( \"toggle\" ),\n\tfadeIn: { opacity: \"show\" },\n\tfadeOut: { opacity: \"hide\" },\n\tfadeToggle: { opacity: \"toggle\" }\n}, function( name, props ) {\n\tjQuery.fn[ name ] = function( speed, easing, callback ) {\n\t\treturn this.animate( props, speed, easing, callback );\n\t};\n} );\n\njQuery.timers = [];\njQuery.fx.tick = function() {\n\tvar timer,\n\t\ti = 0,\n\t\ttimers = jQuery.timers;\n\n\tfxNow = Date.now();\n\n\tfor ( ; i < timers.length; i++ ) {\n\t\ttimer = timers[ i ];\n\n\t\t// Run the timer and safely remove it when done (allowing for external removal)\n\t\tif ( !timer() && timers[ i ] === timer ) {\n\t\t\ttimers.splice( i--, 1 );\n\t\t}\n\t}\n\n\tif ( !timers.length ) {\n\t\tjQuery.fx.stop();\n\t}\n\tfxNow = undefined;\n};\n\njQuery.fx.timer = function( timer ) {\n\tjQuery.timers.push( timer );\n\tjQuery.fx.start();\n};\n\njQuery.fx.interval = 13;\njQuery.fx.start = function() {\n\tif ( inProgress ) {\n\t\treturn;\n\t}\n\n\tinProgress = true;\n\tschedule();\n};\n\njQuery.fx.stop = function() {\n\tinProgress = null;\n};\n\njQuery.fx.speeds = {\n\tslow: 600,\n\tfast: 200,\n\n\t// Default speed\n\t_default: 400\n};\n\n\n// Based off of the plugin by Clint Helfers, with permission.\n// https://web.archive.org/web/20100324014747/http://blindsignals.com/index.php/2009/07/jquery-delay/\njQuery.fn.delay = function( time, type ) {\n\ttime = jQuery.fx ? jQuery.fx.speeds[ time ] || time : time;\n\ttype = type || \"fx\";\n\n\treturn this.queue( type, function( next, hooks ) {\n\t\tvar timeout = window.setTimeout( next, time );\n\t\thooks.stop = function() {\n\t\t\twindow.clearTimeout( timeout );\n\t\t};\n\t} );\n};\n\n\n( function() {\n\tvar input = document.createElement( \"input\" ),\n\t\tselect = document.createElement( \"select\" ),\n\t\topt = select.appendChild( document.createElement( \"option\" ) );\n\n\tinput.type = \"checkbox\";\n\n\t// Support: Android <=4.3 only\n\t// Default value for a checkbox should be \"on\"\n\tsupport.checkOn = input.value !== \"\";\n\n\t// Support: IE <=11 only\n\t// Must access selectedIndex to make default options select\n\tsupport.optSelected = opt.selected;\n\n\t// Support: IE <=11 only\n\t// An input loses its value after becoming a radio\n\tinput = document.createElement( \"input\" );\n\tinput.value = \"t\";\n\tinput.type = \"radio\";\n\tsupport.radioValue = input.value === \"t\";\n} )();\n\n\nvar boolHook,\n\tattrHandle = jQuery.expr.attrHandle;\n\njQuery.fn.extend( {\n\tattr: function( name, value ) {\n\t\treturn access( this, jQuery.attr, name, value, arguments.length > 1 );\n\t},\n\n\tremoveAttr: function( name ) {\n\t\treturn this.each( function() {\n\t\t\tjQuery.removeAttr( this, name );\n\t\t} );\n\t}\n} );\n\njQuery.extend( {\n\tattr: function( elem, name, value ) {\n\t\tvar ret, hooks,\n\t\t\tnType = elem.nodeType;\n\n\t\t// Don't get/set attributes on text, comment and attribute nodes\n\t\tif ( nType === 3 || nType === 8 || nType === 2 ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Fallback to prop when attributes are not supported\n\t\tif ( typeof elem.getAttribute === \"undefined\" ) {\n\t\t\treturn jQuery.prop( elem, name, value );\n\t\t}\n\n\t\t// Attribute hooks are determined by the lowercase version\n\t\t// Grab necessary hook if one is defined\n\t\tif ( nType !== 1 || !jQuery.isXMLDoc( elem ) ) {\n\t\t\thooks = jQuery.attrHooks[ name.toLowerCase() ] ||\n\t\t\t\t( jQuery.expr.match.bool.test( name ) ? boolHook : undefined );\n\t\t}\n\n\t\tif ( value !== undefined ) {\n\t\t\tif ( value === null ) {\n\t\t\t\tjQuery.removeAttr( elem, name );\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif ( hooks && \"set\" in hooks &&\n\t\t\t\t( ret = hooks.set( elem, value, name ) ) !== undefined ) {\n\t\t\t\treturn ret;\n\t\t\t}\n\n\t\t\telem.setAttribute( name, value + \"\" );\n\t\t\treturn value;\n\t\t}\n\n\t\tif ( hooks && \"get\" in hooks && ( ret = hooks.get( elem, name ) ) !== null ) {\n\t\t\treturn ret;\n\t\t}\n\n\t\tret = jQuery.find.attr( elem, name );\n\n\t\t// Non-existent attributes return null, we normalize to undefined\n\t\treturn ret == null ? undefined : ret;\n\t},\n\n\tattrHooks: {\n\t\ttype: {\n\t\t\tset: function( elem, value ) {\n\t\t\t\tif ( !support.radioValue && value === \"radio\" &&\n\t\t\t\t\tnodeName( elem, \"input\" ) ) {\n\t\t\t\t\tvar val = elem.value;\n\t\t\t\t\telem.setAttribute( \"type\", value );\n\t\t\t\t\tif ( val ) {\n\t\t\t\t\t\telem.value = val;\n\t\t\t\t\t}\n\t\t\t\t\treturn value;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t},\n\n\tremoveAttr: function( elem, value ) {\n\t\tvar name,\n\t\t\ti = 0,\n\n\t\t\t// Attribute names can contain non-HTML whitespace characters\n\t\t\t// https://html.spec.whatwg.org/multipage/syntax.html#attributes-2\n\t\t\tattrNames = value && value.match( rnothtmlwhite );\n\n\t\tif ( attrNames && elem.nodeType === 1 ) {\n\t\t\twhile ( ( name = attrNames[ i++ ] ) ) {\n\t\t\t\telem.removeAttribute( name );\n\t\t\t}\n\t\t}\n\t}\n} );\n\n// Hooks for boolean attributes\nboolHook = {\n\tset: function( elem, value, name ) {\n\t\tif ( value === false ) {\n\n\t\t\t// Remove boolean attributes when set to false\n\t\t\tjQuery.removeAttr( elem, name );\n\t\t} else {\n\t\t\telem.setAttribute( name, name );\n\t\t}\n\t\treturn name;\n\t}\n};\n\njQuery.each( jQuery.expr.match.bool.source.match( /\\w+/g ), function( i, name ) {\n\tvar getter = attrHandle[ name ] || jQuery.find.attr;\n\n\tattrHandle[ name ] = function( elem, name, isXML ) {\n\t\tvar ret, handle,\n\t\t\tlowercaseName = name.toLowerCase();\n\n\t\tif ( !isXML ) {\n\n\t\t\t// Avoid an infinite loop by temporarily removing this function from the getter\n\t\t\thandle = attrHandle[ lowercaseName ];\n\t\t\tattrHandle[ lowercaseName ] = ret;\n\t\t\tret = getter( elem, name, isXML ) != null ?\n\t\t\t\tlowercaseName :\n\t\t\t\tnull;\n\t\t\tattrHandle[ lowercaseName ] = handle;\n\t\t}\n\t\treturn ret;\n\t};\n} );\n\n\n\n\nvar rfocusable = /^(?:input|select|textarea|button)$/i,\n\trclickable = /^(?:a|area)$/i;\n\njQuery.fn.extend( {\n\tprop: function( name, value ) {\n\t\treturn access( this, jQuery.prop, name, value, arguments.length > 1 );\n\t},\n\n\tremoveProp: function( name ) {\n\t\treturn this.each( function() {\n\t\t\tdelete this[ jQuery.propFix[ name ] || name ];\n\t\t} );\n\t}\n} );\n\njQuery.extend( {\n\tprop: function( elem, name, value ) {\n\t\tvar ret, hooks,\n\t\t\tnType = elem.nodeType;\n\n\t\t// Don't get/set properties on text, comment and attribute nodes\n\t\tif ( nType === 3 || nType === 8 || nType === 2 ) {\n\t\t\treturn;\n\t\t}\n\n\t\tif ( nType !== 1 || !jQuery.isXMLDoc( elem ) ) {\n\n\t\t\t// Fix name and attach hooks\n\t\t\tname = jQuery.propFix[ name ] || name;\n\t\t\thooks = jQuery.propHooks[ name ];\n\t\t}\n\n\t\tif ( value !== undefined ) {\n\t\t\tif ( hooks && \"set\" in hooks &&\n\t\t\t\t( ret = hooks.set( elem, value, name ) ) !== undefined ) {\n\t\t\t\treturn ret;\n\t\t\t}\n\n\t\t\treturn ( elem[ name ] = value );\n\t\t}\n\n\t\tif ( hooks && \"get\" in hooks && ( ret = hooks.get( elem, name ) ) !== null ) {\n\t\t\treturn ret;\n\t\t}\n\n\t\treturn elem[ name ];\n\t},\n\n\tpropHooks: {\n\t\ttabIndex: {\n\t\t\tget: function( elem ) {\n\n\t\t\t\t// Support: IE <=9 - 11 only\n\t\t\t\t// elem.tabIndex doesn't always return the\n\t\t\t\t// correct value when it hasn't been explicitly set\n\t\t\t\t// https://web.archive.org/web/20141116233347/http://fluidproject.org/blog/2008/01/09/getting-setting-and-removing-tabindex-values-with-javascript/\n\t\t\t\t// Use proper attribute retrieval(#12072)\n\t\t\t\tvar tabindex = jQuery.find.attr( elem, \"tabindex\" );\n\n\t\t\t\tif ( tabindex ) {\n\t\t\t\t\treturn parseInt( tabindex, 10 );\n\t\t\t\t}\n\n\t\t\t\tif (\n\t\t\t\t\trfocusable.test( elem.nodeName ) ||\n\t\t\t\t\trclickable.test( elem.nodeName ) &&\n\t\t\t\t\telem.href\n\t\t\t\t) {\n\t\t\t\t\treturn 0;\n\t\t\t\t}\n\n\t\t\t\treturn -1;\n\t\t\t}\n\t\t}\n\t},\n\n\tpropFix: {\n\t\t\"for\": \"htmlFor\",\n\t\t\"class\": \"className\"\n\t}\n} );\n\n// Support: IE <=11 only\n// Accessing the selectedIndex property\n// forces the browser to respect setting selected\n// on the option\n// The getter ensures a default option is selected\n// when in an optgroup\n// eslint rule \"no-unused-expressions\" is disabled for this code\n// since it considers such accessions noop\nif ( !support.optSelected ) {\n\tjQuery.propHooks.selected = {\n\t\tget: function( elem ) {\n\n\t\t\t/* eslint no-unused-expressions: \"off\" */\n\n\t\t\tvar parent = elem.parentNode;\n\t\t\tif ( parent && parent.parentNode ) {\n\t\t\t\tparent.parentNode.selectedIndex;\n\t\t\t}\n\t\t\treturn null;\n\t\t},\n\t\tset: function( elem ) {\n\n\t\t\t/* eslint no-unused-expressions: \"off\" */\n\n\t\t\tvar parent = elem.parentNode;\n\t\t\tif ( parent ) {\n\t\t\t\tparent.selectedIndex;\n\n\t\t\t\tif ( parent.parentNode ) {\n\t\t\t\t\tparent.parentNode.selectedIndex;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t};\n}\n\njQuery.each( [\n\t\"tabIndex\",\n\t\"readOnly\",\n\t\"maxLength\",\n\t\"cellSpacing\",\n\t\"cellPadding\",\n\t\"rowSpan\",\n\t\"colSpan\",\n\t\"useMap\",\n\t\"frameBorder\",\n\t\"contentEditable\"\n], function() {\n\tjQuery.propFix[ this.toLowerCase() ] = this;\n} );\n\n\n\n\n\t// Strip and collapse whitespace according to HTML spec\n\t// https://infra.spec.whatwg.org/#strip-and-collapse-ascii-whitespace\n\tfunction stripAndCollapse( value ) {\n\t\tvar tokens = value.match( rnothtmlwhite ) || [];\n\t\treturn tokens.join( \" \" );\n\t}\n\n\nfunction getClass( elem ) {\n\treturn elem.getAttribute && elem.getAttribute( \"class\" ) || \"\";\n}\n\nfunction classesToArray( value ) {\n\tif ( Array.isArray( value ) ) {\n\t\treturn value;\n\t}\n\tif ( typeof value === \"string\" ) {\n\t\treturn value.match( rnothtmlwhite ) || [];\n\t}\n\treturn [];\n}\n\njQuery.fn.extend( {\n\taddClass: function( value ) {\n\t\tvar classes, elem, cur, curValue, clazz, j, finalValue,\n\t\t\ti = 0;\n\n\t\tif ( isFunction( value ) ) {\n\t\t\treturn this.each( function( j ) {\n\t\t\t\tjQuery( this ).addClass( value.call( this, j, getClass( this ) ) );\n\t\t\t} );\n\t\t}\n\n\t\tclasses = classesToArray( value );\n\n\t\tif ( classes.length ) {\n\t\t\twhile ( ( elem = this[ i++ ] ) ) {\n\t\t\t\tcurValue = getClass( elem );\n\t\t\t\tcur = elem.nodeType === 1 && ( \" \" + stripAndCollapse( curValue ) + \" \" );\n\n\t\t\t\tif ( cur ) {\n\t\t\t\t\tj = 0;\n\t\t\t\t\twhile ( ( clazz = classes[ j++ ] ) ) {\n\t\t\t\t\t\tif ( cur.indexOf( \" \" + clazz + \" \" ) < 0 ) {\n\t\t\t\t\t\t\tcur += clazz + \" \";\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\t// Only assign if different to avoid unneeded rendering.\n\t\t\t\t\tfinalValue = stripAndCollapse( cur );\n\t\t\t\t\tif ( curValue !== finalValue ) {\n\t\t\t\t\t\telem.setAttribute( \"class\", finalValue );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn this;\n\t},\n\n\tremoveClass: function( value ) {\n\t\tvar classes, elem, cur, curValue, clazz, j, finalValue,\n\t\t\ti = 0;\n\n\t\tif ( isFunction( value ) ) {\n\t\t\treturn this.each( function( j ) {\n\t\t\t\tjQuery( this ).removeClass( value.call( this, j, getClass( this ) ) );\n\t\t\t} );\n\t\t}\n\n\t\tif ( !arguments.length ) {\n\t\t\treturn this.attr( \"class\", \"\" );\n\t\t}\n\n\t\tclasses = classesToArray( value );\n\n\t\tif ( classes.length ) {\n\t\t\twhile ( ( elem = this[ i++ ] ) ) {\n\t\t\t\tcurValue = getClass( elem );\n\n\t\t\t\t// This expression is here for better compressibility (see addClass)\n\t\t\t\tcur = elem.nodeType === 1 && ( \" \" + stripAndCollapse( curValue ) + \" \" );\n\n\t\t\t\tif ( cur ) {\n\t\t\t\t\tj = 0;\n\t\t\t\t\twhile ( ( clazz = classes[ j++ ] ) ) {\n\n\t\t\t\t\t\t// Remove *all* instances\n\t\t\t\t\t\twhile ( cur.indexOf( \" \" + clazz + \" \" ) > -1 ) {\n\t\t\t\t\t\t\tcur = cur.replace( \" \" + clazz + \" \", \" \" );\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\t// Only assign if different to avoid unneeded rendering.\n\t\t\t\t\tfinalValue = stripAndCollapse( cur );\n\t\t\t\t\tif ( curValue !== finalValue ) {\n\t\t\t\t\t\telem.setAttribute( \"class\", finalValue );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn this;\n\t},\n\n\ttoggleClass: function( value, stateVal ) {\n\t\tvar type = typeof value,\n\t\t\tisValidValue = type === \"string\" || Array.isArray( value );\n\n\t\tif ( typeof stateVal === \"boolean\" && isValidValue ) {\n\t\t\treturn stateVal ? this.addClass( value ) : this.removeClass( value );\n\t\t}\n\n\t\tif ( isFunction( value ) ) {\n\t\t\treturn this.each( function( i ) {\n\t\t\t\tjQuery( this ).toggleClass(\n\t\t\t\t\tvalue.call( this, i, getClass( this ), stateVal ),\n\t\t\t\t\tstateVal\n\t\t\t\t);\n\t\t\t} );\n\t\t}\n\n\t\treturn this.each( function() {\n\t\t\tvar className, i, self, classNames;\n\n\t\t\tif ( isValidValue ) {\n\n\t\t\t\t// Toggle individual class names\n\t\t\t\ti = 0;\n\t\t\t\tself = jQuery( this );\n\t\t\t\tclassNames = classesToArray( value );\n\n\t\t\t\twhile ( ( className = classNames[ i++ ] ) ) {\n\n\t\t\t\t\t// Check each className given, space separated list\n\t\t\t\t\tif ( self.hasClass( className ) ) {\n\t\t\t\t\t\tself.removeClass( className );\n\t\t\t\t\t} else {\n\t\t\t\t\t\tself.addClass( className );\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t// Toggle whole class name\n\t\t\t} else if ( value === undefined || type === \"boolean\" ) {\n\t\t\t\tclassName = getClass( this );\n\t\t\t\tif ( className ) {\n\n\t\t\t\t\t// Store className if set\n\t\t\t\t\tdataPriv.set( this, \"__className__\", className );\n\t\t\t\t}\n\n\t\t\t\t// If the element has a class name or if we're passed `false`,\n\t\t\t\t// then remove the whole classname (if there was one, the above saved it).\n\t\t\t\t// Otherwise bring back whatever was previously saved (if anything),\n\t\t\t\t// falling back to the empty string if nothing was stored.\n\t\t\t\tif ( this.setAttribute ) {\n\t\t\t\t\tthis.setAttribute( \"class\",\n\t\t\t\t\t\tclassName || value === false ?\n\t\t\t\t\t\t\"\" :\n\t\t\t\t\t\tdataPriv.get( this, \"__className__\" ) || \"\"\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t}\n\t\t} );\n\t},\n\n\thasClass: function( selector ) {\n\t\tvar className, elem,\n\t\t\ti = 0;\n\n\t\tclassName = \" \" + selector + \" \";\n\t\twhile ( ( elem = this[ i++ ] ) ) {\n\t\t\tif ( elem.nodeType === 1 &&\n\t\t\t\t( \" \" + stripAndCollapse( getClass( elem ) ) + \" \" ).indexOf( className ) > -1 ) {\n\t\t\t\t\treturn true;\n\t\t\t}\n\t\t}\n\n\t\treturn false;\n\t}\n} );\n\n\n\n\nvar rreturn = /\\r/g;\n\njQuery.fn.extend( {\n\tval: function( value ) {\n\t\tvar hooks, ret, valueIsFunction,\n\t\t\telem = this[ 0 ];\n\n\t\tif ( !arguments.length ) {\n\t\t\tif ( elem ) {\n\t\t\t\thooks = jQuery.valHooks[ elem.type ] ||\n\t\t\t\t\tjQuery.valHooks[ elem.nodeName.toLowerCase() ];\n\n\t\t\t\tif ( hooks &&\n\t\t\t\t\t\"get\" in hooks &&\n\t\t\t\t\t( ret = hooks.get( elem, \"value\" ) ) !== undefined\n\t\t\t\t) {\n\t\t\t\t\treturn ret;\n\t\t\t\t}\n\n\t\t\t\tret = elem.value;\n\n\t\t\t\t// Handle most common string cases\n\t\t\t\tif ( typeof ret === \"string\" ) {\n\t\t\t\t\treturn ret.replace( rreturn, \"\" );\n\t\t\t\t}\n\n\t\t\t\t// Handle cases where value is null/undef or number\n\t\t\t\treturn ret == null ? \"\" : ret;\n\t\t\t}\n\n\t\t\treturn;\n\t\t}\n\n\t\tvalueIsFunction = isFunction( value );\n\n\t\treturn this.each( function( i ) {\n\t\t\tvar val;\n\n\t\t\tif ( this.nodeType !== 1 ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif ( valueIsFunction ) {\n\t\t\t\tval = value.call( this, i, jQuery( this ).val() );\n\t\t\t} else {\n\t\t\t\tval = value;\n\t\t\t}\n\n\t\t\t// Treat null/undefined as \"\"; convert numbers to string\n\t\t\tif ( val == null ) {\n\t\t\t\tval = \"\";\n\n\t\t\t} else if ( typeof val === \"number\" ) {\n\t\t\t\tval += \"\";\n\n\t\t\t} else if ( Array.isArray( val ) ) {\n\t\t\t\tval = jQuery.map( val, function( value ) {\n\t\t\t\t\treturn value == null ? \"\" : value + \"\";\n\t\t\t\t} );\n\t\t\t}\n\n\t\t\thooks = jQuery.valHooks[ this.type ] || jQuery.valHooks[ this.nodeName.toLowerCase() ];\n\n\t\t\t// If set returns undefined, fall back to normal setting\n\t\t\tif ( !hooks || !( \"set\" in hooks ) || hooks.set( this, val, \"value\" ) === undefined ) {\n\t\t\t\tthis.value = val;\n\t\t\t}\n\t\t} );\n\t}\n} );\n\njQuery.extend( {\n\tvalHooks: {\n\t\toption: {\n\t\t\tget: function( elem ) {\n\n\t\t\t\tvar val = jQuery.find.attr( elem, \"value\" );\n\t\t\t\treturn val != null ?\n\t\t\t\t\tval :\n\n\t\t\t\t\t// Support: IE <=10 - 11 only\n\t\t\t\t\t// option.text throws exceptions (#14686, #14858)\n\t\t\t\t\t// Strip and collapse whitespace\n\t\t\t\t\t// https://html.spec.whatwg.org/#strip-and-collapse-whitespace\n\t\t\t\t\tstripAndCollapse( jQuery.text( elem ) );\n\t\t\t}\n\t\t},\n\t\tselect: {\n\t\t\tget: function( elem ) {\n\t\t\t\tvar value, option, i,\n\t\t\t\t\toptions = elem.options,\n\t\t\t\t\tindex = elem.selectedIndex,\n\t\t\t\t\tone = elem.type === \"select-one\",\n\t\t\t\t\tvalues = one ? null : [],\n\t\t\t\t\tmax = one ? index + 1 : options.length;\n\n\t\t\t\tif ( index < 0 ) {\n\t\t\t\t\ti = max;\n\n\t\t\t\t} else {\n\t\t\t\t\ti = one ? index : 0;\n\t\t\t\t}\n\n\t\t\t\t// Loop through all the selected options\n\t\t\t\tfor ( ; i < max; i++ ) {\n\t\t\t\t\toption = options[ i ];\n\n\t\t\t\t\t// Support: IE <=9 only\n\t\t\t\t\t// IE8-9 doesn't update selected after form reset (#2551)\n\t\t\t\t\tif ( ( option.selected || i === index ) &&\n\n\t\t\t\t\t\t\t// Don't return options that are disabled or in a disabled optgroup\n\t\t\t\t\t\t\t!option.disabled &&\n\t\t\t\t\t\t\t( !option.parentNode.disabled ||\n\t\t\t\t\t\t\t\t!nodeName( option.parentNode, \"optgroup\" ) ) ) {\n\n\t\t\t\t\t\t// Get the specific value for the option\n\t\t\t\t\t\tvalue = jQuery( option ).val();\n\n\t\t\t\t\t\t// We don't need an array for one selects\n\t\t\t\t\t\tif ( one ) {\n\t\t\t\t\t\t\treturn value;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// Multi-Selects return an array\n\t\t\t\t\t\tvalues.push( value );\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\treturn values;\n\t\t\t},\n\n\t\t\tset: function( elem, value ) {\n\t\t\t\tvar optionSet, option,\n\t\t\t\t\toptions = elem.options,\n\t\t\t\t\tvalues = jQuery.makeArray( value ),\n\t\t\t\t\ti = options.length;\n\n\t\t\t\twhile ( i-- ) {\n\t\t\t\t\toption = options[ i ];\n\n\t\t\t\t\t/* eslint-disable no-cond-assign */\n\n\t\t\t\t\tif ( option.selected =\n\t\t\t\t\t\tjQuery.inArray( jQuery.valHooks.option.get( option ), values ) > -1\n\t\t\t\t\t) {\n\t\t\t\t\t\toptionSet = true;\n\t\t\t\t\t}\n\n\t\t\t\t\t/* eslint-enable no-cond-assign */\n\t\t\t\t}\n\n\t\t\t\t// Force browsers to behave consistently when non-matching value is set\n\t\t\t\tif ( !optionSet ) {\n\t\t\t\t\telem.selectedIndex = -1;\n\t\t\t\t}\n\t\t\t\treturn values;\n\t\t\t}\n\t\t}\n\t}\n} );\n\n// Radios and checkboxes getter/setter\njQuery.each( [ \"radio\", \"checkbox\" ], function() {\n\tjQuery.valHooks[ this ] = {\n\t\tset: function( elem, value ) {\n\t\t\tif ( Array.isArray( value ) ) {\n\t\t\t\treturn ( elem.checked = jQuery.inArray( jQuery( elem ).val(), value ) > -1 );\n\t\t\t}\n\t\t}\n\t};\n\tif ( !support.checkOn ) {\n\t\tjQuery.valHooks[ this ].get = function( elem ) {\n\t\t\treturn elem.getAttribute( \"value\" ) === null ? \"on\" : elem.value;\n\t\t};\n\t}\n} );\n\n\n\n\n// Return jQuery for attributes-only inclusion\n\n\nsupport.focusin = \"onfocusin\" in window;\n\n\nvar rfocusMorph = /^(?:focusinfocus|focusoutblur)$/,\n\tstopPropagationCallback = function( e ) {\n\t\te.stopPropagation();\n\t};\n\njQuery.extend( jQuery.event, {\n\n\ttrigger: function( event, data, elem, onlyHandlers ) {\n\n\t\tvar i, cur, tmp, bubbleType, ontype, handle, special, lastElement,\n\t\t\teventPath = [ elem || document ],\n\t\t\ttype = hasOwn.call( event, \"type\" ) ? event.type : event,\n\t\t\tnamespaces = hasOwn.call( event, \"namespace\" ) ? event.namespace.split( \".\" ) : [];\n\n\t\tcur = lastElement = tmp = elem = elem || document;\n\n\t\t// Don't do events on text and comment nodes\n\t\tif ( elem.nodeType === 3 || elem.nodeType === 8 ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// focus/blur morphs to focusin/out; ensure we're not firing them right now\n\t\tif ( rfocusMorph.test( type + jQuery.event.triggered ) ) {\n\t\t\treturn;\n\t\t}\n\n\t\tif ( type.indexOf( \".\" ) > -1 ) {\n\n\t\t\t// Namespaced trigger; create a regexp to match event type in handle()\n\t\t\tnamespaces = type.split( \".\" );\n\t\t\ttype = namespaces.shift();\n\t\t\tnamespaces.sort();\n\t\t}\n\t\tontype = type.indexOf( \":\" ) < 0 && \"on\" + type;\n\n\t\t// Caller can pass in a jQuery.Event object, Object, or just an event type string\n\t\tevent = event[ jQuery.expando ] ?\n\t\t\tevent :\n\t\t\tnew jQuery.Event( type, typeof event === \"object\" && event );\n\n\t\t// Trigger bitmask: & 1 for native handlers; & 2 for jQuery (always true)\n\t\tevent.isTrigger = onlyHandlers ? 2 : 3;\n\t\tevent.namespace = namespaces.join( \".\" );\n\t\tevent.rnamespace = event.namespace ?\n\t\t\tnew RegExp( \"(^|\\\\.)\" + namespaces.join( \"\\\\.(?:.*\\\\.|)\" ) + \"(\\\\.|$)\" ) :\n\t\t\tnull;\n\n\t\t// Clean up the event in case it is being reused\n\t\tevent.result = undefined;\n\t\tif ( !event.target ) {\n\t\t\tevent.target = elem;\n\t\t}\n\n\t\t// Clone any incoming data and prepend the event, creating the handler arg list\n\t\tdata = data == null ?\n\t\t\t[ event ] :\n\t\t\tjQuery.makeArray( data, [ event ] );\n\n\t\t// Allow special events to draw outside the lines\n\t\tspecial = jQuery.event.special[ type ] || {};\n\t\tif ( !onlyHandlers && special.trigger && special.trigger.apply( elem, data ) === false ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Determine event propagation path in advance, per W3C events spec (#9951)\n\t\t// Bubble up to document, then to window; watch for a global ownerDocument var (#9724)\n\t\tif ( !onlyHandlers && !special.noBubble && !isWindow( elem ) ) {\n\n\t\t\tbubbleType = special.delegateType || type;\n\t\t\tif ( !rfocusMorph.test( bubbleType + type ) ) {\n\t\t\t\tcur = cur.parentNode;\n\t\t\t}\n\t\t\tfor ( ; cur; cur = cur.parentNode ) {\n\t\t\t\teventPath.push( cur );\n\t\t\t\ttmp = cur;\n\t\t\t}\n\n\t\t\t// Only add window if we got to document (e.g., not plain obj or detached DOM)\n\t\t\tif ( tmp === ( elem.ownerDocument || document ) ) {\n\t\t\t\teventPath.push( tmp.defaultView || tmp.parentWindow || window );\n\t\t\t}\n\t\t}\n\n\t\t// Fire handlers on the event path\n\t\ti = 0;\n\t\twhile ( ( cur = eventPath[ i++ ] ) && !event.isPropagationStopped() ) {\n\t\t\tlastElement = cur;\n\t\t\tevent.type = i > 1 ?\n\t\t\t\tbubbleType :\n\t\t\t\tspecial.bindType || type;\n\n\t\t\t// jQuery handler\n\t\t\thandle = ( dataPriv.get( cur, \"events\" ) || {} )[ event.type ] &&\n\t\t\t\tdataPriv.get( cur, \"handle\" );\n\t\t\tif ( handle ) {\n\t\t\t\thandle.apply( cur, data );\n\t\t\t}\n\n\t\t\t// Native handler\n\t\t\thandle = ontype && cur[ ontype ];\n\t\t\tif ( handle && handle.apply && acceptData( cur ) ) {\n\t\t\t\tevent.result = handle.apply( cur, data );\n\t\t\t\tif ( event.result === false ) {\n\t\t\t\t\tevent.preventDefault();\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tevent.type = type;\n\n\t\t// If nobody prevented the default action, do it now\n\t\tif ( !onlyHandlers && !event.isDefaultPrevented() ) {\n\n\t\t\tif ( ( !special._default ||\n\t\t\t\tspecial._default.apply( eventPath.pop(), data ) === false ) &&\n\t\t\t\tacceptData( elem ) ) {\n\n\t\t\t\t// Call a native DOM method on the target with the same name as the event.\n\t\t\t\t// Don't do default actions on window, that's where global variables be (#6170)\n\t\t\t\tif ( ontype && isFunction( elem[ type ] ) && !isWindow( elem ) ) {\n\n\t\t\t\t\t// Don't re-trigger an onFOO event when we call its FOO() method\n\t\t\t\t\ttmp = elem[ ontype ];\n\n\t\t\t\t\tif ( tmp ) {\n\t\t\t\t\t\telem[ ontype ] = null;\n\t\t\t\t\t}\n\n\t\t\t\t\t// Prevent re-triggering of the same event, since we already bubbled it above\n\t\t\t\t\tjQuery.event.triggered = type;\n\n\t\t\t\t\tif ( event.isPropagationStopped() ) {\n\t\t\t\t\t\tlastElement.addEventListener( type, stopPropagationCallback );\n\t\t\t\t\t}\n\n\t\t\t\t\telem[ type ]();\n\n\t\t\t\t\tif ( event.isPropagationStopped() ) {\n\t\t\t\t\t\tlastElement.removeEventListener( type, stopPropagationCallback );\n\t\t\t\t\t}\n\n\t\t\t\t\tjQuery.event.triggered = undefined;\n\n\t\t\t\t\tif ( tmp ) {\n\t\t\t\t\t\telem[ ontype ] = tmp;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn event.result;\n\t},\n\n\t// Piggyback on a donor event to simulate a different one\n\t// Used only for `focus(in | out)` events\n\tsimulate: function( type, elem, event ) {\n\t\tvar e = jQuery.extend(\n\t\t\tnew jQuery.Event(),\n\t\t\tevent,\n\t\t\t{\n\t\t\t\ttype: type,\n\t\t\t\tisSimulated: true\n\t\t\t}\n\t\t);\n\n\t\tjQuery.event.trigger( e, null, elem );\n\t}\n\n} );\n\njQuery.fn.extend( {\n\n\ttrigger: function( type, data ) {\n\t\treturn this.each( function() {\n\t\t\tjQuery.event.trigger( type, data, this );\n\t\t} );\n\t},\n\ttriggerHandler: function( type, data ) {\n\t\tvar elem = this[ 0 ];\n\t\tif ( elem ) {\n\t\t\treturn jQuery.event.trigger( type, data, elem, true );\n\t\t}\n\t}\n} );\n\n\n// Support: Firefox <=44\n// Firefox doesn't have focus(in | out) events\n// Related ticket - https://bugzilla.mozilla.org/show_bug.cgi?id=687787\n//\n// Support: Chrome <=48 - 49, Safari <=9.0 - 9.1\n// focus(in | out) events fire after focus & blur events,\n// which is spec violation - http://www.w3.org/TR/DOM-Level-3-Events/#events-focusevent-event-order\n// Related ticket - https://bugs.chromium.org/p/chromium/issues/detail?id=449857\nif ( !support.focusin ) {\n\tjQuery.each( { focus: \"focusin\", blur: \"focusout\" }, function( orig, fix ) {\n\n\t\t// Attach a single capturing handler on the document while someone wants focusin/focusout\n\t\tvar handler = function( event ) {\n\t\t\tjQuery.event.simulate( fix, event.target, jQuery.event.fix( event ) );\n\t\t};\n\n\t\tjQuery.event.special[ fix ] = {\n\t\t\tsetup: function() {\n\t\t\t\tvar doc = this.ownerDocument || this,\n\t\t\t\t\tattaches = dataPriv.access( doc, fix );\n\n\t\t\t\tif ( !attaches ) {\n\t\t\t\t\tdoc.addEventListener( orig, handler, true );\n\t\t\t\t}\n\t\t\t\tdataPriv.access( doc, fix, ( attaches || 0 ) + 1 );\n\t\t\t},\n\t\t\tteardown: function() {\n\t\t\t\tvar doc = this.ownerDocument || this,\n\t\t\t\t\tattaches = dataPriv.access( doc, fix ) - 1;\n\n\t\t\t\tif ( !attaches ) {\n\t\t\t\t\tdoc.removeEventListener( orig, handler, true );\n\t\t\t\t\tdataPriv.remove( doc, fix );\n\n\t\t\t\t} else {\n\t\t\t\t\tdataPriv.access( doc, fix, attaches );\n\t\t\t\t}\n\t\t\t}\n\t\t};\n\t} );\n}\nvar location = window.location;\n\nvar nonce = Date.now();\n\nvar rquery = ( /\\?/ );\n\n\n\n// Cross-browser xml parsing\njQuery.parseXML = function( data ) {\n\tvar xml;\n\tif ( !data || typeof data !== \"string\" ) {\n\t\treturn null;\n\t}\n\n\t// Support: IE 9 - 11 only\n\t// IE throws on parseFromString with invalid input.\n\ttry {\n\t\txml = ( new window.DOMParser() ).parseFromString( data, \"text/xml\" );\n\t} catch ( e ) {\n\t\txml = undefined;\n\t}\n\n\tif ( !xml || xml.getElementsByTagName( \"parsererror\" ).length ) {\n\t\tjQuery.error( \"Invalid XML: \" + data );\n\t}\n\treturn xml;\n};\n\n\nvar\n\trbracket = /\\[\\]$/,\n\trCRLF = /\\r?\\n/g,\n\trsubmitterTypes = /^(?:submit|button|image|reset|file)$/i,\n\trsubmittable = /^(?:input|select|textarea|keygen)/i;\n\nfunction buildParams( prefix, obj, traditional, add ) {\n\tvar name;\n\n\tif ( Array.isArray( obj ) ) {\n\n\t\t// Serialize array item.\n\t\tjQuery.each( obj, function( i, v ) {\n\t\t\tif ( traditional || rbracket.test( prefix ) ) {\n\n\t\t\t\t// Treat each array item as a scalar.\n\t\t\t\tadd( prefix, v );\n\n\t\t\t} else {\n\n\t\t\t\t// Item is non-scalar (array or object), encode its numeric index.\n\t\t\t\tbuildParams(\n\t\t\t\t\tprefix + \"[\" + ( typeof v === \"object\" && v != null ? i : \"\" ) + \"]\",\n\t\t\t\t\tv,\n\t\t\t\t\ttraditional,\n\t\t\t\t\tadd\n\t\t\t\t);\n\t\t\t}\n\t\t} );\n\n\t} else if ( !traditional && toType( obj ) === \"object\" ) {\n\n\t\t// Serialize object item.\n\t\tfor ( name in obj ) {\n\t\t\tbuildParams( prefix + \"[\" + name + \"]\", obj[ name ], traditional, add );\n\t\t}\n\n\t} else {\n\n\t\t// Serialize scalar item.\n\t\tadd( prefix, obj );\n\t}\n}\n\n// Serialize an array of form elements or a set of\n// key/values into a query string\njQuery.param = function( a, traditional ) {\n\tvar prefix,\n\t\ts = [],\n\t\tadd = function( key, valueOrFunction ) {\n\n\t\t\t// If value is a function, invoke it and use its return value\n\t\t\tvar value = isFunction( valueOrFunction ) ?\n\t\t\t\tvalueOrFunction() :\n\t\t\t\tvalueOrFunction;\n\n\t\t\ts[ s.length ] = encodeURIComponent( key ) + \"=\" +\n\t\t\t\tencodeURIComponent( value == null ? \"\" : value );\n\t\t};\n\n\t// If an array was passed in, assume that it is an array of form elements.\n\tif ( Array.isArray( a ) || ( a.jquery && !jQuery.isPlainObject( a ) ) ) {\n\n\t\t// Serialize the form elements\n\t\tjQuery.each( a, function() {\n\t\t\tadd( this.name, this.value );\n\t\t} );\n\n\t} else {\n\n\t\t// If traditional, encode the \"old\" way (the way 1.3.2 or older\n\t\t// did it), otherwise encode params recursively.\n\t\tfor ( prefix in a ) {\n\t\t\tbuildParams( prefix, a[ prefix ], traditional, add );\n\t\t}\n\t}\n\n\t// Return the resulting serialization\n\treturn s.join( \"&\" );\n};\n\njQuery.fn.extend( {\n\tserialize: function() {\n\t\treturn jQuery.param( this.serializeArray() );\n\t},\n\tserializeArray: function() {\n\t\treturn this.map( function() {\n\n\t\t\t// Can add propHook for \"elements\" to filter or add form elements\n\t\t\tvar elements = jQuery.prop( this, \"elements\" );\n\t\t\treturn elements ? jQuery.makeArray( elements ) : this;\n\t\t} )\n\t\t.filter( function() {\n\t\t\tvar type = this.type;\n\n\t\t\t// Use .is( \":disabled\" ) so that fieldset[disabled] works\n\t\t\treturn this.name && !jQuery( this ).is( \":disabled\" ) &&\n\t\t\t\trsubmittable.test( this.nodeName ) && !rsubmitterTypes.test( type ) &&\n\t\t\t\t( this.checked || !rcheckableType.test( type ) );\n\t\t} )\n\t\t.map( function( i, elem ) {\n\t\t\tvar val = jQuery( this ).val();\n\n\t\t\tif ( val == null ) {\n\t\t\t\treturn null;\n\t\t\t}\n\n\t\t\tif ( Array.isArray( val ) ) {\n\t\t\t\treturn jQuery.map( val, function( val ) {\n\t\t\t\t\treturn { name: elem.name, value: val.replace( rCRLF, \"\\r\\n\" ) };\n\t\t\t\t} );\n\t\t\t}\n\n\t\t\treturn { name: elem.name, value: val.replace( rCRLF, \"\\r\\n\" ) };\n\t\t} ).get();\n\t}\n} );\n\n\nvar\n\tr20 = /%20/g,\n\trhash = /#.*$/,\n\trantiCache = /([?&])_=[^&]*/,\n\trheaders = /^(.*?):[ \\t]*([^\\r\\n]*)$/mg,\n\n\t// #7653, #8125, #8152: local protocol detection\n\trlocalProtocol = /^(?:about|app|app-storage|.+-extension|file|res|widget):$/,\n\trnoContent = /^(?:GET|HEAD)$/,\n\trprotocol = /^\\/\\//,\n\n\t/* Prefilters\n\t * 1) They are useful to introduce custom dataTypes (see ajax/jsonp.js for an example)\n\t * 2) These are called:\n\t *    - BEFORE asking for a transport\n\t *    - AFTER param serialization (s.data is a string if s.processData is true)\n\t * 3) key is the dataType\n\t * 4) the catchall symbol \"*\" can be used\n\t * 5) execution will start with transport dataType and THEN continue down to \"*\" if needed\n\t */\n\tprefilters = {},\n\n\t/* Transports bindings\n\t * 1) key is the dataType\n\t * 2) the catchall symbol \"*\" can be used\n\t * 3) selection will start with transport dataType and THEN go to \"*\" if needed\n\t */\n\ttransports = {},\n\n\t// Avoid comment-prolog char sequence (#10098); must appease lint and evade compression\n\tallTypes = \"*/\".concat( \"*\" ),\n\n\t// Anchor tag for parsing the document origin\n\toriginAnchor = document.createElement( \"a\" );\n\toriginAnchor.href = location.href;\n\n// Base \"constructor\" for jQuery.ajaxPrefilter and jQuery.ajaxTransport\nfunction addToPrefiltersOrTransports( structure ) {\n\n\t// dataTypeExpression is optional and defaults to \"*\"\n\treturn function( dataTypeExpression, func ) {\n\n\t\tif ( typeof dataTypeExpression !== \"string\" ) {\n\t\t\tfunc = dataTypeExpression;\n\t\t\tdataTypeExpression = \"*\";\n\t\t}\n\n\t\tvar dataType,\n\t\t\ti = 0,\n\t\t\tdataTypes = dataTypeExpression.toLowerCase().match( rnothtmlwhite ) || [];\n\n\t\tif ( isFunction( func ) ) {\n\n\t\t\t// For each dataType in the dataTypeExpression\n\t\t\twhile ( ( dataType = dataTypes[ i++ ] ) ) {\n\n\t\t\t\t// Prepend if requested\n\t\t\t\tif ( dataType[ 0 ] === \"+\" ) {\n\t\t\t\t\tdataType = dataType.slice( 1 ) || \"*\";\n\t\t\t\t\t( structure[ dataType ] = structure[ dataType ] || [] ).unshift( func );\n\n\t\t\t\t// Otherwise append\n\t\t\t\t} else {\n\t\t\t\t\t( structure[ dataType ] = structure[ dataType ] || [] ).push( func );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t};\n}\n\n// Base inspection function for prefilters and transports\nfunction inspectPrefiltersOrTransports( structure, options, originalOptions, jqXHR ) {\n\n\tvar inspected = {},\n\t\tseekingTransport = ( structure === transports );\n\n\tfunction inspect( dataType ) {\n\t\tvar selected;\n\t\tinspected[ dataType ] = true;\n\t\tjQuery.each( structure[ dataType ] || [], function( _, prefilterOrFactory ) {\n\t\t\tvar dataTypeOrTransport = prefilterOrFactory( options, originalOptions, jqXHR );\n\t\t\tif ( typeof dataTypeOrTransport === \"string\" &&\n\t\t\t\t!seekingTransport && !inspected[ dataTypeOrTransport ] ) {\n\n\t\t\t\toptions.dataTypes.unshift( dataTypeOrTransport );\n\t\t\t\tinspect( dataTypeOrTransport );\n\t\t\t\treturn false;\n\t\t\t} else if ( seekingTransport ) {\n\t\t\t\treturn !( selected = dataTypeOrTransport );\n\t\t\t}\n\t\t} );\n\t\treturn selected;\n\t}\n\n\treturn inspect( options.dataTypes[ 0 ] ) || !inspected[ \"*\" ] && inspect( \"*\" );\n}\n\n// A special extend for ajax options\n// that takes \"flat\" options (not to be deep extended)\n// Fixes #9887\nfunction ajaxExtend( target, src ) {\n\tvar key, deep,\n\t\tflatOptions = jQuery.ajaxSettings.flatOptions || {};\n\n\tfor ( key in src ) {\n\t\tif ( src[ key ] !== undefined ) {\n\t\t\t( flatOptions[ key ] ? target : ( deep || ( deep = {} ) ) )[ key ] = src[ key ];\n\t\t}\n\t}\n\tif ( deep ) {\n\t\tjQuery.extend( true, target, deep );\n\t}\n\n\treturn target;\n}\n\n/* Handles responses to an ajax request:\n * - finds the right dataType (mediates between content-type and expected dataType)\n * - returns the corresponding response\n */\nfunction ajaxHandleResponses( s, jqXHR, responses ) {\n\n\tvar ct, type, finalDataType, firstDataType,\n\t\tcontents = s.contents,\n\t\tdataTypes = s.dataTypes;\n\n\t// Remove auto dataType and get content-type in the process\n\twhile ( dataTypes[ 0 ] === \"*\" ) {\n\t\tdataTypes.shift();\n\t\tif ( ct === undefined ) {\n\t\t\tct = s.mimeType || jqXHR.getResponseHeader( \"Content-Type\" );\n\t\t}\n\t}\n\n\t// Check if we're dealing with a known content-type\n\tif ( ct ) {\n\t\tfor ( type in contents ) {\n\t\t\tif ( contents[ type ] && contents[ type ].test( ct ) ) {\n\t\t\t\tdataTypes.unshift( type );\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t}\n\n\t// Check to see if we have a response for the expected dataType\n\tif ( dataTypes[ 0 ] in responses ) {\n\t\tfinalDataType = dataTypes[ 0 ];\n\t} else {\n\n\t\t// Try convertible dataTypes\n\t\tfor ( type in responses ) {\n\t\t\tif ( !dataTypes[ 0 ] || s.converters[ type + \" \" + dataTypes[ 0 ] ] ) {\n\t\t\t\tfinalDataType = type;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tif ( !firstDataType ) {\n\t\t\t\tfirstDataType = type;\n\t\t\t}\n\t\t}\n\n\t\t// Or just use first one\n\t\tfinalDataType = finalDataType || firstDataType;\n\t}\n\n\t// If we found a dataType\n\t// We add the dataType to the list if needed\n\t// and return the corresponding response\n\tif ( finalDataType ) {\n\t\tif ( finalDataType !== dataTypes[ 0 ] ) {\n\t\t\tdataTypes.unshift( finalDataType );\n\t\t}\n\t\treturn responses[ finalDataType ];\n\t}\n}\n\n/* Chain conversions given the request and the original response\n * Also sets the responseXXX fields on the jqXHR instance\n */\nfunction ajaxConvert( s, response, jqXHR, isSuccess ) {\n\tvar conv2, current, conv, tmp, prev,\n\t\tconverters = {},\n\n\t\t// Work with a copy of dataTypes in case we need to modify it for conversion\n\t\tdataTypes = s.dataTypes.slice();\n\n\t// Create converters map with lowercased keys\n\tif ( dataTypes[ 1 ] ) {\n\t\tfor ( conv in s.converters ) {\n\t\t\tconverters[ conv.toLowerCase() ] = s.converters[ conv ];\n\t\t}\n\t}\n\n\tcurrent = dataTypes.shift();\n\n\t// Convert to each sequential dataType\n\twhile ( current ) {\n\n\t\tif ( s.responseFields[ current ] ) {\n\t\t\tjqXHR[ s.responseFields[ current ] ] = response;\n\t\t}\n\n\t\t// Apply the dataFilter if provided\n\t\tif ( !prev && isSuccess && s.dataFilter ) {\n\t\t\tresponse = s.dataFilter( response, s.dataType );\n\t\t}\n\n\t\tprev = current;\n\t\tcurrent = dataTypes.shift();\n\n\t\tif ( current ) {\n\n\t\t\t// There's only work to do if current dataType is non-auto\n\t\t\tif ( current === \"*\" ) {\n\n\t\t\t\tcurrent = prev;\n\n\t\t\t// Convert response if prev dataType is non-auto and differs from current\n\t\t\t} else if ( prev !== \"*\" && prev !== current ) {\n\n\t\t\t\t// Seek a direct converter\n\t\t\t\tconv = converters[ prev + \" \" + current ] || converters[ \"* \" + current ];\n\n\t\t\t\t// If none found, seek a pair\n\t\t\t\tif ( !conv ) {\n\t\t\t\t\tfor ( conv2 in converters ) {\n\n\t\t\t\t\t\t// If conv2 outputs current\n\t\t\t\t\t\ttmp = conv2.split( \" \" );\n\t\t\t\t\t\tif ( tmp[ 1 ] === current ) {\n\n\t\t\t\t\t\t\t// If prev can be converted to accepted input\n\t\t\t\t\t\t\tconv = converters[ prev + \" \" + tmp[ 0 ] ] ||\n\t\t\t\t\t\t\t\tconverters[ \"* \" + tmp[ 0 ] ];\n\t\t\t\t\t\t\tif ( conv ) {\n\n\t\t\t\t\t\t\t\t// Condense equivalence converters\n\t\t\t\t\t\t\t\tif ( conv === true ) {\n\t\t\t\t\t\t\t\t\tconv = converters[ conv2 ];\n\n\t\t\t\t\t\t\t\t// Otherwise, insert the intermediate dataType\n\t\t\t\t\t\t\t\t} else if ( converters[ conv2 ] !== true ) {\n\t\t\t\t\t\t\t\t\tcurrent = tmp[ 0 ];\n\t\t\t\t\t\t\t\t\tdataTypes.unshift( tmp[ 1 ] );\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// Apply converter (if not an equivalence)\n\t\t\t\tif ( conv !== true ) {\n\n\t\t\t\t\t// Unless errors are allowed to bubble, catch and return them\n\t\t\t\t\tif ( conv && s.throws ) {\n\t\t\t\t\t\tresponse = conv( response );\n\t\t\t\t\t} else {\n\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\tresponse = conv( response );\n\t\t\t\t\t\t} catch ( e ) {\n\t\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\t\tstate: \"parsererror\",\n\t\t\t\t\t\t\t\terror: conv ? e : \"No conversion from \" + prev + \" to \" + current\n\t\t\t\t\t\t\t};\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\treturn { state: \"success\", data: response };\n}\n\njQuery.extend( {\n\n\t// Counter for holding the number of active queries\n\tactive: 0,\n\n\t// Last-Modified header cache for next request\n\tlastModified: {},\n\tetag: {},\n\n\tajaxSettings: {\n\t\turl: location.href,\n\t\ttype: \"GET\",\n\t\tisLocal: rlocalProtocol.test( location.protocol ),\n\t\tglobal: true,\n\t\tprocessData: true,\n\t\tasync: true,\n\t\tcontentType: \"application/x-www-form-urlencoded; charset=UTF-8\",\n\n\t\t/*\n\t\ttimeout: 0,\n\t\tdata: null,\n\t\tdataType: null,\n\t\tusername: null,\n\t\tpassword: null,\n\t\tcache: null,\n\t\tthrows: false,\n\t\ttraditional: false,\n\t\theaders: {},\n\t\t*/\n\n\t\taccepts: {\n\t\t\t\"*\": allTypes,\n\t\t\ttext: \"text/plain\",\n\t\t\thtml: \"text/html\",\n\t\t\txml: \"application/xml, text/xml\",\n\t\t\tjson: \"application/json, text/javascript\"\n\t\t},\n\n\t\tcontents: {\n\t\t\txml: /\\bxml\\b/,\n\t\t\thtml: /\\bhtml/,\n\t\t\tjson: /\\bjson\\b/\n\t\t},\n\n\t\tresponseFields: {\n\t\t\txml: \"responseXML\",\n\t\t\ttext: \"responseText\",\n\t\t\tjson: \"responseJSON\"\n\t\t},\n\n\t\t// Data converters\n\t\t// Keys separate source (or catchall \"*\") and destination types with a single space\n\t\tconverters: {\n\n\t\t\t// Convert anything to text\n\t\t\t\"* text\": String,\n\n\t\t\t// Text to html (true = no transformation)\n\t\t\t\"text html\": true,\n\n\t\t\t// Evaluate text as a json expression\n\t\t\t\"text json\": JSON.parse,\n\n\t\t\t// Parse text as xml\n\t\t\t\"text xml\": jQuery.parseXML\n\t\t},\n\n\t\t// For options that shouldn't be deep extended:\n\t\t// you can add your own custom options here if\n\t\t// and when you create one that shouldn't be\n\t\t// deep extended (see ajaxExtend)\n\t\tflatOptions: {\n\t\t\turl: true,\n\t\t\tcontext: true\n\t\t}\n\t},\n\n\t// Creates a full fledged settings object into target\n\t// with both ajaxSettings and settings fields.\n\t// If target is omitted, writes into ajaxSettings.\n\tajaxSetup: function( target, settings ) {\n\t\treturn settings ?\n\n\t\t\t// Building a settings object\n\t\t\tajaxExtend( ajaxExtend( target, jQuery.ajaxSettings ), settings ) :\n\n\t\t\t// Extending ajaxSettings\n\t\t\tajaxExtend( jQuery.ajaxSettings, target );\n\t},\n\n\tajaxPrefilter: addToPrefiltersOrTransports( prefilters ),\n\tajaxTransport: addToPrefiltersOrTransports( transports ),\n\n\t// Main method\n\tajax: function( url, options ) {\n\n\t\t// If url is an object, simulate pre-1.5 signature\n\t\tif ( typeof url === \"object\" ) {\n\t\t\toptions = url;\n\t\t\turl = undefined;\n\t\t}\n\n\t\t// Force options to be an object\n\t\toptions = options || {};\n\n\t\tvar transport,\n\n\t\t\t// URL without anti-cache param\n\t\t\tcacheURL,\n\n\t\t\t// Response headers\n\t\t\tresponseHeadersString,\n\t\t\tresponseHeaders,\n\n\t\t\t// timeout handle\n\t\t\ttimeoutTimer,\n\n\t\t\t// Url cleanup var\n\t\t\turlAnchor,\n\n\t\t\t// Request state (becomes false upon send and true upon completion)\n\t\t\tcompleted,\n\n\t\t\t// To know if global events are to be dispatched\n\t\t\tfireGlobals,\n\n\t\t\t// Loop variable\n\t\t\ti,\n\n\t\t\t// uncached part of the url\n\t\t\tuncached,\n\n\t\t\t// Create the final options object\n\t\t\ts = jQuery.ajaxSetup( {}, options ),\n\n\t\t\t// Callbacks context\n\t\t\tcallbackContext = s.context || s,\n\n\t\t\t// Context for global events is callbackContext if it is a DOM node or jQuery collection\n\t\t\tglobalEventContext = s.context &&\n\t\t\t\t( callbackContext.nodeType || callbackContext.jquery ) ?\n\t\t\t\t\tjQuery( callbackContext ) :\n\t\t\t\t\tjQuery.event,\n\n\t\t\t// Deferreds\n\t\t\tdeferred = jQuery.Deferred(),\n\t\t\tcompleteDeferred = jQuery.Callbacks( \"once memory\" ),\n\n\t\t\t// Status-dependent callbacks\n\t\t\tstatusCode = s.statusCode || {},\n\n\t\t\t// Headers (they are sent all at once)\n\t\t\trequestHeaders = {},\n\t\t\trequestHeadersNames = {},\n\n\t\t\t// Default abort message\n\t\t\tstrAbort = \"canceled\",\n\n\t\t\t// Fake xhr\n\t\t\tjqXHR = {\n\t\t\t\treadyState: 0,\n\n\t\t\t\t// Builds headers hashtable if needed\n\t\t\t\tgetResponseHeader: function( key ) {\n\t\t\t\t\tvar match;\n\t\t\t\t\tif ( completed ) {\n\t\t\t\t\t\tif ( !responseHeaders ) {\n\t\t\t\t\t\t\tresponseHeaders = {};\n\t\t\t\t\t\t\twhile ( ( match = rheaders.exec( responseHeadersString ) ) ) {\n\t\t\t\t\t\t\t\tresponseHeaders[ match[ 1 ].toLowerCase() ] = match[ 2 ];\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\tmatch = responseHeaders[ key.toLowerCase() ];\n\t\t\t\t\t}\n\t\t\t\t\treturn match == null ? null : match;\n\t\t\t\t},\n\n\t\t\t\t// Raw string\n\t\t\t\tgetAllResponseHeaders: function() {\n\t\t\t\t\treturn completed ? responseHeadersString : null;\n\t\t\t\t},\n\n\t\t\t\t// Caches the header\n\t\t\t\tsetRequestHeader: function( name, value ) {\n\t\t\t\t\tif ( completed == null ) {\n\t\t\t\t\t\tname = requestHeadersNames[ name.toLowerCase() ] =\n\t\t\t\t\t\t\trequestHeadersNames[ name.toLowerCase() ] || name;\n\t\t\t\t\t\trequestHeaders[ name ] = value;\n\t\t\t\t\t}\n\t\t\t\t\treturn this;\n\t\t\t\t},\n\n\t\t\t\t// Overrides response content-type header\n\t\t\t\toverrideMimeType: function( type ) {\n\t\t\t\t\tif ( completed == null ) {\n\t\t\t\t\t\ts.mimeType = type;\n\t\t\t\t\t}\n\t\t\t\t\treturn this;\n\t\t\t\t},\n\n\t\t\t\t// Status-dependent callbacks\n\t\t\t\tstatusCode: function( map ) {\n\t\t\t\t\tvar code;\n\t\t\t\t\tif ( map ) {\n\t\t\t\t\t\tif ( completed ) {\n\n\t\t\t\t\t\t\t// Execute the appropriate callbacks\n\t\t\t\t\t\t\tjqXHR.always( map[ jqXHR.status ] );\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\t// Lazy-add the new callbacks in a way that preserves old ones\n\t\t\t\t\t\t\tfor ( code in map ) {\n\t\t\t\t\t\t\t\tstatusCode[ code ] = [ statusCode[ code ], map[ code ] ];\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\treturn this;\n\t\t\t\t},\n\n\t\t\t\t// Cancel the request\n\t\t\t\tabort: function( statusText ) {\n\t\t\t\t\tvar finalText = statusText || strAbort;\n\t\t\t\t\tif ( transport ) {\n\t\t\t\t\t\ttransport.abort( finalText );\n\t\t\t\t\t}\n\t\t\t\t\tdone( 0, finalText );\n\t\t\t\t\treturn this;\n\t\t\t\t}\n\t\t\t};\n\n\t\t// Attach deferreds\n\t\tdeferred.promise( jqXHR );\n\n\t\t// Add protocol if not provided (prefilters might expect it)\n\t\t// Handle falsy url in the settings object (#10093: consistency with old signature)\n\t\t// We also use the url parameter if available\n\t\ts.url = ( ( url || s.url || location.href ) + \"\" )\n\t\t\t.replace( rprotocol, location.protocol + \"//\" );\n\n\t\t// Alias method option to type as per ticket #12004\n\t\ts.type = options.method || options.type || s.method || s.type;\n\n\t\t// Extract dataTypes list\n\t\ts.dataTypes = ( s.dataType || \"*\" ).toLowerCase().match( rnothtmlwhite ) || [ \"\" ];\n\n\t\t// A cross-domain request is in order when the origin doesn't match the current origin.\n\t\tif ( s.crossDomain == null ) {\n\t\t\turlAnchor = document.createElement( \"a\" );\n\n\t\t\t// Support: IE <=8 - 11, Edge 12 - 15\n\t\t\t// IE throws exception on accessing the href property if url is malformed,\n\t\t\t// e.g. http://example.com:80x/\n\t\t\ttry {\n\t\t\t\turlAnchor.href = s.url;\n\n\t\t\t\t// Support: IE <=8 - 11 only\n\t\t\t\t// Anchor's host property isn't correctly set when s.url is relative\n\t\t\t\turlAnchor.href = urlAnchor.href;\n\t\t\t\ts.crossDomain = originAnchor.protocol + \"//\" + originAnchor.host !==\n\t\t\t\t\turlAnchor.protocol + \"//\" + urlAnchor.host;\n\t\t\t} catch ( e ) {\n\n\t\t\t\t// If there is an error parsing the URL, assume it is crossDomain,\n\t\t\t\t// it can be rejected by the transport if it is invalid\n\t\t\t\ts.crossDomain = true;\n\t\t\t}\n\t\t}\n\n\t\t// Convert data if not already a string\n\t\tif ( s.data && s.processData && typeof s.data !== \"string\" ) {\n\t\t\ts.data = jQuery.param( s.data, s.traditional );\n\t\t}\n\n\t\t// Apply prefilters\n\t\tinspectPrefiltersOrTransports( prefilters, s, options, jqXHR );\n\n\t\t// If request was aborted inside a prefilter, stop there\n\t\tif ( completed ) {\n\t\t\treturn jqXHR;\n\t\t}\n\n\t\t// We can fire global events as of now if asked to\n\t\t// Don't fire events if jQuery.event is undefined in an AMD-usage scenario (#15118)\n\t\tfireGlobals = jQuery.event && s.global;\n\n\t\t// Watch for a new set of requests\n\t\tif ( fireGlobals && jQuery.active++ === 0 ) {\n\t\t\tjQuery.event.trigger( \"ajaxStart\" );\n\t\t}\n\n\t\t// Uppercase the type\n\t\ts.type = s.type.toUpperCase();\n\n\t\t// Determine if request has content\n\t\ts.hasContent = !rnoContent.test( s.type );\n\n\t\t// Save the URL in case we're toying with the If-Modified-Since\n\t\t// and/or If-None-Match header later on\n\t\t// Remove hash to simplify url manipulation\n\t\tcacheURL = s.url.replace( rhash, \"\" );\n\n\t\t// More options handling for requests with no content\n\t\tif ( !s.hasContent ) {\n\n\t\t\t// Remember the hash so we can put it back\n\t\t\tuncached = s.url.slice( cacheURL.length );\n\n\t\t\t// If data is available and should be processed, append data to url\n\t\t\tif ( s.data && ( s.processData || typeof s.data === \"string\" ) ) {\n\t\t\t\tcacheURL += ( rquery.test( cacheURL ) ? \"&\" : \"?\" ) + s.data;\n\n\t\t\t\t// #9682: remove data so that it's not used in an eventual retry\n\t\t\t\tdelete s.data;\n\t\t\t}\n\n\t\t\t// Add or update anti-cache param if needed\n\t\t\tif ( s.cache === false ) {\n\t\t\t\tcacheURL = cacheURL.replace( rantiCache, \"$1\" );\n\t\t\t\tuncached = ( rquery.test( cacheURL ) ? \"&\" : \"?\" ) + \"_=\" + ( nonce++ ) + uncached;\n\t\t\t}\n\n\t\t\t// Put hash and anti-cache on the URL that will be requested (gh-1732)\n\t\t\ts.url = cacheURL + uncached;\n\n\t\t// Change '%20' to '+' if this is encoded form body content (gh-2658)\n\t\t} else if ( s.data && s.processData &&\n\t\t\t( s.contentType || \"\" ).indexOf( \"application/x-www-form-urlencoded\" ) === 0 ) {\n\t\t\ts.data = s.data.replace( r20, \"+\" );\n\t\t}\n\n\t\t// Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.\n\t\tif ( s.ifModified ) {\n\t\t\tif ( jQuery.lastModified[ cacheURL ] ) {\n\t\t\t\tjqXHR.setRequestHeader( \"If-Modified-Since\", jQuery.lastModified[ cacheURL ] );\n\t\t\t}\n\t\t\tif ( jQuery.etag[ cacheURL ] ) {\n\t\t\t\tjqXHR.setRequestHeader( \"If-None-Match\", jQuery.etag[ cacheURL ] );\n\t\t\t}\n\t\t}\n\n\t\t// Set the correct header, if data is being sent\n\t\tif ( s.data && s.hasContent && s.contentType !== false || options.contentType ) {\n\t\t\tjqXHR.setRequestHeader( \"Content-Type\", s.contentType );\n\t\t}\n\n\t\t// Set the Accepts header for the server, depending on the dataType\n\t\tjqXHR.setRequestHeader(\n\t\t\t\"Accept\",\n\t\t\ts.dataTypes[ 0 ] && s.accepts[ s.dataTypes[ 0 ] ] ?\n\t\t\t\ts.accepts[ s.dataTypes[ 0 ] ] +\n\t\t\t\t\t( s.dataTypes[ 0 ] !== \"*\" ? \", \" + allTypes + \"; q=0.01\" : \"\" ) :\n\t\t\t\ts.accepts[ \"*\" ]\n\t\t);\n\n\t\t// Check for headers option\n\t\tfor ( i in s.headers ) {\n\t\t\tjqXHR.setRequestHeader( i, s.headers[ i ] );\n\t\t}\n\n\t\t// Allow custom headers/mimetypes and early abort\n\t\tif ( s.beforeSend &&\n\t\t\t( s.beforeSend.call( callbackContext, jqXHR, s ) === false || completed ) ) {\n\n\t\t\t// Abort if not done already and return\n\t\t\treturn jqXHR.abort();\n\t\t}\n\n\t\t// Aborting is no longer a cancellation\n\t\tstrAbort = \"abort\";\n\n\t\t// Install callbacks on deferreds\n\t\tcompleteDeferred.add( s.complete );\n\t\tjqXHR.done( s.success );\n\t\tjqXHR.fail( s.error );\n\n\t\t// Get transport\n\t\ttransport = inspectPrefiltersOrTransports( transports, s, options, jqXHR );\n\n\t\t// If no transport, we auto-abort\n\t\tif ( !transport ) {\n\t\t\tdone( -1, \"No Transport\" );\n\t\t} else {\n\t\t\tjqXHR.readyState = 1;\n\n\t\t\t// Send global event\n\t\t\tif ( fireGlobals ) {\n\t\t\t\tglobalEventContext.trigger( \"ajaxSend\", [ jqXHR, s ] );\n\t\t\t}\n\n\t\t\t// If request was aborted inside ajaxSend, stop there\n\t\t\tif ( completed ) {\n\t\t\t\treturn jqXHR;\n\t\t\t}\n\n\t\t\t// Timeout\n\t\t\tif ( s.async && s.timeout > 0 ) {\n\t\t\t\ttimeoutTimer = window.setTimeout( function() {\n\t\t\t\t\tjqXHR.abort( \"timeout\" );\n\t\t\t\t}, s.timeout );\n\t\t\t}\n\n\t\t\ttry {\n\t\t\t\tcompleted = false;\n\t\t\t\ttransport.send( requestHeaders, done );\n\t\t\t} catch ( e ) {\n\n\t\t\t\t// Rethrow post-completion exceptions\n\t\t\t\tif ( completed ) {\n\t\t\t\t\tthrow e;\n\t\t\t\t}\n\n\t\t\t\t// Propagate others as results\n\t\t\t\tdone( -1, e );\n\t\t\t}\n\t\t}\n\n\t\t// Callback for when everything is done\n\t\tfunction done( status, nativeStatusText, responses, headers ) {\n\t\t\tvar isSuccess, success, error, response, modified,\n\t\t\t\tstatusText = nativeStatusText;\n\n\t\t\t// Ignore repeat invocations\n\t\t\tif ( completed ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tcompleted = true;\n\n\t\t\t// Clear timeout if it exists\n\t\t\tif ( timeoutTimer ) {\n\t\t\t\twindow.clearTimeout( timeoutTimer );\n\t\t\t}\n\n\t\t\t// Dereference transport for early garbage collection\n\t\t\t// (no matter how long the jqXHR object will be used)\n\t\t\ttransport = undefined;\n\n\t\t\t// Cache response headers\n\t\t\tresponseHeadersString = headers || \"\";\n\n\t\t\t// Set readyState\n\t\t\tjqXHR.readyState = status > 0 ? 4 : 0;\n\n\t\t\t// Determine if successful\n\t\t\tisSuccess = status >= 200 && status < 300 || status === 304;\n\n\t\t\t// Get response data\n\t\t\tif ( responses ) {\n\t\t\t\tresponse = ajaxHandleResponses( s, jqXHR, responses );\n\t\t\t}\n\n\t\t\t// Convert no matter what (that way responseXXX fields are always set)\n\t\t\tresponse = ajaxConvert( s, response, jqXHR, isSuccess );\n\n\t\t\t// If successful, handle type chaining\n\t\t\tif ( isSuccess ) {\n\n\t\t\t\t// Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.\n\t\t\t\tif ( s.ifModified ) {\n\t\t\t\t\tmodified = jqXHR.getResponseHeader( \"Last-Modified\" );\n\t\t\t\t\tif ( modified ) {\n\t\t\t\t\t\tjQuery.lastModified[ cacheURL ] = modified;\n\t\t\t\t\t}\n\t\t\t\t\tmodified = jqXHR.getResponseHeader( \"etag\" );\n\t\t\t\t\tif ( modified ) {\n\t\t\t\t\t\tjQuery.etag[ cacheURL ] = modified;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// if no content\n\t\t\t\tif ( status === 204 || s.type === \"HEAD\" ) {\n\t\t\t\t\tstatusText = \"nocontent\";\n\n\t\t\t\t// if not modified\n\t\t\t\t} else if ( status === 304 ) {\n\t\t\t\t\tstatusText = \"notmodified\";\n\n\t\t\t\t// If we have data, let's convert it\n\t\t\t\t} else {\n\t\t\t\t\tstatusText = response.state;\n\t\t\t\t\tsuccess = response.data;\n\t\t\t\t\terror = response.error;\n\t\t\t\t\tisSuccess = !error;\n\t\t\t\t}\n\t\t\t} else {\n\n\t\t\t\t// Extract error from statusText and normalize for non-aborts\n\t\t\t\terror = statusText;\n\t\t\t\tif ( status || !statusText ) {\n\t\t\t\t\tstatusText = \"error\";\n\t\t\t\t\tif ( status < 0 ) {\n\t\t\t\t\t\tstatus = 0;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Set data for the fake xhr object\n\t\t\tjqXHR.status = status;\n\t\t\tjqXHR.statusText = ( nativeStatusText || statusText ) + \"\";\n\n\t\t\t// Success/Error\n\t\t\tif ( isSuccess ) {\n\t\t\t\tdeferred.resolveWith( callbackContext, [ success, statusText, jqXHR ] );\n\t\t\t} else {\n\t\t\t\tdeferred.rejectWith( callbackContext, [ jqXHR, statusText, error ] );\n\t\t\t}\n\n\t\t\t// Status-dependent callbacks\n\t\t\tjqXHR.statusCode( statusCode );\n\t\t\tstatusCode = undefined;\n\n\t\t\tif ( fireGlobals ) {\n\t\t\t\tglobalEventContext.trigger( isSuccess ? \"ajaxSuccess\" : \"ajaxError\",\n\t\t\t\t\t[ jqXHR, s, isSuccess ? success : error ] );\n\t\t\t}\n\n\t\t\t// Complete\n\t\t\tcompleteDeferred.fireWith( callbackContext, [ jqXHR, statusText ] );\n\n\t\t\tif ( fireGlobals ) {\n\t\t\t\tglobalEventContext.trigger( \"ajaxComplete\", [ jqXHR, s ] );\n\n\t\t\t\t// Handle the global AJAX counter\n\t\t\t\tif ( !( --jQuery.active ) ) {\n\t\t\t\t\tjQuery.event.trigger( \"ajaxStop\" );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn jqXHR;\n\t},\n\n\tgetJSON: function( url, data, callback ) {\n\t\treturn jQuery.get( url, data, callback, \"json\" );\n\t},\n\n\tgetScript: function( url, callback ) {\n\t\treturn jQuery.get( url, undefined, callback, \"script\" );\n\t}\n} );\n\njQuery.each( [ \"get\", \"post\" ], function( i, method ) {\n\tjQuery[ method ] = function( url, data, callback, type ) {\n\n\t\t// Shift arguments if data argument was omitted\n\t\tif ( isFunction( data ) ) {\n\t\t\ttype = type || callback;\n\t\t\tcallback = data;\n\t\t\tdata = undefined;\n\t\t}\n\n\t\t// The url can be an options object (which then must have .url)\n\t\treturn jQuery.ajax( jQuery.extend( {\n\t\t\turl: url,\n\t\t\ttype: method,\n\t\t\tdataType: type,\n\t\t\tdata: data,\n\t\t\tsuccess: callback\n\t\t}, jQuery.isPlainObject( url ) && url ) );\n\t};\n} );\n\n\njQuery._evalUrl = function( url ) {\n\treturn jQuery.ajax( {\n\t\turl: url,\n\n\t\t// Make this explicit, since user can override this through ajaxSetup (#11264)\n\t\ttype: \"GET\",\n\t\tdataType: \"script\",\n\t\tcache: true,\n\t\tasync: false,\n\t\tglobal: false,\n\t\t\"throws\": true\n\t} );\n};\n\n\njQuery.fn.extend( {\n\twrapAll: function( html ) {\n\t\tvar wrap;\n\n\t\tif ( this[ 0 ] ) {\n\t\t\tif ( isFunction( html ) ) {\n\t\t\t\thtml = html.call( this[ 0 ] );\n\t\t\t}\n\n\t\t\t// The elements to wrap the target around\n\t\t\twrap = jQuery( html, this[ 0 ].ownerDocument ).eq( 0 ).clone( true );\n\n\t\t\tif ( this[ 0 ].parentNode ) {\n\t\t\t\twrap.insertBefore( this[ 0 ] );\n\t\t\t}\n\n\t\t\twrap.map( function() {\n\t\t\t\tvar elem = this;\n\n\t\t\t\twhile ( elem.firstElementChild ) {\n\t\t\t\t\telem = elem.firstElementChild;\n\t\t\t\t}\n\n\t\t\t\treturn elem;\n\t\t\t} ).append( this );\n\t\t}\n\n\t\treturn this;\n\t},\n\n\twrapInner: function( html ) {\n\t\tif ( isFunction( html ) ) {\n\t\t\treturn this.each( function( i ) {\n\t\t\t\tjQuery( this ).wrapInner( html.call( this, i ) );\n\t\t\t} );\n\t\t}\n\n\t\treturn this.each( function() {\n\t\t\tvar self = jQuery( this ),\n\t\t\t\tcontents = self.contents();\n\n\t\t\tif ( contents.length ) {\n\t\t\t\tcontents.wrapAll( html );\n\n\t\t\t} else {\n\t\t\t\tself.append( html );\n\t\t\t}\n\t\t} );\n\t},\n\n\twrap: function( html ) {\n\t\tvar htmlIsFunction = isFunction( html );\n\n\t\treturn this.each( function( i ) {\n\t\t\tjQuery( this ).wrapAll( htmlIsFunction ? html.call( this, i ) : html );\n\t\t} );\n\t},\n\n\tunwrap: function( selector ) {\n\t\tthis.parent( selector ).not( \"body\" ).each( function() {\n\t\t\tjQuery( this ).replaceWith( this.childNodes );\n\t\t} );\n\t\treturn this;\n\t}\n} );\n\n\njQuery.expr.pseudos.hidden = function( elem ) {\n\treturn !jQuery.expr.pseudos.visible( elem );\n};\njQuery.expr.pseudos.visible = function( elem ) {\n\treturn !!( elem.offsetWidth || elem.offsetHeight || elem.getClientRects().length );\n};\n\n\n\n\njQuery.ajaxSettings.xhr = function() {\n\ttry {\n\t\treturn new window.XMLHttpRequest();\n\t} catch ( e ) {}\n};\n\nvar xhrSuccessStatus = {\n\n\t\t// File protocol always yields status code 0, assume 200\n\t\t0: 200,\n\n\t\t// Support: IE <=9 only\n\t\t// #1450: sometimes IE returns 1223 when it should be 204\n\t\t1223: 204\n\t},\n\txhrSupported = jQuery.ajaxSettings.xhr();\n\nsupport.cors = !!xhrSupported && ( \"withCredentials\" in xhrSupported );\nsupport.ajax = xhrSupported = !!xhrSupported;\n\njQuery.ajaxTransport( function( options ) {\n\tvar callback, errorCallback;\n\n\t// Cross domain only allowed if supported through XMLHttpRequest\n\tif ( support.cors || xhrSupported && !options.crossDomain ) {\n\t\treturn {\n\t\t\tsend: function( headers, complete ) {\n\t\t\t\tvar i,\n\t\t\t\t\txhr = options.xhr();\n\n\t\t\t\txhr.open(\n\t\t\t\t\toptions.type,\n\t\t\t\t\toptions.url,\n\t\t\t\t\toptions.async,\n\t\t\t\t\toptions.username,\n\t\t\t\t\toptions.password\n\t\t\t\t);\n\n\t\t\t\t// Apply custom fields if provided\n\t\t\t\tif ( options.xhrFields ) {\n\t\t\t\t\tfor ( i in options.xhrFields ) {\n\t\t\t\t\t\txhr[ i ] = options.xhrFields[ i ];\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// Override mime type if needed\n\t\t\t\tif ( options.mimeType && xhr.overrideMimeType ) {\n\t\t\t\t\txhr.overrideMimeType( options.mimeType );\n\t\t\t\t}\n\n\t\t\t\t// X-Requested-With header\n\t\t\t\t// For cross-domain requests, seeing as conditions for a preflight are\n\t\t\t\t// akin to a jigsaw puzzle, we simply never set it to be sure.\n\t\t\t\t// (it can always be set on a per-request basis or even using ajaxSetup)\n\t\t\t\t// For same-domain requests, won't change header if already provided.\n\t\t\t\tif ( !options.crossDomain && !headers[ \"X-Requested-With\" ] ) {\n\t\t\t\t\theaders[ \"X-Requested-With\" ] = \"XMLHttpRequest\";\n\t\t\t\t}\n\n\t\t\t\t// Set headers\n\t\t\t\tfor ( i in headers ) {\n\t\t\t\t\txhr.setRequestHeader( i, headers[ i ] );\n\t\t\t\t}\n\n\t\t\t\t// Callback\n\t\t\t\tcallback = function( type ) {\n\t\t\t\t\treturn function() {\n\t\t\t\t\t\tif ( callback ) {\n\t\t\t\t\t\t\tcallback = errorCallback = xhr.onload =\n\t\t\t\t\t\t\t\txhr.onerror = xhr.onabort = xhr.ontimeout =\n\t\t\t\t\t\t\t\t\txhr.onreadystatechange = null;\n\n\t\t\t\t\t\t\tif ( type === \"abort\" ) {\n\t\t\t\t\t\t\t\txhr.abort();\n\t\t\t\t\t\t\t} else if ( type === \"error\" ) {\n\n\t\t\t\t\t\t\t\t// Support: IE <=9 only\n\t\t\t\t\t\t\t\t// On a manual native abort, IE9 throws\n\t\t\t\t\t\t\t\t// errors on any property access that is not readyState\n\t\t\t\t\t\t\t\tif ( typeof xhr.status !== \"number\" ) {\n\t\t\t\t\t\t\t\t\tcomplete( 0, \"error\" );\n\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\tcomplete(\n\n\t\t\t\t\t\t\t\t\t\t// File: protocol always yields status 0; see #8605, #14207\n\t\t\t\t\t\t\t\t\t\txhr.status,\n\t\t\t\t\t\t\t\t\t\txhr.statusText\n\t\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tcomplete(\n\t\t\t\t\t\t\t\t\txhrSuccessStatus[ xhr.status ] || xhr.status,\n\t\t\t\t\t\t\t\t\txhr.statusText,\n\n\t\t\t\t\t\t\t\t\t// Support: IE <=9 only\n\t\t\t\t\t\t\t\t\t// IE9 has no XHR2 but throws on binary (trac-11426)\n\t\t\t\t\t\t\t\t\t// For XHR2 non-text, let the caller handle it (gh-2498)\n\t\t\t\t\t\t\t\t\t( xhr.responseType || \"text\" ) !== \"text\"  ||\n\t\t\t\t\t\t\t\t\ttypeof xhr.responseText !== \"string\" ?\n\t\t\t\t\t\t\t\t\t\t{ binary: xhr.response } :\n\t\t\t\t\t\t\t\t\t\t{ text: xhr.responseText },\n\t\t\t\t\t\t\t\t\txhr.getAllResponseHeaders()\n\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t};\n\t\t\t\t};\n\n\t\t\t\t// Listen to events\n\t\t\t\txhr.onload = callback();\n\t\t\t\terrorCallback = xhr.onerror = xhr.ontimeout = callback( \"error\" );\n\n\t\t\t\t// Support: IE 9 only\n\t\t\t\t// Use onreadystatechange to replace onabort\n\t\t\t\t// to handle uncaught aborts\n\t\t\t\tif ( xhr.onabort !== undefined ) {\n\t\t\t\t\txhr.onabort = errorCallback;\n\t\t\t\t} else {\n\t\t\t\t\txhr.onreadystatechange = function() {\n\n\t\t\t\t\t\t// Check readyState before timeout as it changes\n\t\t\t\t\t\tif ( xhr.readyState === 4 ) {\n\n\t\t\t\t\t\t\t// Allow onerror to be called first,\n\t\t\t\t\t\t\t// but that will not handle a native abort\n\t\t\t\t\t\t\t// Also, save errorCallback to a variable\n\t\t\t\t\t\t\t// as xhr.onerror cannot be accessed\n\t\t\t\t\t\t\twindow.setTimeout( function() {\n\t\t\t\t\t\t\t\tif ( callback ) {\n\t\t\t\t\t\t\t\t\terrorCallback();\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t} );\n\t\t\t\t\t\t}\n\t\t\t\t\t};\n\t\t\t\t}\n\n\t\t\t\t// Create the abort callback\n\t\t\t\tcallback = callback( \"abort\" );\n\n\t\t\t\ttry {\n\n\t\t\t\t\t// Do send the request (this may raise an exception)\n\t\t\t\t\txhr.send( options.hasContent && options.data || null );\n\t\t\t\t} catch ( e ) {\n\n\t\t\t\t\t// #14683: Only rethrow if this hasn't been notified as an error yet\n\t\t\t\t\tif ( callback ) {\n\t\t\t\t\t\tthrow e;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t},\n\n\t\t\tabort: function() {\n\t\t\t\tif ( callback ) {\n\t\t\t\t\tcallback();\n\t\t\t\t}\n\t\t\t}\n\t\t};\n\t}\n} );\n\n\n\n\n// Prevent auto-execution of scripts when no explicit dataType was provided (See gh-2432)\njQuery.ajaxPrefilter( function( s ) {\n\tif ( s.crossDomain ) {\n\t\ts.contents.script = false;\n\t}\n} );\n\n// Install script dataType\njQuery.ajaxSetup( {\n\taccepts: {\n\t\tscript: \"text/javascript, application/javascript, \" +\n\t\t\t\"application/ecmascript, application/x-ecmascript\"\n\t},\n\tcontents: {\n\t\tscript: /\\b(?:java|ecma)script\\b/\n\t},\n\tconverters: {\n\t\t\"text script\": function( text ) {\n\t\t\tjQuery.globalEval( text );\n\t\t\treturn text;\n\t\t}\n\t}\n} );\n\n// Handle cache's special case and crossDomain\njQuery.ajaxPrefilter( \"script\", function( s ) {\n\tif ( s.cache === undefined ) {\n\t\ts.cache = false;\n\t}\n\tif ( s.crossDomain ) {\n\t\ts.type = \"GET\";\n\t}\n} );\n\n// Bind script tag hack transport\njQuery.ajaxTransport( \"script\", function( s ) {\n\n\t// This transport only deals with cross domain requests\n\tif ( s.crossDomain ) {\n\t\tvar script, callback;\n\t\treturn {\n\t\t\tsend: function( _, complete ) {\n\t\t\t\tscript = jQuery( \"<script>\" ).prop( {\n\t\t\t\t\tcharset: s.scriptCharset,\n\t\t\t\t\tsrc: s.url\n\t\t\t\t} ).on(\n\t\t\t\t\t\"load error\",\n\t\t\t\t\tcallback = function( evt ) {\n\t\t\t\t\t\tscript.remove();\n\t\t\t\t\t\tcallback = null;\n\t\t\t\t\t\tif ( evt ) {\n\t\t\t\t\t\t\tcomplete( evt.type === \"error\" ? 404 : 200, evt.type );\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t);\n\n\t\t\t\t// Use native DOM manipulation to avoid our domManip AJAX trickery\n\t\t\t\tdocument.head.appendChild( script[ 0 ] );\n\t\t\t},\n\t\t\tabort: function() {\n\t\t\t\tif ( callback ) {\n\t\t\t\t\tcallback();\n\t\t\t\t}\n\t\t\t}\n\t\t};\n\t}\n} );\n\n\n\n\nvar oldCallbacks = [],\n\trjsonp = /(=)\\?(?=&|$)|\\?\\?/;\n\n// Default jsonp settings\njQuery.ajaxSetup( {\n\tjsonp: \"callback\",\n\tjsonpCallback: function() {\n\t\tvar callback = oldCallbacks.pop() || ( jQuery.expando + \"_\" + ( nonce++ ) );\n\t\tthis[ callback ] = true;\n\t\treturn callback;\n\t}\n} );\n\n// Detect, normalize options and install callbacks for jsonp requests\njQuery.ajaxPrefilter( \"json jsonp\", function( s, originalSettings, jqXHR ) {\n\n\tvar callbackName, overwritten, responseContainer,\n\t\tjsonProp = s.jsonp !== false && ( rjsonp.test( s.url ) ?\n\t\t\t\"url\" :\n\t\t\ttypeof s.data === \"string\" &&\n\t\t\t\t( s.contentType || \"\" )\n\t\t\t\t\t.indexOf( \"application/x-www-form-urlencoded\" ) === 0 &&\n\t\t\t\trjsonp.test( s.data ) && \"data\"\n\t\t);\n\n\t// Handle iff the expected data type is \"jsonp\" or we have a parameter to set\n\tif ( jsonProp || s.dataTypes[ 0 ] === \"jsonp\" ) {\n\n\t\t// Get callback name, remembering preexisting value associated with it\n\t\tcallbackName = s.jsonpCallback = isFunction( s.jsonpCallback ) ?\n\t\t\ts.jsonpCallback() :\n\t\t\ts.jsonpCallback;\n\n\t\t// Insert callback into url or form data\n\t\tif ( jsonProp ) {\n\t\t\ts[ jsonProp ] = s[ jsonProp ].replace( rjsonp, \"$1\" + callbackName );\n\t\t} else if ( s.jsonp !== false ) {\n\t\t\ts.url += ( rquery.test( s.url ) ? \"&\" : \"?\" ) + s.jsonp + \"=\" + callbackName;\n\t\t}\n\n\t\t// Use data converter to retrieve json after script execution\n\t\ts.converters[ \"script json\" ] = function() {\n\t\t\tif ( !responseContainer ) {\n\t\t\t\tjQuery.error( callbackName + \" was not called\" );\n\t\t\t}\n\t\t\treturn responseContainer[ 0 ];\n\t\t};\n\n\t\t// Force json dataType\n\t\ts.dataTypes[ 0 ] = \"json\";\n\n\t\t// Install callback\n\t\toverwritten = window[ callbackName ];\n\t\twindow[ callbackName ] = function() {\n\t\t\tresponseContainer = arguments;\n\t\t};\n\n\t\t// Clean-up function (fires after converters)\n\t\tjqXHR.always( function() {\n\n\t\t\t// If previous value didn't exist - remove it\n\t\t\tif ( overwritten === undefined ) {\n\t\t\t\tjQuery( window ).removeProp( callbackName );\n\n\t\t\t// Otherwise restore preexisting value\n\t\t\t} else {\n\t\t\t\twindow[ callbackName ] = overwritten;\n\t\t\t}\n\n\t\t\t// Save back as free\n\t\t\tif ( s[ callbackName ] ) {\n\n\t\t\t\t// Make sure that re-using the options doesn't screw things around\n\t\t\t\ts.jsonpCallback = originalSettings.jsonpCallback;\n\n\t\t\t\t// Save the callback name for future use\n\t\t\t\toldCallbacks.push( callbackName );\n\t\t\t}\n\n\t\t\t// Call if it was a function and we have a response\n\t\t\tif ( responseContainer && isFunction( overwritten ) ) {\n\t\t\t\toverwritten( responseContainer[ 0 ] );\n\t\t\t}\n\n\t\t\tresponseContainer = overwritten = undefined;\n\t\t} );\n\n\t\t// Delegate to script\n\t\treturn \"script\";\n\t}\n} );\n\n\n\n\n// Support: Safari 8 only\n// In Safari 8 documents created via document.implementation.createHTMLDocument\n// collapse sibling forms: the second one becomes a child of the first one.\n// Because of that, this security measure has to be disabled in Safari 8.\n// https://bugs.webkit.org/show_bug.cgi?id=137337\nsupport.createHTMLDocument = ( function() {\n\tvar body = document.implementation.createHTMLDocument( \"\" ).body;\n\tbody.innerHTML = \"<form></form><form></form>\";\n\treturn body.childNodes.length === 2;\n} )();\n\n\n// Argument \"data\" should be string of html\n// context (optional): If specified, the fragment will be created in this context,\n// defaults to document\n// keepScripts (optional): If true, will include scripts passed in the html string\njQuery.parseHTML = function( data, context, keepScripts ) {\n\tif ( typeof data !== \"string\" ) {\n\t\treturn [];\n\t}\n\tif ( typeof context === \"boolean\" ) {\n\t\tkeepScripts = context;\n\t\tcontext = false;\n\t}\n\n\tvar base, parsed, scripts;\n\n\tif ( !context ) {\n\n\t\t// Stop scripts or inline event handlers from being executed immediately\n\t\t// by using document.implementation\n\t\tif ( support.createHTMLDocument ) {\n\t\t\tcontext = document.implementation.createHTMLDocument( \"\" );\n\n\t\t\t// Set the base href for the created document\n\t\t\t// so any parsed elements with URLs\n\t\t\t// are based on the document's URL (gh-2965)\n\t\t\tbase = context.createElement( \"base\" );\n\t\t\tbase.href = document.location.href;\n\t\t\tcontext.head.appendChild( base );\n\t\t} else {\n\t\t\tcontext = document;\n\t\t}\n\t}\n\n\tparsed = rsingleTag.exec( data );\n\tscripts = !keepScripts && [];\n\n\t// Single tag\n\tif ( parsed ) {\n\t\treturn [ context.createElement( parsed[ 1 ] ) ];\n\t}\n\n\tparsed = buildFragment( [ data ], context, scripts );\n\n\tif ( scripts && scripts.length ) {\n\t\tjQuery( scripts ).remove();\n\t}\n\n\treturn jQuery.merge( [], parsed.childNodes );\n};\n\n\n/**\n * Load a url into a page\n */\njQuery.fn.load = function( url, params, callback ) {\n\tvar selector, type, response,\n\t\tself = this,\n\t\toff = url.indexOf( \" \" );\n\n\tif ( off > -1 ) {\n\t\tselector = stripAndCollapse( url.slice( off ) );\n\t\turl = url.slice( 0, off );\n\t}\n\n\t// If it's a function\n\tif ( isFunction( params ) ) {\n\n\t\t// We assume that it's the callback\n\t\tcallback = params;\n\t\tparams = undefined;\n\n\t// Otherwise, build a param string\n\t} else if ( params && typeof params === \"object\" ) {\n\t\ttype = \"POST\";\n\t}\n\n\t// If we have elements to modify, make the request\n\tif ( self.length > 0 ) {\n\t\tjQuery.ajax( {\n\t\t\turl: url,\n\n\t\t\t// If \"type\" variable is undefined, then \"GET\" method will be used.\n\t\t\t// Make value of this field explicit since\n\t\t\t// user can override it through ajaxSetup method\n\t\t\ttype: type || \"GET\",\n\t\t\tdataType: \"html\",\n\t\t\tdata: params\n\t\t} ).done( function( responseText ) {\n\n\t\t\t// Save response for use in complete callback\n\t\t\tresponse = arguments;\n\n\t\t\tself.html( selector ?\n\n\t\t\t\t// If a selector was specified, locate the right elements in a dummy div\n\t\t\t\t// Exclude scripts to avoid IE 'Permission Denied' errors\n\t\t\t\tjQuery( \"<div>\" ).append( jQuery.parseHTML( responseText ) ).find( selector ) :\n\n\t\t\t\t// Otherwise use the full result\n\t\t\t\tresponseText );\n\n\t\t// If the request succeeds, this function gets \"data\", \"status\", \"jqXHR\"\n\t\t// but they are ignored because response was set above.\n\t\t// If it fails, this function gets \"jqXHR\", \"status\", \"error\"\n\t\t} ).always( callback && function( jqXHR, status ) {\n\t\t\tself.each( function() {\n\t\t\t\tcallback.apply( this, response || [ jqXHR.responseText, status, jqXHR ] );\n\t\t\t} );\n\t\t} );\n\t}\n\n\treturn this;\n};\n\n\n\n\n// Attach a bunch of functions for handling common AJAX events\njQuery.each( [\n\t\"ajaxStart\",\n\t\"ajaxStop\",\n\t\"ajaxComplete\",\n\t\"ajaxError\",\n\t\"ajaxSuccess\",\n\t\"ajaxSend\"\n], function( i, type ) {\n\tjQuery.fn[ type ] = function( fn ) {\n\t\treturn this.on( type, fn );\n\t};\n} );\n\n\n\n\njQuery.expr.pseudos.animated = function( elem ) {\n\treturn jQuery.grep( jQuery.timers, function( fn ) {\n\t\treturn elem === fn.elem;\n\t} ).length;\n};\n\n\n\n\njQuery.offset = {\n\tsetOffset: function( elem, options, i ) {\n\t\tvar curPosition, curLeft, curCSSTop, curTop, curOffset, curCSSLeft, calculatePosition,\n\t\t\tposition = jQuery.css( elem, \"position\" ),\n\t\t\tcurElem = jQuery( elem ),\n\t\t\tprops = {};\n\n\t\t// Set position first, in-case top/left are set even on static elem\n\t\tif ( position === \"static\" ) {\n\t\t\telem.style.position = \"relative\";\n\t\t}\n\n\t\tcurOffset = curElem.offset();\n\t\tcurCSSTop = jQuery.css( elem, \"top\" );\n\t\tcurCSSLeft = jQuery.css( elem, \"left\" );\n\t\tcalculatePosition = ( position === \"absolute\" || position === \"fixed\" ) &&\n\t\t\t( curCSSTop + curCSSLeft ).indexOf( \"auto\" ) > -1;\n\n\t\t// Need to be able to calculate position if either\n\t\t// top or left is auto and position is either absolute or fixed\n\t\tif ( calculatePosition ) {\n\t\t\tcurPosition = curElem.position();\n\t\t\tcurTop = curPosition.top;\n\t\t\tcurLeft = curPosition.left;\n\n\t\t} else {\n\t\t\tcurTop = parseFloat( curCSSTop ) || 0;\n\t\t\tcurLeft = parseFloat( curCSSLeft ) || 0;\n\t\t}\n\n\t\tif ( isFunction( options ) ) {\n\n\t\t\t// Use jQuery.extend here to allow modification of coordinates argument (gh-1848)\n\t\t\toptions = options.call( elem, i, jQuery.extend( {}, curOffset ) );\n\t\t}\n\n\t\tif ( options.top != null ) {\n\t\t\tprops.top = ( options.top - curOffset.top ) + curTop;\n\t\t}\n\t\tif ( options.left != null ) {\n\t\t\tprops.left = ( options.left - curOffset.left ) + curLeft;\n\t\t}\n\n\t\tif ( \"using\" in options ) {\n\t\t\toptions.using.call( elem, props );\n\n\t\t} else {\n\t\t\tcurElem.css( props );\n\t\t}\n\t}\n};\n\njQuery.fn.extend( {\n\n\t// offset() relates an element's border box to the document origin\n\toffset: function( options ) {\n\n\t\t// Preserve chaining for setter\n\t\tif ( arguments.length ) {\n\t\t\treturn options === undefined ?\n\t\t\t\tthis :\n\t\t\t\tthis.each( function( i ) {\n\t\t\t\t\tjQuery.offset.setOffset( this, options, i );\n\t\t\t\t} );\n\t\t}\n\n\t\tvar rect, win,\n\t\t\telem = this[ 0 ];\n\n\t\tif ( !elem ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Return zeros for disconnected and hidden (display: none) elements (gh-2310)\n\t\t// Support: IE <=11 only\n\t\t// Running getBoundingClientRect on a\n\t\t// disconnected node in IE throws an error\n\t\tif ( !elem.getClientRects().length ) {\n\t\t\treturn { top: 0, left: 0 };\n\t\t}\n\n\t\t// Get document-relative position by adding viewport scroll to viewport-relative gBCR\n\t\trect = elem.getBoundingClientRect();\n\t\twin = elem.ownerDocument.defaultView;\n\t\treturn {\n\t\t\ttop: rect.top + win.pageYOffset,\n\t\t\tleft: rect.left + win.pageXOffset\n\t\t};\n\t},\n\n\t// position() relates an element's margin box to its offset parent's padding box\n\t// This corresponds to the behavior of CSS absolute positioning\n\tposition: function() {\n\t\tif ( !this[ 0 ] ) {\n\t\t\treturn;\n\t\t}\n\n\t\tvar offsetParent, offset, doc,\n\t\t\telem = this[ 0 ],\n\t\t\tparentOffset = { top: 0, left: 0 };\n\n\t\t// position:fixed elements are offset from the viewport, which itself always has zero offset\n\t\tif ( jQuery.css( elem, \"position\" ) === \"fixed\" ) {\n\n\t\t\t// Assume position:fixed implies availability of getBoundingClientRect\n\t\t\toffset = elem.getBoundingClientRect();\n\n\t\t} else {\n\t\t\toffset = this.offset();\n\n\t\t\t// Account for the *real* offset parent, which can be the document or its root element\n\t\t\t// when a statically positioned element is identified\n\t\t\tdoc = elem.ownerDocument;\n\t\t\toffsetParent = elem.offsetParent || doc.documentElement;\n\t\t\twhile ( offsetParent &&\n\t\t\t\t( offsetParent === doc.body || offsetParent === doc.documentElement ) &&\n\t\t\t\tjQuery.css( offsetParent, \"position\" ) === \"static\" ) {\n\n\t\t\t\toffsetParent = offsetParent.parentNode;\n\t\t\t}\n\t\t\tif ( offsetParent && offsetParent !== elem && offsetParent.nodeType === 1 ) {\n\n\t\t\t\t// Incorporate borders into its offset, since they are outside its content origin\n\t\t\t\tparentOffset = jQuery( offsetParent ).offset();\n\t\t\t\tparentOffset.top += jQuery.css( offsetParent, \"borderTopWidth\", true );\n\t\t\t\tparentOffset.left += jQuery.css( offsetParent, \"borderLeftWidth\", true );\n\t\t\t}\n\t\t}\n\n\t\t// Subtract parent offsets and element margins\n\t\treturn {\n\t\t\ttop: offset.top - parentOffset.top - jQuery.css( elem, \"marginTop\", true ),\n\t\t\tleft: offset.left - parentOffset.left - jQuery.css( elem, \"marginLeft\", true )\n\t\t};\n\t},\n\n\t// This method will return documentElement in the following cases:\n\t// 1) For the element inside the iframe without offsetParent, this method will return\n\t//    documentElement of the parent window\n\t// 2) For the hidden or detached element\n\t// 3) For body or html element, i.e. in case of the html node - it will return itself\n\t//\n\t// but those exceptions were never presented as a real life use-cases\n\t// and might be considered as more preferable results.\n\t//\n\t// This logic, however, is not guaranteed and can change at any point in the future\n\toffsetParent: function() {\n\t\treturn this.map( function() {\n\t\t\tvar offsetParent = this.offsetParent;\n\n\t\t\twhile ( offsetParent && jQuery.css( offsetParent, \"position\" ) === \"static\" ) {\n\t\t\t\toffsetParent = offsetParent.offsetParent;\n\t\t\t}\n\n\t\t\treturn offsetParent || documentElement;\n\t\t} );\n\t}\n} );\n\n// Create scrollLeft and scrollTop methods\njQuery.each( { scrollLeft: \"pageXOffset\", scrollTop: \"pageYOffset\" }, function( method, prop ) {\n\tvar top = \"pageYOffset\" === prop;\n\n\tjQuery.fn[ method ] = function( val ) {\n\t\treturn access( this, function( elem, method, val ) {\n\n\t\t\t// Coalesce documents and windows\n\t\t\tvar win;\n\t\t\tif ( isWindow( elem ) ) {\n\t\t\t\twin = elem;\n\t\t\t} else if ( elem.nodeType === 9 ) {\n\t\t\t\twin = elem.defaultView;\n\t\t\t}\n\n\t\t\tif ( val === undefined ) {\n\t\t\t\treturn win ? win[ prop ] : elem[ method ];\n\t\t\t}\n\n\t\t\tif ( win ) {\n\t\t\t\twin.scrollTo(\n\t\t\t\t\t!top ? val : win.pageXOffset,\n\t\t\t\t\ttop ? val : win.pageYOffset\n\t\t\t\t);\n\n\t\t\t} else {\n\t\t\t\telem[ method ] = val;\n\t\t\t}\n\t\t}, method, val, arguments.length );\n\t};\n} );\n\n// Support: Safari <=7 - 9.1, Chrome <=37 - 49\n// Add the top/left cssHooks using jQuery.fn.position\n// Webkit bug: https://bugs.webkit.org/show_bug.cgi?id=29084\n// Blink bug: https://bugs.chromium.org/p/chromium/issues/detail?id=589347\n// getComputedStyle returns percent when specified for top/left/bottom/right;\n// rather than make the css module depend on the offset module, just check for it here\njQuery.each( [ \"top\", \"left\" ], function( i, prop ) {\n\tjQuery.cssHooks[ prop ] = addGetHookIf( support.pixelPosition,\n\t\tfunction( elem, computed ) {\n\t\t\tif ( computed ) {\n\t\t\t\tcomputed = curCSS( elem, prop );\n\n\t\t\t\t// If curCSS returns percentage, fallback to offset\n\t\t\t\treturn rnumnonpx.test( computed ) ?\n\t\t\t\t\tjQuery( elem ).position()[ prop ] + \"px\" :\n\t\t\t\t\tcomputed;\n\t\t\t}\n\t\t}\n\t);\n} );\n\n\n// Create innerHeight, innerWidth, height, width, outerHeight and outerWidth methods\njQuery.each( { Height: \"height\", Width: \"width\" }, function( name, type ) {\n\tjQuery.each( { padding: \"inner\" + name, content: type, \"\": \"outer\" + name },\n\t\tfunction( defaultExtra, funcName ) {\n\n\t\t// Margin is only for outerHeight, outerWidth\n\t\tjQuery.fn[ funcName ] = function( margin, value ) {\n\t\t\tvar chainable = arguments.length && ( defaultExtra || typeof margin !== \"boolean\" ),\n\t\t\t\textra = defaultExtra || ( margin === true || value === true ? \"margin\" : \"border\" );\n\n\t\t\treturn access( this, function( elem, type, value ) {\n\t\t\t\tvar doc;\n\n\t\t\t\tif ( isWindow( elem ) ) {\n\n\t\t\t\t\t// $( window ).outerWidth/Height return w/h including scrollbars (gh-1729)\n\t\t\t\t\treturn funcName.indexOf( \"outer\" ) === 0 ?\n\t\t\t\t\t\telem[ \"inner\" + name ] :\n\t\t\t\t\t\telem.document.documentElement[ \"client\" + name ];\n\t\t\t\t}\n\n\t\t\t\t// Get document width or height\n\t\t\t\tif ( elem.nodeType === 9 ) {\n\t\t\t\t\tdoc = elem.documentElement;\n\n\t\t\t\t\t// Either scroll[Width/Height] or offset[Width/Height] or client[Width/Height],\n\t\t\t\t\t// whichever is greatest\n\t\t\t\t\treturn Math.max(\n\t\t\t\t\t\telem.body[ \"scroll\" + name ], doc[ \"scroll\" + name ],\n\t\t\t\t\t\telem.body[ \"offset\" + name ], doc[ \"offset\" + name ],\n\t\t\t\t\t\tdoc[ \"client\" + name ]\n\t\t\t\t\t);\n\t\t\t\t}\n\n\t\t\t\treturn value === undefined ?\n\n\t\t\t\t\t// Get width or height on the element, requesting but not forcing parseFloat\n\t\t\t\t\tjQuery.css( elem, type, extra ) :\n\n\t\t\t\t\t// Set width or height on the element\n\t\t\t\t\tjQuery.style( elem, type, value, extra );\n\t\t\t}, type, chainable ? margin : undefined, chainable );\n\t\t};\n\t} );\n} );\n\n\njQuery.each( ( \"blur focus focusin focusout resize scroll click dblclick \" +\n\t\"mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave \" +\n\t\"change select submit keydown keypress keyup contextmenu\" ).split( \" \" ),\n\tfunction( i, name ) {\n\n\t// Handle event binding\n\tjQuery.fn[ name ] = function( data, fn ) {\n\t\treturn arguments.length > 0 ?\n\t\t\tthis.on( name, null, data, fn ) :\n\t\t\tthis.trigger( name );\n\t};\n} );\n\njQuery.fn.extend( {\n\thover: function( fnOver, fnOut ) {\n\t\treturn this.mouseenter( fnOver ).mouseleave( fnOut || fnOver );\n\t}\n} );\n\n\n\n\njQuery.fn.extend( {\n\n\tbind: function( types, data, fn ) {\n\t\treturn this.on( types, null, data, fn );\n\t},\n\tunbind: function( types, fn ) {\n\t\treturn this.off( types, null, fn );\n\t},\n\n\tdelegate: function( selector, types, data, fn ) {\n\t\treturn this.on( types, selector, data, fn );\n\t},\n\tundelegate: function( selector, types, fn ) {\n\n\t\t// ( namespace ) or ( selector, types [, fn] )\n\t\treturn arguments.length === 1 ?\n\t\t\tthis.off( selector, \"**\" ) :\n\t\t\tthis.off( types, selector || \"**\", fn );\n\t}\n} );\n\n// Bind a function to a context, optionally partially applying any\n// arguments.\n// jQuery.proxy is deprecated to promote standards (specifically Function#bind)\n// However, it is not slated for removal any time soon\njQuery.proxy = function( fn, context ) {\n\tvar tmp, args, proxy;\n\n\tif ( typeof context === \"string\" ) {\n\t\ttmp = fn[ context ];\n\t\tcontext = fn;\n\t\tfn = tmp;\n\t}\n\n\t// Quick check to determine if target is callable, in the spec\n\t// this throws a TypeError, but we will just return undefined.\n\tif ( !isFunction( fn ) ) {\n\t\treturn undefined;\n\t}\n\n\t// Simulated bind\n\targs = slice.call( arguments, 2 );\n\tproxy = function() {\n\t\treturn fn.apply( context || this, args.concat( slice.call( arguments ) ) );\n\t};\n\n\t// Set the guid of unique handler to the same of original handler, so it can be removed\n\tproxy.guid = fn.guid = fn.guid || jQuery.guid++;\n\n\treturn proxy;\n};\n\njQuery.holdReady = function( hold ) {\n\tif ( hold ) {\n\t\tjQuery.readyWait++;\n\t} else {\n\t\tjQuery.ready( true );\n\t}\n};\njQuery.isArray = Array.isArray;\njQuery.parseJSON = JSON.parse;\njQuery.nodeName = nodeName;\njQuery.isFunction = isFunction;\njQuery.isWindow = isWindow;\njQuery.camelCase = camelCase;\njQuery.type = toType;\n\njQuery.now = Date.now;\n\njQuery.isNumeric = function( obj ) {\n\n\t// As of jQuery 3.0, isNumeric is limited to\n\t// strings and numbers (primitives or objects)\n\t// that can be coerced to finite numbers (gh-2662)\n\tvar type = jQuery.type( obj );\n\treturn ( type === \"number\" || type === \"string\" ) &&\n\n\t\t// parseFloat NaNs numeric-cast false positives (\"\")\n\t\t// ...but misinterprets leading-number strings, particularly hex literals (\"0x...\")\n\t\t// subtraction forces infinities to NaN\n\t\t!isNaN( obj - parseFloat( obj ) );\n};\n\n\n\n\n// Register as a named AMD module, since jQuery can be concatenated with other\n// files that may use define, but not via a proper concatenation script that\n// understands anonymous AMD modules. A named AMD is safest and most robust\n// way to register. Lowercase jquery is used because AMD module names are\n// derived from file names, and jQuery is normally delivered in a lowercase\n// file name. Do this after creating the global so that if an AMD module wants\n// to call noConflict to hide this version of jQuery, it will work.\n\n// Note that for maximum portability, libraries that are not jQuery should\n// declare themselves as anonymous modules, and avoid setting a global if an\n// AMD loader is present. jQuery is a special case. For more information, see\n// https://github.com/jrburke/requirejs/wiki/Updating-existing-libraries#wiki-anon\n\nif ( typeof define === \"function\" && define.amd ) {\n\tdefine( \"jquery\", [], function() {\n\t\treturn jQuery;\n\t} );\n}\n\n\n\n\nvar\n\n\t// Map over jQuery in case of overwrite\n\t_jQuery = window.jQuery,\n\n\t// Map over the $ in case of overwrite\n\t_$ = window.$;\n\njQuery.noConflict = function( deep ) {\n\tif ( window.$ === jQuery ) {\n\t\twindow.$ = _$;\n\t}\n\n\tif ( deep && window.jQuery === jQuery ) {\n\t\twindow.jQuery = _jQuery;\n\t}\n\n\treturn jQuery;\n};\n\n// Expose jQuery and $ identifiers, even in AMD\n// (#7102#comment:10, https://github.com/jquery/jquery/pull/557)\n// and CommonJS for browser emulators (#13566)\nif ( !noGlobal ) {\n\twindow.jQuery = window.$ = jQuery;\n}\n\n\n\n\nreturn jQuery;\n} );\n","/*! jQuery UI - v1.12.1 - 2018-05-20\n* http://jqueryui.com\n* Includes: widget.js, position.js, keycode.js, scroll-parent.js, unique-id.js\n* Copyright jQuery Foundation and other contributors; Licensed MIT */\n\n;(function( factory ) {\n\tif ( typeof define === \"function\" && define.amd ) {\n\t\t// AMD. Register as an anonymous module.\n\t\tdefine( [ \"jquery\" ], factory );\n\t} else if ( typeof module === \"object\" && module.exports ) {\n\t\t// Node/CommonJS\n\t\tmodule.exports = factory(require(\"jquery\"));\n\t} else {\n\t\t// Browser globals\n\t\tfactory( jQuery );\n\t}\n}(function( $ ) {\n\n$.ui = $.ui || {};\n\nvar version = $.ui.version = \"1.12.1\";\n\n\n/*!\n * jQuery UI Widget 1.12.1\n * http://jqueryui.com\n *\n * Copyright jQuery Foundation and other contributors\n * Released under the MIT license.\n * http://jquery.org/license\n */\n\n//>>label: Widget\n//>>group: Core\n//>>description: Provides a factory for creating stateful widgets with a common API.\n//>>docs: http://api.jqueryui.com/jQuery.widget/\n//>>demos: http://jqueryui.com/widget/\n\n\n\nvar widgetUuid = 0;\nvar widgetSlice = Array.prototype.slice;\n\n$.cleanData = $.cleanData || ( function( orig ) {\n\treturn function( elems ) {\n\t\tvar events, elem, i;\n\t\tfor ( i = 0; ( elem = elems[ i ] ) != null; i++ ) {\n\t\t\ttry {\n\n\t\t\t\t// Only trigger remove when necessary to save time\n\t\t\t\tevents = $._data( elem, \"events\" );\n\t\t\t\tif ( events && events.remove ) {\n\t\t\t\t\t$( elem ).triggerHandler( \"remove\" );\n\t\t\t\t}\n\n\t\t\t// Http://bugs.jquery.com/ticket/8235\n\t\t\t} catch ( e ) {}\n\t\t}\n\t\torig( elems );\n\t};\n} )( $.cleanData );\n\n$.widget = $.widget || function( name, base, prototype ) {\n\tvar existingConstructor, constructor, basePrototype;\n\n\t// ProxiedPrototype allows the provided prototype to remain unmodified\n\t// so that it can be used as a mixin for multiple widgets (#8876)\n\tvar proxiedPrototype = {};\n\n\tvar namespace = name.split( \".\" )[ 0 ];\n\tname = name.split( \".\" )[ 1 ];\n\tvar fullName = namespace + \"-\" + name;\n\n\tif ( !prototype ) {\n\t\tprototype = base;\n\t\tbase = $.Widget;\n\t}\n\n\tif ( $.isArray( prototype ) ) {\n\t\tprototype = $.extend.apply( null, [ {} ].concat( prototype ) );\n\t}\n\n\t// Create selector for plugin\n\t$.expr[ \":\" ][ fullName.toLowerCase() ] = function( elem ) {\n\t\treturn !!$.data( elem, fullName );\n\t};\n\n\t$[ namespace ] = $[ namespace ] || {};\n\texistingConstructor = $[ namespace ][ name ];\n\tconstructor = $[ namespace ][ name ] = function( options, element ) {\n\n\t\t// Allow instantiation without \"new\" keyword\n\t\tif ( !this._createWidget ) {\n\t\t\treturn new constructor( options, element );\n\t\t}\n\n\t\t// Allow instantiation without initializing for simple inheritance\n\t\t// must use \"new\" keyword (the code above always passes args)\n\t\tif ( arguments.length ) {\n\t\t\tthis._createWidget( options, element );\n\t\t}\n\t};\n\n\t// Extend with the existing constructor to carry over any static properties\n\t$.extend( constructor, existingConstructor, {\n\t\tversion: prototype.version,\n\n\t\t// Copy the object used to create the prototype in case we need to\n\t\t// redefine the widget later\n\t\t_proto: $.extend( {}, prototype ),\n\n\t\t// Track widgets that inherit from this widget in case this widget is\n\t\t// redefined after a widget inherits from it\n\t\t_childConstructors: []\n\t} );\n\n\tbasePrototype = new base();\n\n\t// We need to make the options hash a property directly on the new instance\n\t// otherwise we'll modify the options hash on the prototype that we're\n\t// inheriting from\n\tbasePrototype.options = $.widget.extend( {}, basePrototype.options );\n\t$.each( prototype, function( prop, value ) {\n\t\tif ( !$.isFunction( value ) ) {\n\t\t\tproxiedPrototype[ prop ] = value;\n\t\t\treturn;\n\t\t}\n\t\tproxiedPrototype[ prop ] = ( function() {\n\t\t\tfunction _super() {\n\t\t\t\treturn base.prototype[ prop ].apply( this, arguments );\n\t\t\t}\n\n\t\t\tfunction _superApply( args ) {\n\t\t\t\treturn base.prototype[ prop ].apply( this, args );\n\t\t\t}\n\n\t\t\treturn function() {\n\t\t\t\tvar __super = this._super;\n\t\t\t\tvar __superApply = this._superApply;\n\t\t\t\tvar returnValue;\n\n\t\t\t\tthis._super = _super;\n\t\t\t\tthis._superApply = _superApply;\n\n\t\t\t\treturnValue = value.apply( this, arguments );\n\n\t\t\t\tthis._super = __super;\n\t\t\t\tthis._superApply = __superApply;\n\n\t\t\t\treturn returnValue;\n\t\t\t};\n\t\t} )();\n\t} );\n\tconstructor.prototype = $.widget.extend( basePrototype, {\n\n\t\t// TODO: remove support for widgetEventPrefix\n\t\t// always use the name + a colon as the prefix, e.g., draggable:start\n\t\t// don't prefix for widgets that aren't DOM-based\n\t\twidgetEventPrefix: existingConstructor ? ( basePrototype.widgetEventPrefix || name ) : name\n\t}, proxiedPrototype, {\n\t\tconstructor: constructor,\n\t\tnamespace: namespace,\n\t\twidgetName: name,\n\t\twidgetFullName: fullName\n\t} );\n\n\t// If this widget is being redefined then we need to find all widgets that\n\t// are inheriting from it and redefine all of them so that they inherit from\n\t// the new version of this widget. We're essentially trying to replace one\n\t// level in the prototype chain.\n\tif ( existingConstructor ) {\n\t\t$.each( existingConstructor._childConstructors, function( i, child ) {\n\t\t\tvar childPrototype = child.prototype;\n\n\t\t\t// Redefine the child widget using the same prototype that was\n\t\t\t// originally used, but inherit from the new version of the base\n\t\t\t$.widget( childPrototype.namespace + \".\" + childPrototype.widgetName, constructor,\n\t\t\t\tchild._proto );\n\t\t} );\n\n\t\t// Remove the list of existing child constructors from the old constructor\n\t\t// so the old child constructors can be garbage collected\n\t\tdelete existingConstructor._childConstructors;\n\t} else {\n\t\tbase._childConstructors.push( constructor );\n\t}\n\n\t$.widget.bridge( name, constructor );\n\n\treturn constructor;\n};\n\n$.widget.extend = function( target ) {\n\tvar input = widgetSlice.call( arguments, 1 );\n\tvar inputIndex = 0;\n\tvar inputLength = input.length;\n\tvar key;\n\tvar value;\n\n\tfor ( ; inputIndex < inputLength; inputIndex++ ) {\n\t\tfor ( key in input[ inputIndex ] ) {\n\t\t\tvalue = input[ inputIndex ][ key ];\n\t\t\tif ( input[ inputIndex ].hasOwnProperty( key ) && value !== undefined ) {\n\n\t\t\t\t// Clone objects\n\t\t\t\tif ( $.isPlainObject( value ) ) {\n\t\t\t\t\ttarget[ key ] = $.isPlainObject( target[ key ] ) ?\n\t\t\t\t\t\t$.widget.extend( {}, target[ key ], value ) :\n\n\t\t\t\t\t\t// Don't extend strings, arrays, etc. with objects\n\t\t\t\t\t\t$.widget.extend( {}, value );\n\n\t\t\t\t// Copy everything else by reference\n\t\t\t\t} else {\n\t\t\t\t\ttarget[ key ] = value;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\treturn target;\n};\n\n$.widget.bridge = function( name, object ) {\n\tvar fullName = object.prototype.widgetFullName || name;\n\t$.fn[ name ] = function( options ) {\n\t\tvar isMethodCall = typeof options === \"string\";\n\t\tvar args = widgetSlice.call( arguments, 1 );\n\t\tvar returnValue = this;\n\n\t\tif ( isMethodCall ) {\n\n\t\t\t// If this is an empty collection, we need to have the instance method\n\t\t\t// return undefined instead of the jQuery instance\n\t\t\tif ( !this.length && options === \"instance\" ) {\n\t\t\t\treturnValue = undefined;\n\t\t\t} else {\n\t\t\t\tthis.each( function() {\n\t\t\t\t\tvar methodValue;\n\t\t\t\t\tvar instance = $.data( this, fullName );\n\n\t\t\t\t\tif ( options === \"instance\" ) {\n\t\t\t\t\t\treturnValue = instance;\n\t\t\t\t\t\treturn false;\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( !instance ) {\n\t\t\t\t\t\treturn $.error( \"cannot call methods on \" + name +\n\t\t\t\t\t\t\t\" prior to initialization; \" +\n\t\t\t\t\t\t\t\"attempted to call method '\" + options + \"'\" );\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( !$.isFunction( instance[ options ] ) || options.charAt( 0 ) === \"_\" ) {\n\t\t\t\t\t\treturn $.error( \"no such method '\" + options + \"' for \" + name +\n\t\t\t\t\t\t\t\" widget instance\" );\n\t\t\t\t\t}\n\n\t\t\t\t\tmethodValue = instance[ options ].apply( instance, args );\n\n\t\t\t\t\tif ( methodValue !== instance && methodValue !== undefined ) {\n\t\t\t\t\t\treturnValue = methodValue && methodValue.jquery ?\n\t\t\t\t\t\t\treturnValue.pushStack( methodValue.get() ) :\n\t\t\t\t\t\t\tmethodValue;\n\t\t\t\t\t\treturn false;\n\t\t\t\t\t}\n\t\t\t\t} );\n\t\t\t}\n\t\t} else {\n\n\t\t\t// Allow multiple hashes to be passed on init\n\t\t\tif ( args.length ) {\n\t\t\t\toptions = $.widget.extend.apply( null, [ options ].concat( args ) );\n\t\t\t}\n\n\t\t\tthis.each( function() {\n\t\t\t\tvar instance = $.data( this, fullName );\n\t\t\t\tif ( instance ) {\n\t\t\t\t\tinstance.option( options || {} );\n\t\t\t\t\tif ( instance._init ) {\n\t\t\t\t\t\tinstance._init();\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\t$.data( this, fullName, new object( options, this ) );\n\t\t\t\t}\n\t\t\t} );\n\t\t}\n\n\t\treturn returnValue;\n\t};\n};\n\n$.Widget = $.Widget || function( /* options, element */ ) {};\n$.Widget._childConstructors = [];\n\n$.Widget.prototype = {\n\twidgetName: \"widget\",\n\twidgetEventPrefix: \"\",\n\tdefaultElement: \"<div>\",\n\n\toptions: {\n\t\tclasses: {},\n\t\tdisabled: false,\n\n\t\t// Callbacks\n\t\tcreate: null\n\t},\n\n\t_createWidget: function( options, element ) {\n\t\telement = $( element || this.defaultElement || this )[ 0 ];\n\t\tthis.element = $( element );\n\t\tthis.uuid = widgetUuid++;\n\t\tthis.eventNamespace = \".\" + this.widgetName + this.uuid;\n\n\t\tthis.bindings = $();\n\t\tthis.hoverable = $();\n\t\tthis.focusable = $();\n\t\tthis.classesElementLookup = {};\n\n\t\tif ( element !== this ) {\n\t\t\t$.data( element, this.widgetFullName, this );\n\t\t\tthis._on( true, this.element, {\n\t\t\t\tremove: function( event ) {\n\t\t\t\t\tif ( event.target === element ) {\n\t\t\t\t\t\tthis.destroy();\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} );\n\t\t\tthis.document = $( element.style ?\n\n\t\t\t\t// Element within the document\n\t\t\t\telement.ownerDocument :\n\n\t\t\t\t// Element is window or document\n\t\t\t\telement.document || element );\n\t\t\tthis.window = $( this.document[ 0 ].defaultView || this.document[ 0 ].parentWindow );\n\t\t}\n\n\t\tthis.options = $.widget.extend( {},\n\t\t\tthis.options,\n\t\t\tthis._getCreateOptions(),\n\t\t\toptions );\n\n\t\tthis._create();\n\n\t\tif ( this.options.disabled ) {\n\t\t\tthis._setOptionDisabled( this.options.disabled );\n\t\t}\n\n\t\tthis._trigger( \"create\", null, this._getCreateEventData() );\n\t\tthis._init();\n\t},\n\n\t_getCreateOptions: function() {\n\t\treturn {};\n\t},\n\n\t_getCreateEventData: $.noop,\n\n\t_create: $.noop,\n\n\t_init: $.noop,\n\n\tdestroy: function() {\n\t\tvar that = this;\n\n\t\tthis._destroy();\n\t\t$.each( this.classesElementLookup, function( key, value ) {\n\t\t\tthat._removeClass( value, key );\n\t\t} );\n\n\t\t// We can probably remove the unbind calls in 2.0\n\t\t// all event bindings should go through this._on()\n\t\tthis.element\n\t\t\t.off( this.eventNamespace )\n\t\t\t.removeData( this.widgetFullName );\n\t\tthis.widget()\n\t\t\t.off( this.eventNamespace )\n\t\t\t.removeAttr( \"aria-disabled\" );\n\n\t\t// Clean up events and states\n\t\tthis.bindings.off( this.eventNamespace );\n\t},\n\n\t_destroy: $.noop,\n\n\twidget: function() {\n\t\treturn this.element;\n\t},\n\n\toption: function( key, value ) {\n\t\tvar options = key;\n\t\tvar parts;\n\t\tvar curOption;\n\t\tvar i;\n\n\t\tif ( arguments.length === 0 ) {\n\n\t\t\t// Don't return a reference to the internal hash\n\t\t\treturn $.widget.extend( {}, this.options );\n\t\t}\n\n\t\tif ( typeof key === \"string\" ) {\n\n\t\t\t// Handle nested keys, e.g., \"foo.bar\" => { foo: { bar: ___ } }\n\t\t\toptions = {};\n\t\t\tparts = key.split( \".\" );\n\t\t\tkey = parts.shift();\n\t\t\tif ( parts.length ) {\n\t\t\t\tcurOption = options[ key ] = $.widget.extend( {}, this.options[ key ] );\n\t\t\t\tfor ( i = 0; i < parts.length - 1; i++ ) {\n\t\t\t\t\tcurOption[ parts[ i ] ] = curOption[ parts[ i ] ] || {};\n\t\t\t\t\tcurOption = curOption[ parts[ i ] ];\n\t\t\t\t}\n\t\t\t\tkey = parts.pop();\n\t\t\t\tif ( arguments.length === 1 ) {\n\t\t\t\t\treturn curOption[ key ] === undefined ? null : curOption[ key ];\n\t\t\t\t}\n\t\t\t\tcurOption[ key ] = value;\n\t\t\t} else {\n\t\t\t\tif ( arguments.length === 1 ) {\n\t\t\t\t\treturn this.options[ key ] === undefined ? null : this.options[ key ];\n\t\t\t\t}\n\t\t\t\toptions[ key ] = value;\n\t\t\t}\n\t\t}\n\n\t\tthis._setOptions( options );\n\n\t\treturn this;\n\t},\n\n\t_setOptions: function( options ) {\n\t\tvar key;\n\n\t\tfor ( key in options ) {\n\t\t\tthis._setOption( key, options[ key ] );\n\t\t}\n\n\t\treturn this;\n\t},\n\n\t_setOption: function( key, value ) {\n\t\tif ( key === \"classes\" ) {\n\t\t\tthis._setOptionClasses( value );\n\t\t}\n\n\t\tthis.options[ key ] = value;\n\n\t\tif ( key === \"disabled\" ) {\n\t\t\tthis._setOptionDisabled( value );\n\t\t}\n\n\t\treturn this;\n\t},\n\n\t_setOptionClasses: function( value ) {\n\t\tvar classKey, elements, currentElements;\n\n\t\tfor ( classKey in value ) {\n\t\t\tcurrentElements = this.classesElementLookup[ classKey ];\n\t\t\tif ( value[ classKey ] === this.options.classes[ classKey ] ||\n\t\t\t\t\t!currentElements ||\n\t\t\t\t\t!currentElements.length ) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\t// We are doing this to create a new jQuery object because the _removeClass() call\n\t\t\t// on the next line is going to destroy the reference to the current elements being\n\t\t\t// tracked. We need to save a copy of this collection so that we can add the new classes\n\t\t\t// below.\n\t\t\telements = $( currentElements.get() );\n\t\t\tthis._removeClass( currentElements, classKey );\n\n\t\t\t// We don't use _addClass() here, because that uses this.options.classes\n\t\t\t// for generating the string of classes. We want to use the value passed in from\n\t\t\t// _setOption(), this is the new value of the classes option which was passed to\n\t\t\t// _setOption(). We pass this value directly to _classes().\n\t\t\telements.addClass( this._classes( {\n\t\t\t\telement: elements,\n\t\t\t\tkeys: classKey,\n\t\t\t\tclasses: value,\n\t\t\t\tadd: true\n\t\t\t} ) );\n\t\t}\n\t},\n\n\t_setOptionDisabled: function( value ) {\n\t\tthis._toggleClass( this.widget(), this.widgetFullName + \"-disabled\", null, !!value );\n\n\t\t// If the widget is becoming disabled, then nothing is interactive\n\t\tif ( value ) {\n\t\t\tthis._removeClass( this.hoverable, null, \"ui-state-hover\" );\n\t\t\tthis._removeClass( this.focusable, null, \"ui-state-focus\" );\n\t\t}\n\t},\n\n\tenable: function() {\n\t\treturn this._setOptions( { disabled: false } );\n\t},\n\n\tdisable: function() {\n\t\treturn this._setOptions( { disabled: true } );\n\t},\n\n\t_classes: function( options ) {\n\t\tvar full = [];\n\t\tvar that = this;\n\n\t\toptions = $.extend( {\n\t\t\telement: this.element,\n\t\t\tclasses: this.options.classes || {}\n\t\t}, options );\n\n\t\tfunction processClassString( classes, checkOption ) {\n\t\t\tvar current, i;\n\t\t\tfor ( i = 0; i < classes.length; i++ ) {\n\t\t\t\tcurrent = that.classesElementLookup[ classes[ i ] ] || $();\n\t\t\t\tif ( options.add ) {\n\t\t\t\t\tcurrent = $( $.unique( current.get().concat( options.element.get() ) ) );\n\t\t\t\t} else {\n\t\t\t\t\tcurrent = $( current.not( options.element ).get() );\n\t\t\t\t}\n\t\t\t\tthat.classesElementLookup[ classes[ i ] ] = current;\n\t\t\t\tfull.push( classes[ i ] );\n\t\t\t\tif ( checkOption && options.classes[ classes[ i ] ] ) {\n\t\t\t\t\tfull.push( options.classes[ classes[ i ] ] );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tthis._on( options.element, {\n\t\t\t\"remove\": \"_untrackClassesElement\"\n\t\t} );\n\n\t\tif ( options.keys ) {\n\t\t\tprocessClassString( options.keys.match( /\\S+/g ) || [], true );\n\t\t}\n\t\tif ( options.extra ) {\n\t\t\tprocessClassString( options.extra.match( /\\S+/g ) || [] );\n\t\t}\n\n\t\treturn full.join( \" \" );\n\t},\n\n\t_untrackClassesElement: function( event ) {\n\t\tvar that = this;\n\t\t$.each( that.classesElementLookup, function( key, value ) {\n\t\t\tif ( $.inArray( event.target, value ) !== -1 ) {\n\t\t\t\tthat.classesElementLookup[ key ] = $( value.not( event.target ).get() );\n\t\t\t}\n\t\t} );\n\t},\n\n\t_removeClass: function( element, keys, extra ) {\n\t\treturn this._toggleClass( element, keys, extra, false );\n\t},\n\n\t_addClass: function( element, keys, extra ) {\n\t\treturn this._toggleClass( element, keys, extra, true );\n\t},\n\n\t_toggleClass: function( element, keys, extra, add ) {\n\t\tadd = ( typeof add === \"boolean\" ) ? add : extra;\n\t\tvar shift = ( typeof element === \"string\" || element === null ),\n\t\t\toptions = {\n\t\t\t\textra: shift ? keys : extra,\n\t\t\t\tkeys: shift ? element : keys,\n\t\t\t\telement: shift ? this.element : element,\n\t\t\t\tadd: add\n\t\t\t};\n\t\toptions.element.toggleClass( this._classes( options ), add );\n\t\treturn this;\n\t},\n\n\t_on: function( suppressDisabledCheck, element, handlers ) {\n\t\tvar delegateElement;\n\t\tvar instance = this;\n\n\t\t// No suppressDisabledCheck flag, shuffle arguments\n\t\tif ( typeof suppressDisabledCheck !== \"boolean\" ) {\n\t\t\thandlers = element;\n\t\t\telement = suppressDisabledCheck;\n\t\t\tsuppressDisabledCheck = false;\n\t\t}\n\n\t\t// No element argument, shuffle and use this.element\n\t\tif ( !handlers ) {\n\t\t\thandlers = element;\n\t\t\telement = this.element;\n\t\t\tdelegateElement = this.widget();\n\t\t} else {\n\t\t\telement = delegateElement = $( element );\n\t\t\tthis.bindings = this.bindings.add( element );\n\t\t}\n\n\t\t$.each( handlers, function( event, handler ) {\n\t\t\tfunction handlerProxy() {\n\n\t\t\t\t// Allow widgets to customize the disabled handling\n\t\t\t\t// - disabled as an array instead of boolean\n\t\t\t\t// - disabled class as method for disabling individual parts\n\t\t\t\tif ( !suppressDisabledCheck &&\n\t\t\t\t\t\t( instance.options.disabled === true ||\n\t\t\t\t\t\t$( this ).hasClass( \"ui-state-disabled\" ) ) ) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\treturn ( typeof handler === \"string\" ? instance[ handler ] : handler )\n\t\t\t\t\t.apply( instance, arguments );\n\t\t\t}\n\n\t\t\t// Copy the guid so direct unbinding works\n\t\t\tif ( typeof handler !== \"string\" ) {\n\t\t\t\thandlerProxy.guid = handler.guid =\n\t\t\t\t\thandler.guid || handlerProxy.guid || $.guid++;\n\t\t\t}\n\n\t\t\tvar match = event.match( /^([\\w:-]*)\\s*(.*)$/ );\n\t\t\tvar eventName = match[ 1 ] + instance.eventNamespace;\n\t\t\tvar selector = match[ 2 ];\n\n\t\t\tif ( selector ) {\n\t\t\t\tdelegateElement.on( eventName, selector, handlerProxy );\n\t\t\t} else {\n\t\t\t\telement.on( eventName, handlerProxy );\n\t\t\t}\n\t\t} );\n\t},\n\n\t_off: function( element, eventName ) {\n\t\teventName = ( eventName || \"\" ).split( \" \" ).join( this.eventNamespace + \" \" ) +\n\t\t\tthis.eventNamespace;\n\t\telement.off( eventName ).off( eventName );\n\n\t\t// Clear the stack to avoid memory leaks (#10056)\n\t\tthis.bindings = $( this.bindings.not( element ).get() );\n\t\tthis.focusable = $( this.focusable.not( element ).get() );\n\t\tthis.hoverable = $( this.hoverable.not( element ).get() );\n\t},\n\n\t_delay: function( handler, delay ) {\n\t\tfunction handlerProxy() {\n\t\t\treturn ( typeof handler === \"string\" ? instance[ handler ] : handler )\n\t\t\t\t.apply( instance, arguments );\n\t\t}\n\t\tvar instance = this;\n\t\treturn setTimeout( handlerProxy, delay || 0 );\n\t},\n\n\t_hoverable: function( element ) {\n\t\tthis.hoverable = this.hoverable.add( element );\n\t\tthis._on( element, {\n\t\t\tmouseenter: function( event ) {\n\t\t\t\tthis._addClass( $( event.currentTarget ), null, \"ui-state-hover\" );\n\t\t\t},\n\t\t\tmouseleave: function( event ) {\n\t\t\t\tthis._removeClass( $( event.currentTarget ), null, \"ui-state-hover\" );\n\t\t\t}\n\t\t} );\n\t},\n\n\t_focusable: function( element ) {\n\t\tthis.focusable = this.focusable.add( element );\n\t\tthis._on( element, {\n\t\t\tfocusin: function( event ) {\n\t\t\t\tthis._addClass( $( event.currentTarget ), null, \"ui-state-focus\" );\n\t\t\t},\n\t\t\tfocusout: function( event ) {\n\t\t\t\tthis._removeClass( $( event.currentTarget ), null, \"ui-state-focus\" );\n\t\t\t}\n\t\t} );\n\t},\n\n\t_trigger: function( type, event, data ) {\n\t\tvar prop, orig;\n\t\tvar callback = this.options[ type ];\n\n\t\tdata = data || {};\n\t\tevent = $.Event( event );\n\t\tevent.type = ( type === this.widgetEventPrefix ?\n\t\t\ttype :\n\t\t\tthis.widgetEventPrefix + type ).toLowerCase();\n\n\t\t// The original event may come from any element\n\t\t// so we need to reset the target on the new event\n\t\tevent.target = this.element[ 0 ];\n\n\t\t// Copy original event properties over to the new event\n\t\torig = event.originalEvent;\n\t\tif ( orig ) {\n\t\t\tfor ( prop in orig ) {\n\t\t\t\tif ( !( prop in event ) ) {\n\t\t\t\t\tevent[ prop ] = orig[ prop ];\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tthis.element.trigger( event, data );\n\t\treturn !( $.isFunction( callback ) &&\n\t\t\tcallback.apply( this.element[ 0 ], [ event ].concat( data ) ) === false ||\n\t\t\tevent.isDefaultPrevented() );\n\t}\n};\n\n$.each( { show: \"fadeIn\", hide: \"fadeOut\" }, function( method, defaultEffect ) {\n\t$.Widget.prototype[ \"_\" + method ] = function( element, options, callback ) {\n\t\tif ( typeof options === \"string\" ) {\n\t\t\toptions = { effect: options };\n\t\t}\n\n\t\tvar hasOptions;\n\t\tvar effectName = !options ?\n\t\t\tmethod :\n\t\t\toptions === true || typeof options === \"number\" ?\n\t\t\t\tdefaultEffect :\n\t\t\t\toptions.effect || defaultEffect;\n\n\t\toptions = options || {};\n\t\tif ( typeof options === \"number\" ) {\n\t\t\toptions = { duration: options };\n\t\t}\n\n\t\thasOptions = !$.isEmptyObject( options );\n\t\toptions.complete = callback;\n\n\t\tif ( options.delay ) {\n\t\t\telement.delay( options.delay );\n\t\t}\n\n\t\tif ( hasOptions && $.effects && $.effects.effect[ effectName ] ) {\n\t\t\telement[ method ]( options );\n\t\t} else if ( effectName !== method && element[ effectName ] ) {\n\t\t\telement[ effectName ]( options.duration, options.easing, callback );\n\t\t} else {\n\t\t\telement.queue( function( next ) {\n\t\t\t\t$( this )[ method ]();\n\t\t\t\tif ( callback ) {\n\t\t\t\t\tcallback.call( element[ 0 ] );\n\t\t\t\t}\n\t\t\t\tnext();\n\t\t\t} );\n\t\t}\n\t};\n} );\n\nvar widget = $.widget;\n\n\n/*!\n * jQuery UI Position 1.12.1\n * http://jqueryui.com\n *\n * Copyright jQuery Foundation and other contributors\n * Released under the MIT license.\n * http://jquery.org/license\n *\n * http://api.jqueryui.com/position/\n */\n\n//>>label: Position\n//>>group: Core\n//>>description: Positions elements relative to other elements.\n//>>docs: http://api.jqueryui.com/position/\n//>>demos: http://jqueryui.com/position/\n\n\n( function() {\nvar cachedScrollbarWidth,\n\tmax = Math.max,\n\tabs = Math.abs,\n\trhorizontal = /left|center|right/,\n\trvertical = /top|center|bottom/,\n\troffset = /[\\+\\-]\\d+(\\.[\\d]+)?%?/,\n\trposition = /^\\w+/,\n\trpercent = /%$/,\n\t_position = $.fn.position;\n\nfunction getOffsets( offsets, width, height ) {\n\treturn [\n\t\tparseFloat( offsets[ 0 ] ) * ( rpercent.test( offsets[ 0 ] ) ? width / 100 : 1 ),\n\t\tparseFloat( offsets[ 1 ] ) * ( rpercent.test( offsets[ 1 ] ) ? height / 100 : 1 )\n\t];\n}\n\nfunction parseCss( element, property ) {\n\treturn parseInt( $.css( element, property ), 10 ) || 0;\n}\n\nfunction getDimensions( elem ) {\n\tvar raw = elem[ 0 ];\n\tif ( raw.nodeType === 9 ) {\n\t\treturn {\n\t\t\twidth: elem.width(),\n\t\t\theight: elem.height(),\n\t\t\toffset: { top: 0, left: 0 }\n\t\t};\n\t}\n\tif ( $.isWindow( raw ) ) {\n\t\treturn {\n\t\t\twidth: elem.width(),\n\t\t\theight: elem.height(),\n\t\t\toffset: { top: elem.scrollTop(), left: elem.scrollLeft() }\n\t\t};\n\t}\n\tif ( raw.preventDefault ) {\n\t\treturn {\n\t\t\twidth: 0,\n\t\t\theight: 0,\n\t\t\toffset: { top: raw.pageY, left: raw.pageX }\n\t\t};\n\t}\n\treturn {\n\t\twidth: elem.outerWidth(),\n\t\theight: elem.outerHeight(),\n\t\toffset: elem.offset()\n\t};\n}\n\n$.position = $.position || {\n\tscrollbarWidth: function() {\n\t\tif ( cachedScrollbarWidth !== undefined ) {\n\t\t\treturn cachedScrollbarWidth;\n\t\t}\n\t\tvar w1, w2,\n\t\t\tdiv = $( \"<div \" +\n\t\t\t\t\"style='display:block;position:absolute;width:50px;height:50px;overflow:hidden;'>\" +\n\t\t\t\t\"<div style='height:100px;width:auto;'></div></div>\" ),\n\t\t\tinnerDiv = div.children()[ 0 ];\n\n\t\t$( \"body\" ).append( div );\n\t\tw1 = innerDiv.offsetWidth;\n\t\tdiv.css( \"overflow\", \"scroll\" );\n\n\t\tw2 = innerDiv.offsetWidth;\n\n\t\tif ( w1 === w2 ) {\n\t\t\tw2 = div[ 0 ].clientWidth;\n\t\t}\n\n\t\tdiv.remove();\n\n\t\treturn ( cachedScrollbarWidth = w1 - w2 );\n\t},\n\tgetScrollInfo: function( within ) {\n\t\tvar overflowX = within.isWindow || within.isDocument ? \"\" :\n\t\t\t\twithin.element.css( \"overflow-x\" ),\n\t\t\toverflowY = within.isWindow || within.isDocument ? \"\" :\n\t\t\t\twithin.element.css( \"overflow-y\" ),\n\t\t\thasOverflowX = overflowX === \"scroll\" ||\n\t\t\t\t( overflowX === \"auto\" && within.width < within.element[ 0 ].scrollWidth ),\n\t\t\thasOverflowY = overflowY === \"scroll\" ||\n\t\t\t\t( overflowY === \"auto\" && within.height < within.element[ 0 ].scrollHeight );\n\t\treturn {\n\t\t\twidth: hasOverflowY ? $.position.scrollbarWidth() : 0,\n\t\t\theight: hasOverflowX ? $.position.scrollbarWidth() : 0\n\t\t};\n\t},\n\tgetWithinInfo: function( element ) {\n\t\tvar withinElement = $( element || window ),\n\t\t\tisWindow = $.isWindow( withinElement[ 0 ] ),\n\t\t\tisDocument = !!withinElement[ 0 ] && withinElement[ 0 ].nodeType === 9,\n\t\t\thasOffset = !isWindow && !isDocument;\n\t\treturn {\n\t\t\telement: withinElement,\n\t\t\tisWindow: isWindow,\n\t\t\tisDocument: isDocument,\n\t\t\toffset: hasOffset ? $( element ).offset() : { left: 0, top: 0 },\n\t\t\tscrollLeft: withinElement.scrollLeft(),\n\t\t\tscrollTop: withinElement.scrollTop(),\n\t\t\twidth: withinElement.outerWidth(),\n\t\t\theight: withinElement.outerHeight()\n\t\t};\n\t}\n};\n\n$.fn.position = function( options ) {\n\tif ( !options || !options.of ) {\n\t\treturn _position.apply( this, arguments );\n\t}\n\n\t// Make a copy, we don't want to modify arguments\n\toptions = $.extend( {}, options );\n\n\tvar atOffset, targetWidth, targetHeight, targetOffset, basePosition, dimensions,\n\t\ttarget = $( options.of ),\n\t\twithin = $.position.getWithinInfo( options.within ),\n\t\tscrollInfo = $.position.getScrollInfo( within ),\n\t\tcollision = ( options.collision || \"flip\" ).split( \" \" ),\n\t\toffsets = {};\n\n\tdimensions = getDimensions( target );\n\tif ( target[ 0 ].preventDefault ) {\n\n\t\t// Force left top to allow flipping\n\t\toptions.at = \"left top\";\n\t}\n\ttargetWidth = dimensions.width;\n\ttargetHeight = dimensions.height;\n\ttargetOffset = dimensions.offset;\n\n\t// Clone to reuse original targetOffset later\n\tbasePosition = $.extend( {}, targetOffset );\n\n\t// Force my and at to have valid horizontal and vertical positions\n\t// if a value is missing or invalid, it will be converted to center\n\t$.each( [ \"my\", \"at\" ], function() {\n\t\tvar pos = ( options[ this ] || \"\" ).split( \" \" ),\n\t\t\thorizontalOffset,\n\t\t\tverticalOffset;\n\n\t\tif ( pos.length === 1 ) {\n\t\t\tpos = rhorizontal.test( pos[ 0 ] ) ?\n\t\t\t\tpos.concat( [ \"center\" ] ) :\n\t\t\t\trvertical.test( pos[ 0 ] ) ?\n\t\t\t\t\t[ \"center\" ].concat( pos ) :\n\t\t\t\t\t[ \"center\", \"center\" ];\n\t\t}\n\t\tpos[ 0 ] = rhorizontal.test( pos[ 0 ] ) ? pos[ 0 ] : \"center\";\n\t\tpos[ 1 ] = rvertical.test( pos[ 1 ] ) ? pos[ 1 ] : \"center\";\n\n\t\t// Calculate offsets\n\t\thorizontalOffset = roffset.exec( pos[ 0 ] );\n\t\tverticalOffset = roffset.exec( pos[ 1 ] );\n\t\toffsets[ this ] = [\n\t\t\thorizontalOffset ? horizontalOffset[ 0 ] : 0,\n\t\t\tverticalOffset ? verticalOffset[ 0 ] : 0\n\t\t];\n\n\t\t// Reduce to just the positions without the offsets\n\t\toptions[ this ] = [\n\t\t\trposition.exec( pos[ 0 ] )[ 0 ],\n\t\t\trposition.exec( pos[ 1 ] )[ 0 ]\n\t\t];\n\t} );\n\n\t// Normalize collision option\n\tif ( collision.length === 1 ) {\n\t\tcollision[ 1 ] = collision[ 0 ];\n\t}\n\n\tif ( options.at[ 0 ] === \"right\" ) {\n\t\tbasePosition.left += targetWidth;\n\t} else if ( options.at[ 0 ] === \"center\" ) {\n\t\tbasePosition.left += targetWidth / 2;\n\t}\n\n\tif ( options.at[ 1 ] === \"bottom\" ) {\n\t\tbasePosition.top += targetHeight;\n\t} else if ( options.at[ 1 ] === \"center\" ) {\n\t\tbasePosition.top += targetHeight / 2;\n\t}\n\n\tatOffset = getOffsets( offsets.at, targetWidth, targetHeight );\n\tbasePosition.left += atOffset[ 0 ];\n\tbasePosition.top += atOffset[ 1 ];\n\n\treturn this.each( function() {\n\t\tvar collisionPosition, using,\n\t\t\telem = $( this ),\n\t\t\telemWidth = elem.outerWidth(),\n\t\t\telemHeight = elem.outerHeight(),\n\t\t\tmarginLeft = parseCss( this, \"marginLeft\" ),\n\t\t\tmarginTop = parseCss( this, \"marginTop\" ),\n\t\t\tcollisionWidth = elemWidth + marginLeft + parseCss( this, \"marginRight\" ) +\n\t\t\t\tscrollInfo.width,\n\t\t\tcollisionHeight = elemHeight + marginTop + parseCss( this, \"marginBottom\" ) +\n\t\t\t\tscrollInfo.height,\n\t\t\tposition = $.extend( {}, basePosition ),\n\t\t\tmyOffset = getOffsets( offsets.my, elem.outerWidth(), elem.outerHeight() );\n\n\t\tif ( options.my[ 0 ] === \"right\" ) {\n\t\t\tposition.left -= elemWidth;\n\t\t} else if ( options.my[ 0 ] === \"center\" ) {\n\t\t\tposition.left -= elemWidth / 2;\n\t\t}\n\n\t\tif ( options.my[ 1 ] === \"bottom\" ) {\n\t\t\tposition.top -= elemHeight;\n\t\t} else if ( options.my[ 1 ] === \"center\" ) {\n\t\t\tposition.top -= elemHeight / 2;\n\t\t}\n\n\t\tposition.left += myOffset[ 0 ];\n\t\tposition.top += myOffset[ 1 ];\n\n\t\tcollisionPosition = {\n\t\t\tmarginLeft: marginLeft,\n\t\t\tmarginTop: marginTop\n\t\t};\n\n\t\t$.each( [ \"left\", \"top\" ], function( i, dir ) {\n\t\t\tif ( $.ui.position[ collision[ i ] ] ) {\n\t\t\t\t$.ui.position[ collision[ i ] ][ dir ]( position, {\n\t\t\t\t\ttargetWidth: targetWidth,\n\t\t\t\t\ttargetHeight: targetHeight,\n\t\t\t\t\telemWidth: elemWidth,\n\t\t\t\t\telemHeight: elemHeight,\n\t\t\t\t\tcollisionPosition: collisionPosition,\n\t\t\t\t\tcollisionWidth: collisionWidth,\n\t\t\t\t\tcollisionHeight: collisionHeight,\n\t\t\t\t\toffset: [ atOffset[ 0 ] + myOffset[ 0 ], atOffset [ 1 ] + myOffset[ 1 ] ],\n\t\t\t\t\tmy: options.my,\n\t\t\t\t\tat: options.at,\n\t\t\t\t\twithin: within,\n\t\t\t\t\telem: elem\n\t\t\t\t} );\n\t\t\t}\n\t\t} );\n\n\t\tif ( options.using ) {\n\n\t\t\t// Adds feedback as second argument to using callback, if present\n\t\t\tusing = function( props ) {\n\t\t\t\tvar left = targetOffset.left - position.left,\n\t\t\t\t\tright = left + targetWidth - elemWidth,\n\t\t\t\t\ttop = targetOffset.top - position.top,\n\t\t\t\t\tbottom = top + targetHeight - elemHeight,\n\t\t\t\t\tfeedback = {\n\t\t\t\t\t\ttarget: {\n\t\t\t\t\t\t\telement: target,\n\t\t\t\t\t\t\tleft: targetOffset.left,\n\t\t\t\t\t\t\ttop: targetOffset.top,\n\t\t\t\t\t\t\twidth: targetWidth,\n\t\t\t\t\t\t\theight: targetHeight\n\t\t\t\t\t\t},\n\t\t\t\t\t\telement: {\n\t\t\t\t\t\t\telement: elem,\n\t\t\t\t\t\t\tleft: position.left,\n\t\t\t\t\t\t\ttop: position.top,\n\t\t\t\t\t\t\twidth: elemWidth,\n\t\t\t\t\t\t\theight: elemHeight\n\t\t\t\t\t\t},\n\t\t\t\t\t\thorizontal: right < 0 ? \"left\" : left > 0 ? \"right\" : \"center\",\n\t\t\t\t\t\tvertical: bottom < 0 ? \"top\" : top > 0 ? \"bottom\" : \"middle\"\n\t\t\t\t\t};\n\t\t\t\tif ( targetWidth < elemWidth && abs( left + right ) < targetWidth ) {\n\t\t\t\t\tfeedback.horizontal = \"center\";\n\t\t\t\t}\n\t\t\t\tif ( targetHeight < elemHeight && abs( top + bottom ) < targetHeight ) {\n\t\t\t\t\tfeedback.vertical = \"middle\";\n\t\t\t\t}\n\t\t\t\tif ( max( abs( left ), abs( right ) ) > max( abs( top ), abs( bottom ) ) ) {\n\t\t\t\t\tfeedback.important = \"horizontal\";\n\t\t\t\t} else {\n\t\t\t\t\tfeedback.important = \"vertical\";\n\t\t\t\t}\n\t\t\t\toptions.using.call( this, props, feedback );\n\t\t\t};\n\t\t}\n\n\t\telem.offset( $.extend( position, { using: using } ) );\n\t} );\n};\n\n$.ui.position = {\n\tfit: {\n\t\tleft: function( position, data ) {\n\t\t\tvar within = data.within,\n\t\t\t\twithinOffset = within.isWindow ? within.scrollLeft : within.offset.left,\n\t\t\t\touterWidth = within.width,\n\t\t\t\tcollisionPosLeft = position.left - data.collisionPosition.marginLeft,\n\t\t\t\toverLeft = withinOffset - collisionPosLeft,\n\t\t\t\toverRight = collisionPosLeft + data.collisionWidth - outerWidth - withinOffset,\n\t\t\t\tnewOverRight;\n\n\t\t\t// Element is wider than within\n\t\t\tif ( data.collisionWidth > outerWidth ) {\n\n\t\t\t\t// Element is initially over the left side of within\n\t\t\t\tif ( overLeft > 0 && overRight <= 0 ) {\n\t\t\t\t\tnewOverRight = position.left + overLeft + data.collisionWidth - outerWidth -\n\t\t\t\t\t\twithinOffset;\n\t\t\t\t\tposition.left += overLeft - newOverRight;\n\n\t\t\t\t// Element is initially over right side of within\n\t\t\t\t} else if ( overRight > 0 && overLeft <= 0 ) {\n\t\t\t\t\tposition.left = withinOffset;\n\n\t\t\t\t// Element is initially over both left and right sides of within\n\t\t\t\t} else {\n\t\t\t\t\tif ( overLeft > overRight ) {\n\t\t\t\t\t\tposition.left = withinOffset + outerWidth - data.collisionWidth;\n\t\t\t\t\t} else {\n\t\t\t\t\t\tposition.left = withinOffset;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t// Too far left -> align with left edge\n\t\t\t} else if ( overLeft > 0 ) {\n\t\t\t\tposition.left += overLeft;\n\n\t\t\t// Too far right -> align with right edge\n\t\t\t} else if ( overRight > 0 ) {\n\t\t\t\tposition.left -= overRight;\n\n\t\t\t// Adjust based on position and margin\n\t\t\t} else {\n\t\t\t\tposition.left = max( position.left - collisionPosLeft, position.left );\n\t\t\t}\n\t\t},\n\t\ttop: function( position, data ) {\n\t\t\tvar within = data.within,\n\t\t\t\twithinOffset = within.isWindow ? within.scrollTop : within.offset.top,\n\t\t\t\touterHeight = data.within.height,\n\t\t\t\tcollisionPosTop = position.top - data.collisionPosition.marginTop,\n\t\t\t\toverTop = withinOffset - collisionPosTop,\n\t\t\t\toverBottom = collisionPosTop + data.collisionHeight - outerHeight - withinOffset,\n\t\t\t\tnewOverBottom;\n\n\t\t\t// Element is taller than within\n\t\t\tif ( data.collisionHeight > outerHeight ) {\n\n\t\t\t\t// Element is initially over the top of within\n\t\t\t\tif ( overTop > 0 && overBottom <= 0 ) {\n\t\t\t\t\tnewOverBottom = position.top + overTop + data.collisionHeight - outerHeight -\n\t\t\t\t\t\twithinOffset;\n\t\t\t\t\tposition.top += overTop - newOverBottom;\n\n\t\t\t\t// Element is initially over bottom of within\n\t\t\t\t} else if ( overBottom > 0 && overTop <= 0 ) {\n\t\t\t\t\tposition.top = withinOffset;\n\n\t\t\t\t// Element is initially over both top and bottom of within\n\t\t\t\t} else {\n\t\t\t\t\tif ( overTop > overBottom ) {\n\t\t\t\t\t\tposition.top = withinOffset + outerHeight - data.collisionHeight;\n\t\t\t\t\t} else {\n\t\t\t\t\t\tposition.top = withinOffset;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t// Too far up -> align with top\n\t\t\t} else if ( overTop > 0 ) {\n\t\t\t\tposition.top += overTop;\n\n\t\t\t// Too far down -> align with bottom edge\n\t\t\t} else if ( overBottom > 0 ) {\n\t\t\t\tposition.top -= overBottom;\n\n\t\t\t// Adjust based on position and margin\n\t\t\t} else {\n\t\t\t\tposition.top = max( position.top - collisionPosTop, position.top );\n\t\t\t}\n\t\t}\n\t},\n\tflip: {\n\t\tleft: function( position, data ) {\n\t\t\tvar within = data.within,\n\t\t\t\twithinOffset = within.offset.left + within.scrollLeft,\n\t\t\t\touterWidth = within.width,\n\t\t\t\toffsetLeft = within.isWindow ? within.scrollLeft : within.offset.left,\n\t\t\t\tcollisionPosLeft = position.left - data.collisionPosition.marginLeft,\n\t\t\t\toverLeft = collisionPosLeft - offsetLeft,\n\t\t\t\toverRight = collisionPosLeft + data.collisionWidth - outerWidth - offsetLeft,\n\t\t\t\tmyOffset = data.my[ 0 ] === \"left\" ?\n\t\t\t\t\t-data.elemWidth :\n\t\t\t\t\tdata.my[ 0 ] === \"right\" ?\n\t\t\t\t\t\tdata.elemWidth :\n\t\t\t\t\t\t0,\n\t\t\t\tatOffset = data.at[ 0 ] === \"left\" ?\n\t\t\t\t\tdata.targetWidth :\n\t\t\t\t\tdata.at[ 0 ] === \"right\" ?\n\t\t\t\t\t\t-data.targetWidth :\n\t\t\t\t\t\t0,\n\t\t\t\toffset = -2 * data.offset[ 0 ],\n\t\t\t\tnewOverRight,\n\t\t\t\tnewOverLeft;\n\n\t\t\tif ( overLeft < 0 ) {\n\t\t\t\tnewOverRight = position.left + myOffset + atOffset + offset + data.collisionWidth -\n\t\t\t\t\touterWidth - withinOffset;\n\t\t\t\tif ( newOverRight < 0 || newOverRight < abs( overLeft ) ) {\n\t\t\t\t\tposition.left += myOffset + atOffset + offset;\n\t\t\t\t}\n\t\t\t} else if ( overRight > 0 ) {\n\t\t\t\tnewOverLeft = position.left - data.collisionPosition.marginLeft + myOffset +\n\t\t\t\t\tatOffset + offset - offsetLeft;\n\t\t\t\tif ( newOverLeft > 0 || abs( newOverLeft ) < overRight ) {\n\t\t\t\t\tposition.left += myOffset + atOffset + offset;\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t\ttop: function( position, data ) {\n\t\t\tvar within = data.within,\n\t\t\t\twithinOffset = within.offset.top + within.scrollTop,\n\t\t\t\touterHeight = within.height,\n\t\t\t\toffsetTop = within.isWindow ? within.scrollTop : within.offset.top,\n\t\t\t\tcollisionPosTop = position.top - data.collisionPosition.marginTop,\n\t\t\t\toverTop = collisionPosTop - offsetTop,\n\t\t\t\toverBottom = collisionPosTop + data.collisionHeight - outerHeight - offsetTop,\n\t\t\t\ttop = data.my[ 1 ] === \"top\",\n\t\t\t\tmyOffset = top ?\n\t\t\t\t\t-data.elemHeight :\n\t\t\t\t\tdata.my[ 1 ] === \"bottom\" ?\n\t\t\t\t\t\tdata.elemHeight :\n\t\t\t\t\t\t0,\n\t\t\t\tatOffset = data.at[ 1 ] === \"top\" ?\n\t\t\t\t\tdata.targetHeight :\n\t\t\t\t\tdata.at[ 1 ] === \"bottom\" ?\n\t\t\t\t\t\t-data.targetHeight :\n\t\t\t\t\t\t0,\n\t\t\t\toffset = -2 * data.offset[ 1 ],\n\t\t\t\tnewOverTop,\n\t\t\t\tnewOverBottom;\n\t\t\tif ( overTop < 0 ) {\n\t\t\t\tnewOverBottom = position.top + myOffset + atOffset + offset + data.collisionHeight -\n\t\t\t\t\touterHeight - withinOffset;\n\t\t\t\tif ( newOverBottom < 0 || newOverBottom < abs( overTop ) ) {\n\t\t\t\t\tposition.top += myOffset + atOffset + offset;\n\t\t\t\t}\n\t\t\t} else if ( overBottom > 0 ) {\n\t\t\t\tnewOverTop = position.top - data.collisionPosition.marginTop + myOffset + atOffset +\n\t\t\t\t\toffset - offsetTop;\n\t\t\t\tif ( newOverTop > 0 || abs( newOverTop ) < overBottom ) {\n\t\t\t\t\tposition.top += myOffset + atOffset + offset;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t},\n\tflipfit: {\n\t\tleft: function() {\n\t\t\t$.ui.position.flip.left.apply( this, arguments );\n\t\t\t$.ui.position.fit.left.apply( this, arguments );\n\t\t},\n\t\ttop: function() {\n\t\t\t$.ui.position.flip.top.apply( this, arguments );\n\t\t\t$.ui.position.fit.top.apply( this, arguments );\n\t\t}\n\t}\n};\n\n} )();\n\nvar position = $.ui.position;\n\n\n/*!\n * jQuery UI Keycode 1.12.1\n * http://jqueryui.com\n *\n * Copyright jQuery Foundation and other contributors\n * Released under the MIT license.\n * http://jquery.org/license\n */\n\n//>>label: Keycode\n//>>group: Core\n//>>description: Provide keycodes as keynames\n//>>docs: http://api.jqueryui.com/jQuery.ui.keyCode/\n\n\nvar keycode = $.ui.keyCode = {\n\tBACKSPACE: 8,\n\tCOMMA: 188,\n\tDELETE: 46,\n\tDOWN: 40,\n\tEND: 35,\n\tENTER: 13,\n\tESCAPE: 27,\n\tHOME: 36,\n\tLEFT: 37,\n\tPAGE_DOWN: 34,\n\tPAGE_UP: 33,\n\tPERIOD: 190,\n\tRIGHT: 39,\n\tSPACE: 32,\n\tTAB: 9,\n\tUP: 38\n};\n\n\n/*!\n * jQuery UI Scroll Parent 1.12.1\n * http://jqueryui.com\n *\n * Copyright jQuery Foundation and other contributors\n * Released under the MIT license.\n * http://jquery.org/license\n */\n\n//>>label: scrollParent\n//>>group: Core\n//>>description: Get the closest ancestor element that is scrollable.\n//>>docs: http://api.jqueryui.com/scrollParent/\n\n\n\nvar scrollParent = $.fn.scrollParent = function( includeHidden ) {\n\tvar position = this.css( \"position\" ),\n\t\texcludeStaticParent = position === \"absolute\",\n\t\toverflowRegex = includeHidden ? /(auto|scroll|hidden)/ : /(auto|scroll)/,\n\t\tscrollParent = this.parents().filter( function() {\n\t\t\tvar parent = $( this );\n\t\t\tif ( excludeStaticParent && parent.css( \"position\" ) === \"static\" ) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\treturn overflowRegex.test( parent.css( \"overflow\" ) + parent.css( \"overflow-y\" ) +\n\t\t\t\tparent.css( \"overflow-x\" ) );\n\t\t} ).eq( 0 );\n\n\treturn position === \"fixed\" || !scrollParent.length ?\n\t\t$( this[ 0 ].ownerDocument || document ) :\n\t\tscrollParent;\n};\n\n\n/*!\n * jQuery UI Unique ID 1.12.1\n * http://jqueryui.com\n *\n * Copyright jQuery Foundation and other contributors\n * Released under the MIT license.\n * http://jquery.org/license\n */\n\n//>>label: uniqueId\n//>>group: Core\n//>>description: Functions to generate and remove uniqueId's\n//>>docs: http://api.jqueryui.com/uniqueId/\n\n\n\nvar uniqueId = $.fn.extend( {\n\tuniqueId: ( function() {\n\t\tvar uuid = 0;\n\n\t\treturn function() {\n\t\t\treturn this.each( function() {\n\t\t\t\tif ( !this.id ) {\n\t\t\t\t\tthis.id = \"ui-id-\" + ( ++uuid );\n\t\t\t\t}\n\t\t\t} );\n\t\t};\n\t} )(),\n\n\tremoveUniqueId: function() {\n\t\treturn this.each( function() {\n\t\t\tif ( /^ui-id-\\d+$/.test( this.id ) ) {\n\t\t\t\t$( this ).removeAttr( \"id\" );\n\t\t\t}\n\t\t} );\n\t}\n} );\n\n\n}));\n","/*!\n * jquery.fancytree.js\n * Tree view control with support for lazy loading and much more.\n * https://github.com/mar10/fancytree/\n *\n * Copyright (c) 2008-2018, Martin Wendt (http://wwWendt.de)\n * Released under the MIT license\n * https://github.com/mar10/fancytree/wiki/LicenseInfo\n *\n * @version 2.30.1\n * @date 2018-11-13T18:58:18Z\n */\n\n/** Core Fancytree module.\n */\n\n// UMD wrapper for the Fancytree core module\n(function(factory) {\n\tif (typeof define === \"function\" && define.amd) {\n\t\t// AMD. Register as an anonymous module.\n\t\tdefine([\"jquery\", \"./jquery.fancytree.ui-deps\"], factory);\n\t} else if (typeof module === \"object\" && module.exports) {\n\t\t// Node/CommonJS\n\t\trequire(\"./jquery.fancytree.ui-deps\");\n\t\tmodule.exports = factory(require(\"jquery\"));\n\t} else {\n\t\t// Browser globals\n\t\tfactory(jQuery);\n\t}\n})(function($) {\n\t\"use strict\";\n\n\t// prevent duplicate loading\n\tif ($.ui && $.ui.fancytree) {\n\t\t$.ui.fancytree.warn(\"Fancytree: ignored duplicate include\");\n\t\treturn;\n\t}\n\n\t/******************************************************************************\n\t * Private functions and variables\n\t */\n\n\tvar i,\n\t\tattr,\n\t\tFT = null, // initialized below\n\t\tTEST_IMG = new RegExp(/\\.|\\//), // strings are considered image urls if they contain '.' or '/'\n\t\tREX_HTML = /[&<>\"'\\/]/g, // Escape those characters\n\t\tREX_TOOLTIP = /[<>\"'\\/]/g, // Don't escape `&` in tooltips\n\t\tRECURSIVE_REQUEST_ERROR = \"$recursive_request\",\n\t\tENTITY_MAP = {\n\t\t\t\"&\": \"&amp;\",\n\t\t\t\"<\": \"&lt;\",\n\t\t\t\">\": \"&gt;\",\n\t\t\t'\"': \"&quot;\",\n\t\t\t\"'\": \"&#39;\",\n\t\t\t\"/\": \"&#x2F;\",\n\t\t},\n\t\tIGNORE_KEYCODES = { 16: true, 17: true, 18: true },\n\t\tSPECIAL_KEYCODES = {\n\t\t\t8: \"backspace\",\n\t\t\t9: \"tab\",\n\t\t\t10: \"return\",\n\t\t\t13: \"return\",\n\t\t\t// 16: null, 17: null, 18: null,  // ignore shift, ctrl, alt\n\t\t\t19: \"pause\",\n\t\t\t20: \"capslock\",\n\t\t\t27: \"esc\",\n\t\t\t32: \"space\",\n\t\t\t33: \"pageup\",\n\t\t\t34: \"pagedown\",\n\t\t\t35: \"end\",\n\t\t\t36: \"home\",\n\t\t\t37: \"left\",\n\t\t\t38: \"up\",\n\t\t\t39: \"right\",\n\t\t\t40: \"down\",\n\t\t\t45: \"insert\",\n\t\t\t46: \"del\",\n\t\t\t59: \";\",\n\t\t\t61: \"=\",\n\t\t\t// 91: null, 93: null,  // ignore left and right meta\n\t\t\t96: \"0\",\n\t\t\t97: \"1\",\n\t\t\t98: \"2\",\n\t\t\t99: \"3\",\n\t\t\t100: \"4\",\n\t\t\t101: \"5\",\n\t\t\t102: \"6\",\n\t\t\t103: \"7\",\n\t\t\t104: \"8\",\n\t\t\t105: \"9\",\n\t\t\t106: \"*\",\n\t\t\t107: \"+\",\n\t\t\t109: \"-\",\n\t\t\t110: \".\",\n\t\t\t111: \"/\",\n\t\t\t112: \"f1\",\n\t\t\t113: \"f2\",\n\t\t\t114: \"f3\",\n\t\t\t115: \"f4\",\n\t\t\t116: \"f5\",\n\t\t\t117: \"f6\",\n\t\t\t118: \"f7\",\n\t\t\t119: \"f8\",\n\t\t\t120: \"f9\",\n\t\t\t121: \"f10\",\n\t\t\t122: \"f11\",\n\t\t\t123: \"f12\",\n\t\t\t144: \"numlock\",\n\t\t\t145: \"scroll\",\n\t\t\t173: \"-\",\n\t\t\t186: \";\",\n\t\t\t187: \"=\",\n\t\t\t188: \",\",\n\t\t\t189: \"-\",\n\t\t\t190: \".\",\n\t\t\t191: \"/\",\n\t\t\t192: \"`\",\n\t\t\t219: \"[\",\n\t\t\t220: \"\\\\\",\n\t\t\t221: \"]\",\n\t\t\t222: \"'\",\n\t\t},\n\t\tMODIFIERS = {\n\t\t\t16: \"shift\",\n\t\t\t17: \"ctrl\",\n\t\t\t18: \"alt\",\n\t\t\t91: \"meta\",\n\t\t\t93: \"meta\",\n\t\t},\n\t\tMOUSE_BUTTONS = { 0: \"\", 1: \"left\", 2: \"middle\", 3: \"right\" },\n\t\t// Boolean attributes that can be set with equivalent class names in the LI tags\n\t\t// Note: v2.23: checkbox and hideCheckbox are *not* in this list\n\t\tCLASS_ATTRS = \"active expanded focus folder lazy radiogroup selected unselectable unselectableIgnore\".split(\n\t\t\t\" \"\n\t\t),\n\t\tCLASS_ATTR_MAP = {},\n\t\t// Top-level Fancytree attributes, that can be set by dict\n\t\tTREE_ATTRS = \"columns types\".split(\" \"),\n\t\t// TREE_ATTR_MAP = {},\n\t\t// Top-level FancytreeNode attributes, that can be set by dict\n\t\tNODE_ATTRS = \"checkbox expanded extraClasses folder icon iconTooltip key lazy partsel radiogroup refKey selected statusNodeType title tooltip type unselectable unselectableIgnore unselectableStatus\".split(\n\t\t\t\" \"\n\t\t),\n\t\tNODE_ATTR_MAP = {},\n\t\t// Mapping of lowercase -> real name (because HTML5 data-... attribute only supports lowercase)\n\t\tNODE_ATTR_LOWERCASE_MAP = {},\n\t\t// Attribute names that should NOT be added to node.data\n\t\tNONE_NODE_DATA_MAP = {\n\t\t\tactive: true,\n\t\t\tchildren: true,\n\t\t\tdata: true,\n\t\t\tfocus: true,\n\t\t};\n\n\tfor (i = 0; i < CLASS_ATTRS.length; i++) {\n\t\tCLASS_ATTR_MAP[CLASS_ATTRS[i]] = true;\n\t}\n\tfor (i = 0; i < NODE_ATTRS.length; i++) {\n\t\tattr = NODE_ATTRS[i];\n\t\tNODE_ATTR_MAP[attr] = true;\n\t\tif (attr !== attr.toLowerCase()) {\n\t\t\tNODE_ATTR_LOWERCASE_MAP[attr.toLowerCase()] = attr;\n\t\t}\n\t}\n\t// for(i=0; i<TREE_ATTRS.length; i++) {\n\t// \tTREE_ATTR_MAP[TREE_ATTRS[i]] = true;\n\t// }\n\n\tfunction _assert(cond, msg) {\n\t\t// TODO: see qunit.js extractStacktrace()\n\t\tif (!cond) {\n\t\t\tmsg = msg ? \": \" + msg : \"\";\n\t\t\t// consoleApply(\"assert\", [!!cond, msg]);\n\t\t\t$.error(\"Fancytree assertion failed\" + msg);\n\t\t}\n\t}\n\n\t_assert($.ui, \"Fancytree requires jQuery UI (http://jqueryui.com)\");\n\n\tfunction consoleApply(method, args) {\n\t\tvar i,\n\t\t\ts,\n\t\t\tfn = window.console ? window.console[method] : null;\n\n\t\tif (fn) {\n\t\t\ttry {\n\t\t\t\tfn.apply(window.console, args);\n\t\t\t} catch (e) {\n\t\t\t\t// IE 8?\n\t\t\t\ts = \"\";\n\t\t\t\tfor (i = 0; i < args.length; i++) {\n\t\t\t\t\ts += args[i];\n\t\t\t\t}\n\t\t\t\tfn(s);\n\t\t\t}\n\t\t}\n\t}\n\n\t/* support: IE8 Polyfil for Date.now() */\n\tif (!Date.now) {\n\t\tDate.now = function now() {\n\t\t\treturn new Date().getTime();\n\t\t};\n\t}\n\n\t/*Return true if x is a FancytreeNode.*/\n\tfunction _isNode(x) {\n\t\treturn !!(x.tree && x.statusNodeType !== undefined);\n\t}\n\n\t/** Return true if dotted version string is equal or higher than requested version.\n\t *\n\t * See http://jsfiddle.net/mar10/FjSAN/\n\t */\n\tfunction isVersionAtLeast(dottedVersion, major, minor, patch) {\n\t\tvar i,\n\t\t\tv,\n\t\t\tt,\n\t\t\tverParts = $.map($.trim(dottedVersion).split(\".\"), function(e) {\n\t\t\t\treturn parseInt(e, 10);\n\t\t\t}),\n\t\t\ttestParts = $.map(\n\t\t\t\tArray.prototype.slice.call(arguments, 1),\n\t\t\t\tfunction(e) {\n\t\t\t\t\treturn parseInt(e, 10);\n\t\t\t\t}\n\t\t\t);\n\n\t\tfor (i = 0; i < testParts.length; i++) {\n\t\t\tv = verParts[i] || 0;\n\t\t\tt = testParts[i] || 0;\n\t\t\tif (v !== t) {\n\t\t\t\treturn v > t;\n\t\t\t}\n\t\t}\n\t\treturn true;\n\t}\n\n\t/**\n\t * Deep-merge a list of objects (but replace array-type options).\n\t *\n\t * jQuery's $.extend(true, ...) method does a deep merge, that also merges Arrays.\n\t * This variant is used to merge extension defaults with user options, and should\n\t * merge objects, but override arrays (for example the `triggerStart: [...]` option\n\t * of ext-edit). Also `null` values are copied over and not skipped.\n\t *\n\t * See issue #876\n\t *\n\t * Example:\n\t * _simpleDeepMerge({}, o1, o2);\n\t */\n\tfunction _simpleDeepMerge() {\n\t\tvar options,\n\t\t\tname,\n\t\t\tsrc,\n\t\t\tcopy,\n\t\t\tclone,\n\t\t\ttarget = arguments[0] || {},\n\t\t\ti = 1,\n\t\t\tlength = arguments.length;\n\n\t\t// Handle case when target is a string or something (possible in deep copy)\n\t\tif (typeof target !== \"object\" && !$.isFunction(target)) {\n\t\t\ttarget = {};\n\t\t}\n\t\tif (i === length) {\n\t\t\tthrow \"need at least two args\";\n\t\t}\n\t\tfor (; i < length; i++) {\n\t\t\t// Only deal with non-null/undefined values\n\t\t\tif ((options = arguments[i]) != null) {\n\t\t\t\t// Extend the base object\n\t\t\t\tfor (name in options) {\n\t\t\t\t\tsrc = target[name];\n\t\t\t\t\tcopy = options[name];\n\t\t\t\t\t// Prevent never-ending loop\n\t\t\t\t\tif (target === copy) {\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\t\t\t\t\t// Recurse if we're merging plain objects\n\t\t\t\t\t// (NOTE: unlike $.extend, we don't merge arrays, but relace them)\n\t\t\t\t\tif (copy && $.isPlainObject(copy)) {\n\t\t\t\t\t\tclone = src && $.isPlainObject(src) ? src : {};\n\t\t\t\t\t\t// Never move original objects, clone them\n\t\t\t\t\t\ttarget[name] = _simpleDeepMerge(clone, copy);\n\t\t\t\t\t\t// Don't bring in undefined values\n\t\t\t\t\t} else if (copy !== undefined) {\n\t\t\t\t\t\ttarget[name] = copy;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\t// Return the modified object\n\t\treturn target;\n\t}\n\n\t/** Return a wrapper that calls sub.methodName() and exposes\n\t *  this             : tree\n\t *  this._local      : tree.ext.EXTNAME\n\t *  this._super      : base.methodName.call()\n\t *  this._superApply : base.methodName.apply()\n\t */\n\tfunction _makeVirtualFunction(methodName, tree, base, extension, extName) {\n\t\t// $.ui.fancytree.debug(\"_makeVirtualFunction\", methodName, tree, base, extension, extName);\n\t\t// if(rexTestSuper && !rexTestSuper.test(func)){\n\t\t//     // extension.methodName() doesn't call _super(), so no wrapper required\n\t\t//     return func;\n\t\t// }\n\t\t// Use an immediate function as closure\n\t\tvar proxy = (function() {\n\t\t\tvar prevFunc = tree[methodName], // org. tree method or prev. proxy\n\t\t\t\tbaseFunc = extension[methodName], //\n\t\t\t\t_local = tree.ext[extName],\n\t\t\t\t_super = function() {\n\t\t\t\t\treturn prevFunc.apply(tree, arguments);\n\t\t\t\t},\n\t\t\t\t_superApply = function(args) {\n\t\t\t\t\treturn prevFunc.apply(tree, args);\n\t\t\t\t};\n\n\t\t\t// Return the wrapper function\n\t\t\treturn function() {\n\t\t\t\tvar prevLocal = tree._local,\n\t\t\t\t\tprevSuper = tree._super,\n\t\t\t\t\tprevSuperApply = tree._superApply;\n\n\t\t\t\ttry {\n\t\t\t\t\ttree._local = _local;\n\t\t\t\t\ttree._super = _super;\n\t\t\t\t\ttree._superApply = _superApply;\n\t\t\t\t\treturn baseFunc.apply(tree, arguments);\n\t\t\t\t} finally {\n\t\t\t\t\ttree._local = prevLocal;\n\t\t\t\t\ttree._super = prevSuper;\n\t\t\t\t\ttree._superApply = prevSuperApply;\n\t\t\t\t}\n\t\t\t};\n\t\t})(); // end of Immediate Function\n\t\treturn proxy;\n\t}\n\n\t/**\n\t * Subclass `base` by creating proxy functions\n\t */\n\tfunction _subclassObject(tree, base, extension, extName) {\n\t\t// $.ui.fancytree.debug(\"_subclassObject\", tree, base, extension, extName);\n\t\tfor (var attrName in extension) {\n\t\t\tif (typeof extension[attrName] === \"function\") {\n\t\t\t\tif (typeof tree[attrName] === \"function\") {\n\t\t\t\t\t// override existing method\n\t\t\t\t\ttree[attrName] = _makeVirtualFunction(\n\t\t\t\t\t\tattrName,\n\t\t\t\t\t\ttree,\n\t\t\t\t\t\tbase,\n\t\t\t\t\t\textension,\n\t\t\t\t\t\textName\n\t\t\t\t\t);\n\t\t\t\t} else if (attrName.charAt(0) === \"_\") {\n\t\t\t\t\t// Create private methods in tree.ext.EXTENSION namespace\n\t\t\t\t\ttree.ext[extName][attrName] = _makeVirtualFunction(\n\t\t\t\t\t\tattrName,\n\t\t\t\t\t\ttree,\n\t\t\t\t\t\tbase,\n\t\t\t\t\t\textension,\n\t\t\t\t\t\textName\n\t\t\t\t\t);\n\t\t\t\t} else {\n\t\t\t\t\t$.error(\n\t\t\t\t\t\t\"Could not override tree.\" +\n\t\t\t\t\t\t\tattrName +\n\t\t\t\t\t\t\t\". Use prefix '_' to create tree.\" +\n\t\t\t\t\t\t\textName +\n\t\t\t\t\t\t\t\"._\" +\n\t\t\t\t\t\t\tattrName\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\t// Create member variables in tree.ext.EXTENSION namespace\n\t\t\t\tif (attrName !== \"options\") {\n\t\t\t\t\ttree.ext[extName][attrName] = extension[attrName];\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\tfunction _getResolvedPromise(context, argArray) {\n\t\tif (context === undefined) {\n\t\t\treturn $.Deferred(function() {\n\t\t\t\tthis.resolve();\n\t\t\t}).promise();\n\t\t} else {\n\t\t\treturn $.Deferred(function() {\n\t\t\t\tthis.resolveWith(context, argArray);\n\t\t\t}).promise();\n\t\t}\n\t}\n\n\tfunction _getRejectedPromise(context, argArray) {\n\t\tif (context === undefined) {\n\t\t\treturn $.Deferred(function() {\n\t\t\t\tthis.reject();\n\t\t\t}).promise();\n\t\t} else {\n\t\t\treturn $.Deferred(function() {\n\t\t\t\tthis.rejectWith(context, argArray);\n\t\t\t}).promise();\n\t\t}\n\t}\n\n\tfunction _makeResolveFunc(deferred, context) {\n\t\treturn function() {\n\t\t\tdeferred.resolveWith(context);\n\t\t};\n\t}\n\n\tfunction _getElementDataAsDict($el) {\n\t\t// Evaluate 'data-NAME' attributes with special treatment for 'data-json'.\n\t\tvar d = $.extend({}, $el.data()),\n\t\t\tjson = d.json;\n\n\t\tdelete d.fancytree; // added to container by widget factory (old jQuery UI)\n\t\tdelete d.uiFancytree; // added to container by widget factory\n\n\t\tif (json) {\n\t\t\tdelete d.json;\n\t\t\t// <li data-json='...'> is already returned as object (http://api.jquery.com/data/#data-html5)\n\t\t\td = $.extend(d, json);\n\t\t}\n\t\treturn d;\n\t}\n\n\tfunction _escapeTooltip(s) {\n\t\treturn (\"\" + s).replace(REX_TOOLTIP, function(s) {\n\t\t\treturn ENTITY_MAP[s];\n\t\t});\n\t}\n\n\t// TODO: use currying\n\tfunction _makeNodeTitleMatcher(s) {\n\t\ts = s.toLowerCase();\n\t\treturn function(node) {\n\t\t\treturn node.title.toLowerCase().indexOf(s) >= 0;\n\t\t};\n\t}\n\n\tfunction _makeNodeTitleStartMatcher(s) {\n\t\tvar reMatch = new RegExp(\"^\" + s, \"i\");\n\t\treturn function(node) {\n\t\t\treturn reMatch.test(node.title);\n\t\t};\n\t}\n\n\t/******************************************************************************\n\t * FancytreeNode\n\t */\n\n\t/**\n\t * Creates a new FancytreeNode\n\t *\n\t * @class FancytreeNode\n\t * @classdesc A FancytreeNode represents the hierarchical data model and operations.\n\t *\n\t * @param {FancytreeNode} parent\n\t * @param {NodeData} obj\n\t *\n\t * @property {Fancytree} tree The tree instance\n\t * @property {FancytreeNode} parent The parent node\n\t * @property {string} key Node id (must be unique inside the tree)\n\t * @property {string} title Display name (may contain HTML)\n\t * @property {object} data Contains all extra data that was passed on node creation\n\t * @property {FancytreeNode[] | null | undefined} children Array of child nodes.<br>\n\t *     For lazy nodes, null or undefined means 'not yet loaded'. Use an empty array\n\t *     to define a node that has no children.\n\t * @property {boolean} expanded Use isExpanded(), setExpanded() to access this property.\n\t * @property {string} extraClasses Additional CSS classes, added to the node's `&lt;span>`.<br>\n\t *     Note: use `node.add/remove/toggleClass()` to modify.\n\t * @property {boolean} folder Folder nodes have different default icons and click behavior.<br>\n\t *     Note: Also non-folders may have children.\n\t * @property {string} statusNodeType null for standard nodes. Otherwise type of special system node: 'error', 'loading', 'nodata', or 'paging'.\n\t * @property {boolean} lazy True if this node is loaded on demand, i.e. on first expansion.\n\t * @property {boolean} selected Use isSelected(), setSelected() to access this property.\n\t * @property {string} tooltip Alternative description used as hover popup\n\t * @property {string} iconTooltip Description used as hover popup for icon. @since 2.27\n\t * @property {string} type Node type, used with tree.types map. @since 2.27\n\t */\n\tfunction FancytreeNode(parent, obj) {\n\t\tvar i, l, name, cl;\n\n\t\tthis.parent = parent;\n\t\tthis.tree = parent.tree;\n\t\tthis.ul = null;\n\t\tthis.li = null; // <li id='key' ftnode=this> tag\n\t\tthis.statusNodeType = null; // if this is a temp. node to display the status of its parent\n\t\tthis._isLoading = false; // if this node itself is loading\n\t\tthis._error = null; // {message: '...'} if a load error occurred\n\t\tthis.data = {};\n\n\t\t// TODO: merge this code with node.toDict()\n\t\t// copy attributes from obj object\n\t\tfor (i = 0, l = NODE_ATTRS.length; i < l; i++) {\n\t\t\tname = NODE_ATTRS[i];\n\t\t\tthis[name] = obj[name];\n\t\t}\n\t\t// unselectableIgnore and unselectableStatus imply unselectable\n\t\tif (\n\t\t\tthis.unselectableIgnore != null ||\n\t\t\tthis.unselectableStatus != null\n\t\t) {\n\t\t\tthis.unselectable = true;\n\t\t}\n\t\tif (obj.hideCheckbox) {\n\t\t\t$.error(\n\t\t\t\t\"'hideCheckbox' node option was removed in v2.23.0: use 'checkbox: false'\"\n\t\t\t);\n\t\t}\n\t\t// node.data += obj.data\n\t\tif (obj.data) {\n\t\t\t$.extend(this.data, obj.data);\n\t\t}\n\t\t// Copy all other attributes to this.data.NAME\n\t\tfor (name in obj) {\n\t\t\tif (\n\t\t\t\t!NODE_ATTR_MAP[name] &&\n\t\t\t\t!$.isFunction(obj[name]) &&\n\t\t\t\t!NONE_NODE_DATA_MAP[name]\n\t\t\t) {\n\t\t\t\t// node.data.NAME = obj.NAME\n\t\t\t\tthis.data[name] = obj[name];\n\t\t\t}\n\t\t}\n\n\t\t// Fix missing key\n\t\tif (this.key == null) {\n\t\t\t// test for null OR undefined\n\t\t\tif (this.tree.options.defaultKey) {\n\t\t\t\tthis.key = this.tree.options.defaultKey(this);\n\t\t\t\t_assert(this.key, \"defaultKey() must return a unique key\");\n\t\t\t} else {\n\t\t\t\tthis.key = \"_\" + FT._nextNodeKey++;\n\t\t\t}\n\t\t} else {\n\t\t\tthis.key = \"\" + this.key; // Convert to string (#217)\n\t\t}\n\n\t\t// Fix tree.activeNode\n\t\t// TODO: not elegant: we use obj.active as marker to set tree.activeNode\n\t\t// when loading from a dictionary.\n\t\tif (obj.active) {\n\t\t\t_assert(\n\t\t\t\tthis.tree.activeNode === null,\n\t\t\t\t\"only one active node allowed\"\n\t\t\t);\n\t\t\tthis.tree.activeNode = this;\n\t\t}\n\t\tif (obj.selected) {\n\t\t\t// #186\n\t\t\tthis.tree.lastSelectedNode = this;\n\t\t}\n\t\t// TODO: handle obj.focus = true\n\n\t\t// Create child nodes\n\t\tcl = obj.children;\n\t\tif (cl) {\n\t\t\tif (cl.length) {\n\t\t\t\tthis._setChildren(cl);\n\t\t\t} else {\n\t\t\t\t// if an empty array was passed for a lazy node, keep it, in order to mark it 'loaded'\n\t\t\t\tthis.children = this.lazy ? [] : null;\n\t\t\t}\n\t\t} else {\n\t\t\tthis.children = null;\n\t\t}\n\t\t// Add to key/ref map (except for root node)\n\t\t//\tif( parent ) {\n\t\tthis.tree._callHook(\"treeRegisterNode\", this.tree, true, this);\n\t\t//\t}\n\t}\n\n\tFancytreeNode.prototype = /** @lends FancytreeNode# */ {\n\t\t/* Return the direct child FancytreeNode with a given key, index. */\n\t\t_findDirectChild: function(ptr) {\n\t\t\tvar i,\n\t\t\t\tl,\n\t\t\t\tcl = this.children;\n\n\t\t\tif (cl) {\n\t\t\t\tif (typeof ptr === \"string\") {\n\t\t\t\t\tfor (i = 0, l = cl.length; i < l; i++) {\n\t\t\t\t\t\tif (cl[i].key === ptr) {\n\t\t\t\t\t\t\treturn cl[i];\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t} else if (typeof ptr === \"number\") {\n\t\t\t\t\treturn this.children[ptr];\n\t\t\t\t} else if (ptr.parent === this) {\n\t\t\t\t\treturn ptr;\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn null;\n\t\t},\n\t\t// TODO: activate()\n\t\t// TODO: activateSilently()\n\t\t/* Internal helper called in recursive addChildren sequence.*/\n\t\t_setChildren: function(children) {\n\t\t\t_assert(\n\t\t\t\tchildren && (!this.children || this.children.length === 0),\n\t\t\t\t\"only init supported\"\n\t\t\t);\n\t\t\tthis.children = [];\n\t\t\tfor (var i = 0, l = children.length; i < l; i++) {\n\t\t\t\tthis.children.push(new FancytreeNode(this, children[i]));\n\t\t\t}\n\t\t},\n\t\t/**\n\t\t * Append (or insert) a list of child nodes.\n\t\t *\n\t\t * @param {NodeData[]} children array of child node definitions (also single child accepted)\n\t\t * @param {FancytreeNode | string | Integer} [insertBefore] child node (or key or index of such).\n\t\t *     If omitted, the new children are appended.\n\t\t * @returns {FancytreeNode} first child added\n\t\t *\n\t\t * @see FancytreeNode#applyPatch\n\t\t */\n\t\taddChildren: function(children, insertBefore) {\n\t\t\tvar i,\n\t\t\t\tl,\n\t\t\t\tpos,\n\t\t\t\torigFirstChild = this.getFirstChild(),\n\t\t\t\torigLastChild = this.getLastChild(),\n\t\t\t\tfirstNode = null,\n\t\t\t\tnodeList = [];\n\n\t\t\tif ($.isPlainObject(children)) {\n\t\t\t\tchildren = [children];\n\t\t\t}\n\t\t\tif (!this.children) {\n\t\t\t\tthis.children = [];\n\t\t\t}\n\t\t\tfor (i = 0, l = children.length; i < l; i++) {\n\t\t\t\tnodeList.push(new FancytreeNode(this, children[i]));\n\t\t\t}\n\t\t\tfirstNode = nodeList[0];\n\t\t\tif (insertBefore == null) {\n\t\t\t\tthis.children = this.children.concat(nodeList);\n\t\t\t} else {\n\t\t\t\t// Returns null if insertBefore is not a direct child:\n\t\t\t\tinsertBefore = this._findDirectChild(insertBefore);\n\t\t\t\tpos = $.inArray(insertBefore, this.children);\n\t\t\t\t_assert(pos >= 0, \"insertBefore must be an existing child\");\n\t\t\t\t// insert nodeList after children[pos]\n\t\t\t\tthis.children.splice.apply(\n\t\t\t\t\tthis.children,\n\t\t\t\t\t[pos, 0].concat(nodeList)\n\t\t\t\t);\n\t\t\t}\n\t\t\tif (origFirstChild && !insertBefore) {\n\t\t\t\t// #708: Fast path -- don't render every child of root, just the new ones!\n\t\t\t\t// #723, #729: but only if it's appended to an existing child list\n\t\t\t\tfor (i = 0, l = nodeList.length; i < l; i++) {\n\t\t\t\t\tnodeList[i].render(); // New nodes were never rendered before\n\t\t\t\t}\n\t\t\t\t// Adjust classes where status may have changed\n\t\t\t\t// Has a first child\n\t\t\t\tif (origFirstChild !== this.getFirstChild()) {\n\t\t\t\t\t// Different first child -- recompute classes\n\t\t\t\t\torigFirstChild.renderStatus();\n\t\t\t\t}\n\t\t\t\tif (origLastChild !== this.getLastChild()) {\n\t\t\t\t\t// Different last child -- recompute classes\n\t\t\t\t\torigLastChild.renderStatus();\n\t\t\t\t}\n\t\t\t} else if (!this.parent || this.parent.ul || this.tr) {\n\t\t\t\t// render if the parent was rendered (or this is a root node)\n\t\t\t\tthis.render();\n\t\t\t}\n\t\t\tif (this.tree.options.selectMode === 3) {\n\t\t\t\tthis.fixSelection3FromEndNodes();\n\t\t\t}\n\t\t\tthis.triggerModifyChild(\n\t\t\t\t\"add\",\n\t\t\t\tnodeList.length === 1 ? nodeList[0] : null\n\t\t\t);\n\t\t\treturn firstNode;\n\t\t},\n\t\t/**\n\t\t * Add class to node's span tag and to .extraClasses.\n\t\t *\n\t\t * @param {string} className class name\n\t\t *\n\t\t * @since 2.17\n\t\t */\n\t\taddClass: function(className) {\n\t\t\treturn this.toggleClass(className, true);\n\t\t},\n\t\t/**\n\t\t * Append or prepend a node, or append a child node.\n\t\t *\n\t\t * This a convenience function that calls addChildren()\n\t\t *\n\t\t * @param {NodeData} node node definition\n\t\t * @param {string} [mode=child] 'before', 'after', 'firstChild', or 'child' ('over' is a synonym for 'child')\n\t\t * @returns {FancytreeNode} new node\n\t\t */\n\t\taddNode: function(node, mode) {\n\t\t\tif (mode === undefined || mode === \"over\") {\n\t\t\t\tmode = \"child\";\n\t\t\t}\n\t\t\tswitch (mode) {\n\t\t\t\tcase \"after\":\n\t\t\t\t\treturn this.getParent().addChildren(\n\t\t\t\t\t\tnode,\n\t\t\t\t\t\tthis.getNextSibling()\n\t\t\t\t\t);\n\t\t\t\tcase \"before\":\n\t\t\t\t\treturn this.getParent().addChildren(node, this);\n\t\t\t\tcase \"firstChild\":\n\t\t\t\t\t// Insert before the first child if any\n\t\t\t\t\tvar insertBefore = this.children ? this.children[0] : null;\n\t\t\t\t\treturn this.addChildren(node, insertBefore);\n\t\t\t\tcase \"child\":\n\t\t\t\tcase \"over\":\n\t\t\t\t\treturn this.addChildren(node);\n\t\t\t}\n\t\t\t_assert(false, \"Invalid mode: \" + mode);\n\t\t},\n\t\t/**Add child status nodes that indicate 'More...', etc.\n\t\t *\n\t\t * This also maintains the node's `partload` property.\n\t\t * @param {boolean|object} node optional node definition. Pass `false` to remove all paging nodes.\n\t\t * @param {string} [mode='child'] 'child'|firstChild'\n\t\t * @since 2.15\n\t\t */\n\t\taddPagingNode: function(node, mode) {\n\t\t\tvar i, n;\n\n\t\t\tmode = mode || \"child\";\n\t\t\tif (node === false) {\n\t\t\t\tfor (i = this.children.length - 1; i >= 0; i--) {\n\t\t\t\t\tn = this.children[i];\n\t\t\t\t\tif (n.statusNodeType === \"paging\") {\n\t\t\t\t\t\tthis.removeChild(n);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tthis.partload = false;\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tnode = $.extend(\n\t\t\t\t{\n\t\t\t\t\ttitle: this.tree.options.strings.moreData,\n\t\t\t\t\tstatusNodeType: \"paging\",\n\t\t\t\t\ticon: false,\n\t\t\t\t},\n\t\t\t\tnode\n\t\t\t);\n\t\t\tthis.partload = true;\n\t\t\treturn this.addNode(node, mode);\n\t\t},\n\t\t/**\n\t\t * Append new node after this.\n\t\t *\n\t\t * This a convenience function that calls addNode(node, 'after')\n\t\t *\n\t\t * @param {NodeData} node node definition\n\t\t * @returns {FancytreeNode} new node\n\t\t */\n\t\tappendSibling: function(node) {\n\t\t\treturn this.addNode(node, \"after\");\n\t\t},\n\t\t/**\n\t\t * Modify existing child nodes.\n\t\t *\n\t\t * @param {NodePatch} patch\n\t\t * @returns {$.Promise}\n\t\t * @see FancytreeNode#addChildren\n\t\t */\n\t\tapplyPatch: function(patch) {\n\t\t\t// patch [key, null] means 'remove'\n\t\t\tif (patch === null) {\n\t\t\t\tthis.remove();\n\t\t\t\treturn _getResolvedPromise(this);\n\t\t\t}\n\t\t\t// TODO: make sure that root node is not collapsed or modified\n\t\t\t// copy (most) attributes to node.ATTR or node.data.ATTR\n\t\t\tvar name,\n\t\t\t\tpromise,\n\t\t\t\tv,\n\t\t\t\tIGNORE_MAP = { children: true, expanded: true, parent: true }; // TODO: should be global\n\n\t\t\tfor (name in patch) {\n\t\t\t\tv = patch[name];\n\t\t\t\tif (!IGNORE_MAP[name] && !$.isFunction(v)) {\n\t\t\t\t\tif (NODE_ATTR_MAP[name]) {\n\t\t\t\t\t\tthis[name] = v;\n\t\t\t\t\t} else {\n\t\t\t\t\t\tthis.data[name] = v;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\t// Remove and/or create children\n\t\t\tif (patch.hasOwnProperty(\"children\")) {\n\t\t\t\tthis.removeChildren();\n\t\t\t\tif (patch.children) {\n\t\t\t\t\t// only if not null and not empty list\n\t\t\t\t\t// TODO: addChildren instead?\n\t\t\t\t\tthis._setChildren(patch.children);\n\t\t\t\t}\n\t\t\t\t// TODO: how can we APPEND or INSERT child nodes?\n\t\t\t}\n\t\t\tif (this.isVisible()) {\n\t\t\t\tthis.renderTitle();\n\t\t\t\tthis.renderStatus();\n\t\t\t}\n\t\t\t// Expand collapse (final step, since this may be async)\n\t\t\tif (patch.hasOwnProperty(\"expanded\")) {\n\t\t\t\tpromise = this.setExpanded(patch.expanded);\n\t\t\t} else {\n\t\t\t\tpromise = _getResolvedPromise(this);\n\t\t\t}\n\t\t\treturn promise;\n\t\t},\n\t\t/** Collapse all sibling nodes.\n\t\t * @returns {$.Promise}\n\t\t */\n\t\tcollapseSiblings: function() {\n\t\t\treturn this.tree._callHook(\"nodeCollapseSiblings\", this);\n\t\t},\n\t\t/** Copy this node as sibling or child of `node`.\n\t\t *\n\t\t * @param {FancytreeNode} node source node\n\t\t * @param {string} [mode=child] 'before' | 'after' | 'child'\n\t\t * @param {Function} [map] callback function(NodeData) that could modify the new node\n\t\t * @returns {FancytreeNode} new\n\t\t */\n\t\tcopyTo: function(node, mode, map) {\n\t\t\treturn node.addNode(this.toDict(true, map), mode);\n\t\t},\n\t\t/** Count direct and indirect children.\n\t\t *\n\t\t * @param {boolean} [deep=true] pass 'false' to only count direct children\n\t\t * @returns {int} number of child nodes\n\t\t */\n\t\tcountChildren: function(deep) {\n\t\t\tvar cl = this.children,\n\t\t\t\ti,\n\t\t\t\tl,\n\t\t\t\tn;\n\t\t\tif (!cl) {\n\t\t\t\treturn 0;\n\t\t\t}\n\t\t\tn = cl.length;\n\t\t\tif (deep !== false) {\n\t\t\t\tfor (i = 0, l = n; i < l; i++) {\n\t\t\t\t\tn += cl[i].countChildren();\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn n;\n\t\t},\n\t\t// TODO: deactivate()\n\t\t/** Write to browser console if debugLevel >= 4 (prepending node info)\n\t\t *\n\t\t * @param {*} msg string or object or array of such\n\t\t */\n\t\tdebug: function(msg) {\n\t\t\tif (this.tree.options.debugLevel >= 4) {\n\t\t\t\tArray.prototype.unshift.call(arguments, this.toString());\n\t\t\t\tconsoleApply(\"log\", arguments);\n\t\t\t}\n\t\t},\n\t\t/** Deprecated.\n\t\t * @deprecated since 2014-02-16. Use resetLazy() instead.\n\t\t */\n\t\tdiscard: function() {\n\t\t\tthis.warn(\n\t\t\t\t\"FancytreeNode.discard() is deprecated since 2014-02-16. Use .resetLazy() instead.\"\n\t\t\t);\n\t\t\treturn this.resetLazy();\n\t\t},\n\t\t/** Remove DOM elements for all descendents. May be called on .collapse event\n\t\t * to keep the DOM small.\n\t\t * @param {boolean} [includeSelf=false]\n\t\t */\n\t\tdiscardMarkup: function(includeSelf) {\n\t\t\tvar fn = includeSelf ? \"nodeRemoveMarkup\" : \"nodeRemoveChildMarkup\";\n\t\t\tthis.tree._callHook(fn, this);\n\t\t},\n\t\t/** Write error to browser console if debugLevel >= 1 (prepending tree info)\n\t\t *\n\t\t * @param {*} msg string or object or array of such\n\t\t */\n\t\terror: function(msg) {\n\t\t\tif (this.options.debugLevel >= 1) {\n\t\t\t\tArray.prototype.unshift.call(arguments, this.toString());\n\t\t\t\tconsoleApply(\"error\", arguments);\n\t\t\t}\n\t\t},\n\t\t/**Find all nodes that match condition (excluding self).\n\t\t *\n\t\t * @param {string | function(node)} match title string to search for, or a\n\t\t *     callback function that returns `true` if a node is matched.\n\t\t * @returns {FancytreeNode[]} array of nodes (may be empty)\n\t\t */\n\t\tfindAll: function(match) {\n\t\t\tmatch = $.isFunction(match) ? match : _makeNodeTitleMatcher(match);\n\t\t\tvar res = [];\n\t\t\tthis.visit(function(n) {\n\t\t\t\tif (match(n)) {\n\t\t\t\t\tres.push(n);\n\t\t\t\t}\n\t\t\t});\n\t\t\treturn res;\n\t\t},\n\t\t/**Find first node that matches condition (excluding self).\n\t\t *\n\t\t * @param {string | function(node)} match title string to search for, or a\n\t\t *     callback function that returns `true` if a node is matched.\n\t\t * @returns {FancytreeNode} matching node or null\n\t\t * @see FancytreeNode#findAll\n\t\t */\n\t\tfindFirst: function(match) {\n\t\t\tmatch = $.isFunction(match) ? match : _makeNodeTitleMatcher(match);\n\t\t\tvar res = null;\n\t\t\tthis.visit(function(n) {\n\t\t\t\tif (match(n)) {\n\t\t\t\t\tres = n;\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t});\n\t\t\treturn res;\n\t\t},\n\t\t/* Apply selection state (internal use only) */\n\t\t_changeSelectStatusAttrs: function(state) {\n\t\t\tvar changed = false,\n\t\t\t\topts = this.tree.options,\n\t\t\t\tunselectable = FT.evalOption(\n\t\t\t\t\t\"unselectable\",\n\t\t\t\t\tthis,\n\t\t\t\t\tthis,\n\t\t\t\t\topts,\n\t\t\t\t\tfalse\n\t\t\t\t),\n\t\t\t\tunselectableStatus = FT.evalOption(\n\t\t\t\t\t\"unselectableStatus\",\n\t\t\t\t\tthis,\n\t\t\t\t\tthis,\n\t\t\t\t\topts,\n\t\t\t\t\tundefined\n\t\t\t\t);\n\n\t\t\tif (unselectable && unselectableStatus != null) {\n\t\t\t\tstate = unselectableStatus;\n\t\t\t}\n\t\t\tswitch (state) {\n\t\t\t\tcase false:\n\t\t\t\t\tchanged = this.selected || this.partsel;\n\t\t\t\t\tthis.selected = false;\n\t\t\t\t\tthis.partsel = false;\n\t\t\t\t\tbreak;\n\t\t\t\tcase true:\n\t\t\t\t\tchanged = !this.selected || !this.partsel;\n\t\t\t\t\tthis.selected = true;\n\t\t\t\t\tthis.partsel = true;\n\t\t\t\t\tbreak;\n\t\t\t\tcase undefined:\n\t\t\t\t\tchanged = this.selected || !this.partsel;\n\t\t\t\t\tthis.selected = false;\n\t\t\t\t\tthis.partsel = true;\n\t\t\t\t\tbreak;\n\t\t\t\tdefault:\n\t\t\t\t\t_assert(false, \"invalid state: \" + state);\n\t\t\t}\n\t\t\t// this.debug(\"fixSelection3AfterLoad() _changeSelectStatusAttrs()\", state, changed);\n\t\t\tif (changed) {\n\t\t\t\tthis.renderStatus();\n\t\t\t}\n\t\t\treturn changed;\n\t\t},\n\t\t/**\n\t\t * Fix selection status, after this node was (de)selected in multi-hier mode.\n\t\t * This includes (de)selecting all children.\n\t\t */\n\t\tfixSelection3AfterClick: function(callOpts) {\n\t\t\tvar flag = this.isSelected();\n\n\t\t\t//\t\tthis.debug(\"fixSelection3AfterClick()\");\n\n\t\t\tthis.visit(function(node) {\n\t\t\t\tnode._changeSelectStatusAttrs(flag);\n\t\t\t});\n\t\t\tthis.fixSelection3FromEndNodes(callOpts);\n\t\t},\n\t\t/**\n\t\t * Fix selection status for multi-hier mode.\n\t\t * Only end-nodes are considered to update the descendants branch and parents.\n\t\t * Should be called after this node has loaded new children or after\n\t\t * children have been modified using the API.\n\t\t */\n\t\tfixSelection3FromEndNodes: function(callOpts) {\n\t\t\tvar opts = this.tree.options;\n\n\t\t\t//\t\tthis.debug(\"fixSelection3FromEndNodes()\");\n\t\t\t_assert(opts.selectMode === 3, \"expected selectMode 3\");\n\n\t\t\t// Visit all end nodes and adjust their parent's `selected` and `partsel`\n\t\t\t// attributes. Return selection state true, false, or undefined.\n\t\t\tfunction _walk(node) {\n\t\t\t\tvar i,\n\t\t\t\t\tl,\n\t\t\t\t\tchild,\n\t\t\t\t\ts,\n\t\t\t\t\tstate,\n\t\t\t\t\tallSelected,\n\t\t\t\t\tsomeSelected,\n\t\t\t\t\tunselIgnore,\n\t\t\t\t\tunselState,\n\t\t\t\t\tchildren = node.children;\n\n\t\t\t\tif (children && children.length) {\n\t\t\t\t\t// check all children recursively\n\t\t\t\t\tallSelected = true;\n\t\t\t\t\tsomeSelected = false;\n\n\t\t\t\t\tfor (i = 0, l = children.length; i < l; i++) {\n\t\t\t\t\t\tchild = children[i];\n\t\t\t\t\t\t// the selection state of a node is not relevant; we need the end-nodes\n\t\t\t\t\t\ts = _walk(child);\n\t\t\t\t\t\t// if( !child.unselectableIgnore ) {\n\t\t\t\t\t\tunselIgnore = FT.evalOption(\n\t\t\t\t\t\t\t\"unselectableIgnore\",\n\t\t\t\t\t\t\tchild,\n\t\t\t\t\t\t\tchild,\n\t\t\t\t\t\t\topts,\n\t\t\t\t\t\t\tfalse\n\t\t\t\t\t\t);\n\t\t\t\t\t\tif (!unselIgnore) {\n\t\t\t\t\t\t\tif (s !== false) {\n\t\t\t\t\t\t\t\tsomeSelected = true;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tif (s !== true) {\n\t\t\t\t\t\t\t\tallSelected = false;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tstate = allSelected\n\t\t\t\t\t\t? true\n\t\t\t\t\t\t: someSelected\n\t\t\t\t\t\t\t? undefined\n\t\t\t\t\t\t\t: false;\n\t\t\t\t} else {\n\t\t\t\t\t// This is an end-node: simply report the status\n\t\t\t\t\tunselState = FT.evalOption(\n\t\t\t\t\t\t\"unselectableStatus\",\n\t\t\t\t\t\tnode,\n\t\t\t\t\t\tnode,\n\t\t\t\t\t\topts,\n\t\t\t\t\t\tundefined\n\t\t\t\t\t);\n\t\t\t\t\tstate = unselState == null ? !!node.selected : !!unselState;\n\t\t\t\t}\n\t\t\t\tnode._changeSelectStatusAttrs(state);\n\t\t\t\treturn state;\n\t\t\t}\n\t\t\t_walk(this);\n\n\t\t\t// Update parent's state\n\t\t\tthis.visitParents(function(node) {\n\t\t\t\tvar i,\n\t\t\t\t\tl,\n\t\t\t\t\tchild,\n\t\t\t\t\tstate,\n\t\t\t\t\tunselIgnore,\n\t\t\t\t\tunselState,\n\t\t\t\t\tchildren = node.children,\n\t\t\t\t\tallSelected = true,\n\t\t\t\t\tsomeSelected = false;\n\n\t\t\t\tfor (i = 0, l = children.length; i < l; i++) {\n\t\t\t\t\tchild = children[i];\n\t\t\t\t\tunselIgnore = FT.evalOption(\n\t\t\t\t\t\t\"unselectableIgnore\",\n\t\t\t\t\t\tchild,\n\t\t\t\t\t\tchild,\n\t\t\t\t\t\topts,\n\t\t\t\t\t\tfalse\n\t\t\t\t\t);\n\t\t\t\t\tif (!unselIgnore) {\n\t\t\t\t\t\tunselState = FT.evalOption(\n\t\t\t\t\t\t\t\"unselectableStatus\",\n\t\t\t\t\t\t\tchild,\n\t\t\t\t\t\t\tchild,\n\t\t\t\t\t\t\topts,\n\t\t\t\t\t\t\tundefined\n\t\t\t\t\t\t);\n\t\t\t\t\t\tstate =\n\t\t\t\t\t\t\tunselState == null\n\t\t\t\t\t\t\t\t? !!child.selected\n\t\t\t\t\t\t\t\t: !!unselState;\n\t\t\t\t\t\t// When fixing the parents, we trust the sibling status (i.e.\n\t\t\t\t\t\t// we don't recurse)\n\t\t\t\t\t\tif (state || child.partsel) {\n\t\t\t\t\t\t\tsomeSelected = true;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (!state) {\n\t\t\t\t\t\t\tallSelected = false;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tstate = allSelected ? true : someSelected ? undefined : false;\n\t\t\t\tnode._changeSelectStatusAttrs(state);\n\t\t\t});\n\t\t},\n\t\t// TODO: focus()\n\t\t/**\n\t\t * Update node data. If dict contains 'children', then also replace\n\t\t * the hole sub tree.\n\t\t * @param {NodeData} dict\n\t\t *\n\t\t * @see FancytreeNode#addChildren\n\t\t * @see FancytreeNode#applyPatch\n\t\t */\n\t\tfromDict: function(dict) {\n\t\t\t// copy all other attributes to this.data.xxx\n\t\t\tfor (var name in dict) {\n\t\t\t\tif (NODE_ATTR_MAP[name]) {\n\t\t\t\t\t// node.NAME = dict.NAME\n\t\t\t\t\tthis[name] = dict[name];\n\t\t\t\t} else if (name === \"data\") {\n\t\t\t\t\t// node.data += dict.data\n\t\t\t\t\t$.extend(this.data, dict.data);\n\t\t\t\t} else if (\n\t\t\t\t\t!$.isFunction(dict[name]) &&\n\t\t\t\t\t!NONE_NODE_DATA_MAP[name]\n\t\t\t\t) {\n\t\t\t\t\t// node.data.NAME = dict.NAME\n\t\t\t\t\tthis.data[name] = dict[name];\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (dict.children) {\n\t\t\t\t// recursively set children and render\n\t\t\t\tthis.removeChildren();\n\t\t\t\tthis.addChildren(dict.children);\n\t\t\t}\n\t\t\tthis.renderTitle();\n\t\t\t/*\n\t\tvar children = dict.children;\n\t\tif(children === undefined){\n\t\t\tthis.data = $.extend(this.data, dict);\n\t\t\tthis.render();\n\t\t\treturn;\n\t\t}\n\t\tdict = $.extend({}, dict);\n\t\tdict.children = undefined;\n\t\tthis.data = $.extend(this.data, dict);\n\t\tthis.removeChildren();\n\t\tthis.addChild(children);\n*/\n\t\t},\n\t\t/** Return the list of child nodes (undefined for unexpanded lazy nodes).\n\t\t * @returns {FancytreeNode[] | undefined}\n\t\t */\n\t\tgetChildren: function() {\n\t\t\tif (this.hasChildren() === undefined) {\n\t\t\t\t// TODO: only required for lazy nodes?\n\t\t\t\treturn undefined; // Lazy node: unloaded, currently loading, or load error\n\t\t\t}\n\t\t\treturn this.children;\n\t\t},\n\t\t/** Return the first child node or null.\n\t\t * @returns {FancytreeNode | null}\n\t\t */\n\t\tgetFirstChild: function() {\n\t\t\treturn this.children ? this.children[0] : null;\n\t\t},\n\t\t/** Return the 0-based child index.\n\t\t * @returns {int}\n\t\t */\n\t\tgetIndex: function() {\n\t\t\t//\t\treturn this.parent.children.indexOf(this);\n\t\t\treturn $.inArray(this, this.parent.children); // indexOf doesn't work in IE7\n\t\t},\n\t\t/** Return the hierarchical child index (1-based, e.g. '3.2.4').\n\t\t * @param {string} [separator=\".\"]\n\t\t * @param {int} [digits=1]\n\t\t * @returns {string}\n\t\t */\n\t\tgetIndexHier: function(separator, digits) {\n\t\t\tseparator = separator || \".\";\n\t\t\tvar s,\n\t\t\t\tres = [];\n\t\t\t$.each(this.getParentList(false, true), function(i, o) {\n\t\t\t\ts = \"\" + (o.getIndex() + 1);\n\t\t\t\tif (digits) {\n\t\t\t\t\t// prepend leading zeroes\n\t\t\t\t\ts = (\"0000000\" + s).substr(-digits);\n\t\t\t\t}\n\t\t\t\tres.push(s);\n\t\t\t});\n\t\t\treturn res.join(separator);\n\t\t},\n\t\t/** Return the parent keys separated by options.keyPathSeparator, e.g. \"id_1/id_17/id_32\".\n\t\t * @param {boolean} [excludeSelf=false]\n\t\t * @returns {string}\n\t\t */\n\t\tgetKeyPath: function(excludeSelf) {\n\t\t\tvar path = [],\n\t\t\t\tsep = this.tree.options.keyPathSeparator;\n\t\t\tthis.visitParents(function(n) {\n\t\t\t\tif (n.parent) {\n\t\t\t\t\tpath.unshift(n.key);\n\t\t\t\t}\n\t\t\t}, !excludeSelf);\n\t\t\treturn sep + path.join(sep);\n\t\t},\n\t\t/** Return the last child of this node or null.\n\t\t * @returns {FancytreeNode | null}\n\t\t */\n\t\tgetLastChild: function() {\n\t\t\treturn this.children\n\t\t\t\t? this.children[this.children.length - 1]\n\t\t\t\t: null;\n\t\t},\n\t\t/** Return node depth. 0: System root node, 1: visible top-level node, 2: first sub-level, ... .\n\t\t * @returns {int}\n\t\t */\n\t\tgetLevel: function() {\n\t\t\tvar level = 0,\n\t\t\t\tdtn = this.parent;\n\t\t\twhile (dtn) {\n\t\t\t\tlevel++;\n\t\t\t\tdtn = dtn.parent;\n\t\t\t}\n\t\t\treturn level;\n\t\t},\n\t\t/** Return the successor node (under the same parent) or null.\n\t\t * @returns {FancytreeNode | null}\n\t\t */\n\t\tgetNextSibling: function() {\n\t\t\t// TODO: use indexOf, if available: (not in IE6)\n\t\t\tif (this.parent) {\n\t\t\t\tvar i,\n\t\t\t\t\tl,\n\t\t\t\t\tac = this.parent.children;\n\n\t\t\t\tfor (i = 0, l = ac.length - 1; i < l; i++) {\n\t\t\t\t\t// up to length-2, so next(last) = null\n\t\t\t\t\tif (ac[i] === this) {\n\t\t\t\t\t\treturn ac[i + 1];\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn null;\n\t\t},\n\t\t/** Return the parent node (null for the system root node).\n\t\t * @returns {FancytreeNode | null}\n\t\t */\n\t\tgetParent: function() {\n\t\t\t// TODO: return null for top-level nodes?\n\t\t\treturn this.parent;\n\t\t},\n\t\t/** Return an array of all parent nodes (top-down).\n\t\t * @param {boolean} [includeRoot=false] Include the invisible system root node.\n\t\t * @param {boolean} [includeSelf=false] Include the node itself.\n\t\t * @returns {FancytreeNode[]}\n\t\t */\n\t\tgetParentList: function(includeRoot, includeSelf) {\n\t\t\tvar l = [],\n\t\t\t\tdtn = includeSelf ? this : this.parent;\n\t\t\twhile (dtn) {\n\t\t\t\tif (includeRoot || dtn.parent) {\n\t\t\t\t\tl.unshift(dtn);\n\t\t\t\t}\n\t\t\t\tdtn = dtn.parent;\n\t\t\t}\n\t\t\treturn l;\n\t\t},\n\t\t/** Return the predecessor node (under the same parent) or null.\n\t\t * @returns {FancytreeNode | null}\n\t\t */\n\t\tgetPrevSibling: function() {\n\t\t\tif (this.parent) {\n\t\t\t\tvar i,\n\t\t\t\t\tl,\n\t\t\t\t\tac = this.parent.children;\n\n\t\t\t\tfor (i = 1, l = ac.length; i < l; i++) {\n\t\t\t\t\t// start with 1, so prev(first) = null\n\t\t\t\t\tif (ac[i] === this) {\n\t\t\t\t\t\treturn ac[i - 1];\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn null;\n\t\t},\n\t\t/**\n\t\t * Return an array of selected descendant nodes.\n\t\t * @param {boolean} [stopOnParents=false] only return the topmost selected\n\t\t *     node (useful with selectMode 3)\n\t\t * @returns {FancytreeNode[]}\n\t\t */\n\t\tgetSelectedNodes: function(stopOnParents) {\n\t\t\tvar nodeList = [];\n\t\t\tthis.visit(function(node) {\n\t\t\t\tif (node.selected) {\n\t\t\t\t\tnodeList.push(node);\n\t\t\t\t\tif (stopOnParents === true) {\n\t\t\t\t\t\treturn \"skip\"; // stop processing this branch\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t});\n\t\t\treturn nodeList;\n\t\t},\n\t\t/** Return true if node has children. Return undefined if not sure, i.e. the node is lazy and not yet loaded).\n\t\t * @returns {boolean | undefined}\n\t\t */\n\t\thasChildren: function() {\n\t\t\tif (this.lazy) {\n\t\t\t\tif (this.children == null) {\n\t\t\t\t\t// null or undefined: Not yet loaded\n\t\t\t\t\treturn undefined;\n\t\t\t\t} else if (this.children.length === 0) {\n\t\t\t\t\t// Loaded, but response was empty\n\t\t\t\t\treturn false;\n\t\t\t\t} else if (\n\t\t\t\t\tthis.children.length === 1 &&\n\t\t\t\t\tthis.children[0].isStatusNode()\n\t\t\t\t) {\n\t\t\t\t\t// Currently loading or load error\n\t\t\t\t\treturn undefined;\n\t\t\t\t}\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\treturn !!(this.children && this.children.length);\n\t\t},\n\t\t/** Return true if node has keyboard focus.\n\t\t * @returns {boolean}\n\t\t */\n\t\thasFocus: function() {\n\t\t\treturn this.tree.hasFocus() && this.tree.focusNode === this;\n\t\t},\n\t\t/** Write to browser console if debugLevel >= 3 (prepending node info)\n\t\t *\n\t\t * @param {*} msg string or object or array of such\n\t\t */\n\t\tinfo: function(msg) {\n\t\t\tif (this.tree.options.debugLevel >= 3) {\n\t\t\t\tArray.prototype.unshift.call(arguments, this.toString());\n\t\t\t\tconsoleApply(\"info\", arguments);\n\t\t\t}\n\t\t},\n\t\t/** Return true if node is active (see also FancytreeNode#isSelected).\n\t\t * @returns {boolean}\n\t\t */\n\t\tisActive: function() {\n\t\t\treturn this.tree.activeNode === this;\n\t\t},\n\t\t/** Return true if node is vertically below `otherNode`, i.e. rendered in a subsequent row.\n\t\t * @param {FancytreeNode} otherNode\n\t\t * @returns {boolean}\n\t\t * @since 2.28\n\t\t */\n\t\tisBelowOf: function(otherNode) {\n\t\t\treturn this.getIndexHier(\".\", 5) > otherNode.getIndexHier(\".\", 5);\n\t\t},\n\t\t/** Return true if node is a direct child of otherNode.\n\t\t * @param {FancytreeNode} otherNode\n\t\t * @returns {boolean}\n\t\t */\n\t\tisChildOf: function(otherNode) {\n\t\t\treturn this.parent && this.parent === otherNode;\n\t\t},\n\t\t/** Return true, if node is a direct or indirect sub node of otherNode.\n\t\t * @param {FancytreeNode} otherNode\n\t\t * @returns {boolean}\n\t\t */\n\t\tisDescendantOf: function(otherNode) {\n\t\t\tif (!otherNode || otherNode.tree !== this.tree) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\tvar p = this.parent;\n\t\t\twhile (p) {\n\t\t\t\tif (p === otherNode) {\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t\tif (p === p.parent) {\n\t\t\t\t\t$.error(\"Recursive parent link: \" + p);\n\t\t\t\t}\n\t\t\t\tp = p.parent;\n\t\t\t}\n\t\t\treturn false;\n\t\t},\n\t\t/** Return true if node is expanded.\n\t\t * @returns {boolean}\n\t\t */\n\t\tisExpanded: function() {\n\t\t\treturn !!this.expanded;\n\t\t},\n\t\t/** Return true if node is the first node of its parent's children.\n\t\t * @returns {boolean}\n\t\t */\n\t\tisFirstSibling: function() {\n\t\t\tvar p = this.parent;\n\t\t\treturn !p || p.children[0] === this;\n\t\t},\n\t\t/** Return true if node is a folder, i.e. has the node.folder attribute set.\n\t\t * @returns {boolean}\n\t\t */\n\t\tisFolder: function() {\n\t\t\treturn !!this.folder;\n\t\t},\n\t\t/** Return true if node is the last node of its parent's children.\n\t\t * @returns {boolean}\n\t\t */\n\t\tisLastSibling: function() {\n\t\t\tvar p = this.parent;\n\t\t\treturn !p || p.children[p.children.length - 1] === this;\n\t\t},\n\t\t/** Return true if node is lazy (even if data was already loaded)\n\t\t * @returns {boolean}\n\t\t */\n\t\tisLazy: function() {\n\t\t\treturn !!this.lazy;\n\t\t},\n\t\t/** Return true if node is lazy and loaded. For non-lazy nodes always return true.\n\t\t * @returns {boolean}\n\t\t */\n\t\tisLoaded: function() {\n\t\t\treturn !this.lazy || this.hasChildren() !== undefined; // Also checks if the only child is a status node\n\t\t},\n\t\t/** Return true if children are currently beeing loaded, i.e. a Ajax request is pending.\n\t\t * @returns {boolean}\n\t\t */\n\t\tisLoading: function() {\n\t\t\treturn !!this._isLoading;\n\t\t},\n\t\t/*\n\t * @deprecated since v2.4.0:  Use isRootNode() instead\n\t */\n\t\tisRoot: function() {\n\t\t\treturn this.isRootNode();\n\t\t},\n\t\t/** Return true if node is partially selected (tri-state).\n\t\t * @returns {boolean}\n\t\t * @since 2.23\n\t\t */\n\t\tisPartsel: function() {\n\t\t\treturn !this.selected && !!this.partsel;\n\t\t},\n\t\t/** (experimental) Return true if this is partially loaded.\n\t\t * @returns {boolean}\n\t\t * @since 2.15\n\t\t */\n\t\tisPartload: function() {\n\t\t\treturn !!this.partload;\n\t\t},\n\t\t/** Return true if this is the (invisible) system root node.\n\t\t * @returns {boolean}\n\t\t * @since 2.4\n\t\t */\n\t\tisRootNode: function() {\n\t\t\treturn this.tree.rootNode === this;\n\t\t},\n\t\t/** Return true if node is selected, i.e. has a checkmark set (see also FancytreeNode#isActive).\n\t\t * @returns {boolean}\n\t\t */\n\t\tisSelected: function() {\n\t\t\treturn !!this.selected;\n\t\t},\n\t\t/** Return true if this node is a temporarily generated system node like\n\t\t * 'loading', 'paging', or 'error' (node.statusNodeType contains the type).\n\t\t * @returns {boolean}\n\t\t */\n\t\tisStatusNode: function() {\n\t\t\treturn !!this.statusNodeType;\n\t\t},\n\t\t/** Return true if this node is a status node of type 'paging'.\n\t\t * @returns {boolean}\n\t\t * @since 2.15\n\t\t */\n\t\tisPagingNode: function() {\n\t\t\treturn this.statusNodeType === \"paging\";\n\t\t},\n\t\t/** Return true if this a top level node, i.e. a direct child of the (invisible) system root node.\n\t\t * @returns {boolean}\n\t\t * @since 2.4\n\t\t */\n\t\tisTopLevel: function() {\n\t\t\treturn this.tree.rootNode === this.parent;\n\t\t},\n\t\t/** Return true if node is lazy and not yet loaded. For non-lazy nodes always return false.\n\t\t * @returns {boolean}\n\t\t */\n\t\tisUndefined: function() {\n\t\t\treturn this.hasChildren() === undefined; // also checks if the only child is a status node\n\t\t},\n\t\t/** Return true if all parent nodes are expanded. Note: this does not check\n\t\t * whether the node is scrolled into the visible part of the screen.\n\t\t * @returns {boolean}\n\t\t */\n\t\tisVisible: function() {\n\t\t\tvar i,\n\t\t\t\tl,\n\t\t\t\tparents = this.getParentList(false, false);\n\n\t\t\tfor (i = 0, l = parents.length; i < l; i++) {\n\t\t\t\tif (!parents[i].expanded) {\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn true;\n\t\t},\n\t\t/** Deprecated.\n\t\t * @deprecated since 2014-02-16: use load() instead.\n\t\t */\n\t\tlazyLoad: function(discard) {\n\t\t\tthis.warn(\n\t\t\t\t\"FancytreeNode.lazyLoad() is deprecated since 2014-02-16. Use .load() instead.\"\n\t\t\t);\n\t\t\treturn this.load(discard);\n\t\t},\n\t\t/**\n\t\t * Load all children of a lazy node if neccessary. The <i>expanded</i> state is maintained.\n\t\t * @param {boolean} [forceReload=false] Pass true to discard any existing nodes before. Otherwise this method does nothing if the node was already loaded.\n\t\t * @returns {$.Promise}\n\t\t */\n\t\tload: function(forceReload) {\n\t\t\tvar res,\n\t\t\t\tsource,\n\t\t\t\tthat = this,\n\t\t\t\twasExpanded = this.isExpanded();\n\n\t\t\t_assert(this.isLazy(), \"load() requires a lazy node\");\n\t\t\t// _assert( forceReload || this.isUndefined(), \"Pass forceReload=true to re-load a lazy node\" );\n\t\t\tif (!forceReload && !this.isUndefined()) {\n\t\t\t\treturn _getResolvedPromise(this);\n\t\t\t}\n\t\t\tif (this.isLoaded()) {\n\t\t\t\tthis.resetLazy(); // also collapses\n\t\t\t}\n\t\t\t// This method is also called by setExpanded() and loadKeyPath(), so we\n\t\t\t// have to avoid recursion.\n\t\t\tsource = this.tree._triggerNodeEvent(\"lazyLoad\", this);\n\t\t\tif (source === false) {\n\t\t\t\t// #69\n\t\t\t\treturn _getResolvedPromise(this);\n\t\t\t}\n\t\t\t_assert(\n\t\t\t\ttypeof source !== \"boolean\",\n\t\t\t\t\"lazyLoad event must return source in data.result\"\n\t\t\t);\n\t\t\tres = this.tree._callHook(\"nodeLoadChildren\", this, source);\n\t\t\tif (wasExpanded) {\n\t\t\t\tthis.expanded = true;\n\t\t\t\tres.always(function() {\n\t\t\t\t\tthat.render();\n\t\t\t\t});\n\t\t\t} else {\n\t\t\t\tres.always(function() {\n\t\t\t\t\tthat.renderStatus(); // fix expander icon to 'loaded'\n\t\t\t\t});\n\t\t\t}\n\t\t\treturn res;\n\t\t},\n\t\t/** Expand all parents and optionally scroll into visible area as neccessary.\n\t\t * Promise is resolved, when lazy loading and animations are done.\n\t\t * @param {object} [opts] passed to `setExpanded()`.\n\t\t *     Defaults to {noAnimation: false, noEvents: false, scrollIntoView: true}\n\t\t * @returns {$.Promise}\n\t\t */\n\t\tmakeVisible: function(opts) {\n\t\t\tvar i,\n\t\t\t\tthat = this,\n\t\t\t\tdeferreds = [],\n\t\t\t\tdfd = new $.Deferred(),\n\t\t\t\tparents = this.getParentList(false, false),\n\t\t\t\tlen = parents.length,\n\t\t\t\teffects = !(opts && opts.noAnimation === true),\n\t\t\t\tscroll = !(opts && opts.scrollIntoView === false);\n\n\t\t\t// Expand bottom-up, so only the top node is animated\n\t\t\tfor (i = len - 1; i >= 0; i--) {\n\t\t\t\t// that.debug(\"pushexpand\" + parents[i]);\n\t\t\t\tdeferreds.push(parents[i].setExpanded(true, opts));\n\t\t\t}\n\t\t\t$.when.apply($, deferreds).done(function() {\n\t\t\t\t// All expands have finished\n\t\t\t\t// that.debug(\"expand DONE\", scroll);\n\t\t\t\tif (scroll) {\n\t\t\t\t\tthat.scrollIntoView(effects).done(function() {\n\t\t\t\t\t\t// that.debug(\"scroll DONE\");\n\t\t\t\t\t\tdfd.resolve();\n\t\t\t\t\t});\n\t\t\t\t} else {\n\t\t\t\t\tdfd.resolve();\n\t\t\t\t}\n\t\t\t});\n\t\t\treturn dfd.promise();\n\t\t},\n\t\t/** Move this node to targetNode.\n\t\t *  @param {FancytreeNode} targetNode\n\t\t *  @param {string} mode <pre>\n\t\t *      'child': append this node as last child of targetNode.\n\t\t *               This is the default. To be compatble with the D'n'd\n\t\t *               hitMode, we also accept 'over'.\n\t\t *      'firstChild': add this node as first child of targetNode.\n\t\t *      'before': add this node as sibling before targetNode.\n\t\t *      'after': add this node as sibling after targetNode.</pre>\n\t\t *  @param {function} [map] optional callback(FancytreeNode) to allow modifcations\n\t\t */\n\t\tmoveTo: function(targetNode, mode, map) {\n\t\t\tif (mode === undefined || mode === \"over\") {\n\t\t\t\tmode = \"child\";\n\t\t\t} else if (mode === \"firstChild\") {\n\t\t\t\tif (targetNode.children && targetNode.children.length) {\n\t\t\t\t\tmode = \"before\";\n\t\t\t\t\ttargetNode = targetNode.children[0];\n\t\t\t\t} else {\n\t\t\t\t\tmode = \"child\";\n\t\t\t\t}\n\t\t\t}\n\t\t\tvar pos,\n\t\t\t\tprevParent = this.parent,\n\t\t\t\ttargetParent =\n\t\t\t\t\tmode === \"child\" ? targetNode : targetNode.parent;\n\n\t\t\tif (this === targetNode) {\n\t\t\t\treturn;\n\t\t\t} else if (!this.parent) {\n\t\t\t\t$.error(\"Cannot move system root\");\n\t\t\t} else if (targetParent.isDescendantOf(this)) {\n\t\t\t\t$.error(\"Cannot move a node to its own descendant\");\n\t\t\t}\n\t\t\tif (targetParent !== prevParent) {\n\t\t\t\tprevParent.triggerModifyChild(\"remove\", this);\n\t\t\t}\n\t\t\t// Unlink this node from current parent\n\t\t\tif (this.parent.children.length === 1) {\n\t\t\t\tif (this.parent === targetParent) {\n\t\t\t\t\treturn; // #258\n\t\t\t\t}\n\t\t\t\tthis.parent.children = this.parent.lazy ? [] : null;\n\t\t\t\tthis.parent.expanded = false;\n\t\t\t} else {\n\t\t\t\tpos = $.inArray(this, this.parent.children);\n\t\t\t\t_assert(pos >= 0, \"invalid source parent\");\n\t\t\t\tthis.parent.children.splice(pos, 1);\n\t\t\t}\n\t\t\t// Remove from source DOM parent\n\t\t\t//\t\tif(this.parent.ul){\n\t\t\t//\t\t\tthis.parent.ul.removeChild(this.li);\n\t\t\t//\t\t}\n\n\t\t\t// Insert this node to target parent's child list\n\t\t\tthis.parent = targetParent;\n\t\t\tif (targetParent.hasChildren()) {\n\t\t\t\tswitch (mode) {\n\t\t\t\t\tcase \"child\":\n\t\t\t\t\t\t// Append to existing target children\n\t\t\t\t\t\ttargetParent.children.push(this);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"before\":\n\t\t\t\t\t\t// Insert this node before target node\n\t\t\t\t\t\tpos = $.inArray(targetNode, targetParent.children);\n\t\t\t\t\t\t_assert(pos >= 0, \"invalid target parent\");\n\t\t\t\t\t\ttargetParent.children.splice(pos, 0, this);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"after\":\n\t\t\t\t\t\t// Insert this node after target node\n\t\t\t\t\t\tpos = $.inArray(targetNode, targetParent.children);\n\t\t\t\t\t\t_assert(pos >= 0, \"invalid target parent\");\n\t\t\t\t\t\ttargetParent.children.splice(pos + 1, 0, this);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tdefault:\n\t\t\t\t\t\t$.error(\"Invalid mode \" + mode);\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\ttargetParent.children = [this];\n\t\t\t}\n\t\t\t// Parent has no <ul> tag yet:\n\t\t\t//\t\tif( !targetParent.ul ) {\n\t\t\t//\t\t\t// This is the parent's first child: create UL tag\n\t\t\t//\t\t\t// (Hidden, because it will be\n\t\t\t//\t\t\ttargetParent.ul = document.createElement(\"ul\");\n\t\t\t//\t\t\ttargetParent.ul.style.display = \"none\";\n\t\t\t//\t\t\ttargetParent.li.appendChild(targetParent.ul);\n\t\t\t//\t\t}\n\t\t\t//\t\t// Issue 319: Add to target DOM parent (only if node was already rendered(expanded))\n\t\t\t//\t\tif(this.li){\n\t\t\t//\t\t\ttargetParent.ul.appendChild(this.li);\n\t\t\t//\t\t}^\n\n\t\t\t// Let caller modify the nodes\n\t\t\tif (map) {\n\t\t\t\ttargetNode.visit(map, true);\n\t\t\t}\n\t\t\tif (targetParent === prevParent) {\n\t\t\t\ttargetParent.triggerModifyChild(\"move\", this);\n\t\t\t} else {\n\t\t\t\t// prevParent.triggerModifyChild(\"remove\", this);\n\t\t\t\ttargetParent.triggerModifyChild(\"add\", this);\n\t\t\t}\n\t\t\t// Handle cross-tree moves\n\t\t\tif (this.tree !== targetNode.tree) {\n\t\t\t\t// Fix node.tree for all source nodes\n\t\t\t\t//\t\t\t_assert(false, \"Cross-tree move is not yet implemented.\");\n\t\t\t\tthis.warn(\"Cross-tree moveTo is experimantal!\");\n\t\t\t\tthis.visit(function(n) {\n\t\t\t\t\t// TODO: fix selection state and activation, ...\n\t\t\t\t\tn.tree = targetNode.tree;\n\t\t\t\t}, true);\n\t\t\t}\n\n\t\t\t// A collaposed node won't re-render children, so we have to remove it manually\n\t\t\t// if( !targetParent.expanded ){\n\t\t\t//   prevParent.ul.removeChild(this.li);\n\t\t\t// }\n\n\t\t\t// Update HTML markup\n\t\t\tif (!prevParent.isDescendantOf(targetParent)) {\n\t\t\t\tprevParent.render();\n\t\t\t}\n\t\t\tif (\n\t\t\t\t!targetParent.isDescendantOf(prevParent) &&\n\t\t\t\ttargetParent !== prevParent\n\t\t\t) {\n\t\t\t\ttargetParent.render();\n\t\t\t}\n\t\t\t// TODO: fix selection state\n\t\t\t// TODO: fix active state\n\n\t\t\t/*\n\t\tvar tree = this.tree;\n\t\tvar opts = tree.options;\n\t\tvar pers = tree.persistence;\n\n\n\t\t// Always expand, if it's below minExpandLevel\n//\t\ttree.logDebug (\"%s._addChildNode(%o), l=%o\", this, ftnode, ftnode.getLevel());\n\t\tif ( opts.minExpandLevel >= ftnode.getLevel() ) {\n//\t\t\ttree.logDebug (\"Force expand for %o\", ftnode);\n\t\t\tthis.bExpanded = true;\n\t\t}\n\n\t\t// In multi-hier mode, update the parents selection state\n\t\t// DT issue #82: only if not initializing, because the children may not exist yet\n//\t\tif( !ftnode.data.isStatusNode() && opts.selectMode==3 && !isInitializing )\n//\t\t\tftnode._fixSelectionState();\n\n\t\t// In multi-hier mode, update the parents selection state\n\t\tif( ftnode.bSelected && opts.selectMode==3 ) {\n\t\t\tvar p = this;\n\t\t\twhile( p ) {\n\t\t\t\tif( !p.hasSubSel )\n\t\t\t\t\tp._setSubSel(true);\n\t\t\t\tp = p.parent;\n\t\t\t}\n\t\t}\n\t\t// render this node and the new child\n\t\tif ( tree.bEnableUpdate )\n\t\t\tthis.render();\n\n\t\treturn ftnode;\n\n*/\n\t\t},\n\t\t/** Set focus relative to this node and optionally activate.\n\t\t *\n\t\t * @param {number} where The keyCode that would normally trigger this move,\n\t\t *\t\te.g. `$.ui.keyCode.LEFT` would collapse the node if it\n\t\t *      is expanded or move to the parent oterwise.\n\t\t * @param {boolean} [activate=true]\n\t\t * @returns {$.Promise}\n\t\t */\n\t\tnavigate: function(where, activate) {\n\t\t\tvar i,\n\t\t\t\tparents,\n\t\t\t\tres,\n\t\t\t\thandled = true,\n\t\t\t\tKC = $.ui.keyCode,\n\t\t\t\tsib = null;\n\n\t\t\t// Navigate to node\n\t\t\tfunction _goto(n) {\n\t\t\t\tif (n) {\n\t\t\t\t\t// setFocus/setActive will scroll later (if autoScroll is specified)\n\t\t\t\t\ttry {\n\t\t\t\t\t\tn.makeVisible({ scrollIntoView: false });\n\t\t\t\t\t} catch (e) {} // #272\n\t\t\t\t\t// Node may still be hidden by a filter\n\t\t\t\t\tif (!$(n.span).is(\":visible\")) {\n\t\t\t\t\t\tn.debug(\"Navigate: skipping hidden node\");\n\t\t\t\t\t\tn.navigate(where, activate);\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t\treturn activate === false ? n.setFocus() : n.setActive();\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tswitch (where) {\n\t\t\t\tcase KC.BACKSPACE:\n\t\t\t\t\tif (this.parent && this.parent.parent) {\n\t\t\t\t\t\tres = _goto(this.parent);\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\tcase KC.HOME:\n\t\t\t\t\tthis.tree.visit(function(n) {\n\t\t\t\t\t\t// goto first visible node\n\t\t\t\t\t\tif ($(n.span).is(\":visible\")) {\n\t\t\t\t\t\t\tres = _goto(n);\n\t\t\t\t\t\t\treturn false;\n\t\t\t\t\t\t}\n\t\t\t\t\t});\n\t\t\t\t\tbreak;\n\t\t\t\tcase KC.END:\n\t\t\t\t\tthis.tree.visit(function(n) {\n\t\t\t\t\t\t// goto last visible node\n\t\t\t\t\t\tif ($(n.span).is(\":visible\")) {\n\t\t\t\t\t\t\tres = n;\n\t\t\t\t\t\t}\n\t\t\t\t\t});\n\t\t\t\t\tif (res) {\n\t\t\t\t\t\tres = _goto(res);\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\tcase KC.LEFT:\n\t\t\t\t\tif (this.expanded) {\n\t\t\t\t\t\tthis.setExpanded(false);\n\t\t\t\t\t\tres = _goto(this);\n\t\t\t\t\t} else if (this.parent && this.parent.parent) {\n\t\t\t\t\t\tres = _goto(this.parent);\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\tcase KC.RIGHT:\n\t\t\t\t\tif (!this.expanded && (this.children || this.lazy)) {\n\t\t\t\t\t\tthis.setExpanded();\n\t\t\t\t\t\tres = _goto(this);\n\t\t\t\t\t} else if (this.children && this.children.length) {\n\t\t\t\t\t\tres = _goto(this.children[0]);\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\tcase KC.UP:\n\t\t\t\t\tsib = this.getPrevSibling();\n\t\t\t\t\t// #359: skip hidden sibling nodes, preventing a _goto() recursion\n\t\t\t\t\twhile (sib && !$(sib.span).is(\":visible\")) {\n\t\t\t\t\t\tsib = sib.getPrevSibling();\n\t\t\t\t\t}\n\t\t\t\t\twhile (\n\t\t\t\t\t\tsib &&\n\t\t\t\t\t\tsib.expanded &&\n\t\t\t\t\t\tsib.children &&\n\t\t\t\t\t\tsib.children.length\n\t\t\t\t\t) {\n\t\t\t\t\t\tsib = sib.children[sib.children.length - 1];\n\t\t\t\t\t}\n\t\t\t\t\tif (!sib && this.parent && this.parent.parent) {\n\t\t\t\t\t\tsib = this.parent;\n\t\t\t\t\t}\n\t\t\t\t\tres = _goto(sib);\n\t\t\t\t\tbreak;\n\t\t\t\tcase KC.DOWN:\n\t\t\t\t\tif (\n\t\t\t\t\t\tthis.expanded &&\n\t\t\t\t\t\tthis.children &&\n\t\t\t\t\t\tthis.children.length\n\t\t\t\t\t) {\n\t\t\t\t\t\tsib = this.children[0];\n\t\t\t\t\t} else {\n\t\t\t\t\t\tparents = this.getParentList(false, true);\n\t\t\t\t\t\tfor (i = parents.length - 1; i >= 0; i--) {\n\t\t\t\t\t\t\tsib = parents[i].getNextSibling();\n\t\t\t\t\t\t\t// #359: skip hidden sibling nodes, preventing a _goto() recursion\n\t\t\t\t\t\t\twhile (sib && !$(sib.span).is(\":visible\")) {\n\t\t\t\t\t\t\t\tsib = sib.getNextSibling();\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tif (sib) {\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tres = _goto(sib);\n\t\t\t\t\tbreak;\n\t\t\t\tdefault:\n\t\t\t\t\thandled = false;\n\t\t\t}\n\t\t\treturn res || _getResolvedPromise();\n\t\t},\n\t\t/**\n\t\t * Remove this node (not allowed for system root).\n\t\t */\n\t\tremove: function() {\n\t\t\treturn this.parent.removeChild(this);\n\t\t},\n\t\t/**\n\t\t * Remove childNode from list of direct children.\n\t\t * @param {FancytreeNode} childNode\n\t\t */\n\t\tremoveChild: function(childNode) {\n\t\t\treturn this.tree._callHook(\"nodeRemoveChild\", this, childNode);\n\t\t},\n\t\t/**\n\t\t * Remove all child nodes and descendents. This converts the node into a leaf.<br>\n\t\t * If this was a lazy node, it is still considered 'loaded'; call node.resetLazy()\n\t\t * in order to trigger lazyLoad on next expand.\n\t\t */\n\t\tremoveChildren: function() {\n\t\t\treturn this.tree._callHook(\"nodeRemoveChildren\", this);\n\t\t},\n\t\t/**\n\t\t * Remove class from node's span tag and .extraClasses.\n\t\t *\n\t\t * @param {string} className class name\n\t\t *\n\t\t * @since 2.17\n\t\t */\n\t\tremoveClass: function(className) {\n\t\t\treturn this.toggleClass(className, false);\n\t\t},\n\t\t/**\n\t\t * This method renders and updates all HTML markup that is required\n\t\t * to display this node in its current state.<br>\n\t\t * Note:\n\t\t * <ul>\n\t\t * <li>It should only be neccessary to call this method after the node object\n\t\t *     was modified by direct access to its properties, because the common\n\t\t *     API methods (node.setTitle(), moveTo(), addChildren(), remove(), ...)\n\t\t *     already handle this.\n\t\t * <li> {@link FancytreeNode#renderTitle} and {@link FancytreeNode#renderStatus}\n\t\t *     are implied. If changes are more local, calling only renderTitle() or\n\t\t *     renderStatus() may be sufficient and faster.\n\t\t * </ul>\n\t\t *\n\t\t * @param {boolean} [force=false] re-render, even if html markup was already created\n\t\t * @param {boolean} [deep=false] also render all descendants, even if parent is collapsed\n\t\t */\n\t\trender: function(force, deep) {\n\t\t\treturn this.tree._callHook(\"nodeRender\", this, force, deep);\n\t\t},\n\t\t/** Create HTML markup for the node's outer &lt;span> (expander, checkbox, icon, and title).\n\t\t * Implies {@link FancytreeNode#renderStatus}.\n\t\t * @see Fancytree_Hooks#nodeRenderTitle\n\t\t */\n\t\trenderTitle: function() {\n\t\t\treturn this.tree._callHook(\"nodeRenderTitle\", this);\n\t\t},\n\t\t/** Update element's CSS classes according to node state.\n\t\t * @see Fancytree_Hooks#nodeRenderStatus\n\t\t */\n\t\trenderStatus: function() {\n\t\t\treturn this.tree._callHook(\"nodeRenderStatus\", this);\n\t\t},\n\t\t/**\n\t\t * (experimental) Replace this node with `source`.\n\t\t * (Currently only available for paging nodes.)\n\t\t * @param {NodeData[]} source List of child node definitions\n\t\t * @since 2.15\n\t\t */\n\t\treplaceWith: function(source) {\n\t\t\tvar res,\n\t\t\t\tparent = this.parent,\n\t\t\t\tpos = $.inArray(this, parent.children),\n\t\t\t\tthat = this;\n\n\t\t\t_assert(\n\t\t\t\tthis.isPagingNode(),\n\t\t\t\t\"replaceWith() currently requires a paging status node\"\n\t\t\t);\n\n\t\t\tres = this.tree._callHook(\"nodeLoadChildren\", this, source);\n\t\t\tres.done(function(data) {\n\t\t\t\t// New nodes are currently children of `this`.\n\t\t\t\tvar children = that.children;\n\t\t\t\t// Prepend newly loaded child nodes to `this`\n\t\t\t\t// Move new children after self\n\t\t\t\tfor (i = 0; i < children.length; i++) {\n\t\t\t\t\tchildren[i].parent = parent;\n\t\t\t\t}\n\t\t\t\tparent.children.splice.apply(\n\t\t\t\t\tparent.children,\n\t\t\t\t\t[pos + 1, 0].concat(children)\n\t\t\t\t);\n\n\t\t\t\t// Remove self\n\t\t\t\tthat.children = null;\n\t\t\t\tthat.remove();\n\t\t\t\t// Redraw new nodes\n\t\t\t\tparent.render();\n\t\t\t\t// TODO: set node.partload = false if this was tha last paging node?\n\t\t\t\t// parent.addPagingNode(false);\n\t\t\t}).fail(function() {\n\t\t\t\tthat.setExpanded();\n\t\t\t});\n\t\t\treturn res;\n\t\t\t// $.error(\"Not implemented: replaceWith()\");\n\t\t},\n\t\t/**\n\t\t * Remove all children, collapse, and set the lazy-flag, so that the lazyLoad\n\t\t * event is triggered on next expand.\n\t\t */\n\t\tresetLazy: function() {\n\t\t\tthis.removeChildren();\n\t\t\tthis.expanded = false;\n\t\t\tthis.lazy = true;\n\t\t\tthis.children = undefined;\n\t\t\tthis.renderStatus();\n\t\t},\n\t\t/** Schedule activity for delayed execution (cancel any pending request).\n\t\t *  scheduleAction('cancel') will only cancel a pending request (if any).\n\t\t * @param {string} mode\n\t\t * @param {number} ms\n\t\t */\n\t\tscheduleAction: function(mode, ms) {\n\t\t\tif (this.tree.timer) {\n\t\t\t\tclearTimeout(this.tree.timer);\n\t\t\t\tthis.tree.debug(\"clearTimeout(%o)\", this.tree.timer);\n\t\t\t}\n\t\t\tthis.tree.timer = null;\n\t\t\tvar self = this; // required for closures\n\t\t\tswitch (mode) {\n\t\t\t\tcase \"cancel\":\n\t\t\t\t\t// Simply made sure that timer was cleared\n\t\t\t\t\tbreak;\n\t\t\t\tcase \"expand\":\n\t\t\t\t\tthis.tree.timer = setTimeout(function() {\n\t\t\t\t\t\tself.tree.debug(\"setTimeout: trigger expand\");\n\t\t\t\t\t\tself.setExpanded(true);\n\t\t\t\t\t}, ms);\n\t\t\t\t\tbreak;\n\t\t\t\tcase \"activate\":\n\t\t\t\t\tthis.tree.timer = setTimeout(function() {\n\t\t\t\t\t\tself.tree.debug(\"setTimeout: trigger activate\");\n\t\t\t\t\t\tself.setActive(true);\n\t\t\t\t\t}, ms);\n\t\t\t\t\tbreak;\n\t\t\t\tdefault:\n\t\t\t\t\t$.error(\"Invalid mode \" + mode);\n\t\t\t}\n\t\t\t//        this.tree.debug(\"setTimeout(%s, %s): %s\", mode, ms, this.tree.timer);\n\t\t},\n\t\t/**\n\t\t *\n\t\t * @param {boolean | PlainObject} [effects=false] animation options.\n\t\t * @param {object} [options=null] {topNode: null, effects: ..., parent: ...} this node will remain visible in\n\t\t *     any case, even if `this` is outside the scroll pane.\n\t\t * @returns {$.Promise}\n\t\t */\n\t\tscrollIntoView: function(effects, options) {\n\t\t\tif (options !== undefined && _isNode(options)) {\n\t\t\t\tthrow \"scrollIntoView() with 'topNode' option is deprecated since 2014-05-08. Use 'options.topNode' instead.\";\n\t\t\t}\n\t\t\t// The scroll parent is typically the plain tree's <UL> container.\n\t\t\t// For ext-table, we choose the nearest parent that has `position: relative`\n\t\t\t// and `overflow` set.\n\t\t\t// (This default can be overridden by the local or global `scrollParent` option.)\n\t\t\tvar opts = $.extend(\n\t\t\t\t\t{\n\t\t\t\t\t\teffects:\n\t\t\t\t\t\t\teffects === true\n\t\t\t\t\t\t\t\t? { duration: 200, queue: false }\n\t\t\t\t\t\t\t\t: effects,\n\t\t\t\t\t\tscrollOfs: this.tree.options.scrollOfs,\n\t\t\t\t\t\tscrollParent: this.tree.options.scrollParent,\n\t\t\t\t\t\ttopNode: null,\n\t\t\t\t\t},\n\t\t\t\t\toptions\n\t\t\t\t),\n\t\t\t\t$scrollParent = opts.scrollParent;\n\n\t\t\tif (!$scrollParent) {\n\t\t\t\t$scrollParent = this.tree.tbody\n\t\t\t\t\t? this.tree.$container.scrollParent()\n\t\t\t\t\t: this.tree.$container;\n\t\t\t} else if (!$scrollParent.jquery) {\n\t\t\t\t// Make sure we have a jQuery object\n\t\t\t\t$scrollParent = $($scrollParent);\n\t\t\t}\n\t\t\tif (\n\t\t\t\t$scrollParent[0] === document ||\n\t\t\t\t$scrollParent[0] === document.body\n\t\t\t) {\n\t\t\t\t// `document` may returned by $().scrollParent(), if nothing is found,\n\t\t\t\t// but would not work: (see #894)\n\t\t\t\tthis.debug(\n\t\t\t\t\t\"scrollIntoView(): normalizing scrollParent to 'window':\",\n\t\t\t\t\t$scrollParent[0]\n\t\t\t\t);\n\t\t\t\t$scrollParent = $(window);\n\t\t\t}\n\n\t\t\tvar topNodeY,\n\t\t\t\tnodeY,\n\t\t\t\thorzScrollbarHeight,\n\t\t\t\tcontainerOffsetTop,\n\t\t\t\tdfd = new $.Deferred(),\n\t\t\t\tthat = this,\n\t\t\t\tnodeHeight = $(this.span).height(),\n\t\t\t\ttopOfs = opts.scrollOfs.top || 0,\n\t\t\t\tbottomOfs = opts.scrollOfs.bottom || 0,\n\t\t\t\tcontainerHeight = $scrollParent.height(),\n\t\t\t\tscrollTop = $scrollParent.scrollTop(),\n\t\t\t\t$animateTarget = $scrollParent,\n\t\t\t\tisParentWindow = $scrollParent[0] === window,\n\t\t\t\ttopNode = opts.topNode || null,\n\t\t\t\tnewScrollTop = null;\n\n\t\t\t// this.debug(\"scrollIntoView(), scrollTop=\" + scrollTop, opts.scrollOfs);\n\t\t\t//\t\t_assert($(this.span).is(\":visible\"), \"scrollIntoView node is invisible\"); // otherwise we cannot calc offsets\n\t\t\tif (!$(this.span).is(\":visible\")) {\n\t\t\t\t// We cannot calc offsets for hidden elements\n\t\t\t\tthis.warn(\"scrollIntoView(): node is invisible.\");\n\t\t\t\treturn _getResolvedPromise();\n\t\t\t}\n\t\t\tif (isParentWindow) {\n\t\t\t\tnodeY = $(this.span).offset().top;\n\t\t\t\ttopNodeY =\n\t\t\t\t\ttopNode && topNode.span ? $(topNode.span).offset().top : 0;\n\t\t\t\t$animateTarget = $(\"html,body\");\n\t\t\t} else {\n\t\t\t\t_assert(\n\t\t\t\t\t$scrollParent[0] !== document &&\n\t\t\t\t\t\t$scrollParent[0] !== document.body,\n\t\t\t\t\t\"scrollParent should be a simple element or `window`, not document or body.\"\n\t\t\t\t);\n\n\t\t\t\t(containerOffsetTop = $scrollParent.offset().top),\n\t\t\t\t\t(nodeY =\n\t\t\t\t\t\t$(this.span).offset().top -\n\t\t\t\t\t\tcontainerOffsetTop +\n\t\t\t\t\t\tscrollTop); // relative to scroll parent\n\t\t\t\ttopNodeY = topNode\n\t\t\t\t\t? $(topNode.span).offset().top -\n\t\t\t\t\t  containerOffsetTop +\n\t\t\t\t\t  scrollTop\n\t\t\t\t\t: 0;\n\t\t\t\thorzScrollbarHeight = Math.max(\n\t\t\t\t\t0,\n\t\t\t\t\t$scrollParent.innerHeight() - $scrollParent[0].clientHeight\n\t\t\t\t);\n\t\t\t\tcontainerHeight -= horzScrollbarHeight;\n\t\t\t}\n\n\t\t\t// this.debug(\"    scrollIntoView(), nodeY=\" + nodeY + \", containerHeight=\" + containerHeight);\n\t\t\tif (nodeY < scrollTop + topOfs) {\n\t\t\t\t// Node is above visible container area\n\t\t\t\tnewScrollTop = nodeY - topOfs;\n\t\t\t\t// this.debug(\"    scrollIntoView(), UPPER newScrollTop=\" + newScrollTop);\n\t\t\t} else if (\n\t\t\t\tnodeY + nodeHeight >\n\t\t\t\tscrollTop + containerHeight - bottomOfs\n\t\t\t) {\n\t\t\t\tnewScrollTop = nodeY + nodeHeight - containerHeight + bottomOfs;\n\t\t\t\t// this.debug(\"    scrollIntoView(), LOWER newScrollTop=\" + newScrollTop);\n\t\t\t\t// If a topNode was passed, make sure that it is never scrolled\n\t\t\t\t// outside the upper border\n\t\t\t\tif (topNode) {\n\t\t\t\t\t_assert(\n\t\t\t\t\t\ttopNode.isRootNode() || $(topNode.span).is(\":visible\"),\n\t\t\t\t\t\t\"topNode must be visible\"\n\t\t\t\t\t);\n\t\t\t\t\tif (topNodeY < newScrollTop) {\n\t\t\t\t\t\tnewScrollTop = topNodeY - topOfs;\n\t\t\t\t\t\t// this.debug(\"    scrollIntoView(), TOP newScrollTop=\" + newScrollTop);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (newScrollTop !== null) {\n\t\t\t\t// this.debug(\"    scrollIntoView(), SET newScrollTop=\" + newScrollTop);\n\t\t\t\tif (opts.effects) {\n\t\t\t\t\topts.effects.complete = function() {\n\t\t\t\t\t\tdfd.resolveWith(that);\n\t\t\t\t\t};\n\t\t\t\t\t$animateTarget.stop(true).animate(\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tscrollTop: newScrollTop,\n\t\t\t\t\t\t},\n\t\t\t\t\t\topts.effects\n\t\t\t\t\t);\n\t\t\t\t} else {\n\t\t\t\t\t$animateTarget[0].scrollTop = newScrollTop;\n\t\t\t\t\tdfd.resolveWith(this);\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tdfd.resolveWith(this);\n\t\t\t}\n\t\t\treturn dfd.promise();\n\t\t},\n\n\t\t/**Activate this node.\n\t\t *\n\t\t * The `cell` option requires the ext-table and ext-ariagrid extensions.\n\t\t *\n\t\t * @param {boolean} [flag=true] pass false to deactivate\n\t\t * @param {object} [opts] additional options. Defaults to {noEvents: false, noFocus: false, cell: null}\n\t\t * @returns {$.Promise}\n\t\t */\n\t\tsetActive: function(flag, opts) {\n\t\t\treturn this.tree._callHook(\"nodeSetActive\", this, flag, opts);\n\t\t},\n\t\t/**Expand or collapse this node. Promise is resolved, when lazy loading and animations are done.\n\t\t * @param {boolean} [flag=true] pass false to collapse\n\t\t * @param {object} [opts] additional options. Defaults to {noAnimation: false, noEvents: false}\n\t\t * @returns {$.Promise}\n\t\t */\n\t\tsetExpanded: function(flag, opts) {\n\t\t\treturn this.tree._callHook(\"nodeSetExpanded\", this, flag, opts);\n\t\t},\n\t\t/**Set keyboard focus to this node.\n\t\t * @param {boolean} [flag=true] pass false to blur\n\t\t * @see Fancytree#setFocus\n\t\t */\n\t\tsetFocus: function(flag) {\n\t\t\treturn this.tree._callHook(\"nodeSetFocus\", this, flag);\n\t\t},\n\t\t/**Select this node, i.e. check the checkbox.\n\t\t * @param {boolean} [flag=true] pass false to deselect\n\t\t * @param {object} [opts] additional options. Defaults to {noEvents: false, p\n\t\t *     propagateDown: null, propagateUp: null, callback: null }\n\t\t */\n\t\tsetSelected: function(flag, opts) {\n\t\t\treturn this.tree._callHook(\"nodeSetSelected\", this, flag, opts);\n\t\t},\n\t\t/**Mark a lazy node as 'error', 'loading', 'nodata', or 'ok'.\n\t\t * @param {string} status 'error'|'empty'|'ok'\n\t\t * @param {string} [message]\n\t\t * @param {string} [details]\n\t\t */\n\t\tsetStatus: function(status, message, details) {\n\t\t\treturn this.tree._callHook(\n\t\t\t\t\"nodeSetStatus\",\n\t\t\t\tthis,\n\t\t\t\tstatus,\n\t\t\t\tmessage,\n\t\t\t\tdetails\n\t\t\t);\n\t\t},\n\t\t/**Rename this node.\n\t\t * @param {string} title\n\t\t */\n\t\tsetTitle: function(title) {\n\t\t\tthis.title = title;\n\t\t\tthis.renderTitle();\n\t\t\tthis.triggerModify(\"rename\");\n\t\t},\n\t\t/**Sort child list by title.\n\t\t * @param {function} [cmp] custom compare function(a, b) that returns -1, 0, or 1 (defaults to sort by title).\n\t\t * @param {boolean} [deep=false] pass true to sort all descendant nodes\n\t\t */\n\t\tsortChildren: function(cmp, deep) {\n\t\t\tvar i,\n\t\t\t\tl,\n\t\t\t\tcl = this.children;\n\n\t\t\tif (!cl) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tcmp =\n\t\t\t\tcmp ||\n\t\t\t\tfunction(a, b) {\n\t\t\t\t\tvar x = a.title.toLowerCase(),\n\t\t\t\t\t\ty = b.title.toLowerCase();\n\t\t\t\t\treturn x === y ? 0 : x > y ? 1 : -1;\n\t\t\t\t};\n\t\t\tcl.sort(cmp);\n\t\t\tif (deep) {\n\t\t\t\tfor (i = 0, l = cl.length; i < l; i++) {\n\t\t\t\t\tif (cl[i].children) {\n\t\t\t\t\t\tcl[i].sortChildren(cmp, \"$norender$\");\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (deep !== \"$norender$\") {\n\t\t\t\tthis.render();\n\t\t\t}\n\t\t\tthis.triggerModifyChild(\"sort\");\n\t\t},\n\t\t/** Convert node (or whole branch) into a plain object.\n\t\t *\n\t\t * The result is compatible with node.addChildren().\n\t\t *\n\t\t * @param {boolean} [recursive=false] include child nodes\n\t\t * @param {function} [callback] callback(dict, node) is called for every node, in order to allow modifications\n\t\t * @returns {NodeData}\n\t\t */\n\t\ttoDict: function(recursive, callback) {\n\t\t\tvar i,\n\t\t\t\tl,\n\t\t\t\tnode,\n\t\t\t\tdict = {},\n\t\t\t\tself = this;\n\n\t\t\t$.each(NODE_ATTRS, function(i, a) {\n\t\t\t\tif (self[a] || self[a] === false) {\n\t\t\t\t\tdict[a] = self[a];\n\t\t\t\t}\n\t\t\t});\n\t\t\tif (!$.isEmptyObject(this.data)) {\n\t\t\t\tdict.data = $.extend({}, this.data);\n\t\t\t\tif ($.isEmptyObject(dict.data)) {\n\t\t\t\t\tdelete dict.data;\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (callback) {\n\t\t\t\tcallback(dict, self);\n\t\t\t}\n\t\t\tif (recursive) {\n\t\t\t\tif (this.hasChildren()) {\n\t\t\t\t\tdict.children = [];\n\t\t\t\t\tfor (i = 0, l = this.children.length; i < l; i++) {\n\t\t\t\t\t\tnode = this.children[i];\n\t\t\t\t\t\tif (!node.isStatusNode()) {\n\t\t\t\t\t\t\tdict.children.push(node.toDict(true, callback));\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\t//                dict.children = null;\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn dict;\n\t\t},\n\t\t/**\n\t\t * Set, clear, or toggle class of node's span tag and .extraClasses.\n\t\t *\n\t\t * @param {string} className class name (separate multiple classes by space)\n\t\t * @param {boolean} [flag] true/false to add/remove class. If omitted, class is toggled.\n\t\t * @returns {boolean} true if a class was added\n\t\t *\n\t\t * @since 2.17\n\t\t */\n\t\ttoggleClass: function(value, flag) {\n\t\t\tvar className,\n\t\t\t\thasClass,\n\t\t\t\trnotwhite = /\\S+/g,\n\t\t\t\tclassNames = value.match(rnotwhite) || [],\n\t\t\t\ti = 0,\n\t\t\t\twasAdded = false,\n\t\t\t\tstatusElem = this[this.tree.statusClassPropName],\n\t\t\t\tcurClasses = \" \" + (this.extraClasses || \"\") + \" \";\n\n\t\t\t// this.info(\"toggleClass('\" + value + \"', \" + flag + \")\", curClasses);\n\t\t\t// Modify DOM element directly if it already exists\n\t\t\tif (statusElem) {\n\t\t\t\t$(statusElem).toggleClass(value, flag);\n\t\t\t}\n\t\t\t// Modify node.extraClasses to make this change persistent\n\t\t\t// Toggle if flag was not passed\n\t\t\twhile ((className = classNames[i++])) {\n\t\t\t\thasClass = curClasses.indexOf(\" \" + className + \" \") >= 0;\n\t\t\t\tflag = flag === undefined ? !hasClass : !!flag;\n\t\t\t\tif (flag) {\n\t\t\t\t\tif (!hasClass) {\n\t\t\t\t\t\tcurClasses += className + \" \";\n\t\t\t\t\t\twasAdded = true;\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\twhile (curClasses.indexOf(\" \" + className + \" \") > -1) {\n\t\t\t\t\t\tcurClasses = curClasses.replace(\n\t\t\t\t\t\t\t\" \" + className + \" \",\n\t\t\t\t\t\t\t\" \"\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\tthis.extraClasses = $.trim(curClasses);\n\t\t\t// this.info(\"-> toggleClass('\" + value + \"', \" + flag + \"): '\" + this.extraClasses + \"'\");\n\t\t\treturn wasAdded;\n\t\t},\n\t\t/** Flip expanded status. */\n\t\ttoggleExpanded: function() {\n\t\t\treturn this.tree._callHook(\"nodeToggleExpanded\", this);\n\t\t},\n\t\t/** Flip selection status. */\n\t\ttoggleSelected: function() {\n\t\t\treturn this.tree._callHook(\"nodeToggleSelected\", this);\n\t\t},\n\t\ttoString: function() {\n\t\t\treturn \"FancytreeNode@\" + this.key + \"[title='\" + this.title + \"']\";\n\t\t\t// return \"<FancytreeNode(#\" + this.key + \", '\" + this.title + \"')>\";\n\t\t},\n\t\t/**\n\t\t * Trigger `modifyChild` event on a parent to signal that a child was modified.\n\t\t * @param {string} operation Type of change: 'add', 'remove', 'rename', 'move', 'data', ...\n\t\t * @param {FancytreeNode} [childNode]\n\t\t * @param {object} [extra]\n\t\t */\n\t\ttriggerModifyChild: function(operation, childNode, extra) {\n\t\t\tvar data,\n\t\t\t\tmodifyChild = this.tree.options.modifyChild;\n\n\t\t\tif (modifyChild) {\n\t\t\t\tif (childNode && childNode.parent !== this) {\n\t\t\t\t\t$.error(\n\t\t\t\t\t\t\"childNode \" + childNode + \" is not a child of \" + this\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\tdata = {\n\t\t\t\t\tnode: this,\n\t\t\t\t\ttree: this.tree,\n\t\t\t\t\toperation: operation,\n\t\t\t\t\tchildNode: childNode || null,\n\t\t\t\t};\n\t\t\t\tif (extra) {\n\t\t\t\t\t$.extend(data, extra);\n\t\t\t\t}\n\t\t\t\tmodifyChild({ type: \"modifyChild\" }, data);\n\t\t\t}\n\t\t},\n\t\t/**\n\t\t * Trigger `modifyChild` event on node.parent(!).\n\t\t * @param {string} operation Type of change: 'add', 'remove', 'rename', 'move', 'data', ...\n\t\t * @param {object} [extra]\n\t\t */\n\t\ttriggerModify: function(operation, extra) {\n\t\t\tthis.parent.triggerModifyChild(operation, this, extra);\n\t\t},\n\t\t/** Call fn(node) for all child nodes in hierarchical order (depth-first).<br>\n\t\t * Stop iteration, if fn() returns false. Skip current branch, if fn() returns \"skip\".<br>\n\t\t * Return false if iteration was stopped.\n\t\t *\n\t\t * @param {function} fn the callback function.\n\t\t *     Return false to stop iteration, return \"skip\" to skip this node and\n\t\t *     its children only.\n\t\t * @param {boolean} [includeSelf=false]\n\t\t * @returns {boolean}\n\t\t */\n\t\tvisit: function(fn, includeSelf) {\n\t\t\tvar i,\n\t\t\t\tl,\n\t\t\t\tres = true,\n\t\t\t\tchildren = this.children;\n\n\t\t\tif (includeSelf === true) {\n\t\t\t\tres = fn(this);\n\t\t\t\tif (res === false || res === \"skip\") {\n\t\t\t\t\treturn res;\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (children) {\n\t\t\t\tfor (i = 0, l = children.length; i < l; i++) {\n\t\t\t\t\tres = children[i].visit(fn, true);\n\t\t\t\t\tif (res === false) {\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn res;\n\t\t},\n\t\t/** Call fn(node) for all child nodes and recursively load lazy children.<br>\n\t\t * <b>Note:</b> If you need this method, you probably should consider to review\n\t\t * your architecture! Recursivley loading nodes is a perfect way for lazy\n\t\t * programmers to flood the server with requests ;-)\n\t\t *\n\t\t * @param {function} [fn] optional callback function.\n\t\t *     Return false to stop iteration, return \"skip\" to skip this node and\n\t\t *     its children only.\n\t\t * @param {boolean} [includeSelf=false]\n\t\t * @returns {$.Promise}\n\t\t * @since 2.4\n\t\t */\n\t\tvisitAndLoad: function(fn, includeSelf, _recursion) {\n\t\t\tvar dfd,\n\t\t\t\tres,\n\t\t\t\tloaders,\n\t\t\t\tnode = this;\n\n\t\t\t// node.debug(\"visitAndLoad\");\n\t\t\tif (fn && includeSelf === true) {\n\t\t\t\tres = fn(node);\n\t\t\t\tif (res === false || res === \"skip\") {\n\t\t\t\t\treturn _recursion ? res : _getResolvedPromise();\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (!node.children && !node.lazy) {\n\t\t\t\treturn _getResolvedPromise();\n\t\t\t}\n\t\t\tdfd = new $.Deferred();\n\t\t\tloaders = [];\n\t\t\t// node.debug(\"load()...\");\n\t\t\tnode.load().done(function() {\n\t\t\t\t// node.debug(\"load()... done.\");\n\t\t\t\tfor (var i = 0, l = node.children.length; i < l; i++) {\n\t\t\t\t\tres = node.children[i].visitAndLoad(fn, true, true);\n\t\t\t\t\tif (res === false) {\n\t\t\t\t\t\tdfd.reject();\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t} else if (res !== \"skip\") {\n\t\t\t\t\t\tloaders.push(res); // Add promise to the list\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\t$.when.apply(this, loaders).then(function() {\n\t\t\t\t\tdfd.resolve();\n\t\t\t\t});\n\t\t\t});\n\t\t\treturn dfd.promise();\n\t\t},\n\t\t/** Call fn(node) for all parent nodes, bottom-up, including invisible system root.<br>\n\t\t * Stop iteration, if fn() returns false.<br>\n\t\t * Return false if iteration was stopped.\n\t\t *\n\t\t * @param {function} fn the callback function.\n\t\t *     Return false to stop iteration, return \"skip\" to skip this node and children only.\n\t\t * @param {boolean} [includeSelf=false]\n\t\t * @returns {boolean}\n\t\t */\n\t\tvisitParents: function(fn, includeSelf) {\n\t\t\t// Visit parent nodes (bottom up)\n\t\t\tif (includeSelf && fn(this) === false) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\tvar p = this.parent;\n\t\t\twhile (p) {\n\t\t\t\tif (fn(p) === false) {\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t\tp = p.parent;\n\t\t\t}\n\t\t\treturn true;\n\t\t},\n\t\t/** Call fn(node) for all sibling nodes.<br>\n\t\t * Stop iteration, if fn() returns false.<br>\n\t\t * Return false if iteration was stopped.\n\t\t *\n\t\t * @param {function} fn the callback function.\n\t\t *     Return false to stop iteration.\n\t\t * @param {boolean} [includeSelf=false]\n\t\t * @returns {boolean}\n\t\t */\n\t\tvisitSiblings: function(fn, includeSelf) {\n\t\t\tvar i,\n\t\t\t\tl,\n\t\t\t\tn,\n\t\t\t\tac = this.parent.children;\n\n\t\t\tfor (i = 0, l = ac.length; i < l; i++) {\n\t\t\t\tn = ac[i];\n\t\t\t\tif (includeSelf || n !== this) {\n\t\t\t\t\tif (fn(n) === false) {\n\t\t\t\t\t\treturn false;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn true;\n\t\t},\n\t\t/** Write warning to browser console if debugLevel >= 2 (prepending node info)\n\t\t *\n\t\t * @param {*} msg string or object or array of such\n\t\t */\n\t\twarn: function(msg) {\n\t\t\tif (this.tree.options.debugLevel >= 2) {\n\t\t\t\tArray.prototype.unshift.call(arguments, this.toString());\n\t\t\t\tconsoleApply(\"warn\", arguments);\n\t\t\t}\n\t\t},\n\t};\n\n\t/******************************************************************************\n\t * Fancytree\n\t */\n\t/**\n\t * Construct a new tree object.\n\t *\n\t * @class Fancytree\n\t * @classdesc The controller behind a fancytree.\n\t * This class also contains 'hook methods': see {@link Fancytree_Hooks}.\n\t *\n\t * @param {Widget} widget\n\t *\n\t * @property {string} _id Automatically generated unique tree instance ID, e.g. \"1\".\n\t * @property {string} _ns Automatically generated unique tree namespace, e.g. \".fancytree-1\".\n\t * @property {FancytreeNode} activeNode Currently active node or null.\n\t * @property {string} ariaPropName Property name of FancytreeNode that contains the element which will receive the aria attributes.\n\t *     Typically \"li\", but \"tr\" for table extension.\n\t * @property {jQueryObject} $container Outer &lt;ul> element (or &lt;table> element for ext-table).\n\t * @property {jQueryObject} $div A jQuery object containing the element used to instantiate the tree widget (`widget.element`)\n\t * @property {object|array} columns Recommended place to store shared column meta data. @since 2.27\n\t * @property {object} data Metadata, i.e. properties that may be passed to `source` in addition to a children array.\n\t * @property {object} ext Hash of all active plugin instances.\n\t * @property {FancytreeNode} focusNode Currently focused node or null.\n\t * @property {FancytreeNode} lastSelectedNode Used to implement selectMode 1 (single select)\n\t * @property {string} nodeContainerAttrName Property name of FancytreeNode that contains the outer element of single nodes.\n\t *     Typically \"li\", but \"tr\" for table extension.\n\t * @property {FancytreeOptions} options Current options, i.e. default options + options passed to constructor.\n\t * @property {FancytreeNode} rootNode Invisible system root node.\n\t * @property {string} statusClassPropName Property name of FancytreeNode that contains the element which will receive the status classes.\n\t *     Typically \"span\", but \"tr\" for table extension.\n\t * @property {object} types Map for shared type specific meta data, used with node.type attribute. @since 2.27\n\t * @property {object} widget Base widget instance.\n\t */\n\tfunction Fancytree(widget) {\n\t\tthis.widget = widget;\n\t\tthis.$div = widget.element;\n\t\tthis.options = widget.options;\n\t\tif (this.options) {\n\t\t\tif (\n\t\t\t\t$.isFunction(this.options.lazyload) &&\n\t\t\t\t!$.isFunction(this.options.lazyLoad)\n\t\t\t) {\n\t\t\t\tthis.options.lazyLoad = function() {\n\t\t\t\t\tFT.warn(\n\t\t\t\t\t\t\"The 'lazyload' event is deprecated since 2014-02-25. Use 'lazyLoad' (with uppercase L) instead.\"\n\t\t\t\t\t);\n\t\t\t\t\treturn widget.options.lazyload.apply(this, arguments);\n\t\t\t\t};\n\t\t\t}\n\t\t\tif ($.isFunction(this.options.loaderror)) {\n\t\t\t\t$.error(\n\t\t\t\t\t\"The 'loaderror' event was renamed since 2014-07-03. Use 'loadError' (with uppercase E) instead.\"\n\t\t\t\t);\n\t\t\t}\n\t\t\tif (this.options.fx !== undefined) {\n\t\t\t\tFT.warn(\n\t\t\t\t\t\"The 'fx' option was replaced by 'toggleEffect' since 2014-11-30.\"\n\t\t\t\t);\n\t\t\t}\n\t\t\tif (this.options.removeNode !== undefined) {\n\t\t\t\t$.error(\n\t\t\t\t\t\"The 'removeNode' event was replaced by 'modifyChild' since 2.20 (2016-09-10).\"\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\t\tthis.ext = {}; // Active extension instances\n\t\tthis.types = {};\n\t\tthis.columns = {};\n\t\t// allow to init tree.data.foo from <div data-foo=''>\n\t\tthis.data = _getElementDataAsDict(this.$div);\n\t\t// TODO: use widget.uuid instead?\n\t\tthis._id = $.ui.fancytree._nextId++;\n\t\t// TODO: use widget.eventNamespace instead?\n\t\tthis._ns = \".fancytree-\" + this._id; // append for namespaced events\n\t\tthis.activeNode = null;\n\t\tthis.focusNode = null;\n\t\tthis._hasFocus = null;\n\t\tthis._tempCache = {};\n\t\tthis._lastMousedownNode = null;\n\t\tthis._enableUpdate = true;\n\t\tthis.lastSelectedNode = null;\n\t\tthis.systemFocusElement = null;\n\t\tthis.lastQuicksearchTerm = \"\";\n\t\tthis.lastQuicksearchTime = 0;\n\n\t\tthis.statusClassPropName = \"span\";\n\t\tthis.ariaPropName = \"li\";\n\t\tthis.nodeContainerAttrName = \"li\";\n\n\t\t// Remove previous markup if any\n\t\tthis.$div.find(\">ul.fancytree-container\").remove();\n\n\t\t// Create a node without parent.\n\t\tvar fakeParent = { tree: this },\n\t\t\t$ul;\n\t\tthis.rootNode = new FancytreeNode(fakeParent, {\n\t\t\ttitle: \"root\",\n\t\t\tkey: \"root_\" + this._id,\n\t\t\tchildren: null,\n\t\t\texpanded: true,\n\t\t});\n\t\tthis.rootNode.parent = null;\n\n\t\t// Create root markup\n\t\t$ul = $(\"<ul>\", {\n\t\t\tclass: \"ui-fancytree fancytree-container fancytree-plain\",\n\t\t}).appendTo(this.$div);\n\t\tthis.$container = $ul;\n\t\tthis.rootNode.ul = $ul[0];\n\n\t\tif (this.options.debugLevel == null) {\n\t\t\tthis.options.debugLevel = FT.debugLevel;\n\t\t}\n\t\t// // Add container to the TAB chain\n\t\t// // See http://www.w3.org/TR/wai-aria-practices/#focus_activedescendant\n\t\t// // #577: Allow to set tabindex to \"0\", \"-1\" and \"\"\n\t\t// this.$container.attr(\"tabindex\", this.options.tabindex);\n\n\t\t// if( this.options.rtl ) {\n\t\t// \tthis.$container.attr(\"DIR\", \"RTL\").addClass(\"fancytree-rtl\");\n\t\t// // }else{\n\t\t// //\tthis.$container.attr(\"DIR\", null).removeClass(\"fancytree-rtl\");\n\t\t// }\n\t\t// if(this.options.aria){\n\t\t// \tthis.$container.attr(\"role\", \"tree\");\n\t\t// \tif( this.options.selectMode !== 1 ) {\n\t\t// \t\tthis.$container.attr(\"aria-multiselectable\", true);\n\t\t// \t}\n\t\t// }\n\t}\n\n\tFancytree.prototype = /** @lends Fancytree# */ {\n\t\t/* Return a context object that can be re-used for _callHook().\n\t * @param {Fancytree | FancytreeNode | EventData} obj\n\t * @param {Event} originalEvent\n\t * @param {Object} extra\n\t * @returns {EventData}\n\t */\n\t\t_makeHookContext: function(obj, originalEvent, extra) {\n\t\t\tvar ctx, tree;\n\t\t\tif (obj.node !== undefined) {\n\t\t\t\t// obj is already a context object\n\t\t\t\tif (originalEvent && obj.originalEvent !== originalEvent) {\n\t\t\t\t\t$.error(\"invalid args\");\n\t\t\t\t}\n\t\t\t\tctx = obj;\n\t\t\t} else if (obj.tree) {\n\t\t\t\t// obj is a FancytreeNode\n\t\t\t\ttree = obj.tree;\n\t\t\t\tctx = {\n\t\t\t\t\tnode: obj,\n\t\t\t\t\ttree: tree,\n\t\t\t\t\twidget: tree.widget,\n\t\t\t\t\toptions: tree.widget.options,\n\t\t\t\t\toriginalEvent: originalEvent,\n\t\t\t\t\ttypeInfo: tree.types[obj.type] || {},\n\t\t\t\t};\n\t\t\t} else if (obj.widget) {\n\t\t\t\t// obj is a Fancytree\n\t\t\t\tctx = {\n\t\t\t\t\tnode: null,\n\t\t\t\t\ttree: obj,\n\t\t\t\t\twidget: obj.widget,\n\t\t\t\t\toptions: obj.widget.options,\n\t\t\t\t\toriginalEvent: originalEvent,\n\t\t\t\t};\n\t\t\t} else {\n\t\t\t\t$.error(\"invalid args\");\n\t\t\t}\n\t\t\tif (extra) {\n\t\t\t\t$.extend(ctx, extra);\n\t\t\t}\n\t\t\treturn ctx;\n\t\t},\n\t\t/* Trigger a hook function: funcName(ctx, [...]).\n\t *\n\t * @param {string} funcName\n\t * @param {Fancytree|FancytreeNode|EventData} contextObject\n\t * @param {any}  [_extraArgs] optional additional arguments\n\t * @returns {any}\n\t */\n\t\t_callHook: function(funcName, contextObject, _extraArgs) {\n\t\t\tvar ctx = this._makeHookContext(contextObject),\n\t\t\t\tfn = this[funcName],\n\t\t\t\targs = Array.prototype.slice.call(arguments, 2);\n\t\t\tif (!$.isFunction(fn)) {\n\t\t\t\t$.error(\"_callHook('\" + funcName + \"') is not a function\");\n\t\t\t}\n\t\t\targs.unshift(ctx);\n\t\t\t//\t\tthis.debug(\"_hook\", funcName, ctx.node && ctx.node.toString() || ctx.tree.toString(), args);\n\t\t\treturn fn.apply(this, args);\n\t\t},\n\t\t_setExpiringValue: function(key, value, ms) {\n\t\t\tthis._tempCache[key] = {\n\t\t\t\tvalue: value,\n\t\t\t\texpire: Date.now() + (+ms || 50),\n\t\t\t};\n\t\t},\n\t\t_getExpiringValue: function(key) {\n\t\t\tvar entry = this._tempCache[key];\n\t\t\tif (entry && entry.expire > Date.now()) {\n\t\t\t\treturn entry.value;\n\t\t\t}\n\t\t\tdelete this._tempCache[key];\n\t\t\treturn null;\n\t\t},\n\t\t/* Check if current extensions dependencies are met and throw an error if not.\n\t *\n\t * This method may be called inside the `treeInit` hook for custom extensions.\n\t *\n\t * @param {string} extension name of the required extension\n\t * @param {boolean} [required=true] pass `false` if the extension is optional, but we want to check for order if it is present\n\t * @param {boolean} [before] `true` if `name` must be included before this, `false` otherwise (use `null` if order doesn't matter)\n\t * @param {string} [message] optional error message (defaults to a descriptve error message)\n\t */\n\t\t_requireExtension: function(name, required, before, message) {\n\t\t\tif (before != null) {\n\t\t\t\tbefore = !!before;\n\t\t\t}\n\t\t\tvar thisName = this._local.name,\n\t\t\t\textList = this.options.extensions,\n\t\t\t\tisBefore =\n\t\t\t\t\t$.inArray(name, extList) < $.inArray(thisName, extList),\n\t\t\t\tisMissing = required && this.ext[name] == null,\n\t\t\t\tbadOrder = !isMissing && before != null && before !== isBefore;\n\n\t\t\t_assert(thisName && thisName !== name, \"invalid or same name\");\n\n\t\t\tif (isMissing || badOrder) {\n\t\t\t\tif (!message) {\n\t\t\t\t\tif (isMissing || required) {\n\t\t\t\t\t\tmessage =\n\t\t\t\t\t\t\t\"'\" +\n\t\t\t\t\t\t\tthisName +\n\t\t\t\t\t\t\t\"' extension requires '\" +\n\t\t\t\t\t\t\tname +\n\t\t\t\t\t\t\t\"'\";\n\t\t\t\t\t\tif (badOrder) {\n\t\t\t\t\t\t\tmessage +=\n\t\t\t\t\t\t\t\t\" to be registered \" +\n\t\t\t\t\t\t\t\t(before ? \"before\" : \"after\") +\n\t\t\t\t\t\t\t\t\" itself\";\n\t\t\t\t\t\t}\n\t\t\t\t\t} else {\n\t\t\t\t\t\tmessage =\n\t\t\t\t\t\t\t\"If used together, `\" +\n\t\t\t\t\t\t\tname +\n\t\t\t\t\t\t\t\"` must be registered \" +\n\t\t\t\t\t\t\t(before ? \"before\" : \"after\") +\n\t\t\t\t\t\t\t\" `\" +\n\t\t\t\t\t\t\tthisName +\n\t\t\t\t\t\t\t\"`\";\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\t$.error(message);\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\treturn true;\n\t\t},\n\t\t/** Activate node with a given key and fire focus and activate events.\n\t\t *\n\t\t * A previously activated node will be deactivated.\n\t\t * If activeVisible option is set, all parents will be expanded as necessary.\n\t\t * Pass key = false, to deactivate the current node only.\n\t\t * @param {string} key\n\t\t * @param {object} [opts] additional options. Defaults to {noEvents: false, noFocus: false}\n\t\t * @returns {FancytreeNode} activated node (null, if not found)\n\t\t */\n\t\tactivateKey: function(key, opts) {\n\t\t\tvar node = this.getNodeByKey(key);\n\t\t\tif (node) {\n\t\t\t\tnode.setActive(true, opts);\n\t\t\t} else if (this.activeNode) {\n\t\t\t\tthis.activeNode.setActive(false, opts);\n\t\t\t}\n\t\t\treturn node;\n\t\t},\n\t\t/** (experimental) Add child status nodes that indicate 'More...', ....\n\t\t * @param {boolean|object} node optional node definition. Pass `false` to remove all paging nodes.\n\t\t * @param {string} [mode='append'] 'child'|firstChild'\n\t\t * @since 2.15\n\t\t */\n\t\taddPagingNode: function(node, mode) {\n\t\t\treturn this.rootNode.addPagingNode(node, mode);\n\t\t},\n\t\t/** (experimental) Modify existing data model.\n\t\t *\n\t\t * @param {Array} patchList array of [key, NodePatch] arrays\n\t\t * @returns {$.Promise} resolved, when all patches have been applied\n\t\t * @see TreePatch\n\t\t */\n\t\tapplyPatch: function(patchList) {\n\t\t\tvar dfd,\n\t\t\t\ti,\n\t\t\t\tp2,\n\t\t\t\tkey,\n\t\t\t\tpatch,\n\t\t\t\tnode,\n\t\t\t\tpatchCount = patchList.length,\n\t\t\t\tdeferredList = [];\n\n\t\t\tfor (i = 0; i < patchCount; i++) {\n\t\t\t\tp2 = patchList[i];\n\t\t\t\t_assert(\n\t\t\t\t\tp2.length === 2,\n\t\t\t\t\t\"patchList must be an array of length-2-arrays\"\n\t\t\t\t);\n\t\t\t\tkey = p2[0];\n\t\t\t\tpatch = p2[1];\n\t\t\t\tnode = key === null ? this.rootNode : this.getNodeByKey(key);\n\t\t\t\tif (node) {\n\t\t\t\t\tdfd = new $.Deferred();\n\t\t\t\t\tdeferredList.push(dfd);\n\t\t\t\t\tnode.applyPatch(patch).always(_makeResolveFunc(dfd, node));\n\t\t\t\t} else {\n\t\t\t\t\tthis.warn(\"could not find node with key '\" + key + \"'\");\n\t\t\t\t}\n\t\t\t}\n\t\t\t// Return a promise that is resolved, when ALL patches were applied\n\t\t\treturn $.when.apply($, deferredList).promise();\n\t\t},\n\t\t/* TODO: implement in dnd extension\n\tcancelDrag: function() {\n\t\tvar dd = $.ui.ddmanager.current;\n\t\tif(dd){\n\t\t\tdd.cancel();\n\t\t}\n\t},\n   */\n\t\t/** Remove all nodes.\n\t\t * @since 2.14\n\t\t */\n\t\tclear: function(source) {\n\t\t\tthis._callHook(\"treeClear\", this);\n\t\t},\n\t\t/** Return the number of nodes.\n\t\t * @returns {integer}\n\t\t */\n\t\tcount: function() {\n\t\t\treturn this.rootNode.countChildren();\n\t\t},\n\t\t/** Write to browser console if debugLevel >= 4 (prepending tree name)\n\t\t *\n\t\t * @param {*} msg string or object or array of such\n\t\t */\n\t\tdebug: function(msg) {\n\t\t\tif (this.options.debugLevel >= 4) {\n\t\t\t\tArray.prototype.unshift.call(arguments, this.toString());\n\t\t\t\tconsoleApply(\"log\", arguments);\n\t\t\t}\n\t\t},\n\t\t/** Enable (or disable) the tree control.\n\t\t *\n\t\t * @param {boolean} [flag=true] pass false to disable\n\t\t * @since 2.30\n\t\t */\n\t\tenable: function(flag) {\n\t\t\tif (flag === false) {\n\t\t\t\tthis.widget.disable();\n\t\t\t} else {\n\t\t\t\tthis.widget.enable();\n\t\t\t}\n\t\t},\n\t\t/** Temporarily suppress rendering to improve performance on bulk-updates.\n\t\t *\n\t\t * @param {boolean} flag\n\t\t * @returns {boolean} previous status\n\t\t * @since 2.19\n\t\t */\n\t\tenableUpdate: function(flag) {\n\t\t\tflag = flag !== false; // Confusing use of '!'\n\t\t\t/*jshint -W018 */ if (!!this._enableUpdate === !!flag) {\n\t\t\t\treturn flag;\n\t\t\t}\n\t\t\t/*jshint +W018 */\n\t\t\tthis._enableUpdate = flag;\n\t\t\tif (flag) {\n\t\t\t\tthis.debug(\"enableUpdate(true): redraw \"); //, this._dirtyRoots);\n\t\t\t\tthis.render();\n\t\t\t} else {\n\t\t\t\t// \tthis._dirtyRoots = null;\n\t\t\t\tthis.debug(\"enableUpdate(false)...\");\n\t\t\t}\n\t\t\treturn !flag; // return previous value\n\t\t},\n\t\t/** Expand (or collapse) all parent nodes.\n\t\t *\n\t\t * This convenience method uses `tree.visit()` and `tree.setExpanded()`\n\t\t * internally.\n\t\t *\n\t\t * @param {boolean} [flag=true] pass false to collapse\n\t\t * @param {object} [opts] passed to setExpanded()\n\t\t * @since 2.30\n\t\t */\n\t\texpandAll: function(flag, opts) {\n\t\t\tflag = flag !== false;\n\t\t\tthis.visit(function(node) {\n\t\t\t\tif (\n\t\t\t\t\tnode.hasChildren() !== false &&\n\t\t\t\t\tnode.isExpanded() !== flag\n\t\t\t\t) {\n\t\t\t\t\tnode.setExpanded(flag, opts);\n\t\t\t\t}\n\t\t\t});\n\t\t},\n\t\t/**Find all nodes that matches condition.\n\t\t *\n\t\t * @param {string | function(node)} match title string to search for, or a\n\t\t *     callback function that returns `true` if a node is matched.\n\t\t * @returns {FancytreeNode[]} array of nodes (may be empty)\n\t\t * @see FancytreeNode#findAll\n\t\t * @since 2.12\n\t\t */\n\t\tfindAll: function(match) {\n\t\t\treturn this.rootNode.findAll(match);\n\t\t},\n\t\t/**Find first node that matches condition.\n\t\t *\n\t\t * @param {string | function(node)} match title string to search for, or a\n\t\t *     callback function that returns `true` if a node is matched.\n\t\t * @returns {FancytreeNode} matching node or null\n\t\t * @see FancytreeNode#findFirst\n\t\t * @since 2.12\n\t\t */\n\t\tfindFirst: function(match) {\n\t\t\treturn this.rootNode.findFirst(match);\n\t\t},\n\t\t/** Find the next visible node that starts with `match`, starting at `startNode`\n\t\t * and wrap-around at the end.\n\t\t *\n\t\t * @param {string|function} match\n\t\t * @param {FancytreeNode} [startNode] defaults to first node\n\t\t * @returns {FancytreeNode} matching node or null\n\t\t */\n\t\tfindNextNode: function(match, startNode, visibleOnly) {\n\t\t\tmatch =\n\t\t\t\ttypeof match === \"string\"\n\t\t\t\t\t? _makeNodeTitleStartMatcher(match)\n\t\t\t\t\t: match;\n\t\t\tstartNode = startNode || this.getFirstChild();\n\n\t\t\tvar stopNode = null,\n\t\t\t\tparentChildren = startNode.parent.children,\n\t\t\t\tmatchingNode = null,\n\t\t\t\twalkVisible = function(parent, idx, fn) {\n\t\t\t\t\tvar i,\n\t\t\t\t\t\tgrandParent,\n\t\t\t\t\t\tparentChildren = parent.children,\n\t\t\t\t\t\tsiblingCount = parentChildren.length,\n\t\t\t\t\t\tnode = parentChildren[idx];\n\t\t\t\t\t// visit node itself\n\t\t\t\t\tif (node && fn(node) === false) {\n\t\t\t\t\t\treturn false;\n\t\t\t\t\t}\n\t\t\t\t\t// visit descendants\n\t\t\t\t\tif (node && node.children && node.expanded) {\n\t\t\t\t\t\tif (walkVisible(node, 0, fn) === false) {\n\t\t\t\t\t\t\treturn false;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\t// visit subsequent siblings\n\t\t\t\t\tfor (i = idx + 1; i < siblingCount; i++) {\n\t\t\t\t\t\tif (walkVisible(parent, i, fn) === false) {\n\t\t\t\t\t\t\treturn false;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\t// visit parent's subsequent siblings\n\t\t\t\t\tgrandParent = parent.parent;\n\t\t\t\t\tif (grandParent) {\n\t\t\t\t\t\treturn walkVisible(\n\t\t\t\t\t\t\tgrandParent,\n\t\t\t\t\t\t\tgrandParent.children.indexOf(parent) + 1,\n\t\t\t\t\t\t\tfn\n\t\t\t\t\t\t);\n\t\t\t\t\t} else {\n\t\t\t\t\t\t// wrap-around: restart with first node\n\t\t\t\t\t\treturn walkVisible(parent, 0, fn);\n\t\t\t\t\t}\n\t\t\t\t};\n\n\t\t\twalkVisible(\n\t\t\t\tstartNode.parent,\n\t\t\t\tparentChildren.indexOf(startNode),\n\t\t\t\tfunction(node) {\n\t\t\t\t\t// Stop iteration if we see the start node a second time\n\t\t\t\t\tif (node === stopNode) {\n\t\t\t\t\t\treturn false;\n\t\t\t\t\t}\n\t\t\t\t\tstopNode = stopNode || node;\n\t\t\t\t\t// Ignore nodes hidden by a filter\n\t\t\t\t\tif (!$(node.span).is(\":visible\")) {\n\t\t\t\t\t\tnode.debug(\"quicksearch: skipping hidden node\");\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t\t// Test if we found a match, but search for a second match if this\n\t\t\t\t\t// was the currently active node\n\t\t\t\t\tif (match(node)) {\n\t\t\t\t\t\t// node.debug(\"quicksearch match \" + node.title, startNode);\n\t\t\t\t\t\tmatchingNode = node;\n\t\t\t\t\t\tif (matchingNode !== startNode) {\n\t\t\t\t\t\t\treturn false;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t);\n\t\t\treturn matchingNode;\n\t\t},\n\t\t// TODO: fromDict\n\t\t/**\n\t\t * Generate INPUT elements that can be submitted with html forms.\n\t\t *\n\t\t * In selectMode 3 only the topmost selected nodes are considered, unless\n\t\t * `opts.stopOnParents: false` is passed.\n\t\t *\n\t\t * @example\n\t\t * // Generate input elements for active and selected nodes\n\t\t * tree.generateFormElements();\n\t\t * // Generate input elements selected nodes, using a custom `name` attribute\n\t\t * tree.generateFormElements(\"cust_sel\", false);\n\t\t * // Generate input elements using a custom filter\n\t\t * tree.generateFormElements(true, true, { filter: function(node) {\n\t\t *     return node.isSelected() && node.data.yes;\n\t\t * }});\n\t\t *\n\t\t * @param {boolean | string} [selected=true] Pass false to disable, pass a string to override the field name (default: 'ft_ID[]')\n\t\t * @param {boolean | string} [active=true] Pass false to disable, pass a string to override the field name (default: 'ft_ID_active')\n\t\t * @param {object} [opts] default { filter: null, stopOnParents: true }\n\t\t */\n\t\tgenerateFormElements: function(selected, active, opts) {\n\t\t\topts = opts || {};\n\n\t\t\tvar nodeList,\n\t\t\t\tselectedName =\n\t\t\t\t\ttypeof selected === \"string\"\n\t\t\t\t\t\t? selected\n\t\t\t\t\t\t: \"ft_\" + this._id + \"[]\",\n\t\t\t\tactiveName =\n\t\t\t\t\ttypeof active === \"string\"\n\t\t\t\t\t\t? active\n\t\t\t\t\t\t: \"ft_\" + this._id + \"_active\",\n\t\t\t\tid = \"fancytree_result_\" + this._id,\n\t\t\t\t$result = $(\"#\" + id),\n\t\t\t\tstopOnParents =\n\t\t\t\t\tthis.options.selectMode === 3 &&\n\t\t\t\t\topts.stopOnParents !== false;\n\n\t\t\tif ($result.length) {\n\t\t\t\t$result.empty();\n\t\t\t} else {\n\t\t\t\t$result = $(\"<div>\", {\n\t\t\t\t\tid: id,\n\t\t\t\t})\n\t\t\t\t\t.hide()\n\t\t\t\t\t.insertAfter(this.$container);\n\t\t\t}\n\t\t\tif (active !== false && this.activeNode) {\n\t\t\t\t$result.append(\n\t\t\t\t\t$(\"<input>\", {\n\t\t\t\t\t\ttype: \"radio\",\n\t\t\t\t\t\tname: activeName,\n\t\t\t\t\t\tvalue: this.activeNode.key,\n\t\t\t\t\t\tchecked: true,\n\t\t\t\t\t})\n\t\t\t\t);\n\t\t\t}\n\t\t\tfunction _appender(node) {\n\t\t\t\t$result.append(\n\t\t\t\t\t$(\"<input>\", {\n\t\t\t\t\t\ttype: \"checkbox\",\n\t\t\t\t\t\tname: selectedName,\n\t\t\t\t\t\tvalue: node.key,\n\t\t\t\t\t\tchecked: true,\n\t\t\t\t\t})\n\t\t\t\t);\n\t\t\t}\n\t\t\tif (opts.filter) {\n\t\t\t\tthis.visit(function(node) {\n\t\t\t\t\tvar res = opts.filter(node);\n\t\t\t\t\tif (res === \"skip\") {\n\t\t\t\t\t\treturn res;\n\t\t\t\t\t}\n\t\t\t\t\tif (res !== false) {\n\t\t\t\t\t\t_appender(node);\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t} else if (selected !== false) {\n\t\t\t\tnodeList = this.getSelectedNodes(stopOnParents);\n\t\t\t\t$.each(nodeList, function(idx, node) {\n\t\t\t\t\t_appender(node);\n\t\t\t\t});\n\t\t\t}\n\t\t},\n\t\t/**\n\t\t * Return the currently active node or null.\n\t\t * @returns {FancytreeNode}\n\t\t */\n\t\tgetActiveNode: function() {\n\t\t\treturn this.activeNode;\n\t\t},\n\t\t/** Return the first top level node if any (not the invisible root node).\n\t\t * @returns {FancytreeNode | null}\n\t\t */\n\t\tgetFirstChild: function() {\n\t\t\treturn this.rootNode.getFirstChild();\n\t\t},\n\t\t/**\n\t\t * Return node that has keyboard focus or null.\n\t\t * @returns {FancytreeNode}\n\t\t */\n\t\tgetFocusNode: function() {\n\t\t\treturn this.focusNode;\n\t\t},\n\t\t/**\n\t\t * Return current option value.\n\t\t * (Note: this is the preferred variant of `$().fancytree(\"option\", \"KEY\")`)\n\t\t *\n\t\t * @param {string} name option name (may contain '.')\n\t\t * @returns {any}\n\t\t */\n\t\tgetOption: function(optionName) {\n\t\t\treturn this.widget.option(optionName);\n\t\t},\n\t\t/**\n\t\t * Return node with a given key or null if not found.\n\t\t *\n\t\t * @param {string} key\n\t\t * @param {FancytreeNode} [searchRoot] only search below this node\n\t\t * @returns {FancytreeNode | null}\n\t\t */\n\t\tgetNodeByKey: function(key, searchRoot) {\n\t\t\t// Search the DOM by element ID (assuming this is faster than traversing all nodes).\n\t\t\tvar el, match;\n\t\t\t// TODO: use tree.keyMap if available\n\t\t\t// TODO: check opts.generateIds === true\n\t\t\tif (!searchRoot) {\n\t\t\t\tel = document.getElementById(this.options.idPrefix + key);\n\t\t\t\tif (el) {\n\t\t\t\t\treturn el.ftnode ? el.ftnode : null;\n\t\t\t\t}\n\t\t\t}\n\t\t\t// Not found in the DOM, but still may be in an unrendered part of tree\n\t\t\tsearchRoot = searchRoot || this.rootNode;\n\t\t\tmatch = null;\n\t\t\tsearchRoot.visit(function(node) {\n\t\t\t\tif (node.key === key) {\n\t\t\t\t\tmatch = node;\n\t\t\t\t\treturn false; // Stop iteration\n\t\t\t\t}\n\t\t\t}, true);\n\t\t\treturn match;\n\t\t},\n\t\t/** Return the invisible system root node.\n\t\t * @returns {FancytreeNode}\n\t\t */\n\t\tgetRootNode: function() {\n\t\t\treturn this.rootNode;\n\t\t},\n\t\t/**\n\t\t * Return an array of selected nodes.\n\t\t * @param {boolean} [stopOnParents=false] only return the topmost selected\n\t\t *     node (useful with selectMode 3)\n\t\t * @returns {FancytreeNode[]}\n\t\t */\n\t\tgetSelectedNodes: function(stopOnParents) {\n\t\t\treturn this.rootNode.getSelectedNodes(stopOnParents);\n\t\t},\n\t\t/** Return true if the tree control has keyboard focus\n\t\t * @returns {boolean}\n\t\t */\n\t\thasFocus: function() {\n\t\t\treturn !!this._hasFocus;\n\t\t},\n\t\t/** Write to browser console if debugLevel >= 3 (prepending tree name)\n\t\t * @param {*} msg string or object or array of such\n\t\t */\n\t\tinfo: function(msg) {\n\t\t\tif (this.options.debugLevel >= 3) {\n\t\t\t\tArray.prototype.unshift.call(arguments, this.toString());\n\t\t\t\tconsoleApply(\"info\", arguments);\n\t\t\t}\n\t\t},\n\t\t/*\n\tTODO: isInitializing: function() {\n\t\treturn ( this.phase==\"init\" || this.phase==\"postInit\" );\n\t},\n\tTODO: isReloading: function() {\n\t\treturn ( this.phase==\"init\" || this.phase==\"postInit\" ) && this.options.persist && this.persistence.cookiesFound;\n\t},\n\tTODO: isUserEvent: function() {\n\t\treturn ( this.phase==\"userEvent\" );\n\t},\n*/\n\n\t\t/**\n\t\t * Make sure that a node with a given ID is loaded, by traversing - and\n\t\t * loading - its parents. This method is meant for lazy hierarchies.\n\t\t * A callback is executed for every node as we go.\n\t\t * @example\n\t\t * // Resolve using node.key:\n\t\t * tree.loadKeyPath(\"/_3/_23/_26/_27\", function(node, status){\n\t\t *   if(status === \"loaded\") {\n\t\t *     console.log(\"loaded intermediate node \" + node);\n\t\t *   }else if(status === \"ok\") {\n\t\t *     node.activate();\n\t\t *   }\n\t\t * });\n\t\t * // Use deferred promise:\n\t\t * tree.loadKeyPath(\"/_3/_23/_26/_27\").progress(function(data){\n\t\t *   if(data.status === \"loaded\") {\n\t\t *     console.log(\"loaded intermediate node \" + data.node);\n\t\t *   }else if(data.status === \"ok\") {\n\t\t *     node.activate();\n\t\t *   }\n\t\t * }).done(function(){\n\t\t *    ...\n\t\t * });\n\t\t * // Custom path segment resolver:\n\t\t * tree.loadKeyPath(\"/321/431/21/2\", {\n\t\t *   matchKey: function(node, key){\n\t\t *     return node.data.refKey === key;\n\t\t *   },\n\t\t *   callback: function(node, status){\n\t\t *     if(status === \"loaded\") {\n\t\t *       console.log(\"loaded intermediate node \" + node);\n\t\t *     }else if(status === \"ok\") {\n\t\t *       node.activate();\n\t\t *     }\n\t\t *   }\n\t\t * });\n\t\t * @param {string | string[]} keyPathList one or more key paths (e.g. '/3/2_1/7')\n\t\t * @param {function | object} optsOrCallback callback(node, status) is called for every visited node ('loading', 'loaded', 'ok', 'error').\n\t\t *     Pass an object to define custom key matchers for the path segments: {callback: function, matchKey: function}.\n\t\t * @returns {$.Promise}\n\t\t */\n\t\tloadKeyPath: function(keyPathList, optsOrCallback) {\n\t\t\tvar callback,\n\t\t\t\ti,\n\t\t\t\tpath,\n\t\t\t\tself = this,\n\t\t\t\tdfd = new $.Deferred(),\n\t\t\t\tparent = this.getRootNode(),\n\t\t\t\tsep = this.options.keyPathSeparator,\n\t\t\t\tpathSegList = [],\n\t\t\t\topts = $.extend({}, optsOrCallback);\n\n\t\t\t// Prepare options\n\t\t\tif (typeof optsOrCallback === \"function\") {\n\t\t\t\tcallback = optsOrCallback;\n\t\t\t} else if (optsOrCallback && optsOrCallback.callback) {\n\t\t\t\tcallback = optsOrCallback.callback;\n\t\t\t}\n\t\t\topts.callback = function(ctx, node, status) {\n\t\t\t\tif (callback) {\n\t\t\t\t\tcallback.call(ctx, node, status);\n\t\t\t\t}\n\t\t\t\tdfd.notifyWith(ctx, [{ node: node, status: status }]);\n\t\t\t};\n\t\t\tif (opts.matchKey == null) {\n\t\t\t\topts.matchKey = function(node, key) {\n\t\t\t\t\treturn node.key === key;\n\t\t\t\t};\n\t\t\t}\n\t\t\t// Convert array of path strings to array of segment arrays\n\t\t\tif (!$.isArray(keyPathList)) {\n\t\t\t\tkeyPathList = [keyPathList];\n\t\t\t}\n\t\t\tfor (i = 0; i < keyPathList.length; i++) {\n\t\t\t\tpath = keyPathList[i];\n\t\t\t\t// strip leading slash\n\t\t\t\tif (path.charAt(0) === sep) {\n\t\t\t\t\tpath = path.substr(1);\n\t\t\t\t}\n\t\t\t\t// segListMap[path] = { parent: parent, segList: path.split(sep) };\n\t\t\t\tpathSegList.push(path.split(sep));\n\t\t\t\t// targetList.push({ parent: parent, segList: path.split(sep)/* , path: path*/});\n\t\t\t}\n\t\t\t// The timeout forces async behavior always (even if nodes are all loaded)\n\t\t\t// This way a potential progress() event will fire.\n\t\t\tsetTimeout(function() {\n\t\t\t\tself._loadKeyPathImpl(dfd, opts, parent, pathSegList).done(\n\t\t\t\t\tfunction() {\n\t\t\t\t\t\tdfd.resolve();\n\t\t\t\t\t}\n\t\t\t\t);\n\t\t\t}, 0);\n\t\t\treturn dfd.promise();\n\t\t},\n\t\t/*\n\t * Resolve a list of paths, relative to one parent node.\n\t */\n\t\t_loadKeyPathImpl: function(dfd, opts, parent, pathSegList) {\n\t\t\tvar deferredList,\n\t\t\t\ti,\n\t\t\t\tkey,\n\t\t\t\tnode,\n\t\t\t\tremainMap,\n\t\t\t\ttmpParent,\n\t\t\t\tsegList,\n\t\t\t\tsubDfd,\n\t\t\t\tself = this;\n\n\t\t\tfunction __findChild(parent, key) {\n\t\t\t\t// console.log(\"__findChild\", key, parent);\n\t\t\t\tvar i,\n\t\t\t\t\tl,\n\t\t\t\t\tcl = parent.children;\n\n\t\t\t\tif (cl) {\n\t\t\t\t\tfor (i = 0, l = cl.length; i < l; i++) {\n\t\t\t\t\t\tif (opts.matchKey(cl[i], key)) {\n\t\t\t\t\t\t\treturn cl[i];\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn null;\n\t\t\t}\n\n\t\t\t// console.log(\"_loadKeyPathImpl, parent=\", parent, \", pathSegList=\", pathSegList);\n\n\t\t\t// Pass 1:\n\t\t\t// Handle all path segments for nodes that are already loaded.\n\t\t\t// Collect distinct top-most lazy nodes in a map.\n\t\t\t// Note that we can use node.key to de-dupe entries, even if a custom matcher would\n\t\t\t// look for other node attributes.\n\t\t\t// map[node.key] => {node: node, pathList: [list of remaining rest-paths]}\n\t\t\tremainMap = {};\n\n\t\t\tfor (i = 0; i < pathSegList.length; i++) {\n\t\t\t\tsegList = pathSegList[i];\n\t\t\t\t// target = targetList[i];\n\n\t\t\t\t// Traverse and pop path segments (i.e. keys), until we hit a lazy, unloaded node\n\t\t\t\ttmpParent = parent;\n\t\t\t\twhile (segList.length) {\n\t\t\t\t\tkey = segList.shift();\n\t\t\t\t\tnode = __findChild(tmpParent, key);\n\t\t\t\t\tif (!node) {\n\t\t\t\t\t\tthis.warn(\n\t\t\t\t\t\t\t\"loadKeyPath: key not found: \" +\n\t\t\t\t\t\t\t\tkey +\n\t\t\t\t\t\t\t\t\" (parent: \" +\n\t\t\t\t\t\t\t\ttmpParent +\n\t\t\t\t\t\t\t\t\")\"\n\t\t\t\t\t\t);\n\t\t\t\t\t\topts.callback(this, key, \"error\");\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t} else if (segList.length === 0) {\n\t\t\t\t\t\topts.callback(this, node, \"ok\");\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t} else if (!node.lazy || node.hasChildren() !== undefined) {\n\t\t\t\t\t\topts.callback(this, node, \"loaded\");\n\t\t\t\t\t\ttmpParent = node;\n\t\t\t\t\t} else {\n\t\t\t\t\t\topts.callback(this, node, \"loaded\");\n\t\t\t\t\t\tkey = node.key; //target.segList.join(sep);\n\t\t\t\t\t\tif (remainMap[key]) {\n\t\t\t\t\t\t\tremainMap[key].pathSegList.push(segList);\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tremainMap[key] = {\n\t\t\t\t\t\t\t\tparent: node,\n\t\t\t\t\t\t\t\tpathSegList: [segList],\n\t\t\t\t\t\t\t};\n\t\t\t\t\t\t}\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\t// console.log(\"_loadKeyPathImpl AFTER pass 1, remainMap=\", remainMap);\n\n\t\t\t// Now load all lazy nodes and continue iteration for remaining paths\n\t\t\tdeferredList = [];\n\n\t\t\t// Avoid jshint warning 'Don't make functions within a loop.':\n\t\t\tfunction __lazyload(dfd, parent, pathSegList) {\n\t\t\t\t// console.log(\"__lazyload\", parent, \"pathSegList=\", pathSegList);\n\t\t\t\topts.callback(self, parent, \"loading\");\n\t\t\t\tparent\n\t\t\t\t\t.load()\n\t\t\t\t\t.done(function() {\n\t\t\t\t\t\tself._loadKeyPathImpl\n\t\t\t\t\t\t\t.call(self, dfd, opts, parent, pathSegList)\n\t\t\t\t\t\t\t.always(_makeResolveFunc(dfd, self));\n\t\t\t\t\t})\n\t\t\t\t\t.fail(function(errMsg) {\n\t\t\t\t\t\tself.warn(\"loadKeyPath: error loading lazy \" + parent);\n\t\t\t\t\t\topts.callback(self, node, \"error\");\n\t\t\t\t\t\tdfd.rejectWith(self);\n\t\t\t\t\t});\n\t\t\t}\n\t\t\t// remainMap contains parent nodes, each with a list of relative sub-paths.\n\t\t\t// We start loading all of them now, and pass the the list to each loader.\n\t\t\tfor (var nodeKey in remainMap) {\n\t\t\t\tvar remain = remainMap[nodeKey];\n\t\t\t\t// console.log(\"for(): remain=\", remain, \"remainMap=\", remainMap);\n\t\t\t\t// key = remain.segList.shift();\n\t\t\t\t// node = __findChild(remain.parent, key);\n\t\t\t\t// if (node == null) {  // #576\n\t\t\t\t// \t// Issue #576, refactored for v2.27:\n\t\t\t\t// \t// The root cause was, that sometimes the wrong parent was used here\n\t\t\t\t// \t// to find the next segment.\n\t\t\t\t// \t// Falling back to getNodeByKey() was a hack that no longer works if a custom\n\t\t\t\t// \t// matcher is used, because we cannot assume that a single segment-key is unique\n\t\t\t\t// \t// throughout the tree.\n\t\t\t\t// \tself.error(\"loadKeyPath: error loading child by key '\" + key + \"' (parent: \" + target.parent + \")\", target);\n\t\t\t\t// \t// \tnode = self.getNodeByKey(key);\n\t\t\t\t// \tcontinue;\n\t\t\t\t// }\n\t\t\t\tsubDfd = new $.Deferred();\n\t\t\t\tdeferredList.push(subDfd);\n\t\t\t\t__lazyload(subDfd, remain.parent, remain.pathSegList);\n\t\t\t}\n\t\t\t// Return a promise that is resolved, when ALL paths were loaded\n\t\t\treturn $.when.apply($, deferredList).promise();\n\t\t},\n\t\t/** Re-fire beforeActivate, activate, and (optional) focus events.\n\t\t * Calling this method in the `init` event, will activate the node that\n\t\t * was marked 'active' in the source data, and optionally set the keyboard\n\t\t * focus.\n\t\t * @param [setFocus=false]\n\t\t */\n\t\treactivate: function(setFocus) {\n\t\t\tvar res,\n\t\t\t\tnode = this.activeNode;\n\n\t\t\tif (!node) {\n\t\t\t\treturn _getResolvedPromise();\n\t\t\t}\n\t\t\tthis.activeNode = null; // Force re-activating\n\t\t\tres = node.setActive(true, { noFocus: true });\n\t\t\tif (setFocus) {\n\t\t\t\tnode.setFocus();\n\t\t\t}\n\t\t\treturn res;\n\t\t},\n\t\t/** Reload tree from source and return a promise.\n\t\t * @param [source] optional new source (defaults to initial source data)\n\t\t * @returns {$.Promise}\n\t\t */\n\t\treload: function(source) {\n\t\t\tthis._callHook(\"treeClear\", this);\n\t\t\treturn this._callHook(\"treeLoad\", this, source);\n\t\t},\n\t\t/**Render tree (i.e. create DOM elements for all top-level nodes).\n\t\t * @param {boolean} [force=false] create DOM elemnts, even if parent is collapsed\n\t\t * @param {boolean} [deep=false]\n\t\t */\n\t\trender: function(force, deep) {\n\t\t\treturn this.rootNode.render(force, deep);\n\t\t},\n\t\t/**(De)select all nodes.\n\t\t * @param {boolean} [flag=true]\n\t\t * @since 2.28\n\t\t */\n\t\tselectAll: function(flag) {\n\t\t\tthis.visit(function(node) {\n\t\t\t\tnode.setSelected(flag);\n\t\t\t});\n\t\t},\n\t\t// TODO: selectKey: function(key, select)\n\t\t// TODO: serializeArray: function(stopOnParents)\n\t\t/**\n\t\t * @param {boolean} [flag=true]\n\t\t */\n\t\tsetFocus: function(flag) {\n\t\t\treturn this._callHook(\"treeSetFocus\", this, flag);\n\t\t},\n\t\t/**\n\t\t * Set current option value.\n\t\t * (Note: this is the preferred variant of `$().fancytree(\"option\", \"KEY\", VALUE)`)\n\t\t * @param {string} name option name (may contain '.')\n\t\t * @param {any} new value\n\t\t */\n\t\tsetOption: function(optionName, value) {\n\t\t\treturn this.widget.option(optionName, value);\n\t\t},\n\t\t/**\n\t\t * Return all nodes as nested list of {@link NodeData}.\n\t\t *\n\t\t * @param {boolean} [includeRoot=false] Returns the hidden system root node (and its children)\n\t\t * @param {function} [callback] callback(dict, node) is called for every node, in order to allow modifications\n\t\t * @returns {Array | object}\n\t\t * @see FancytreeNode#toDict\n\t\t */\n\t\ttoDict: function(includeRoot, callback) {\n\t\t\tvar res = this.rootNode.toDict(true, callback);\n\t\t\treturn includeRoot ? res : res.children;\n\t\t},\n\t\t/* Implicitly called for string conversions.\n\t * @returns {string}\n\t */\n\t\ttoString: function() {\n\t\t\treturn \"Fancytree@\" + this._id;\n\t\t\t// return \"<Fancytree(#\" + this._id + \")>\";\n\t\t},\n\t\t/* _trigger a widget event with additional node ctx.\n\t * @see EventData\n\t */\n\t\t_triggerNodeEvent: function(type, node, originalEvent, extra) {\n\t\t\t//\t\tthis.debug(\"_trigger(\" + type + \"): '\" + ctx.node.title + \"'\", ctx);\n\t\t\tvar ctx = this._makeHookContext(node, originalEvent, extra),\n\t\t\t\tres = this.widget._trigger(type, originalEvent, ctx);\n\t\t\tif (res !== false && ctx.result !== undefined) {\n\t\t\t\treturn ctx.result;\n\t\t\t}\n\t\t\treturn res;\n\t\t},\n\t\t/* _trigger a widget event with additional tree data. */\n\t\t_triggerTreeEvent: function(type, originalEvent, extra) {\n\t\t\t//\t\tthis.debug(\"_trigger(\" + type + \")\", ctx);\n\t\t\tvar ctx = this._makeHookContext(this, originalEvent, extra),\n\t\t\t\tres = this.widget._trigger(type, originalEvent, ctx);\n\n\t\t\tif (res !== false && ctx.result !== undefined) {\n\t\t\t\treturn ctx.result;\n\t\t\t}\n\t\t\treturn res;\n\t\t},\n\t\t/** Call fn(node) for all nodes in hierarchical order (depth-first).\n\t\t *\n\t\t * @param {function} fn the callback function.\n\t\t *     Return false to stop iteration, return \"skip\" to skip this node and children only.\n\t\t * @returns {boolean} false, if the iterator was stopped.\n\t\t */\n\t\tvisit: function(fn) {\n\t\t\treturn this.rootNode.visit(fn, false);\n\t\t},\n\t\t/** Call fn(node) for all nodes in vertical order, top down (or bottom up).<br>\n\t\t * Stop iteration, if fn() returns false.<br>\n\t\t * Return false if iteration was stopped.\n\t\t *\n\t\t * @param {function} fn the callback function.\n\t\t *     Return false to stop iteration, return \"skip\" to skip this node and children only.\n\t\t * @param {object} [options]\n\t\t *     Defaults:\n\t\t *     {start: First top node, reverse: false, includeSelf: true, includeHidden: false}\n\t\t * @returns {boolean}\n\t\t * @since 2.28\n\t\t */\n\t\tvisitRows: function(fn, opts) {\n\t\t\tif (opts && opts.reverse) {\n\t\t\t\tdelete opts.reverse;\n\t\t\t\treturn this._visitRowsUp(fn, opts);\n\t\t\t}\n\t\t\tvar i,\n\t\t\t\tnextIdx,\n\t\t\t\tparent,\n\t\t\t\tres,\n\t\t\t\tsiblings,\n\t\t\t\tsiblingOfs = 0,\n\t\t\t\tskipFirstNode = opts.includeSelf === false,\n\t\t\t\tincludeHidden = !!opts.includeHidden,\n\t\t\t\tnode = opts.start || this.rootNode.children[0];\n\n\t\t\tparent = node.parent;\n\t\t\twhile (parent) {\n\t\t\t\t// visit siblings\n\t\t\t\tsiblings = parent.children;\n\t\t\t\tnextIdx = siblings.indexOf(node) + siblingOfs;\n\n\t\t\t\tfor (i = nextIdx; i < siblings.length; i++) {\n\t\t\t\t\tnode = siblings[i];\n\t\t\t\t\tif (!skipFirstNode && fn(node) === false) {\n\t\t\t\t\t\treturn false;\n\t\t\t\t\t}\n\t\t\t\t\tskipFirstNode = false;\n\t\t\t\t\t// Dive into node's child nodes\n\t\t\t\t\tif (\n\t\t\t\t\t\tnode.children &&\n\t\t\t\t\t\tnode.children.length &&\n\t\t\t\t\t\t(includeHidden || node.expanded)\n\t\t\t\t\t) {\n\t\t\t\t\t\t// Disable warning: Functions declared within loops referencing an outer\n\t\t\t\t\t\t// scoped variable may lead to confusing semantics:\n\t\t\t\t\t\t/*jshint -W083 */\n\t\t\t\t\t\tres = node.visit(function(n) {\n\t\t\t\t\t\t\tif (fn(n) === false) {\n\t\t\t\t\t\t\t\treturn false;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tif (!includeHidden && n.children && !n.expanded) {\n\t\t\t\t\t\t\t\treturn \"skip\";\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}, false);\n\t\t\t\t\t\t/*jshint +W083 */\n\t\t\t\t\t\tif (res === false) {\n\t\t\t\t\t\t\treturn false;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\t// Visit parent nodes (bottom up)\n\t\t\t\tnode = parent;\n\t\t\t\tparent = parent.parent;\n\t\t\t\tsiblingOfs = 1; //\n\t\t\t}\n\t\t\treturn true;\n\t\t},\n\t\t/* Call fn(node) for all nodes in vertical order, bottom up.\n\t */\n\t\t_visitRowsUp: function(fn, opts) {\n\t\t\tvar children,\n\t\t\t\tidx,\n\t\t\t\tparent,\n\t\t\t\tincludeHidden = !!opts.includeHidden,\n\t\t\t\tnode = opts.start || this.rootNode.children[0];\n\n\t\t\twhile (true) {\n\t\t\t\tparent = node.parent;\n\t\t\t\tchildren = parent.children;\n\n\t\t\t\tif (children[0] === node) {\n\t\t\t\t\t// If this is already the first sibling, goto parent\n\t\t\t\t\tnode = parent;\n\t\t\t\t\tchildren = parent.children;\n\t\t\t\t} else {\n\t\t\t\t\t// Otherwise, goto prev. sibling\n\t\t\t\t\tidx = children.indexOf(node);\n\t\t\t\t\tnode = children[idx - 1];\n\t\t\t\t\t// If the prev. sibling has children, follow down to last descendant\n\t\t\t\t\twhile (\n\t\t\t\t\t\t(includeHidden || node.expanded) &&\n\t\t\t\t\t\tnode.children &&\n\t\t\t\t\t\tnode.children.length\n\t\t\t\t\t) {\n\t\t\t\t\t\tchildren = node.children;\n\t\t\t\t\t\tparent = node;\n\t\t\t\t\t\tnode = children[children.length - 1];\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\t// Skip invisible\n\t\t\t\tif (!includeHidden && !$(node.span).is(\":visible\")) {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tif (fn(node) === false) {\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t\t/** Write warning to browser console if debugLevel >= 2 (prepending tree info)\n\t\t *\n\t\t * @param {*} msg string or object or array of such\n\t\t */\n\t\twarn: function(msg) {\n\t\t\tif (this.options.debugLevel >= 2) {\n\t\t\t\tArray.prototype.unshift.call(arguments, this.toString());\n\t\t\t\tconsoleApply(\"warn\", arguments);\n\t\t\t}\n\t\t},\n\t};\n\n\t/**\n\t * These additional methods of the {@link Fancytree} class are 'hook functions'\n\t * that can be used and overloaded by extensions.\n\t * (See <a href=\"https://github.com/mar10/fancytree/wiki/TutorialExtensions\">writing extensions</a>.)\n\t * @mixin Fancytree_Hooks\n\t */\n\t$.extend(\n\t\tFancytree.prototype,\n\t\t/** @lends Fancytree_Hooks# */\n\t\t{\n\t\t\t/** Default handling for mouse click events.\n\t\t\t *\n\t\t\t * @param {EventData} ctx\n\t\t\t */\n\t\t\tnodeClick: function(ctx) {\n\t\t\t\tvar activate,\n\t\t\t\t\texpand,\n\t\t\t\t\t// event = ctx.originalEvent,\n\t\t\t\t\ttargetType = ctx.targetType,\n\t\t\t\t\tnode = ctx.node;\n\n\t\t\t\t//\t    this.debug(\"ftnode.onClick(\" + event.type + \"): ftnode:\" + this + \", button:\" + event.button + \", which: \" + event.which, ctx);\n\t\t\t\t// TODO: use switch\n\t\t\t\t// TODO: make sure clicks on embedded <input> doesn't steal focus (see table sample)\n\t\t\t\tif (targetType === \"expander\") {\n\t\t\t\t\tif (node.isLoading()) {\n\t\t\t\t\t\t// #495: we probably got a click event while a lazy load is pending.\n\t\t\t\t\t\t// The 'expanded' state is not yet set, so 'toggle' would expand\n\t\t\t\t\t\t// and trigger lazyLoad again.\n\t\t\t\t\t\t// It would be better to allow to collapse/expand the status node\n\t\t\t\t\t\t// while loading (instead of ignoring), but that would require some\n\t\t\t\t\t\t// more work.\n\t\t\t\t\t\tnode.debug(\"Got 2nd click while loading: ignored\");\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t\t// Clicking the expander icon always expands/collapses\n\t\t\t\t\tthis._callHook(\"nodeToggleExpanded\", ctx);\n\t\t\t\t} else if (targetType === \"checkbox\") {\n\t\t\t\t\t// Clicking the checkbox always (de)selects\n\t\t\t\t\tthis._callHook(\"nodeToggleSelected\", ctx);\n\t\t\t\t\tif (ctx.options.focusOnSelect) {\n\t\t\t\t\t\t// #358\n\t\t\t\t\t\tthis._callHook(\"nodeSetFocus\", ctx, true);\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\t// Honor `clickFolderMode` for\n\t\t\t\t\texpand = false;\n\t\t\t\t\tactivate = true;\n\t\t\t\t\tif (node.folder) {\n\t\t\t\t\t\tswitch (ctx.options.clickFolderMode) {\n\t\t\t\t\t\t\tcase 2: // expand only\n\t\t\t\t\t\t\t\texpand = true;\n\t\t\t\t\t\t\t\tactivate = false;\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\tcase 3: // expand and activate\n\t\t\t\t\t\t\t\tactivate = true;\n\t\t\t\t\t\t\t\texpand = true; //!node.isExpanded();\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t// else 1 or 4: just activate\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tif (activate) {\n\t\t\t\t\t\tthis.nodeSetFocus(ctx);\n\t\t\t\t\t\tthis._callHook(\"nodeSetActive\", ctx, true);\n\t\t\t\t\t}\n\t\t\t\t\tif (expand) {\n\t\t\t\t\t\tif (!activate) {\n\t\t\t\t\t\t\t//                    this._callHook(\"nodeSetFocus\", ctx);\n\t\t\t\t\t\t}\n\t\t\t\t\t\t//\t\t\t\tthis._callHook(\"nodeSetExpanded\", ctx, true);\n\t\t\t\t\t\tthis._callHook(\"nodeToggleExpanded\", ctx);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\t// Make sure that clicks stop, otherwise <a href='#'> jumps to the top\n\t\t\t\t// if(event.target.localName === \"a\" && event.target.className === \"fancytree-title\"){\n\t\t\t\t// \tevent.preventDefault();\n\t\t\t\t// }\n\t\t\t\t// TODO: return promise?\n\t\t\t},\n\t\t\t/** Collapse all other  children of same parent.\n\t\t\t *\n\t\t\t * @param {EventData} ctx\n\t\t\t * @param {object} callOpts\n\t\t\t */\n\t\t\tnodeCollapseSiblings: function(ctx, callOpts) {\n\t\t\t\t// TODO: return promise?\n\t\t\t\tvar ac,\n\t\t\t\t\ti,\n\t\t\t\t\tl,\n\t\t\t\t\tnode = ctx.node;\n\n\t\t\t\tif (node.parent) {\n\t\t\t\t\tac = node.parent.children;\n\t\t\t\t\tfor (i = 0, l = ac.length; i < l; i++) {\n\t\t\t\t\t\tif (ac[i] !== node && ac[i].expanded) {\n\t\t\t\t\t\t\tthis._callHook(\n\t\t\t\t\t\t\t\t\"nodeSetExpanded\",\n\t\t\t\t\t\t\t\tac[i],\n\t\t\t\t\t\t\t\tfalse,\n\t\t\t\t\t\t\t\tcallOpts\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t},\n\t\t\t/** Default handling for mouse douleclick events.\n\t\t\t * @param {EventData} ctx\n\t\t\t */\n\t\t\tnodeDblclick: function(ctx) {\n\t\t\t\t// TODO: return promise?\n\t\t\t\tif (\n\t\t\t\t\tctx.targetType === \"title\" &&\n\t\t\t\t\tctx.options.clickFolderMode === 4\n\t\t\t\t) {\n\t\t\t\t\t// this.nodeSetFocus(ctx);\n\t\t\t\t\t// this._callHook(\"nodeSetActive\", ctx, true);\n\t\t\t\t\tthis._callHook(\"nodeToggleExpanded\", ctx);\n\t\t\t\t}\n\t\t\t\t// TODO: prevent text selection on dblclicks\n\t\t\t\tif (ctx.targetType === \"title\") {\n\t\t\t\t\tctx.originalEvent.preventDefault();\n\t\t\t\t}\n\t\t\t},\n\t\t\t/** Default handling for mouse keydown events.\n\t\t\t *\n\t\t\t * NOTE: this may be called with node == null if tree (but no node) has focus.\n\t\t\t * @param {EventData} ctx\n\t\t\t */\n\t\t\tnodeKeydown: function(ctx) {\n\t\t\t\t// TODO: return promise?\n\t\t\t\tvar matchNode,\n\t\t\t\t\tstamp,\n\t\t\t\t\tres,\n\t\t\t\t\tfocusNode,\n\t\t\t\t\tevent = ctx.originalEvent,\n\t\t\t\t\tnode = ctx.node,\n\t\t\t\t\ttree = ctx.tree,\n\t\t\t\t\topts = ctx.options,\n\t\t\t\t\twhich = event.which,\n\t\t\t\t\t// #909: Use event.key, to get unicode characters.\n\t\t\t\t\t// We can't use `/\\w/.test(key)`, because that would\n\t\t\t\t\t// only detect plain ascii alpha-numerics. But we still need\n\t\t\t\t\t// to ignore modifier-only, whitespace, cursor-keys, etc.\n\t\t\t\t\tkey = event.key || String.fromCharCode(which),\n\t\t\t\t\tisAlnum = !MODIFIERS[which] && !SPECIAL_KEYCODES[which],\n\t\t\t\t\t$target = $(event.target),\n\t\t\t\t\thandled = true,\n\t\t\t\t\tactivate = !(event.ctrlKey || !opts.autoActivate);\n\n\t\t\t\t// (node || FT).debug(\"ftnode.nodeKeydown(\" + event.type + \"): ftnode:\" + this + \", charCode:\" + event.charCode + \", keyCode: \" + event.keyCode + \", which: \" + event.which);\n\t\t\t\t// FT.debug( \"eventToString(): \" + FT.eventToString(event) + \", key='\" + key + \"', isAlnum: \" + isAlnum );\n\n\t\t\t\t// Set focus to active (or first node) if no other node has the focus yet\n\t\t\t\tif (!node) {\n\t\t\t\t\tfocusNode = this.getActiveNode() || this.getFirstChild();\n\t\t\t\t\tif (focusNode) {\n\t\t\t\t\t\tfocusNode.setFocus();\n\t\t\t\t\t\tnode = ctx.node = this.focusNode;\n\t\t\t\t\t\tnode.debug(\"Keydown force focus on active node\");\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif (\n\t\t\t\t\topts.quicksearch &&\n\t\t\t\t\tisAlnum &&\n\t\t\t\t\t!$target.is(\":input:enabled\")\n\t\t\t\t) {\n\t\t\t\t\t// Allow to search for longer streaks if typed in quickly\n\t\t\t\t\tstamp = Date.now();\n\t\t\t\t\tif (stamp - tree.lastQuicksearchTime > 500) {\n\t\t\t\t\t\ttree.lastQuicksearchTerm = \"\";\n\t\t\t\t\t}\n\t\t\t\t\ttree.lastQuicksearchTime = stamp;\n\t\t\t\t\ttree.lastQuicksearchTerm += key;\n\t\t\t\t\t// tree.debug(\"quicksearch find\", tree.lastQuicksearchTerm);\n\t\t\t\t\tmatchNode = tree.findNextNode(\n\t\t\t\t\t\ttree.lastQuicksearchTerm,\n\t\t\t\t\t\ttree.getActiveNode()\n\t\t\t\t\t);\n\t\t\t\t\tif (matchNode) {\n\t\t\t\t\t\tmatchNode.setActive();\n\t\t\t\t\t}\n\t\t\t\t\tevent.preventDefault();\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tswitch (FT.eventToString(event)) {\n\t\t\t\t\tcase \"+\":\n\t\t\t\t\tcase \"=\": // 187: '+' @ Chrome, Safari\n\t\t\t\t\t\ttree.nodeSetExpanded(ctx, true);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"-\":\n\t\t\t\t\t\ttree.nodeSetExpanded(ctx, false);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"space\":\n\t\t\t\t\t\tif (node.isPagingNode()) {\n\t\t\t\t\t\t\ttree._triggerNodeEvent(\"clickPaging\", ctx, event);\n\t\t\t\t\t\t} else if (\n\t\t\t\t\t\t\tFT.evalOption(\"checkbox\", node, node, opts, false)\n\t\t\t\t\t\t) {\n\t\t\t\t\t\t\t// #768\n\t\t\t\t\t\t\ttree.nodeToggleSelected(ctx);\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\ttree.nodeSetActive(ctx, true);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"return\":\n\t\t\t\t\t\ttree.nodeSetActive(ctx, true);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"home\":\n\t\t\t\t\tcase \"end\":\n\t\t\t\t\tcase \"backspace\":\n\t\t\t\t\tcase \"left\":\n\t\t\t\t\tcase \"right\":\n\t\t\t\t\tcase \"up\":\n\t\t\t\t\tcase \"down\":\n\t\t\t\t\t\tres = node.navigate(event.which, activate);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tdefault:\n\t\t\t\t\t\thandled = false;\n\t\t\t\t}\n\t\t\t\tif (handled) {\n\t\t\t\t\tevent.preventDefault();\n\t\t\t\t}\n\t\t\t},\n\n\t\t\t// /** Default handling for mouse keypress events. */\n\t\t\t// nodeKeypress: function(ctx) {\n\t\t\t//     var event = ctx.originalEvent;\n\t\t\t// },\n\n\t\t\t// /** Trigger lazyLoad event (async). */\n\t\t\t// nodeLazyLoad: function(ctx) {\n\t\t\t//     var node = ctx.node;\n\t\t\t//     if(this._triggerNodeEvent())\n\t\t\t// },\n\t\t\t/** Load child nodes (async).\n\t\t\t *\n\t\t\t * @param {EventData} ctx\n\t\t\t * @param {object[]|object|string|$.Promise|function} source\n\t\t\t * @returns {$.Promise} The deferred will be resolved as soon as the (ajax)\n\t\t\t *     data was rendered.\n\t\t\t */\n\t\t\tnodeLoadChildren: function(ctx, source) {\n\t\t\t\tvar ajax,\n\t\t\t\t\tdelay,\n\t\t\t\t\tdfd,\n\t\t\t\t\ttree = ctx.tree,\n\t\t\t\t\tnode = ctx.node,\n\t\t\t\t\trequestId = Date.now();\n\n\t\t\t\tif ($.isFunction(source)) {\n\t\t\t\t\tsource = source.call(tree, { type: \"source\" }, ctx);\n\t\t\t\t\t_assert(\n\t\t\t\t\t\t!$.isFunction(source),\n\t\t\t\t\t\t\"source callback must not return another function\"\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\tif (source.url) {\n\t\t\t\t\tif (node._requestId) {\n\t\t\t\t\t\tnode.warn(\n\t\t\t\t\t\t\t\"Recursive load request #\" +\n\t\t\t\t\t\t\t\trequestId +\n\t\t\t\t\t\t\t\t\" while #\" +\n\t\t\t\t\t\t\t\tnode._requestId +\n\t\t\t\t\t\t\t\t\" is pending.\"\n\t\t\t\t\t\t);\n\t\t\t\t\t\t// } else {\n\t\t\t\t\t\t// \tnode.debug(\"Send load request #\" + requestId);\n\t\t\t\t\t}\n\t\t\t\t\t// `source` is an Ajax options object\n\t\t\t\t\tajax = $.extend({}, ctx.options.ajax, source);\n\t\t\t\t\tnode._requestId = requestId;\n\t\t\t\t\tif (ajax.debugDelay) {\n\t\t\t\t\t\t// simulate a slow server\n\t\t\t\t\t\tdelay = ajax.debugDelay;\n\t\t\t\t\t\tdelete ajax.debugDelay; // remove debug option\n\t\t\t\t\t\tif ($.isArray(delay)) {\n\t\t\t\t\t\t\t// random delay range [min..max]\n\t\t\t\t\t\t\tdelay =\n\t\t\t\t\t\t\t\tdelay[0] +\n\t\t\t\t\t\t\t\tMath.random() * (delay[1] - delay[0]);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tnode.warn(\n\t\t\t\t\t\t\t\"nodeLoadChildren waiting debugDelay \" +\n\t\t\t\t\t\t\t\tMath.round(delay) +\n\t\t\t\t\t\t\t\t\" ms ...\"\n\t\t\t\t\t\t);\n\t\t\t\t\t\tdfd = $.Deferred(function(dfd) {\n\t\t\t\t\t\t\tsetTimeout(function() {\n\t\t\t\t\t\t\t\t$.ajax(ajax)\n\t\t\t\t\t\t\t\t\t.done(function() {\n\t\t\t\t\t\t\t\t\t\tdfd.resolveWith(this, arguments);\n\t\t\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\t\t\t.fail(function() {\n\t\t\t\t\t\t\t\t\t\tdfd.rejectWith(this, arguments);\n\t\t\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\t}, delay);\n\t\t\t\t\t\t});\n\t\t\t\t\t} else {\n\t\t\t\t\t\tdfd = $.ajax(ajax);\n\t\t\t\t\t}\n\n\t\t\t\t\t// Defer the deferred: we want to be able to reject, even if ajax\n\t\t\t\t\t// resolved ok.\n\t\t\t\t\tsource = new $.Deferred();\n\t\t\t\t\tdfd.done(function(data, textStatus, jqXHR) {\n\t\t\t\t\t\tvar errorObj, res;\n\n\t\t\t\t\t\tif (\n\t\t\t\t\t\t\t(this.dataType === \"json\" ||\n\t\t\t\t\t\t\t\tthis.dataType === \"jsonp\") &&\n\t\t\t\t\t\t\ttypeof data === \"string\"\n\t\t\t\t\t\t) {\n\t\t\t\t\t\t\t$.error(\n\t\t\t\t\t\t\t\t\"Ajax request returned a string (did you get the JSON dataType wrong?).\"\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (node._requestId && node._requestId > requestId) {\n\t\t\t\t\t\t\t// The expected request time stamp is later than `requestId`\n\t\t\t\t\t\t\t// (which was kept as as closure variable to this handler function)\n\t\t\t\t\t\t\t// node.warn(\"Ignored load response for obsolete request #\" + requestId + \" (expected #\" + node._requestId + \")\");\n\t\t\t\t\t\t\tsource.rejectWith(this, [RECURSIVE_REQUEST_ERROR]);\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t\t// } else {\n\t\t\t\t\t\t\t// \tnode.debug(\"Response returned for load request #\" + requestId);\n\t\t\t\t\t\t}\n\t\t\t\t\t\t// postProcess is similar to the standard ajax dataFilter hook,\n\t\t\t\t\t\t// but it is also called for JSONP\n\t\t\t\t\t\tif (ctx.options.postProcess) {\n\t\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\t\t// The handler may either\n\t\t\t\t\t\t\t\t//   - modify `ctx.response` in-place (and leave `ctx.result` undefined)\n\t\t\t\t\t\t\t\t//     => res = undefined\n\t\t\t\t\t\t\t\t//   - return a replacement in `ctx.result`\n\t\t\t\t\t\t\t\t//     => res = <new data>\n\t\t\t\t\t\t\t\t// If res contains an `error` property, an error status is displayed\n\t\t\t\t\t\t\t\tres = tree._triggerNodeEvent(\n\t\t\t\t\t\t\t\t\t\"postProcess\",\n\t\t\t\t\t\t\t\t\tctx,\n\t\t\t\t\t\t\t\t\tctx.originalEvent,\n\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\tresponse: data,\n\t\t\t\t\t\t\t\t\t\terror: null,\n\t\t\t\t\t\t\t\t\t\tdataType: this.dataType,\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t} catch (e) {\n\t\t\t\t\t\t\t\tres = {\n\t\t\t\t\t\t\t\t\terror: e,\n\t\t\t\t\t\t\t\t\tmessage: \"\" + e,\n\t\t\t\t\t\t\t\t\tdetails: \"postProcess failed\",\n\t\t\t\t\t\t\t\t};\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tif (res.error) {\n\t\t\t\t\t\t\t\terrorObj = $.isPlainObject(res.error)\n\t\t\t\t\t\t\t\t\t? res.error\n\t\t\t\t\t\t\t\t\t: { message: res.error };\n\t\t\t\t\t\t\t\terrorObj = tree._makeHookContext(\n\t\t\t\t\t\t\t\t\tnode,\n\t\t\t\t\t\t\t\t\tnull,\n\t\t\t\t\t\t\t\t\terrorObj\n\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t\tsource.rejectWith(this, [errorObj]);\n\t\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tif (\n\t\t\t\t\t\t\t\t$.isArray(res) ||\n\t\t\t\t\t\t\t\t($.isPlainObject(res) &&\n\t\t\t\t\t\t\t\t\t$.isArray(res.children))\n\t\t\t\t\t\t\t) {\n\t\t\t\t\t\t\t\t// Use `ctx.result` if valid\n\t\t\t\t\t\t\t\t// (otherwise use existing data, which may have been modified in-place)\n\t\t\t\t\t\t\t\tdata = res;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} else if (\n\t\t\t\t\t\t\tdata &&\n\t\t\t\t\t\t\tdata.hasOwnProperty(\"d\") &&\n\t\t\t\t\t\t\tctx.options.enableAspx\n\t\t\t\t\t\t) {\n\t\t\t\t\t\t\t// Process ASPX WebMethod JSON object inside \"d\" property\n\t\t\t\t\t\t\tdata =\n\t\t\t\t\t\t\t\ttypeof data.d === \"string\"\n\t\t\t\t\t\t\t\t\t? $.parseJSON(data.d)\n\t\t\t\t\t\t\t\t\t: data.d;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tsource.resolveWith(this, [data]);\n\t\t\t\t\t}).fail(function(jqXHR, textStatus, errorThrown) {\n\t\t\t\t\t\tvar errorObj = tree._makeHookContext(node, null, {\n\t\t\t\t\t\t\terror: jqXHR,\n\t\t\t\t\t\t\targs: Array.prototype.slice.call(arguments),\n\t\t\t\t\t\t\tmessage: errorThrown,\n\t\t\t\t\t\t\tdetails: jqXHR.status + \": \" + errorThrown,\n\t\t\t\t\t\t});\n\t\t\t\t\t\tsource.rejectWith(this, [errorObj]);\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t\t// #383: accept and convert ECMAScript 6 Promise\n\t\t\t\tif (\n\t\t\t\t\t$.isFunction(source.then) &&\n\t\t\t\t\t$.isFunction(source[\"catch\"])\n\t\t\t\t) {\n\t\t\t\t\tdfd = source;\n\t\t\t\t\tsource = new $.Deferred();\n\t\t\t\t\tdfd.then(\n\t\t\t\t\t\tfunction(value) {\n\t\t\t\t\t\t\tsource.resolve(value);\n\t\t\t\t\t\t},\n\t\t\t\t\t\tfunction(reason) {\n\t\t\t\t\t\t\tsource.reject(reason);\n\t\t\t\t\t\t}\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\tif ($.isFunction(source.promise)) {\n\t\t\t\t\t// `source` is a deferred, i.e. ajax request\n\t\t\t\t\t// _assert(!node.isLoading(), \"recursive load\");\n\t\t\t\t\ttree.nodeSetStatus(ctx, \"loading\");\n\n\t\t\t\t\tsource\n\t\t\t\t\t\t.done(function(children) {\n\t\t\t\t\t\t\ttree.nodeSetStatus(ctx, \"ok\");\n\t\t\t\t\t\t\tnode._requestId = null;\n\t\t\t\t\t\t})\n\t\t\t\t\t\t.fail(function(error) {\n\t\t\t\t\t\t\tvar ctxErr;\n\n\t\t\t\t\t\t\tif (error === RECURSIVE_REQUEST_ERROR) {\n\t\t\t\t\t\t\t\tnode.warn(\n\t\t\t\t\t\t\t\t\t\"Ignored response for obsolete load request #\" +\n\t\t\t\t\t\t\t\t\t\trequestId +\n\t\t\t\t\t\t\t\t\t\t\" (expected #\" +\n\t\t\t\t\t\t\t\t\t\tnode._requestId +\n\t\t\t\t\t\t\t\t\t\t\")\"\n\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t\t} else if (\n\t\t\t\t\t\t\t\terror.node &&\n\t\t\t\t\t\t\t\terror.error &&\n\t\t\t\t\t\t\t\terror.message\n\t\t\t\t\t\t\t) {\n\t\t\t\t\t\t\t\t// error is already a context object\n\t\t\t\t\t\t\t\tctxErr = error;\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tctxErr = tree._makeHookContext(node, null, {\n\t\t\t\t\t\t\t\t\terror: error, // it can be jqXHR or any custom error\n\t\t\t\t\t\t\t\t\targs: Array.prototype.slice.call(arguments),\n\t\t\t\t\t\t\t\t\tmessage: error\n\t\t\t\t\t\t\t\t\t\t? error.message || error.toString()\n\t\t\t\t\t\t\t\t\t\t: \"\",\n\t\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\t\tif (ctxErr.message === \"[object Object]\") {\n\t\t\t\t\t\t\t\t\tctxErr.message = \"\";\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tnode.warn(\n\t\t\t\t\t\t\t\t\"Load children failed (\" + ctxErr.message + \")\",\n\t\t\t\t\t\t\t\tctxErr\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\tif (\n\t\t\t\t\t\t\t\ttree._triggerNodeEvent(\n\t\t\t\t\t\t\t\t\t\"loadError\",\n\t\t\t\t\t\t\t\t\tctxErr,\n\t\t\t\t\t\t\t\t\tnull\n\t\t\t\t\t\t\t\t) !== false\n\t\t\t\t\t\t\t) {\n\t\t\t\t\t\t\t\ttree.nodeSetStatus(\n\t\t\t\t\t\t\t\t\tctx,\n\t\t\t\t\t\t\t\t\t\"error\",\n\t\t\t\t\t\t\t\t\tctxErr.message,\n\t\t\t\t\t\t\t\t\tctxErr.details\n\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t});\n\t\t\t\t} else {\n\t\t\t\t\tif (ctx.options.postProcess) {\n\t\t\t\t\t\t// #792: Call postProcess for non-deferred source\n\t\t\t\t\t\tvar res = tree._triggerNodeEvent(\n\t\t\t\t\t\t\t\"postProcess\",\n\t\t\t\t\t\t\tctx,\n\t\t\t\t\t\t\tctx.originalEvent,\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tresponse: source,\n\t\t\t\t\t\t\t\terror: null,\n\t\t\t\t\t\t\t\tdataType: typeof source,\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t);\n\n\t\t\t\t\t\tif (\n\t\t\t\t\t\t\t$.isArray(res) ||\n\t\t\t\t\t\t\t($.isPlainObject(res) && $.isArray(res.children))\n\t\t\t\t\t\t) {\n\t\t\t\t\t\t\t// Use `ctx.result` if valid\n\t\t\t\t\t\t\t// (otherwise use existing data, which may have been modified in-place)\n\t\t\t\t\t\t\tsource = res;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\t// $.when(source) resolves also for non-deferreds\n\t\t\t\treturn $.when(source).done(function(children) {\n\t\t\t\t\tvar metaData, noDataRes;\n\n\t\t\t\t\tif ($.isPlainObject(children)) {\n\t\t\t\t\t\t// We got {foo: 'abc', children: [...]}\n\t\t\t\t\t\t// Copy extra properties to tree.data.foo\n\t\t\t\t\t\t_assert(\n\t\t\t\t\t\t\tnode.isRootNode(),\n\t\t\t\t\t\t\t\"source may only be an object for root nodes (expecting an array of child objects otherwise)\"\n\t\t\t\t\t\t);\n\t\t\t\t\t\t_assert(\n\t\t\t\t\t\t\t$.isArray(children.children),\n\t\t\t\t\t\t\t\"if an object is passed as source, it must contain a 'children' array (all other properties are added to 'tree.data')\"\n\t\t\t\t\t\t);\n\t\t\t\t\t\tmetaData = children;\n\t\t\t\t\t\tchildren = children.children;\n\t\t\t\t\t\tdelete metaData.children;\n\t\t\t\t\t\t// Copy some attributes to tree.data\n\t\t\t\t\t\t$.each(TREE_ATTRS, function(i, attr) {\n\t\t\t\t\t\t\tif (metaData[attr] !== undefined) {\n\t\t\t\t\t\t\t\ttree[attr] = metaData[attr];\n\t\t\t\t\t\t\t\tdelete metaData[attr];\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t});\n\t\t\t\t\t\t// Copy all other attributes to tree.data.NAME\n\t\t\t\t\t\t$.extend(tree.data, metaData);\n\t\t\t\t\t}\n\t\t\t\t\t_assert($.isArray(children), \"expected array of children\");\n\t\t\t\t\tnode._setChildren(children);\n\n\t\t\t\t\tif (tree.options.nodata && children.length === 0) {\n\t\t\t\t\t\tif ($.isFunction(tree.options.nodata)) {\n\t\t\t\t\t\t\tnoDataRes = tree.options.nodata.call(\n\t\t\t\t\t\t\t\ttree,\n\t\t\t\t\t\t\t\t{ type: \"nodata\" },\n\t\t\t\t\t\t\t\tctx\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t} else if (\n\t\t\t\t\t\t\ttree.options.nodata === true &&\n\t\t\t\t\t\t\tnode.isRootNode()\n\t\t\t\t\t\t) {\n\t\t\t\t\t\t\tnoDataRes = tree.options.strings.nodata;\n\t\t\t\t\t\t} else if (\n\t\t\t\t\t\t\ttypeof tree.options.nodata === \"string\" &&\n\t\t\t\t\t\t\tnode.isRootNode()\n\t\t\t\t\t\t) {\n\t\t\t\t\t\t\tnoDataRes = tree.options.nodata;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (noDataRes) {\n\t\t\t\t\t\t\tnode.setStatus(\"nodata\", noDataRes);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\t// trigger fancytreeloadchildren\n\t\t\t\t\ttree._triggerNodeEvent(\"loadChildren\", node);\n\t\t\t\t});\n\t\t\t},\n\t\t\t/** [Not Implemented]  */\n\t\t\tnodeLoadKeyPath: function(ctx, keyPathList) {\n\t\t\t\t// TODO: implement and improve\n\t\t\t\t// http://code.google.com/p/dynatree/issues/detail?id=222\n\t\t\t},\n\t\t\t/**\n\t\t\t * Remove a single direct child of ctx.node.\n\t\t\t * @param {EventData} ctx\n\t\t\t * @param {FancytreeNode} childNode dircect child of ctx.node\n\t\t\t */\n\t\t\tnodeRemoveChild: function(ctx, childNode) {\n\t\t\t\tvar idx,\n\t\t\t\t\tnode = ctx.node,\n\t\t\t\t\t// opts = ctx.options,\n\t\t\t\t\tsubCtx = $.extend({}, ctx, { node: childNode }),\n\t\t\t\t\tchildren = node.children;\n\n\t\t\t\t// FT.debug(\"nodeRemoveChild()\", node.toString(), childNode.toString());\n\n\t\t\t\tif (children.length === 1) {\n\t\t\t\t\t_assert(childNode === children[0], \"invalid single child\");\n\t\t\t\t\treturn this.nodeRemoveChildren(ctx);\n\t\t\t\t}\n\t\t\t\tif (\n\t\t\t\t\tthis.activeNode &&\n\t\t\t\t\t(childNode === this.activeNode ||\n\t\t\t\t\t\tthis.activeNode.isDescendantOf(childNode))\n\t\t\t\t) {\n\t\t\t\t\tthis.activeNode.setActive(false); // TODO: don't fire events\n\t\t\t\t}\n\t\t\t\tif (\n\t\t\t\t\tthis.focusNode &&\n\t\t\t\t\t(childNode === this.focusNode ||\n\t\t\t\t\t\tthis.focusNode.isDescendantOf(childNode))\n\t\t\t\t) {\n\t\t\t\t\tthis.focusNode = null;\n\t\t\t\t}\n\t\t\t\t// TODO: persist must take care to clear select and expand cookies\n\t\t\t\tthis.nodeRemoveMarkup(subCtx);\n\t\t\t\tthis.nodeRemoveChildren(subCtx);\n\t\t\t\tidx = $.inArray(childNode, children);\n\t\t\t\t_assert(idx >= 0, \"invalid child\");\n\t\t\t\t// Notify listeners\n\t\t\t\tnode.triggerModifyChild(\"remove\", childNode);\n\t\t\t\t// Unlink to support GC\n\t\t\t\tchildNode.visit(function(n) {\n\t\t\t\t\tn.parent = null;\n\t\t\t\t}, true);\n\t\t\t\tthis._callHook(\"treeRegisterNode\", this, false, childNode);\n\t\t\t\t// remove from child list\n\t\t\t\tchildren.splice(idx, 1);\n\t\t\t},\n\t\t\t/**Remove HTML markup for all descendents of ctx.node.\n\t\t\t * @param {EventData} ctx\n\t\t\t */\n\t\t\tnodeRemoveChildMarkup: function(ctx) {\n\t\t\t\tvar node = ctx.node;\n\n\t\t\t\t// FT.debug(\"nodeRemoveChildMarkup()\", node.toString());\n\t\t\t\t// TODO: Unlink attr.ftnode to support GC\n\t\t\t\tif (node.ul) {\n\t\t\t\t\tif (node.isRootNode()) {\n\t\t\t\t\t\t$(node.ul).empty();\n\t\t\t\t\t} else {\n\t\t\t\t\t\t$(node.ul).remove();\n\t\t\t\t\t\tnode.ul = null;\n\t\t\t\t\t}\n\t\t\t\t\tnode.visit(function(n) {\n\t\t\t\t\t\tn.li = n.ul = null;\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t},\n\t\t\t/**Remove all descendants of ctx.node.\n\t\t\t * @param {EventData} ctx\n\t\t\t */\n\t\t\tnodeRemoveChildren: function(ctx) {\n\t\t\t\tvar subCtx,\n\t\t\t\t\ttree = ctx.tree,\n\t\t\t\t\tnode = ctx.node,\n\t\t\t\t\tchildren = node.children;\n\t\t\t\t// opts = ctx.options;\n\n\t\t\t\t// FT.debug(\"nodeRemoveChildren()\", node.toString());\n\t\t\t\tif (!children) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tif (this.activeNode && this.activeNode.isDescendantOf(node)) {\n\t\t\t\t\tthis.activeNode.setActive(false); // TODO: don't fire events\n\t\t\t\t}\n\t\t\t\tif (this.focusNode && this.focusNode.isDescendantOf(node)) {\n\t\t\t\t\tthis.focusNode = null;\n\t\t\t\t}\n\t\t\t\t// TODO: persist must take care to clear select and expand cookies\n\t\t\t\tthis.nodeRemoveChildMarkup(ctx);\n\t\t\t\t// Unlink children to support GC\n\t\t\t\t// TODO: also delete this.children (not possible using visit())\n\t\t\t\tsubCtx = $.extend({}, ctx);\n\t\t\t\tnode.triggerModifyChild(\"remove\", null);\n\t\t\t\tnode.visit(function(n) {\n\t\t\t\t\tn.parent = null;\n\t\t\t\t\ttree._callHook(\"treeRegisterNode\", tree, false, n);\n\t\t\t\t});\n\t\t\t\tif (node.lazy) {\n\t\t\t\t\t// 'undefined' would be interpreted as 'not yet loaded' for lazy nodes\n\t\t\t\t\tnode.children = [];\n\t\t\t\t} else {\n\t\t\t\t\tnode.children = null;\n\t\t\t\t}\n\t\t\t\tif (!node.isRootNode()) {\n\t\t\t\t\tnode.expanded = false; // #449, #459\n\t\t\t\t}\n\t\t\t\tthis.nodeRenderStatus(ctx);\n\t\t\t},\n\t\t\t/**Remove HTML markup for ctx.node and all its descendents.\n\t\t\t * @param {EventData} ctx\n\t\t\t */\n\t\t\tnodeRemoveMarkup: function(ctx) {\n\t\t\t\tvar node = ctx.node;\n\t\t\t\t// FT.debug(\"nodeRemoveMarkup()\", node.toString());\n\t\t\t\t// TODO: Unlink attr.ftnode to support GC\n\t\t\t\tif (node.li) {\n\t\t\t\t\t$(node.li).remove();\n\t\t\t\t\tnode.li = null;\n\t\t\t\t}\n\t\t\t\tthis.nodeRemoveChildMarkup(ctx);\n\t\t\t},\n\t\t\t/**\n\t\t\t * Create `&lt;li>&lt;span>..&lt;/span> .. &lt;/li>` tags for this node.\n\t\t\t *\n\t\t\t * This method takes care that all HTML markup is created that is required\n\t\t\t * to display this node in its current state.\n\t\t\t *\n\t\t\t * Call this method to create new nodes, or after the strucuture\n\t\t\t * was changed (e.g. after moving this node or adding/removing children)\n\t\t\t * nodeRenderTitle() and nodeRenderStatus() are implied.\n\t\t\t *\n\t\t\t * &lt;code>\n\t\t\t * &lt;li id='KEY' ftnode=NODE>\n\t\t\t *     &lt;span class='fancytree-node fancytree-expanded fancytree-has-children fancytree-lastsib fancytree-exp-el fancytree-ico-e'>\n\t\t\t *         &lt;span class=\"fancytree-expander\">&lt;/span>\n\t\t\t *         &lt;span class=\"fancytree-checkbox\">&lt;/span> // only present in checkbox mode\n\t\t\t *         &lt;span class=\"fancytree-icon\">&lt;/span>\n\t\t\t *         &lt;a href=\"#\" class=\"fancytree-title\"> Node 1 &lt;/a>\n\t\t\t *     &lt;/span>\n\t\t\t *     &lt;ul> // only present if node has children\n\t\t\t *         &lt;li id='KEY' ftnode=NODE> child1 ... &lt;/li>\n\t\t\t *         &lt;li id='KEY' ftnode=NODE> child2 ... &lt;/li>\n\t\t\t *     &lt;/ul>\n\t\t\t * &lt;/li>\n\t\t\t * &lt;/code>\n\t\t\t *\n\t\t\t * @param {EventData} ctx\n\t\t\t * @param {boolean} [force=false] re-render, even if html markup was already created\n\t\t\t * @param {boolean} [deep=false] also render all descendants, even if parent is collapsed\n\t\t\t * @param {boolean} [collapsed=false] force root node to be collapsed, so we can apply animated expand later\n\t\t\t */\n\t\t\tnodeRender: function(ctx, force, deep, collapsed, _recursive) {\n\t\t\t\t/* This method must take care of all cases where the current data mode\n\t\t * (i.e. node hierarchy) does not match the current markup.\n\t\t *\n\t\t * - node was not yet rendered:\n\t\t *   create markup\n\t\t * - node was rendered: exit fast\n\t\t * - children have been added\n\t\t * - children have been removed\n\t\t */\n\t\t\t\tvar childLI,\n\t\t\t\t\tchildNode1,\n\t\t\t\t\tchildNode2,\n\t\t\t\t\ti,\n\t\t\t\t\tl,\n\t\t\t\t\tnext,\n\t\t\t\t\tsubCtx,\n\t\t\t\t\tnode = ctx.node,\n\t\t\t\t\ttree = ctx.tree,\n\t\t\t\t\topts = ctx.options,\n\t\t\t\t\taria = opts.aria,\n\t\t\t\t\tfirstTime = false,\n\t\t\t\t\tparent = node.parent,\n\t\t\t\t\tisRootNode = !parent,\n\t\t\t\t\tchildren = node.children,\n\t\t\t\t\tsuccessorLi = null;\n\t\t\t\t// FT.debug(\"nodeRender(\" + !!force + \", \" + !!deep + \")\", node.toString());\n\n\t\t\t\tif (tree._enableUpdate === false) {\n\t\t\t\t\t// tree.debug(\"no render\", tree._enableUpdate);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tif (!isRootNode && !parent.ul) {\n\t\t\t\t\t// Calling node.collapse on a deep, unrendered node\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\t_assert(isRootNode || parent.ul, \"parent UL must exist\");\n\n\t\t\t\t// Render the node\n\t\t\t\tif (!isRootNode) {\n\t\t\t\t\t// Discard markup on force-mode, or if it is not linked to parent <ul>\n\t\t\t\t\tif (\n\t\t\t\t\t\tnode.li &&\n\t\t\t\t\t\t(force || node.li.parentNode !== node.parent.ul)\n\t\t\t\t\t) {\n\t\t\t\t\t\tif (node.li.parentNode === node.parent.ul) {\n\t\t\t\t\t\t\t// #486: store following node, so we can insert the new markup there later\n\t\t\t\t\t\t\tsuccessorLi = node.li.nextSibling;\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t// May happen, when a top-level node was dropped over another\n\t\t\t\t\t\t\tthis.debug(\n\t\t\t\t\t\t\t\t\"Unlinking \" +\n\t\t\t\t\t\t\t\t\tnode +\n\t\t\t\t\t\t\t\t\t\" (must be child of \" +\n\t\t\t\t\t\t\t\t\tnode.parent +\n\t\t\t\t\t\t\t\t\t\")\"\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t}\n\t\t\t\t\t\t//\t            this.debug(\"nodeRemoveMarkup...\");\n\t\t\t\t\t\tthis.nodeRemoveMarkup(ctx);\n\t\t\t\t\t}\n\t\t\t\t\t// Create <li><span /> </li>\n\t\t\t\t\t//\t\t\tnode.debug(\"render...\");\n\t\t\t\t\tif (!node.li) {\n\t\t\t\t\t\t//\t            node.debug(\"render... really\");\n\t\t\t\t\t\tfirstTime = true;\n\t\t\t\t\t\tnode.li = document.createElement(\"li\");\n\t\t\t\t\t\tnode.li.ftnode = node;\n\n\t\t\t\t\t\tif (node.key && opts.generateIds) {\n\t\t\t\t\t\t\tnode.li.id = opts.idPrefix + node.key;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tnode.span = document.createElement(\"span\");\n\t\t\t\t\t\tnode.span.className = \"fancytree-node\";\n\t\t\t\t\t\tif (aria && !node.tr) {\n\t\t\t\t\t\t\t$(node.li).attr(\"role\", \"treeitem\");\n\t\t\t\t\t\t}\n\t\t\t\t\t\tnode.li.appendChild(node.span);\n\n\t\t\t\t\t\t// Create inner HTML for the <span> (expander, checkbox, icon, and title)\n\t\t\t\t\t\tthis.nodeRenderTitle(ctx);\n\n\t\t\t\t\t\t// Allow tweaking and binding, after node was created for the first time\n\t\t\t\t\t\tif (opts.createNode) {\n\t\t\t\t\t\t\topts.createNode.call(\n\t\t\t\t\t\t\t\ttree,\n\t\t\t\t\t\t\t\t{ type: \"createNode\" },\n\t\t\t\t\t\t\t\tctx\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t}\n\t\t\t\t\t} else {\n\t\t\t\t\t\t//\t\t\t\tthis.nodeRenderTitle(ctx);\n\t\t\t\t\t\tthis.nodeRenderStatus(ctx);\n\t\t\t\t\t}\n\t\t\t\t\t// Allow tweaking after node state was rendered\n\t\t\t\t\tif (opts.renderNode) {\n\t\t\t\t\t\topts.renderNode.call(tree, { type: \"renderNode\" }, ctx);\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// Visit child nodes\n\t\t\t\tif (children) {\n\t\t\t\t\tif (isRootNode || node.expanded || deep === true) {\n\t\t\t\t\t\t// Create a UL to hold the children\n\t\t\t\t\t\tif (!node.ul) {\n\t\t\t\t\t\t\tnode.ul = document.createElement(\"ul\");\n\t\t\t\t\t\t\tif (\n\t\t\t\t\t\t\t\t(collapsed === true && !_recursive) ||\n\t\t\t\t\t\t\t\t!node.expanded\n\t\t\t\t\t\t\t) {\n\t\t\t\t\t\t\t\t// hide top UL, so we can use an animation to show it later\n\t\t\t\t\t\t\t\tnode.ul.style.display = \"none\";\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tif (aria) {\n\t\t\t\t\t\t\t\t$(node.ul).attr(\"role\", \"group\");\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tif (node.li) {\n\t\t\t\t\t\t\t\t// issue #67\n\t\t\t\t\t\t\t\tnode.li.appendChild(node.ul);\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tnode.tree.$div.append(node.ul);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\t// Add child markup\n\t\t\t\t\t\tfor (i = 0, l = children.length; i < l; i++) {\n\t\t\t\t\t\t\tsubCtx = $.extend({}, ctx, { node: children[i] });\n\t\t\t\t\t\t\tthis.nodeRender(subCtx, force, deep, false, true);\n\t\t\t\t\t\t}\n\t\t\t\t\t\t// Remove <li> if nodes have moved to another parent\n\t\t\t\t\t\tchildLI = node.ul.firstChild;\n\t\t\t\t\t\twhile (childLI) {\n\t\t\t\t\t\t\tchildNode2 = childLI.ftnode;\n\t\t\t\t\t\t\tif (childNode2 && childNode2.parent !== node) {\n\t\t\t\t\t\t\t\tnode.debug(\n\t\t\t\t\t\t\t\t\t\"_fixParent: remove missing \" + childNode2,\n\t\t\t\t\t\t\t\t\tchildLI\n\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t\tnext = childLI.nextSibling;\n\t\t\t\t\t\t\t\tchildLI.parentNode.removeChild(childLI);\n\t\t\t\t\t\t\t\tchildLI = next;\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tchildLI = childLI.nextSibling;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\t// Make sure, that <li> order matches node.children order.\n\t\t\t\t\t\tchildLI = node.ul.firstChild;\n\t\t\t\t\t\tfor (i = 0, l = children.length - 1; i < l; i++) {\n\t\t\t\t\t\t\tchildNode1 = children[i];\n\t\t\t\t\t\t\tchildNode2 = childLI.ftnode;\n\t\t\t\t\t\t\tif (childNode1 !== childNode2) {\n\t\t\t\t\t\t\t\t// node.debug(\"_fixOrder: mismatch at index \" + i + \": \" + childNode1 + \" != \" + childNode2);\n\t\t\t\t\t\t\t\tnode.ul.insertBefore(\n\t\t\t\t\t\t\t\t\tchildNode1.li,\n\t\t\t\t\t\t\t\t\tchildNode2.li\n\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tchildLI = childLI.nextSibling;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\t// No children: remove markup if any\n\t\t\t\t\tif (node.ul) {\n\t\t\t\t\t\t//\t\t\t\talert(\"remove child markup for \" + node);\n\t\t\t\t\t\tthis.warn(\"remove child markup for \" + node);\n\t\t\t\t\t\tthis.nodeRemoveChildMarkup(ctx);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif (!isRootNode) {\n\t\t\t\t\t// Update element classes according to node state\n\t\t\t\t\t// this.nodeRenderStatus(ctx);\n\t\t\t\t\t// Finally add the whole structure to the DOM, so the browser can render\n\t\t\t\t\tif (firstTime) {\n\t\t\t\t\t\t// #486: successorLi is set, if we re-rendered (i.e. discarded)\n\t\t\t\t\t\t// existing markup, which  we want to insert at the same position.\n\t\t\t\t\t\t// (null is equivalent to append)\n\t\t\t\t\t\t//\t\t\t\tparent.ul.appendChild(node.li);\n\t\t\t\t\t\tparent.ul.insertBefore(node.li, successorLi);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t},\n\t\t\t/** Create HTML inside the node's outer &lt;span> (i.e. expander, checkbox,\n\t\t\t * icon, and title).\n\t\t\t *\n\t\t\t * nodeRenderStatus() is implied.\n\t\t\t * @param {EventData} ctx\n\t\t\t * @param {string} [title] optinal new title\n\t\t\t */\n\t\t\tnodeRenderTitle: function(ctx, title) {\n\t\t\t\t// set node connector images, links and text\n\t\t\t\tvar checkbox,\n\t\t\t\t\tclassName,\n\t\t\t\t\ticon,\n\t\t\t\t\tnodeTitle,\n\t\t\t\t\trole,\n\t\t\t\t\ttabindex,\n\t\t\t\t\ttooltip,\n\t\t\t\t\ticonTooltip,\n\t\t\t\t\tnode = ctx.node,\n\t\t\t\t\ttree = ctx.tree,\n\t\t\t\t\topts = ctx.options,\n\t\t\t\t\taria = opts.aria,\n\t\t\t\t\tlevel = node.getLevel(),\n\t\t\t\t\tares = [];\n\n\t\t\t\tif (title !== undefined) {\n\t\t\t\t\tnode.title = title;\n\t\t\t\t}\n\t\t\t\tif (!node.span || tree._enableUpdate === false) {\n\t\t\t\t\t// Silently bail out if node was not rendered yet, assuming\n\t\t\t\t\t// node.render() will be called as the node becomes visible\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\t// Connector (expanded, expandable or simple)\n\t\t\t\trole =\n\t\t\t\t\taria && node.hasChildren() !== false\n\t\t\t\t\t\t? \" role='button'\"\n\t\t\t\t\t\t: \"\";\n\t\t\t\tif (level < opts.minExpandLevel) {\n\t\t\t\t\tif (!node.lazy) {\n\t\t\t\t\t\tnode.expanded = true;\n\t\t\t\t\t}\n\t\t\t\t\tif (level > 1) {\n\t\t\t\t\t\tares.push(\n\t\t\t\t\t\t\t\"<span \" +\n\t\t\t\t\t\t\t\trole +\n\t\t\t\t\t\t\t\t\" class='fancytree-expander fancytree-expander-fixed'></span>\"\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t\t// .. else (i.e. for root level) skip expander/connector alltogether\n\t\t\t\t} else {\n\t\t\t\t\tares.push(\n\t\t\t\t\t\t\"<span \" + role + \" class='fancytree-expander'></span>\"\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\t// Checkbox mode\n\t\t\t\tcheckbox = FT.evalOption(\"checkbox\", node, node, opts, false);\n\n\t\t\t\tif (checkbox && !node.isStatusNode()) {\n\t\t\t\t\trole = aria ? \" role='checkbox'\" : \"\";\n\t\t\t\t\tclassName = \"fancytree-checkbox\";\n\t\t\t\t\tif (\n\t\t\t\t\t\tcheckbox === \"radio\" ||\n\t\t\t\t\t\t(node.parent && node.parent.radiogroup)\n\t\t\t\t\t) {\n\t\t\t\t\t\tclassName += \" fancytree-radio\";\n\t\t\t\t\t}\n\t\t\t\t\tares.push(\n\t\t\t\t\t\t\"<span \" + role + \" class='\" + className + \"'></span>\"\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\t// Folder or doctype icon\n\t\t\t\tif (node.data.iconClass !== undefined) {\n\t\t\t\t\t// 2015-11-16\n\t\t\t\t\t// Handle / warn about backward compatibility\n\t\t\t\t\tif (node.icon) {\n\t\t\t\t\t\t$.error(\n\t\t\t\t\t\t\t\"'iconClass' node option is deprecated since v2.14.0: use 'icon' only instead\"\n\t\t\t\t\t\t);\n\t\t\t\t\t} else {\n\t\t\t\t\t\tnode.warn(\n\t\t\t\t\t\t\t\"'iconClass' node option is deprecated since v2.14.0: use 'icon' instead\"\n\t\t\t\t\t\t);\n\t\t\t\t\t\tnode.icon = node.data.iconClass;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\t// If opts.icon is a callback and returns something other than undefined, use that\n\t\t\t\t// else if node.icon is a boolean or string, use that\n\t\t\t\t// else if opts.icon is a boolean or string, use that\n\t\t\t\t// else show standard icon (which may be different for folders or documents)\n\t\t\t\ticon = FT.evalOption(\"icon\", node, node, opts, true);\n\t\t\t\t// if( typeof icon !== \"boolean\" ) {\n\t\t\t\t// \t// icon is defined, but not true/false: must be a string\n\t\t\t\t// \ticon = \"\" + icon;\n\t\t\t\t// }\n\t\t\t\tif (icon !== false) {\n\t\t\t\t\trole = aria ? \" role='presentation'\" : \"\";\n\n\t\t\t\t\ticonTooltip = FT.evalOption(\n\t\t\t\t\t\t\"iconTooltip\",\n\t\t\t\t\t\tnode,\n\t\t\t\t\t\tnode,\n\t\t\t\t\t\topts,\n\t\t\t\t\t\tnull\n\t\t\t\t\t);\n\t\t\t\t\ticonTooltip = iconTooltip\n\t\t\t\t\t\t? \" title='\" + _escapeTooltip(iconTooltip) + \"'\"\n\t\t\t\t\t\t: \"\";\n\n\t\t\t\t\tif (typeof icon === \"string\") {\n\t\t\t\t\t\tif (TEST_IMG.test(icon)) {\n\t\t\t\t\t\t\t// node.icon is an image url. Prepend imagePath\n\t\t\t\t\t\t\ticon =\n\t\t\t\t\t\t\t\ticon.charAt(0) === \"/\"\n\t\t\t\t\t\t\t\t\t? icon\n\t\t\t\t\t\t\t\t\t: (opts.imagePath || \"\") + icon;\n\t\t\t\t\t\t\tares.push(\n\t\t\t\t\t\t\t\t\"<img src='\" +\n\t\t\t\t\t\t\t\t\ticon +\n\t\t\t\t\t\t\t\t\t\"' class='fancytree-icon'\" +\n\t\t\t\t\t\t\t\t\ticonTooltip +\n\t\t\t\t\t\t\t\t\t\" alt='' />\"\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tares.push(\n\t\t\t\t\t\t\t\t\"<span \" +\n\t\t\t\t\t\t\t\t\trole +\n\t\t\t\t\t\t\t\t\t\" class='fancytree-custom-icon \" +\n\t\t\t\t\t\t\t\t\ticon +\n\t\t\t\t\t\t\t\t\t\"'\" +\n\t\t\t\t\t\t\t\t\ticonTooltip +\n\t\t\t\t\t\t\t\t\t\"></span>\"\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t}\n\t\t\t\t\t} else if (icon.text) {\n\t\t\t\t\t\tares.push(\n\t\t\t\t\t\t\t\"<span \" +\n\t\t\t\t\t\t\t\trole +\n\t\t\t\t\t\t\t\t\" class='fancytree-custom-icon \" +\n\t\t\t\t\t\t\t\t(icon.addClass || \"\") +\n\t\t\t\t\t\t\t\t\"'\" +\n\t\t\t\t\t\t\t\ticonTooltip +\n\t\t\t\t\t\t\t\t\">\" +\n\t\t\t\t\t\t\t\tFT.escapeHtml(icon.text) +\n\t\t\t\t\t\t\t\t\"</span>\"\n\t\t\t\t\t\t);\n\t\t\t\t\t} else if (icon.html) {\n\t\t\t\t\t\tares.push(\n\t\t\t\t\t\t\t\"<span \" +\n\t\t\t\t\t\t\t\trole +\n\t\t\t\t\t\t\t\t\" class='fancytree-custom-icon \" +\n\t\t\t\t\t\t\t\t(icon.addClass || \"\") +\n\t\t\t\t\t\t\t\t\"'\" +\n\t\t\t\t\t\t\t\ticonTooltip +\n\t\t\t\t\t\t\t\t\">\" +\n\t\t\t\t\t\t\t\ticon.html +\n\t\t\t\t\t\t\t\t\"</span>\"\n\t\t\t\t\t\t);\n\t\t\t\t\t} else {\n\t\t\t\t\t\t// standard icon: theme css will take care of this\n\t\t\t\t\t\tares.push(\n\t\t\t\t\t\t\t\"<span \" +\n\t\t\t\t\t\t\t\trole +\n\t\t\t\t\t\t\t\t\" class='fancytree-icon'\" +\n\t\t\t\t\t\t\t\ticonTooltip +\n\t\t\t\t\t\t\t\t\"></span>\"\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\t// Node title\n\t\t\t\tnodeTitle = \"\";\n\t\t\t\tif (opts.renderTitle) {\n\t\t\t\t\tnodeTitle =\n\t\t\t\t\t\topts.renderTitle.call(\n\t\t\t\t\t\t\ttree,\n\t\t\t\t\t\t\t{ type: \"renderTitle\" },\n\t\t\t\t\t\t\tctx\n\t\t\t\t\t\t) || \"\";\n\t\t\t\t}\n\t\t\t\tif (!nodeTitle) {\n\t\t\t\t\ttooltip = FT.evalOption(\"tooltip\", node, node, opts, null);\n\t\t\t\t\tif (tooltip === true) {\n\t\t\t\t\t\ttooltip = node.title;\n\t\t\t\t\t}\n\t\t\t\t\t// if( node.tooltip ) {\n\t\t\t\t\t// \ttooltip = node.tooltip;\n\t\t\t\t\t// } else if ( opts.tooltip ) {\n\t\t\t\t\t// \ttooltip = opts.tooltip === true ? node.title : opts.tooltip.call(tree, node);\n\t\t\t\t\t// }\n\t\t\t\t\ttooltip = tooltip\n\t\t\t\t\t\t? \" title='\" + _escapeTooltip(tooltip) + \"'\"\n\t\t\t\t\t\t: \"\";\n\t\t\t\t\ttabindex = opts.titlesTabbable ? \" tabindex='0'\" : \"\";\n\n\t\t\t\t\tnodeTitle =\n\t\t\t\t\t\t\"<span class='fancytree-title'\" +\n\t\t\t\t\t\ttooltip +\n\t\t\t\t\t\ttabindex +\n\t\t\t\t\t\t\">\" +\n\t\t\t\t\t\t(opts.escapeTitles\n\t\t\t\t\t\t\t? FT.escapeHtml(node.title)\n\t\t\t\t\t\t\t: node.title) +\n\t\t\t\t\t\t\"</span>\";\n\t\t\t\t}\n\t\t\t\tares.push(nodeTitle);\n\t\t\t\t// Note: this will trigger focusout, if node had the focus\n\t\t\t\t//$(node.span).html(ares.join(\"\")); // it will cleanup the jQuery data currently associated with SPAN (if any), but it executes more slowly\n\t\t\t\tnode.span.innerHTML = ares.join(\"\");\n\t\t\t\t// Update CSS classes\n\t\t\t\tthis.nodeRenderStatus(ctx);\n\t\t\t\tif (opts.enhanceTitle) {\n\t\t\t\t\tctx.$title = $(\">span.fancytree-title\", node.span);\n\t\t\t\t\tnodeTitle =\n\t\t\t\t\t\topts.enhanceTitle.call(\n\t\t\t\t\t\t\ttree,\n\t\t\t\t\t\t\t{ type: \"enhanceTitle\" },\n\t\t\t\t\t\t\tctx\n\t\t\t\t\t\t) || \"\";\n\t\t\t\t}\n\t\t\t},\n\t\t\t/** Update element classes according to node state.\n\t\t\t * @param {EventData} ctx\n\t\t\t */\n\t\t\tnodeRenderStatus: function(ctx) {\n\t\t\t\t// Set classes for current status\n\t\t\t\tvar $ariaElem,\n\t\t\t\t\tnode = ctx.node,\n\t\t\t\t\ttree = ctx.tree,\n\t\t\t\t\topts = ctx.options,\n\t\t\t\t\t//\t\t\tnodeContainer = node[tree.nodeContainerAttrName],\n\t\t\t\t\thasChildren = node.hasChildren(),\n\t\t\t\t\tisLastSib = node.isLastSibling(),\n\t\t\t\t\taria = opts.aria,\n\t\t\t\t\tcn = opts._classNames,\n\t\t\t\t\tcnList = [],\n\t\t\t\t\tstatusElem = node[tree.statusClassPropName];\n\n\t\t\t\tif (!statusElem || tree._enableUpdate === false) {\n\t\t\t\t\t// if this function is called for an unrendered node, ignore it (will be updated on nect render anyway)\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tif (aria) {\n\t\t\t\t\t$ariaElem = $(node.tr || node.li);\n\t\t\t\t}\n\t\t\t\t// Build a list of class names that we will add to the node <span>\n\t\t\t\tcnList.push(cn.node);\n\t\t\t\tif (tree.activeNode === node) {\n\t\t\t\t\tcnList.push(cn.active);\n\t\t\t\t\t//\t\t\t$(\">span.fancytree-title\", statusElem).attr(\"tabindex\", \"0\");\n\t\t\t\t\t//\t\t\ttree.$container.removeAttr(\"tabindex\");\n\t\t\t\t\t// }else{\n\t\t\t\t\t//\t\t\t$(\">span.fancytree-title\", statusElem).removeAttr(\"tabindex\");\n\t\t\t\t\t//\t\t\ttree.$container.attr(\"tabindex\", \"0\");\n\t\t\t\t}\n\t\t\t\tif (tree.focusNode === node) {\n\t\t\t\t\tcnList.push(cn.focused);\n\t\t\t\t}\n\t\t\t\tif (node.expanded) {\n\t\t\t\t\tcnList.push(cn.expanded);\n\t\t\t\t}\n\t\t\t\tif (aria) {\n\t\t\t\t\tif (hasChildren !== false) {\n\t\t\t\t\t\t$ariaElem.attr(\"aria-expanded\", Boolean(node.expanded));\n\t\t\t\t\t} else {\n\t\t\t\t\t\t$ariaElem.removeAttr(\"aria-expanded\");\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif (node.folder) {\n\t\t\t\t\tcnList.push(cn.folder);\n\t\t\t\t}\n\t\t\t\tif (hasChildren !== false) {\n\t\t\t\t\tcnList.push(cn.hasChildren);\n\t\t\t\t}\n\t\t\t\t// TODO: required?\n\t\t\t\tif (isLastSib) {\n\t\t\t\t\tcnList.push(cn.lastsib);\n\t\t\t\t}\n\t\t\t\tif (node.lazy && node.children == null) {\n\t\t\t\t\tcnList.push(cn.lazy);\n\t\t\t\t}\n\t\t\t\tif (node.partload) {\n\t\t\t\t\tcnList.push(cn.partload);\n\t\t\t\t}\n\t\t\t\tif (node.partsel) {\n\t\t\t\t\tcnList.push(cn.partsel);\n\t\t\t\t}\n\t\t\t\tif (FT.evalOption(\"unselectable\", node, node, opts, false)) {\n\t\t\t\t\tcnList.push(cn.unselectable);\n\t\t\t\t}\n\t\t\t\tif (node._isLoading) {\n\t\t\t\t\tcnList.push(cn.loading);\n\t\t\t\t}\n\t\t\t\tif (node._error) {\n\t\t\t\t\tcnList.push(cn.error);\n\t\t\t\t}\n\t\t\t\tif (node.statusNodeType) {\n\t\t\t\t\tcnList.push(cn.statusNodePrefix + node.statusNodeType);\n\t\t\t\t}\n\t\t\t\tif (node.selected) {\n\t\t\t\t\tcnList.push(cn.selected);\n\t\t\t\t\tif (aria) {\n\t\t\t\t\t\t$ariaElem.attr(\"aria-selected\", true);\n\t\t\t\t\t}\n\t\t\t\t} else if (aria) {\n\t\t\t\t\t$ariaElem.attr(\"aria-selected\", false);\n\t\t\t\t}\n\t\t\t\tif (node.extraClasses) {\n\t\t\t\t\tcnList.push(node.extraClasses);\n\t\t\t\t}\n\t\t\t\t// IE6 doesn't correctly evaluate multiple class names,\n\t\t\t\t// so we create combined class names that can be used in the CSS\n\t\t\t\tif (hasChildren === false) {\n\t\t\t\t\tcnList.push(\n\t\t\t\t\t\tcn.combinedExpanderPrefix + \"n\" + (isLastSib ? \"l\" : \"\")\n\t\t\t\t\t);\n\t\t\t\t} else {\n\t\t\t\t\tcnList.push(\n\t\t\t\t\t\tcn.combinedExpanderPrefix +\n\t\t\t\t\t\t\t(node.expanded ? \"e\" : \"c\") +\n\t\t\t\t\t\t\t(node.lazy && node.children == null ? \"d\" : \"\") +\n\t\t\t\t\t\t\t(isLastSib ? \"l\" : \"\")\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\tcnList.push(\n\t\t\t\t\tcn.combinedIconPrefix +\n\t\t\t\t\t\t(node.expanded ? \"e\" : \"c\") +\n\t\t\t\t\t\t(node.folder ? \"f\" : \"\")\n\t\t\t\t);\n\t\t\t\t//        node.span.className = cnList.join(\" \");\n\t\t\t\tstatusElem.className = cnList.join(\" \");\n\n\t\t\t\t// TODO: we should not set this in the <span> tag also, if we set it here:\n\t\t\t\t// Maybe most (all) of the classes should be set in LI instead of SPAN?\n\t\t\t\tif (node.li) {\n\t\t\t\t\t// #719: we have to consider that there may be already other classes:\n\t\t\t\t\t$(node.li).toggleClass(cn.lastsib, isLastSib);\n\t\t\t\t}\n\t\t\t},\n\t\t\t/** Activate node.\n\t\t\t * flag defaults to true.\n\t\t\t * If flag is true, the node is activated (must be a synchronous operation)\n\t\t\t * If flag is false, the node is deactivated (must be a synchronous operation)\n\t\t\t * @param {EventData} ctx\n\t\t\t * @param {boolean} [flag=true]\n\t\t\t * @param {object} [opts] additional options. Defaults to {noEvents: false, noFocus: false}\n\t\t\t * @returns {$.Promise}\n\t\t\t */\n\t\t\tnodeSetActive: function(ctx, flag, callOpts) {\n\t\t\t\t// Handle user click / [space] / [enter], according to clickFolderMode.\n\t\t\t\tcallOpts = callOpts || {};\n\t\t\t\tvar subCtx,\n\t\t\t\t\tnode = ctx.node,\n\t\t\t\t\ttree = ctx.tree,\n\t\t\t\t\topts = ctx.options,\n\t\t\t\t\tnoEvents = callOpts.noEvents === true,\n\t\t\t\t\tnoFocus = callOpts.noFocus === true,\n\t\t\t\t\tscroll = callOpts.scrollIntoView !== false,\n\t\t\t\t\tisActive = node === tree.activeNode;\n\n\t\t\t\t// flag defaults to true\n\t\t\t\tflag = flag !== false;\n\t\t\t\t// node.debug(\"nodeSetActive\", flag);\n\n\t\t\t\tif (isActive === flag) {\n\t\t\t\t\t// Nothing to do\n\t\t\t\t\treturn _getResolvedPromise(node);\n\t\t\t\t} else if (\n\t\t\t\t\tflag &&\n\t\t\t\t\t!noEvents &&\n\t\t\t\t\tthis._triggerNodeEvent(\n\t\t\t\t\t\t\"beforeActivate\",\n\t\t\t\t\t\tnode,\n\t\t\t\t\t\tctx.originalEvent\n\t\t\t\t\t) === false\n\t\t\t\t) {\n\t\t\t\t\t// Callback returned false\n\t\t\t\t\treturn _getRejectedPromise(node, [\"rejected\"]);\n\t\t\t\t}\n\t\t\t\tif (flag) {\n\t\t\t\t\tif (tree.activeNode) {\n\t\t\t\t\t\t_assert(\n\t\t\t\t\t\t\ttree.activeNode !== node,\n\t\t\t\t\t\t\t\"node was active (inconsistency)\"\n\t\t\t\t\t\t);\n\t\t\t\t\t\tsubCtx = $.extend({}, ctx, { node: tree.activeNode });\n\t\t\t\t\t\ttree.nodeSetActive(subCtx, false);\n\t\t\t\t\t\t_assert(\n\t\t\t\t\t\t\ttree.activeNode === null,\n\t\t\t\t\t\t\t\"deactivate was out of sync?\"\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\n\t\t\t\t\tif (opts.activeVisible) {\n\t\t\t\t\t\t// If no focus is set (noFocus: true) and there is no focused node, this node is made visible.\n\t\t\t\t\t\t// scroll = noFocus && tree.focusNode == null;\n\t\t\t\t\t\t// #863: scroll by default (unless `scrollIntoView: false` was passed)\n\t\t\t\t\t\tnode.makeVisible({ scrollIntoView: scroll });\n\t\t\t\t\t}\n\t\t\t\t\ttree.activeNode = node;\n\t\t\t\t\ttree.nodeRenderStatus(ctx);\n\t\t\t\t\tif (!noFocus) {\n\t\t\t\t\t\ttree.nodeSetFocus(ctx);\n\t\t\t\t\t}\n\t\t\t\t\tif (!noEvents) {\n\t\t\t\t\t\ttree._triggerNodeEvent(\n\t\t\t\t\t\t\t\"activate\",\n\t\t\t\t\t\t\tnode,\n\t\t\t\t\t\t\tctx.originalEvent\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\t_assert(\n\t\t\t\t\t\ttree.activeNode === node,\n\t\t\t\t\t\t\"node was not active (inconsistency)\"\n\t\t\t\t\t);\n\t\t\t\t\ttree.activeNode = null;\n\t\t\t\t\tthis.nodeRenderStatus(ctx);\n\t\t\t\t\tif (!noEvents) {\n\t\t\t\t\t\tctx.tree._triggerNodeEvent(\n\t\t\t\t\t\t\t\"deactivate\",\n\t\t\t\t\t\t\tnode,\n\t\t\t\t\t\t\tctx.originalEvent\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn _getResolvedPromise(node);\n\t\t\t},\n\t\t\t/** Expand or collapse node, return Deferred.promise.\n\t\t\t *\n\t\t\t * @param {EventData} ctx\n\t\t\t * @param {boolean} [flag=true]\n\t\t\t * @param {object} [opts] additional options. Defaults to {noAnimation: false, noEvents: false}\n\t\t\t * @returns {$.Promise} The deferred will be resolved as soon as the (lazy)\n\t\t\t *     data was retrieved, rendered, and the expand animation finshed.\n\t\t\t */\n\t\t\tnodeSetExpanded: function(ctx, flag, callOpts) {\n\t\t\t\tcallOpts = callOpts || {};\n\t\t\t\tvar _afterLoad,\n\t\t\t\t\tdfd,\n\t\t\t\t\ti,\n\t\t\t\t\tl,\n\t\t\t\t\tparents,\n\t\t\t\t\tprevAC,\n\t\t\t\t\tnode = ctx.node,\n\t\t\t\t\ttree = ctx.tree,\n\t\t\t\t\topts = ctx.options,\n\t\t\t\t\tnoAnimation = callOpts.noAnimation === true,\n\t\t\t\t\tnoEvents = callOpts.noEvents === true;\n\n\t\t\t\t// flag defaults to true\n\t\t\t\tflag = flag !== false;\n\n\t\t\t\t// node.debug(\"nodeSetExpanded(\" + flag + \")\");\n\n\t\t\t\tif ((node.expanded && flag) || (!node.expanded && !flag)) {\n\t\t\t\t\t// Nothing to do\n\t\t\t\t\t// node.debug(\"nodeSetExpanded(\" + flag + \"): nothing to do\");\n\t\t\t\t\treturn _getResolvedPromise(node);\n\t\t\t\t} else if (flag && !node.lazy && !node.hasChildren()) {\n\t\t\t\t\t// Prevent expanding of empty nodes\n\t\t\t\t\t// return _getRejectedPromise(node, [\"empty\"]);\n\t\t\t\t\treturn _getResolvedPromise(node);\n\t\t\t\t} else if (!flag && node.getLevel() < opts.minExpandLevel) {\n\t\t\t\t\t// Prevent collapsing locked levels\n\t\t\t\t\treturn _getRejectedPromise(node, [\"locked\"]);\n\t\t\t\t} else if (\n\t\t\t\t\t!noEvents &&\n\t\t\t\t\tthis._triggerNodeEvent(\n\t\t\t\t\t\t\"beforeExpand\",\n\t\t\t\t\t\tnode,\n\t\t\t\t\t\tctx.originalEvent\n\t\t\t\t\t) === false\n\t\t\t\t) {\n\t\t\t\t\t// Callback returned false\n\t\t\t\t\treturn _getRejectedPromise(node, [\"rejected\"]);\n\t\t\t\t}\n\t\t\t\t// If this node inside a collpased node, no animation and scrolling is needed\n\t\t\t\tif (!noAnimation && !node.isVisible()) {\n\t\t\t\t\tnoAnimation = callOpts.noAnimation = true;\n\t\t\t\t}\n\n\t\t\t\tdfd = new $.Deferred();\n\n\t\t\t\t// Auto-collapse mode: collapse all siblings\n\t\t\t\tif (flag && !node.expanded && opts.autoCollapse) {\n\t\t\t\t\tparents = node.getParentList(false, true);\n\t\t\t\t\tprevAC = opts.autoCollapse;\n\t\t\t\t\ttry {\n\t\t\t\t\t\topts.autoCollapse = false;\n\t\t\t\t\t\tfor (i = 0, l = parents.length; i < l; i++) {\n\t\t\t\t\t\t\t// TODO: should return promise?\n\t\t\t\t\t\t\tthis._callHook(\n\t\t\t\t\t\t\t\t\"nodeCollapseSiblings\",\n\t\t\t\t\t\t\t\tparents[i],\n\t\t\t\t\t\t\t\tcallOpts\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t}\n\t\t\t\t\t} finally {\n\t\t\t\t\t\topts.autoCollapse = prevAC;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\t// Trigger expand/collapse after expanding\n\t\t\t\tdfd.done(function() {\n\t\t\t\t\tvar lastChild = node.getLastChild();\n\n\t\t\t\t\tif (flag && opts.autoScroll && !noAnimation && lastChild) {\n\t\t\t\t\t\t// Scroll down to last child, but keep current node visible\n\t\t\t\t\t\tlastChild\n\t\t\t\t\t\t\t.scrollIntoView(true, { topNode: node })\n\t\t\t\t\t\t\t.always(function() {\n\t\t\t\t\t\t\t\tif (!noEvents) {\n\t\t\t\t\t\t\t\t\tctx.tree._triggerNodeEvent(\n\t\t\t\t\t\t\t\t\t\tflag ? \"expand\" : \"collapse\",\n\t\t\t\t\t\t\t\t\t\tctx\n\t\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t});\n\t\t\t\t\t} else {\n\t\t\t\t\t\tif (!noEvents) {\n\t\t\t\t\t\t\tctx.tree._triggerNodeEvent(\n\t\t\t\t\t\t\t\tflag ? \"expand\" : \"collapse\",\n\t\t\t\t\t\t\t\tctx\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t\t// vvv Code below is executed after loading finished:\n\t\t\t\t_afterLoad = function(callback) {\n\t\t\t\t\tvar cn = opts._classNames,\n\t\t\t\t\t\tisVisible,\n\t\t\t\t\t\tisExpanded,\n\t\t\t\t\t\teffect = opts.toggleEffect;\n\n\t\t\t\t\tnode.expanded = flag;\n\t\t\t\t\t// Create required markup, but make sure the top UL is hidden, so we\n\t\t\t\t\t// can animate later\n\t\t\t\t\ttree._callHook(\"nodeRender\", ctx, false, false, true);\n\n\t\t\t\t\t// Hide children, if node is collapsed\n\t\t\t\t\tif (node.ul) {\n\t\t\t\t\t\tisVisible = node.ul.style.display !== \"none\";\n\t\t\t\t\t\tisExpanded = !!node.expanded;\n\t\t\t\t\t\tif (isVisible === isExpanded) {\n\t\t\t\t\t\t\tnode.warn(\n\t\t\t\t\t\t\t\t\"nodeSetExpanded: UL.style.display already set\"\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t} else if (!effect || noAnimation) {\n\t\t\t\t\t\t\tnode.ul.style.display =\n\t\t\t\t\t\t\t\tnode.expanded || !parent ? \"\" : \"none\";\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t// The UI toggle() effect works with the ext-wide extension,\n\t\t\t\t\t\t\t// while jQuery.animate() has problems when the title span\n\t\t\t\t\t\t\t// has position: absolute.\n\t\t\t\t\t\t\t// Since jQuery UI 1.12, the blind effect requires the parent\n\t\t\t\t\t\t\t// element to have 'position: relative'.\n\t\t\t\t\t\t\t// See #716, #717\n\t\t\t\t\t\t\t$(node.li).addClass(cn.animating); // #717\n\n\t\t\t\t\t\t\tif (!$.isFunction($(node.ul)[effect.effect])) {\n\t\t\t\t\t\t\t\t// The UI toggle() effect works with the ext-wide extension,\n\t\t\t\t\t\t\t\t// while jQuery.animate() has problems when the title span\n\t\t\t\t\t\t\t\t// has positon: absolute.\n\t\t\t\t\t\t\t\t// Since jQuery UI 1.12, the blind effect requires the parent\n\t\t\t\t\t\t\t\t// element to have 'position: relative'.\n\t\t\t\t\t\t\t\t// See #716, #717\n\t\t\t\t\t\t\t\t// tree.debug(\"use specified effect (\" + effect.effect + \") with the jqueryui.toggle method\");\n\n\t\t\t\t\t\t\t\t// try to stop an animation that might be already in progress\n\t\t\t\t\t\t\t\t$(node.ul).stop(true, true); //< does not work after resetLazy has been called for a node whose animation wasn't complete and effect was \"blind\"\n\n\t\t\t\t\t\t\t\t// dirty fix to remove a defunct animation (effect: \"blind\") after resetLazy has been called\n\t\t\t\t\t\t\t\t$(node.ul)\n\t\t\t\t\t\t\t\t\t.parent()\n\t\t\t\t\t\t\t\t\t.find(\".ui-effects-placeholder\")\n\t\t\t\t\t\t\t\t\t.remove();\n\n\t\t\t\t\t\t\t\t$(node.ul).toggle(\n\t\t\t\t\t\t\t\t\teffect.effect,\n\t\t\t\t\t\t\t\t\teffect.options,\n\t\t\t\t\t\t\t\t\teffect.duration,\n\t\t\t\t\t\t\t\t\tfunction() {\n\t\t\t\t\t\t\t\t\t\t// node.debug(\"fancytree-animating end: \" + node.li.className);\n\t\t\t\t\t\t\t\t\t\t$(this).removeClass(cn.animating); // #716\n\t\t\t\t\t\t\t\t\t\t$(node.li).removeClass(cn.animating); // #717\n\t\t\t\t\t\t\t\t\t\tcallback();\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\ttree.debug(\n\t\t\t\t\t\t\t\t\t\"use jquery.\" + effect.effect + \" method\"\n\t\t\t\t\t\t\t\t);\n\n\t\t\t\t\t\t\t\t$(node.ul)[effect.effect]({\n\t\t\t\t\t\t\t\t\tduration: effect.duration,\n\t\t\t\t\t\t\t\t\talways: function() {\n\t\t\t\t\t\t\t\t\t\t// node.debug(\"fancytree-animating end: \" + node.li.className);\n\t\t\t\t\t\t\t\t\t\t$(this).removeClass(cn.animating); // #716\n\t\t\t\t\t\t\t\t\t\t$(node.li).removeClass(cn.animating); // #717\n\t\t\t\t\t\t\t\t\t\tcallback();\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tcallback();\n\t\t\t\t};\n\t\t\t\t// ^^^ Code above is executed after loading finshed.\n\n\t\t\t\t// Load lazy nodes, if any. Then continue with _afterLoad()\n\t\t\t\tif (flag && node.lazy && node.hasChildren() === undefined) {\n\t\t\t\t\t// node.debug(\"nodeSetExpanded: load start...\");\n\t\t\t\t\tnode.load()\n\t\t\t\t\t\t.done(function() {\n\t\t\t\t\t\t\t// node.debug(\"nodeSetExpanded: load done\");\n\t\t\t\t\t\t\tif (dfd.notifyWith) {\n\t\t\t\t\t\t\t\t// requires jQuery 1.6+\n\t\t\t\t\t\t\t\tdfd.notifyWith(node, [\"loaded\"]);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t_afterLoad(function() {\n\t\t\t\t\t\t\t\tdfd.resolveWith(node);\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t})\n\t\t\t\t\t\t.fail(function(errMsg) {\n\t\t\t\t\t\t\t_afterLoad(function() {\n\t\t\t\t\t\t\t\tdfd.rejectWith(node, [\n\t\t\t\t\t\t\t\t\t\"load failed (\" + errMsg + \")\",\n\t\t\t\t\t\t\t\t]);\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t});\n\t\t\t\t\t/*\n\t\t\tvar source = tree._triggerNodeEvent(\"lazyLoad\", node, ctx.originalEvent);\n\t\t\t_assert(typeof source !== \"boolean\", \"lazyLoad event must return source in data.result\");\n\t\t\tnode.debug(\"nodeSetExpanded: load start...\");\n\t\t\tthis._callHook(\"nodeLoadChildren\", ctx, source).done(function(){\n\t\t\t\tnode.debug(\"nodeSetExpanded: load done\");\n\t\t\t\tif(dfd.notifyWith){ // requires jQuery 1.6+\n\t\t\t\t\tdfd.notifyWith(node, [\"loaded\"]);\n\t\t\t\t}\n\t\t\t\t_afterLoad.call(tree);\n\t\t\t}).fail(function(errMsg){\n\t\t\t\tdfd.rejectWith(node, [\"load failed (\" + errMsg + \")\"]);\n\t\t\t});\n*/\n\t\t\t\t} else {\n\t\t\t\t\t_afterLoad(function() {\n\t\t\t\t\t\tdfd.resolveWith(node);\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t\t// node.debug(\"nodeSetExpanded: returns\");\n\t\t\t\treturn dfd.promise();\n\t\t\t},\n\t\t\t/** Focus or blur this node.\n\t\t\t * @param {EventData} ctx\n\t\t\t * @param {boolean} [flag=true]\n\t\t\t */\n\t\t\tnodeSetFocus: function(ctx, flag) {\n\t\t\t\t// ctx.node.debug(\"nodeSetFocus(\" + flag + \")\");\n\t\t\t\tvar ctx2,\n\t\t\t\t\ttree = ctx.tree,\n\t\t\t\t\tnode = ctx.node,\n\t\t\t\t\topts = tree.options,\n\t\t\t\t\t// et = ctx.originalEvent && ctx.originalEvent.type,\n\t\t\t\t\tisInput = ctx.originalEvent\n\t\t\t\t\t\t? $(ctx.originalEvent.target).is(\":input\")\n\t\t\t\t\t\t: false;\n\n\t\t\t\tflag = flag !== false;\n\n\t\t\t\t// (node || tree).debug(\"nodeSetFocus(\" + flag + \"), event: \" + et + \", isInput: \"+ isInput);\n\t\t\t\t// Blur previous node if any\n\t\t\t\tif (tree.focusNode) {\n\t\t\t\t\tif (tree.focusNode === node && flag) {\n\t\t\t\t\t\t// node.debug(\"nodeSetFocus(\" + flag + \"): nothing to do\");\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t\tctx2 = $.extend({}, ctx, { node: tree.focusNode });\n\t\t\t\t\ttree.focusNode = null;\n\t\t\t\t\tthis._triggerNodeEvent(\"blur\", ctx2);\n\t\t\t\t\tthis._callHook(\"nodeRenderStatus\", ctx2);\n\t\t\t\t}\n\t\t\t\t// Set focus to container and node\n\t\t\t\tif (flag) {\n\t\t\t\t\tif (!this.hasFocus()) {\n\t\t\t\t\t\tnode.debug(\"nodeSetFocus: forcing container focus\");\n\t\t\t\t\t\tthis._callHook(\"treeSetFocus\", ctx, true, {\n\t\t\t\t\t\t\tcalledByNode: true,\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\t\t\t\t\tnode.makeVisible({ scrollIntoView: false });\n\t\t\t\t\ttree.focusNode = node;\n\t\t\t\t\tif (opts.titlesTabbable) {\n\t\t\t\t\t\tif (!isInput) {\n\t\t\t\t\t\t\t// #621\n\t\t\t\t\t\t\t$(node.span)\n\t\t\t\t\t\t\t\t.find(\".fancytree-title\")\n\t\t\t\t\t\t\t\t.focus();\n\t\t\t\t\t\t}\n\t\t\t\t\t} else {\n\t\t\t\t\t\t// We cannot set KB focus to a node, so use the tree container\n\t\t\t\t\t\t// #563, #570: IE scrolls on every call to .focus(), if the container\n\t\t\t\t\t\t// is partially outside the viewport. So do it only, when absolutely\n\t\t\t\t\t\t// neccessary:\n\t\t\t\t\t\tif (\n\t\t\t\t\t\t\t$(document.activeElement).closest(\n\t\t\t\t\t\t\t\t\".fancytree-container\"\n\t\t\t\t\t\t\t).length === 0\n\t\t\t\t\t\t) {\n\t\t\t\t\t\t\t$(tree.$container).focus();\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tif (opts.aria) {\n\t\t\t\t\t\t// Set active descendant to node's span ID (create one, if needed)\n\t\t\t\t\t\t$(tree.$container).attr(\n\t\t\t\t\t\t\t\"aria-activedescendant\",\n\t\t\t\t\t\t\t$(node.tr || node.li)\n\t\t\t\t\t\t\t\t.uniqueId()\n\t\t\t\t\t\t\t\t.attr(\"id\")\n\t\t\t\t\t\t);\n\t\t\t\t\t\t// \"ftal_\" + opts.idPrefix + node.key);\n\t\t\t\t\t}\n\t\t\t\t\t//\t\t\t$(node.span).find(\".fancytree-title\").focus();\n\t\t\t\t\tthis._triggerNodeEvent(\"focus\", ctx);\n\t\t\t\t\t//          if( opts.autoActivate ){\n\t\t\t\t\t//              tree.nodeSetActive(ctx, true);\n\t\t\t\t\t//          }\n\t\t\t\t\tif (opts.autoScroll) {\n\t\t\t\t\t\tnode.scrollIntoView();\n\t\t\t\t\t}\n\t\t\t\t\tthis._callHook(\"nodeRenderStatus\", ctx);\n\t\t\t\t}\n\t\t\t},\n\t\t\t/** (De)Select node, return new status (sync).\n\t\t\t *\n\t\t\t * @param {EventData} ctx\n\t\t\t * @param {boolean} [flag=true]\n\t\t\t * @param {object} [opts] additional options. Defaults to {noEvents: false,\n\t\t\t *     propagateDown: null, propagateUp: null,\n\t\t\t *     callback: null,\n\t\t\t *     }\n\t\t\t * @returns {boolean} previous status\n\t\t\t */\n\t\t\tnodeSetSelected: function(ctx, flag, callOpts) {\n\t\t\t\tcallOpts = callOpts || {};\n\t\t\t\tvar node = ctx.node,\n\t\t\t\t\ttree = ctx.tree,\n\t\t\t\t\topts = ctx.options,\n\t\t\t\t\tnoEvents = callOpts.noEvents === true,\n\t\t\t\t\tparent = node.parent;\n\n\t\t\t\t// flag defaults to true\n\t\t\t\tflag = flag !== false;\n\n\t\t\t\t// node.debug(\"nodeSetSelected(\" + flag + \")\", ctx);\n\n\t\t\t\t// Cannot (de)select unselectable nodes directly (only by propagation or\n\t\t\t\t// by setting the `.selected` property)\n\t\t\t\tif (FT.evalOption(\"unselectable\", node, node, opts, false)) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\t// Remember the user's intent, in case down -> up propagation prevents\n\t\t\t\t// applying it to node.selected\n\t\t\t\tnode._lastSelectIntent = flag; // Confusing use of '!'\n\n\t\t\t\t// Nothing to do?\n\t\t\t\t/*jshint -W018 */ if (!!node.selected === flag) {\n\t\t\t\t\tif (opts.selectMode === 3 && node.partsel && !flag) {\n\t\t\t\t\t\t// If propagation prevented selecting this node last time, we still\n\t\t\t\t\t\t// want to allow to apply setSelected(false) now\n\t\t\t\t\t} else {\n\t\t\t\t\t\treturn flag;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\t/*jshint +W018 */\n\n\t\t\t\tif (\n\t\t\t\t\t!noEvents &&\n\t\t\t\t\tthis._triggerNodeEvent(\n\t\t\t\t\t\t\"beforeSelect\",\n\t\t\t\t\t\tnode,\n\t\t\t\t\t\tctx.originalEvent\n\t\t\t\t\t) === false\n\t\t\t\t) {\n\t\t\t\t\treturn !!node.selected;\n\t\t\t\t}\n\t\t\t\tif (flag && opts.selectMode === 1) {\n\t\t\t\t\t// single selection mode (we don't uncheck all tree nodes, for performance reasons)\n\t\t\t\t\tif (tree.lastSelectedNode) {\n\t\t\t\t\t\ttree.lastSelectedNode.setSelected(false);\n\t\t\t\t\t}\n\t\t\t\t\tnode.selected = flag;\n\t\t\t\t} else if (\n\t\t\t\t\topts.selectMode === 3 &&\n\t\t\t\t\tparent &&\n\t\t\t\t\t!parent.radiogroup &&\n\t\t\t\t\t!node.radiogroup\n\t\t\t\t) {\n\t\t\t\t\t// multi-hierarchical selection mode\n\t\t\t\t\tnode.selected = flag;\n\t\t\t\t\tnode.fixSelection3AfterClick(callOpts);\n\t\t\t\t} else if (parent && parent.radiogroup) {\n\t\t\t\t\tnode.visitSiblings(function(n) {\n\t\t\t\t\t\tn._changeSelectStatusAttrs(flag && n === node);\n\t\t\t\t\t}, true);\n\t\t\t\t} else {\n\t\t\t\t\t// default: selectMode: 2, multi selection mode\n\t\t\t\t\tnode.selected = flag;\n\t\t\t\t}\n\t\t\t\tthis.nodeRenderStatus(ctx);\n\t\t\t\ttree.lastSelectedNode = flag ? node : null;\n\t\t\t\tif (!noEvents) {\n\t\t\t\t\ttree._triggerNodeEvent(\"select\", ctx);\n\t\t\t\t}\n\t\t\t},\n\t\t\t/** Show node status (ok, loading, error, nodata) using styles and a dummy child node.\n\t\t\t *\n\t\t\t * @param {EventData} ctx\n\t\t\t * @param status\n\t\t\t * @param message\n\t\t\t * @param details\n\t\t\t * @since 2.3\n\t\t\t */\n\t\t\tnodeSetStatus: function(ctx, status, message, details) {\n\t\t\t\tvar node = ctx.node,\n\t\t\t\t\ttree = ctx.tree;\n\n\t\t\t\tfunction _clearStatusNode() {\n\t\t\t\t\t// Remove dedicated dummy node, if any\n\t\t\t\t\tvar firstChild = node.children ? node.children[0] : null;\n\t\t\t\t\tif (firstChild && firstChild.isStatusNode()) {\n\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\t// I've seen exceptions here with loadKeyPath...\n\t\t\t\t\t\t\tif (node.ul) {\n\t\t\t\t\t\t\t\tnode.ul.removeChild(firstChild.li);\n\t\t\t\t\t\t\t\tfirstChild.li = null; // avoid leaks (DT issue 215)\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} catch (e) {}\n\t\t\t\t\t\tif (node.children.length === 1) {\n\t\t\t\t\t\t\tnode.children = [];\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tnode.children.shift();\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tfunction _setStatusNode(data, type) {\n\t\t\t\t\t// Create/modify the dedicated dummy node for 'loading...' or\n\t\t\t\t\t// 'error!' status. (only called for direct child of the invisible\n\t\t\t\t\t// system root)\n\t\t\t\t\tvar firstChild = node.children ? node.children[0] : null;\n\t\t\t\t\tif (firstChild && firstChild.isStatusNode()) {\n\t\t\t\t\t\t$.extend(firstChild, data);\n\t\t\t\t\t\tfirstChild.statusNodeType = type;\n\t\t\t\t\t\ttree._callHook(\"nodeRenderTitle\", firstChild);\n\t\t\t\t\t} else {\n\t\t\t\t\t\tnode._setChildren([data]);\n\t\t\t\t\t\tnode.children[0].statusNodeType = type;\n\t\t\t\t\t\ttree.render();\n\t\t\t\t\t}\n\t\t\t\t\treturn node.children[0];\n\t\t\t\t}\n\n\t\t\t\tswitch (status) {\n\t\t\t\t\tcase \"ok\":\n\t\t\t\t\t\t_clearStatusNode();\n\t\t\t\t\t\tnode._isLoading = false;\n\t\t\t\t\t\tnode._error = null;\n\t\t\t\t\t\tnode.renderStatus();\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"loading\":\n\t\t\t\t\t\tif (!node.parent) {\n\t\t\t\t\t\t\t_setStatusNode(\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\ttitle:\n\t\t\t\t\t\t\t\t\t\ttree.options.strings.loading +\n\t\t\t\t\t\t\t\t\t\t(message ? \" (\" + message + \")\" : \"\"),\n\t\t\t\t\t\t\t\t\t// icon: true,  // needed for 'loding' icon\n\t\t\t\t\t\t\t\t\tcheckbox: false,\n\t\t\t\t\t\t\t\t\ttooltip: details,\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\tstatus\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tnode._isLoading = true;\n\t\t\t\t\t\tnode._error = null;\n\t\t\t\t\t\tnode.renderStatus();\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"error\":\n\t\t\t\t\t\t_setStatusNode(\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\ttitle:\n\t\t\t\t\t\t\t\t\ttree.options.strings.loadError +\n\t\t\t\t\t\t\t\t\t(message ? \" (\" + message + \")\" : \"\"),\n\t\t\t\t\t\t\t\t// icon: false,\n\t\t\t\t\t\t\t\tcheckbox: false,\n\t\t\t\t\t\t\t\ttooltip: details,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\tstatus\n\t\t\t\t\t\t);\n\t\t\t\t\t\tnode._isLoading = false;\n\t\t\t\t\t\tnode._error = { message: message, details: details };\n\t\t\t\t\t\tnode.renderStatus();\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"nodata\":\n\t\t\t\t\t\t_setStatusNode(\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\ttitle: message || tree.options.strings.noData,\n\t\t\t\t\t\t\t\t// icon: false,\n\t\t\t\t\t\t\t\tcheckbox: false,\n\t\t\t\t\t\t\t\ttooltip: details,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\tstatus\n\t\t\t\t\t\t);\n\t\t\t\t\t\tnode._isLoading = false;\n\t\t\t\t\t\tnode._error = null;\n\t\t\t\t\t\tnode.renderStatus();\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tdefault:\n\t\t\t\t\t\t$.error(\"invalid node status \" + status);\n\t\t\t\t}\n\t\t\t},\n\t\t\t/**\n\t\t\t *\n\t\t\t * @param {EventData} ctx\n\t\t\t */\n\t\t\tnodeToggleExpanded: function(ctx) {\n\t\t\t\treturn this.nodeSetExpanded(ctx, !ctx.node.expanded);\n\t\t\t},\n\t\t\t/**\n\t\t\t * @param {EventData} ctx\n\t\t\t */\n\t\t\tnodeToggleSelected: function(ctx) {\n\t\t\t\tvar node = ctx.node,\n\t\t\t\t\tflag = !node.selected;\n\n\t\t\t\t// In selectMode: 3 this node may be unselected+partsel, even if\n\t\t\t\t// setSelected(true) was called before, due to `unselectable` children.\n\t\t\t\t// In this case, we now toggle as `setSelected(false)`\n\t\t\t\tif (\n\t\t\t\t\tnode.partsel &&\n\t\t\t\t\t!node.selected &&\n\t\t\t\t\tnode._lastSelectIntent === true\n\t\t\t\t) {\n\t\t\t\t\tflag = false;\n\t\t\t\t\tnode.selected = true; // so it is not considered 'nothing to do'\n\t\t\t\t}\n\t\t\t\tnode._lastSelectIntent = flag;\n\t\t\t\treturn this.nodeSetSelected(ctx, flag);\n\t\t\t},\n\t\t\t/** Remove all nodes.\n\t\t\t * @param {EventData} ctx\n\t\t\t */\n\t\t\ttreeClear: function(ctx) {\n\t\t\t\tvar tree = ctx.tree;\n\t\t\t\ttree.activeNode = null;\n\t\t\t\ttree.focusNode = null;\n\t\t\t\ttree.$div.find(\">ul.fancytree-container\").empty();\n\t\t\t\t// TODO: call destructors and remove reference loops\n\t\t\t\ttree.rootNode.children = null;\n\t\t\t},\n\t\t\t/** Widget was created (called only once, even it re-initialized).\n\t\t\t * @param {EventData} ctx\n\t\t\t */\n\t\t\ttreeCreate: function(ctx) {},\n\t\t\t/** Widget was destroyed.\n\t\t\t * @param {EventData} ctx\n\t\t\t */\n\t\t\ttreeDestroy: function(ctx) {\n\t\t\t\tthis.$div.find(\">ul.fancytree-container\").remove();\n\t\t\t\tthis.$source &&\n\t\t\t\t\tthis.$source.removeClass(\"fancytree-helper-hidden\");\n\t\t\t},\n\t\t\t/** Widget was (re-)initialized.\n\t\t\t * @param {EventData} ctx\n\t\t\t */\n\t\t\ttreeInit: function(ctx) {\n\t\t\t\tvar tree = ctx.tree,\n\t\t\t\t\topts = tree.options;\n\n\t\t\t\t//this.debug(\"Fancytree.treeInit()\");\n\t\t\t\t// Add container to the TAB chain\n\t\t\t\t// See http://www.w3.org/TR/wai-aria-practices/#focus_activedescendant\n\t\t\t\t// #577: Allow to set tabindex to \"0\", \"-1\" and \"\"\n\t\t\t\ttree.$container.attr(\"tabindex\", opts.tabindex);\n\n\t\t\t\t// Copy some attributes to tree.data\n\t\t\t\t$.each(TREE_ATTRS, function(i, attr) {\n\t\t\t\t\tif (opts[attr] !== undefined) {\n\t\t\t\t\t\ttree.info(\"Move option \" + attr + \" to tree\");\n\t\t\t\t\t\ttree[attr] = opts[attr];\n\t\t\t\t\t\tdelete opts[attr];\n\t\t\t\t\t}\n\t\t\t\t});\n\n\t\t\t\tif (opts.rtl) {\n\t\t\t\t\ttree.$container\n\t\t\t\t\t\t.attr(\"DIR\", \"RTL\")\n\t\t\t\t\t\t.addClass(\"fancytree-rtl\");\n\t\t\t\t} else {\n\t\t\t\t\ttree.$container\n\t\t\t\t\t\t.removeAttr(\"DIR\")\n\t\t\t\t\t\t.removeClass(\"fancytree-rtl\");\n\t\t\t\t}\n\t\t\t\tif (opts.aria) {\n\t\t\t\t\ttree.$container.attr(\"role\", \"tree\");\n\t\t\t\t\tif (opts.selectMode !== 1) {\n\t\t\t\t\t\ttree.$container.attr(\"aria-multiselectable\", true);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tthis.treeLoad(ctx);\n\t\t\t},\n\t\t\t/** Parse Fancytree from source, as configured in the options.\n\t\t\t * @param {EventData} ctx\n\t\t\t * @param {object} [source] optional new source (use last data otherwise)\n\t\t\t */\n\t\t\ttreeLoad: function(ctx, source) {\n\t\t\t\tvar metaData,\n\t\t\t\t\ttype,\n\t\t\t\t\t$ul,\n\t\t\t\t\ttree = ctx.tree,\n\t\t\t\t\t$container = ctx.widget.element,\n\t\t\t\t\tdfd,\n\t\t\t\t\t// calling context for root node\n\t\t\t\t\trootCtx = $.extend({}, ctx, { node: this.rootNode });\n\n\t\t\t\tif (tree.rootNode.children) {\n\t\t\t\t\tthis.treeClear(ctx);\n\t\t\t\t}\n\t\t\t\tsource = source || this.options.source;\n\n\t\t\t\tif (!source) {\n\t\t\t\t\ttype = $container.data(\"type\") || \"html\";\n\t\t\t\t\tswitch (type) {\n\t\t\t\t\t\tcase \"html\":\n\t\t\t\t\t\t\t$ul = $container.find(\">ul:first\");\n\t\t\t\t\t\t\t$ul.addClass(\n\t\t\t\t\t\t\t\t\"ui-fancytree-source fancytree-helper-hidden\"\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\tsource = $.ui.fancytree.parseHtml($ul);\n\t\t\t\t\t\t\t// allow to init tree.data.foo from <ul data-foo=''>\n\t\t\t\t\t\t\tthis.data = $.extend(\n\t\t\t\t\t\t\t\tthis.data,\n\t\t\t\t\t\t\t\t_getElementDataAsDict($ul)\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase \"json\":\n\t\t\t\t\t\t\tsource = $.parseJSON($container.text());\n\t\t\t\t\t\t\t// $container already contains the <ul>, but we remove the plain (json) text\n\t\t\t\t\t\t\t// $container.empty();\n\t\t\t\t\t\t\t$container\n\t\t\t\t\t\t\t\t.contents()\n\t\t\t\t\t\t\t\t.filter(function() {\n\t\t\t\t\t\t\t\t\treturn this.nodeType === 3;\n\t\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\t\t.remove();\n\t\t\t\t\t\t\tif ($.isPlainObject(source)) {\n\t\t\t\t\t\t\t\t// We got {foo: 'abc', children: [...]}\n\t\t\t\t\t\t\t\t_assert(\n\t\t\t\t\t\t\t\t\t$.isArray(source.children),\n\t\t\t\t\t\t\t\t\t\"if an object is passed as source, it must contain a 'children' array (all other properties are added to 'tree.data')\"\n\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t\tmetaData = source;\n\t\t\t\t\t\t\t\tsource = source.children;\n\t\t\t\t\t\t\t\tdelete metaData.children;\n\t\t\t\t\t\t\t\t// Copy some attributes to tree.data\n\t\t\t\t\t\t\t\t$.each(TREE_ATTRS, function(i, attr) {\n\t\t\t\t\t\t\t\t\tif (metaData[attr] !== undefined) {\n\t\t\t\t\t\t\t\t\t\ttree[attr] = metaData[attr];\n\t\t\t\t\t\t\t\t\t\tdelete metaData[attr];\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\t\t// Copy extra properties to tree.data.foo\n\t\t\t\t\t\t\t\t$.extend(tree.data, metaData);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tdefault:\n\t\t\t\t\t\t\t$.error(\"Invalid data-type: \" + type);\n\t\t\t\t\t}\n\t\t\t\t} else if (typeof source === \"string\") {\n\t\t\t\t\t// TODO: source is an element ID\n\t\t\t\t\t$.error(\"Not implemented\");\n\t\t\t\t}\n\n\t\t\t\t// Trigger fancytreeinit after nodes have been loaded\n\t\t\t\tdfd = this.nodeLoadChildren(rootCtx, source)\n\t\t\t\t\t.done(function() {\n\t\t\t\t\t\ttree.render();\n\t\t\t\t\t\tif (ctx.options.selectMode === 3) {\n\t\t\t\t\t\t\ttree.rootNode.fixSelection3FromEndNodes();\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (tree.activeNode && tree.options.activeVisible) {\n\t\t\t\t\t\t\ttree.activeNode.makeVisible();\n\t\t\t\t\t\t}\n\t\t\t\t\t\ttree._triggerTreeEvent(\"init\", null, { status: true });\n\t\t\t\t\t})\n\t\t\t\t\t.fail(function() {\n\t\t\t\t\t\ttree.render();\n\t\t\t\t\t\ttree._triggerTreeEvent(\"init\", null, { status: false });\n\t\t\t\t\t});\n\t\t\t\treturn dfd;\n\t\t\t},\n\t\t\t/** Node was inserted into or removed from the tree.\n\t\t\t * @param {EventData} ctx\n\t\t\t * @param {boolean} add\n\t\t\t * @param {FancytreeNode} node\n\t\t\t */\n\t\t\ttreeRegisterNode: function(ctx, add, node) {},\n\t\t\t/** Widget got focus.\n\t\t\t * @param {EventData} ctx\n\t\t\t * @param {boolean} [flag=true]\n\t\t\t */\n\t\t\ttreeSetFocus: function(ctx, flag, callOpts) {\n\t\t\t\tvar targetNode;\n\n\t\t\t\tflag = flag !== false;\n\n\t\t\t\t// this.debug(\"treeSetFocus(\" + flag + \"), callOpts: \", callOpts, this.hasFocus());\n\t\t\t\t// this.debug(\"    focusNode: \" + this.focusNode);\n\t\t\t\t// this.debug(\"    activeNode: \" + this.activeNode);\n\t\t\t\tif (flag !== this.hasFocus()) {\n\t\t\t\t\tthis._hasFocus = flag;\n\t\t\t\t\tif (!flag && this.focusNode) {\n\t\t\t\t\t\t// Node also looses focus if widget blurs\n\t\t\t\t\t\tthis.focusNode.setFocus(false);\n\t\t\t\t\t} else if (flag && (!callOpts || !callOpts.calledByNode)) {\n\t\t\t\t\t\t$(this.$container).focus();\n\t\t\t\t\t}\n\t\t\t\t\tthis.$container.toggleClass(\"fancytree-treefocus\", flag);\n\t\t\t\t\tthis._triggerTreeEvent(flag ? \"focusTree\" : \"blurTree\");\n\t\t\t\t\tif (flag && !this.activeNode) {\n\t\t\t\t\t\t// #712: Use last mousedowned node ('click' event fires after focusin)\n\t\t\t\t\t\ttargetNode =\n\t\t\t\t\t\t\tthis._lastMousedownNode || this.getFirstChild();\n\t\t\t\t\t\ttargetNode && targetNode.setFocus();\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t},\n\t\t\t/** Widget option was set using `$().fancytree(\"option\", \"KEY\", VALUE)`.\n\t\t\t *\n\t\t\t * Note: `key` may reference a nested option, e.g. 'dnd5.scroll'.\n\t\t\t * In this case `value`contains the complete, modified `dnd5` option hash.\n\t\t\t * We can check for changed values like\n\t\t\t *     if( value.scroll !== tree.options.dnd5.scroll ) {...}\n\t\t\t *\n\t\t\t * @param {EventData} ctx\n\t\t\t * @param {string} key option name\n\t\t\t * @param {any} value option value\n\t\t\t */\n\t\t\ttreeSetOption: function(ctx, key, value) {\n\t\t\t\tvar tree = ctx.tree,\n\t\t\t\t\tcallDefault = true,\n\t\t\t\t\tcallCreate = false,\n\t\t\t\t\tcallRender = false;\n\n\t\t\t\tswitch (key) {\n\t\t\t\t\tcase \"aria\":\n\t\t\t\t\tcase \"checkbox\":\n\t\t\t\t\tcase \"icon\":\n\t\t\t\t\tcase \"minExpandLevel\":\n\t\t\t\t\tcase \"tabindex\":\n\t\t\t\t\t\t// tree._callHook(\"treeCreate\", tree);\n\t\t\t\t\t\tcallCreate = true;\n\t\t\t\t\t\tcallRender = true;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"escapeTitles\":\n\t\t\t\t\tcase \"tooltip\":\n\t\t\t\t\t\tcallRender = true;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"rtl\":\n\t\t\t\t\t\tif (value === false) {\n\t\t\t\t\t\t\ttree.$container\n\t\t\t\t\t\t\t\t.removeAttr(\"DIR\")\n\t\t\t\t\t\t\t\t.removeClass(\"fancytree-rtl\");\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\ttree.$container\n\t\t\t\t\t\t\t\t.attr(\"DIR\", \"RTL\")\n\t\t\t\t\t\t\t\t.addClass(\"fancytree-rtl\");\n\t\t\t\t\t\t}\n\t\t\t\t\t\tcallRender = true;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"source\":\n\t\t\t\t\t\tcallDefault = false;\n\t\t\t\t\t\ttree._callHook(\"treeLoad\", tree, value);\n\t\t\t\t\t\tcallRender = true;\n\t\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\ttree.debug(\n\t\t\t\t\t\"set option \" +\n\t\t\t\t\t\tkey +\n\t\t\t\t\t\t\"=\" +\n\t\t\t\t\t\tvalue +\n\t\t\t\t\t\t\" <\" +\n\t\t\t\t\t\ttypeof value +\n\t\t\t\t\t\t\">\"\n\t\t\t\t);\n\t\t\t\tif (callDefault) {\n\t\t\t\t\tif (this.widget._super) {\n\t\t\t\t\t\t// jQuery UI 1.9+\n\t\t\t\t\t\tthis.widget._super.call(this.widget, key, value);\n\t\t\t\t\t} else {\n\t\t\t\t\t\t// jQuery UI <= 1.8, we have to manually invoke the _setOption method from the base widget\n\t\t\t\t\t\t$.Widget.prototype._setOption.call(\n\t\t\t\t\t\t\tthis.widget,\n\t\t\t\t\t\t\tkey,\n\t\t\t\t\t\t\tvalue\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif (callCreate) {\n\t\t\t\t\ttree._callHook(\"treeCreate\", tree);\n\t\t\t\t}\n\t\t\t\tif (callRender) {\n\t\t\t\t\ttree.render(true, false); // force, not-deep\n\t\t\t\t}\n\t\t\t},\n\t\t}\n\t);\n\n\t/*******************************************************************************\n\t * jQuery UI widget boilerplate\n\t */\n\n\t/**\n\t * The plugin (derrived from <a href=\" http://api.jqueryui.com/jQuery.widget/\">jQuery.Widget</a>).<br>\n\t * This constructor is not called directly. Use `$(selector).fancytree({})`\n\t * to initialize the plugin instead.<br>\n\t * <pre class=\"sh_javascript sunlight-highlight-javascript\">// Access widget methods and members:\n\t * var tree = $(\"#tree\").fancytree(\"getTree\");\n\t * var node = $(\"#tree\").fancytree(\"getActiveNode\", \"1234\");\n\t * </pre>\n\t *\n\t * @mixin Fancytree_Widget\n\t */\n\n\t$.widget(\n\t\t\"ui.fancytree\",\n\t\t/** @lends Fancytree_Widget# */\n\t\t{\n\t\t\t/**These options will be used as defaults\n\t\t\t * @type {FancytreeOptions}\n\t\t\t */\n\t\t\toptions: {\n\t\t\t\tactiveVisible: true,\n\t\t\t\tajax: {\n\t\t\t\t\ttype: \"GET\",\n\t\t\t\t\tcache: false, // false: Append random '_' argument to the request url to prevent caching.\n\t\t\t\t\t//          timeout: 0, // >0: Make sure we get an ajax error if server is unreachable\n\t\t\t\t\tdataType: \"json\", // Expect json format and pass json object to callbacks.\n\t\t\t\t}, //\n\t\t\t\taria: true,\n\t\t\t\tautoActivate: true,\n\t\t\t\tautoCollapse: false,\n\t\t\t\tautoScroll: false,\n\t\t\t\tcheckbox: false,\n\t\t\t\tclickFolderMode: 4,\n\t\t\t\tdebugLevel: null, // 0..4 (null: use global setting $.ui.fancytree.debugInfo)\n\t\t\t\tdisabled: false, // TODO: required anymore?\n\t\t\t\tenableAspx: true,\n\t\t\t\tescapeTitles: false,\n\t\t\t\textensions: [],\n\t\t\t\t// fx: { height: \"toggle\", duration: 200 },\n\t\t\t\t// toggleEffect: { effect: \"drop\", options: {direction: \"left\"}, duration: 200 },\n\t\t\t\t// toggleEffect: { effect: \"slide\", options: {direction: \"up\"}, duration: 200 },\n\t\t\t\t//toggleEffect: { effect: \"blind\", options: {direction: \"vertical\", scale: \"box\"}, duration: 200 },\n\t\t\t\ttoggleEffect: { effect: \"slideToggle\", duration: 200 }, //< \"toggle\" or \"slideToggle\" to use jQuery instead of jQueryUI for toggleEffect animation\n\t\t\t\tgenerateIds: false,\n\t\t\t\ticon: true,\n\t\t\t\tidPrefix: \"ft_\",\n\t\t\t\tfocusOnSelect: false,\n\t\t\t\tkeyboard: true,\n\t\t\t\tkeyPathSeparator: \"/\",\n\t\t\t\tminExpandLevel: 1,\n\t\t\t\tnodata: true, // (bool, string, or callback) display message, when no data available\n\t\t\t\tquicksearch: false,\n\t\t\t\trtl: false,\n\t\t\t\tscrollOfs: { top: 0, bottom: 0 },\n\t\t\t\tscrollParent: null,\n\t\t\t\tselectMode: 2,\n\t\t\t\tstrings: {\n\t\t\t\t\tloading: \"Loading...\", // &#8230; would be escaped when escapeTitles is true\n\t\t\t\t\tloadError: \"Load error!\",\n\t\t\t\t\tmoreData: \"More...\",\n\t\t\t\t\tnoData: \"No data.\",\n\t\t\t\t},\n\t\t\t\ttabindex: \"0\",\n\t\t\t\ttitlesTabbable: false,\n\t\t\t\ttooltip: false,\n\t\t\t\t_classNames: {\n\t\t\t\t\tnode: \"fancytree-node\",\n\t\t\t\t\tfolder: \"fancytree-folder\",\n\t\t\t\t\tanimating: \"fancytree-animating\",\n\t\t\t\t\tcombinedExpanderPrefix: \"fancytree-exp-\",\n\t\t\t\t\tcombinedIconPrefix: \"fancytree-ico-\",\n\t\t\t\t\thasChildren: \"fancytree-has-children\",\n\t\t\t\t\tactive: \"fancytree-active\",\n\t\t\t\t\tselected: \"fancytree-selected\",\n\t\t\t\t\texpanded: \"fancytree-expanded\",\n\t\t\t\t\tlazy: \"fancytree-lazy\",\n\t\t\t\t\tfocused: \"fancytree-focused\",\n\t\t\t\t\tpartload: \"fancytree-partload\",\n\t\t\t\t\tpartsel: \"fancytree-partsel\",\n\t\t\t\t\tradio: \"fancytree-radio\",\n\t\t\t\t\t// radiogroup: \"fancytree-radiogroup\",\n\t\t\t\t\tunselectable: \"fancytree-unselectable\",\n\t\t\t\t\tlastsib: \"fancytree-lastsib\",\n\t\t\t\t\tloading: \"fancytree-loading\",\n\t\t\t\t\terror: \"fancytree-error\",\n\t\t\t\t\tstatusNodePrefix: \"fancytree-statusnode-\",\n\t\t\t\t},\n\t\t\t\t// events\n\t\t\t\tlazyLoad: null,\n\t\t\t\tpostProcess: null,\n\t\t\t},\n\t\t\t/* Set up the widget, Called on first $().fancytree() */\n\t\t\t_create: function() {\n\t\t\t\tthis.tree = new Fancytree(this);\n\n\t\t\t\tthis.$source =\n\t\t\t\t\tthis.source || this.element.data(\"type\") === \"json\"\n\t\t\t\t\t\t? this.element\n\t\t\t\t\t\t: this.element.find(\">ul:first\");\n\t\t\t\t// Subclass Fancytree instance with all enabled extensions\n\t\t\t\tvar extension,\n\t\t\t\t\textName,\n\t\t\t\t\ti,\n\t\t\t\t\topts = this.options,\n\t\t\t\t\textensions = opts.extensions,\n\t\t\t\t\tbase = this.tree;\n\n\t\t\t\tfor (i = 0; i < extensions.length; i++) {\n\t\t\t\t\textName = extensions[i];\n\t\t\t\t\textension = $.ui.fancytree._extensions[extName];\n\t\t\t\t\tif (!extension) {\n\t\t\t\t\t\t$.error(\n\t\t\t\t\t\t\t\"Could not apply extension '\" +\n\t\t\t\t\t\t\t\textName +\n\t\t\t\t\t\t\t\t\"' (it is not registered, did you forget to include it?)\"\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t\t// Add extension options as tree.options.EXTENSION\n\t\t\t\t\t//\t\t\t_assert(!this.tree.options[extName], \"Extension name must not exist as option name: \" + extName);\n\n\t\t\t\t\t// console.info(\"extend \" + extName, extension.options, this.tree.options[extName])\n\t\t\t\t\t// issue #876: we want to replace custom array-options, not merge them\n\t\t\t\t\tthis.tree.options[extName] = _simpleDeepMerge(\n\t\t\t\t\t\t{},\n\t\t\t\t\t\textension.options,\n\t\t\t\t\t\tthis.tree.options[extName]\n\t\t\t\t\t);\n\t\t\t\t\t// this.tree.options[extName] = $.extend(true, {}, extension.options, this.tree.options[extName]);\n\n\t\t\t\t\t// console.info(\"extend \" + extName + \" =>\", this.tree.options[extName])\n\t\t\t\t\t// console.info(\"extend \" + extName + \" org default =>\", extension.options)\n\n\t\t\t\t\t// Add a namespace tree.ext.EXTENSION, to hold instance data\n\t\t\t\t\t_assert(\n\t\t\t\t\t\tthis.tree.ext[extName] === undefined,\n\t\t\t\t\t\t\"Extension name must not exist as Fancytree.ext attribute: '\" +\n\t\t\t\t\t\t\textName +\n\t\t\t\t\t\t\t\"'\"\n\t\t\t\t\t);\n\t\t\t\t\t//\t\t\tthis.tree[extName] = extension;\n\t\t\t\t\tthis.tree.ext[extName] = {};\n\t\t\t\t\t// Subclass Fancytree methods using proxies.\n\t\t\t\t\t_subclassObject(this.tree, base, extension, extName);\n\t\t\t\t\t// current extension becomes base for the next extension\n\t\t\t\t\tbase = extension;\n\t\t\t\t}\n\t\t\t\t//\n\t\t\t\tif (opts.icons !== undefined) {\n\t\t\t\t\t// 2015-11-16\n\t\t\t\t\tif (opts.icon !== true) {\n\t\t\t\t\t\t$.error(\n\t\t\t\t\t\t\t\"'icons' tree option is deprecated since v2.14.0: use 'icon' only instead\"\n\t\t\t\t\t\t);\n\t\t\t\t\t} else {\n\t\t\t\t\t\tthis.tree.warn(\n\t\t\t\t\t\t\t\"'icons' tree option is deprecated since v2.14.0: use 'icon' instead\"\n\t\t\t\t\t\t);\n\t\t\t\t\t\topts.icon = opts.icons;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif (opts.iconClass !== undefined) {\n\t\t\t\t\t// 2015-11-16\n\t\t\t\t\tif (opts.icon) {\n\t\t\t\t\t\t$.error(\n\t\t\t\t\t\t\t\"'iconClass' tree option is deprecated since v2.14.0: use 'icon' only instead\"\n\t\t\t\t\t\t);\n\t\t\t\t\t} else {\n\t\t\t\t\t\tthis.tree.warn(\n\t\t\t\t\t\t\t\"'iconClass' tree option is deprecated since v2.14.0: use 'icon' instead\"\n\t\t\t\t\t\t);\n\t\t\t\t\t\topts.icon = opts.iconClass;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif (opts.tabbable !== undefined) {\n\t\t\t\t\t// 2016-04-04\n\t\t\t\t\topts.tabindex = opts.tabbable ? \"0\" : \"-1\";\n\t\t\t\t\tthis.tree.warn(\n\t\t\t\t\t\t\"'tabbable' tree option is deprecated since v2.17.0: use 'tabindex='\" +\n\t\t\t\t\t\t\topts.tabindex +\n\t\t\t\t\t\t\t\"' instead\"\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\t//\n\t\t\t\tthis.tree._callHook(\"treeCreate\", this.tree);\n\t\t\t\t// Note: 'fancytreecreate' event is fired by widget base class\n\t\t\t\t//        this.tree._triggerTreeEvent(\"create\");\n\t\t\t},\n\n\t\t\t/* Called on every $().fancytree() */\n\t\t\t_init: function() {\n\t\t\t\tthis.tree._callHook(\"treeInit\", this.tree);\n\t\t\t\t// TODO: currently we call bind after treeInit, because treeInit\n\t\t\t\t// might change tree.$container.\n\t\t\t\t// It would be better, to move event binding into hooks altogether\n\t\t\t\tthis._bind();\n\t\t\t},\n\n\t\t\t/* Use the _setOption method to respond to changes to options. */\n\t\t\t_setOption: function(key, value) {\n\t\t\t\treturn this.tree._callHook(\n\t\t\t\t\t\"treeSetOption\",\n\t\t\t\t\tthis.tree,\n\t\t\t\t\tkey,\n\t\t\t\t\tvalue\n\t\t\t\t);\n\t\t\t},\n\n\t\t\t/** Use the destroy method to clean up any modifications your widget has made to the DOM */\n\t\t\tdestroy: function() {\n\t\t\t\tthis._unbind();\n\t\t\t\tthis.tree._callHook(\"treeDestroy\", this.tree);\n\t\t\t\t// In jQuery UI 1.8, you must invoke the destroy method from the base widget\n\t\t\t\t$.Widget.prototype.destroy.call(this);\n\t\t\t\t// TODO: delete tree and nodes to make garbage collect easier?\n\t\t\t\t// TODO: In jQuery UI 1.9 and above, you would define _destroy instead of destroy and not call the base method\n\t\t\t},\n\n\t\t\t// -------------------------------------------------------------------------\n\n\t\t\t/* Remove all event handlers for our namespace */\n\t\t\t_unbind: function() {\n\t\t\t\tvar ns = this.tree._ns;\n\t\t\t\tthis.element.off(ns);\n\t\t\t\tthis.tree.$container.off(ns);\n\t\t\t\t$(document).off(ns);\n\t\t\t},\n\t\t\t/* Add mouse and kyboard handlers to the container */\n\t\t\t_bind: function() {\n\t\t\t\tvar that = this,\n\t\t\t\t\topts = this.options,\n\t\t\t\t\ttree = this.tree,\n\t\t\t\t\tns = tree._ns;\n\t\t\t\t// selstartEvent = ( $.support.selectstart ? \"selectstart\" : \"mousedown\" )\n\n\t\t\t\t// Remove all previuous handlers for this tree\n\t\t\t\tthis._unbind();\n\n\t\t\t\t//alert(\"keydown\" + ns + \"foc=\" + tree.hasFocus() + tree.$container);\n\t\t\t\t// tree.debug(\"bind events; container: \", tree.$container);\n\t\t\t\ttree.$container\n\t\t\t\t\t.on(\"focusin\" + ns + \" focusout\" + ns, function(event) {\n\t\t\t\t\t\tvar node = FT.getNode(event),\n\t\t\t\t\t\t\tflag = event.type === \"focusin\";\n\n\t\t\t\t\t\tif (!flag && node && $(event.target).is(\"a\")) {\n\t\t\t\t\t\t\t// #764\n\t\t\t\t\t\t\tnode.debug(\n\t\t\t\t\t\t\t\t\"Ignored focusout on embedded <a> element.\"\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\t\t\t\t\t\t// tree.treeOnFocusInOut.call(tree, event);\n\t\t\t\t\t\t// tree.debug(\"Tree container got event \" + event.type, node, event, FT.getEventTarget(event));\n\t\t\t\t\t\tif (flag) {\n\t\t\t\t\t\t\tif (tree._getExpiringValue(\"focusin\")) {\n\t\t\t\t\t\t\t\t// #789: IE 11 may send duplicate focusin events\n\t\t\t\t\t\t\t\ttree.debug(\"Ignored double focusin.\");\n\t\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\ttree._setExpiringValue(\"focusin\", true, 50);\n\n\t\t\t\t\t\t\tif (!node) {\n\t\t\t\t\t\t\t\t// #789: IE 11 may send focusin before mousdown(?)\n\t\t\t\t\t\t\t\tnode = tree._getExpiringValue(\"mouseDownNode\");\n\t\t\t\t\t\t\t\tif (node) {\n\t\t\t\t\t\t\t\t\ttree.debug(\n\t\t\t\t\t\t\t\t\t\t\"Reconstruct mouse target for focusin from recent event.\"\n\t\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (node) {\n\t\t\t\t\t\t\t// For example clicking into an <input> that is part of a node\n\t\t\t\t\t\t\ttree._callHook(\n\t\t\t\t\t\t\t\t\"nodeSetFocus\",\n\t\t\t\t\t\t\t\ttree._makeHookContext(node, event),\n\t\t\t\t\t\t\t\tflag\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tif (\n\t\t\t\t\t\t\t\ttree.tbody &&\n\t\t\t\t\t\t\t\t$(event.target).parents(\n\t\t\t\t\t\t\t\t\t\"table.fancytree-container > thead\"\n\t\t\t\t\t\t\t\t).length\n\t\t\t\t\t\t\t) {\n\t\t\t\t\t\t\t\t// #767: ignore events in the table's header\n\t\t\t\t\t\t\t\ttree.debug(\n\t\t\t\t\t\t\t\t\t\"Ignore focus event outside table body.\",\n\t\t\t\t\t\t\t\t\tevent\n\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\ttree._callHook(\"treeSetFocus\", tree, flag);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t})\n\t\t\t\t\t.on(\"selectstart\" + ns, \"span.fancytree-title\", function(\n\t\t\t\t\t\tevent\n\t\t\t\t\t) {\n\t\t\t\t\t\t// prevent mouse-drags to select text ranges\n\t\t\t\t\t\t// tree.debug(\"<span title> got event \" + event.type);\n\t\t\t\t\t\tevent.preventDefault();\n\t\t\t\t\t})\n\t\t\t\t\t.on(\"keydown\" + ns, function(event) {\n\t\t\t\t\t\t// TODO: also bind keyup and keypress\n\t\t\t\t\t\t// tree.debug(\"got event \" + event.type + \", hasFocus:\" + tree.hasFocus());\n\t\t\t\t\t\t// if(opts.disabled || opts.keyboard === false || !tree.hasFocus() ){\n\t\t\t\t\t\tif (opts.disabled || opts.keyboard === false) {\n\t\t\t\t\t\t\treturn true;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tvar res,\n\t\t\t\t\t\t\tnode = tree.focusNode, // node may be null\n\t\t\t\t\t\t\tctx = tree._makeHookContext(node || tree, event),\n\t\t\t\t\t\t\tprevPhase = tree.phase;\n\n\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\ttree.phase = \"userEvent\";\n\t\t\t\t\t\t\t// If a 'fancytreekeydown' handler returns false, skip the default\n\t\t\t\t\t\t\t// handling (implemented by tree.nodeKeydown()).\n\t\t\t\t\t\t\tif (node) {\n\t\t\t\t\t\t\t\tres = tree._triggerNodeEvent(\n\t\t\t\t\t\t\t\t\t\"keydown\",\n\t\t\t\t\t\t\t\t\tnode,\n\t\t\t\t\t\t\t\t\tevent\n\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tres = tree._triggerTreeEvent(\"keydown\", event);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tif (res === \"preventNav\") {\n\t\t\t\t\t\t\t\tres = true; // prevent keyboard navigation, but don't prevent default handling of embedded input controls\n\t\t\t\t\t\t\t} else if (res !== false) {\n\t\t\t\t\t\t\t\tres = tree._callHook(\"nodeKeydown\", ctx);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\treturn res;\n\t\t\t\t\t\t} finally {\n\t\t\t\t\t\t\ttree.phase = prevPhase;\n\t\t\t\t\t\t}\n\t\t\t\t\t})\n\t\t\t\t\t.on(\"mousedown\" + ns, function(event) {\n\t\t\t\t\t\tvar et = FT.getEventTarget(event);\n\t\t\t\t\t\t// that.tree.debug(\"event(\" + event.type + \"): node: \", et.node);\n\t\t\t\t\t\t// #712: Store the clicked node, so we can use it when we get a focusin event\n\t\t\t\t\t\t//       ('click' event fires after focusin)\n\t\t\t\t\t\t// tree.debug(\"event(\" + event.type + \"): node: \", et.node);\n\t\t\t\t\t\ttree._lastMousedownNode = et ? et.node : null;\n\t\t\t\t\t\t// #789: Store the node also for a short period, so we can use it\n\t\t\t\t\t\t// in a *resulting* focusin event\n\t\t\t\t\t\ttree._setExpiringValue(\n\t\t\t\t\t\t\t\"mouseDownNode\",\n\t\t\t\t\t\t\ttree._lastMousedownNode\n\t\t\t\t\t\t);\n\t\t\t\t\t})\n\t\t\t\t\t.on(\"click\" + ns + \" dblclick\" + ns, function(event) {\n\t\t\t\t\t\tif (opts.disabled) {\n\t\t\t\t\t\t\treturn true;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tvar ctx,\n\t\t\t\t\t\t\tet = FT.getEventTarget(event),\n\t\t\t\t\t\t\tnode = et.node,\n\t\t\t\t\t\t\ttree = that.tree,\n\t\t\t\t\t\t\tprevPhase = tree.phase;\n\n\t\t\t\t\t\t// that.tree.debug(\"event(\" + event.type + \"): node: \", node);\n\t\t\t\t\t\tif (!node) {\n\t\t\t\t\t\t\treturn true; // Allow bubbling of other events\n\t\t\t\t\t\t}\n\t\t\t\t\t\tctx = tree._makeHookContext(node, event);\n\t\t\t\t\t\t// that.tree.debug(\"event(\" + event.type + \"): node: \", node);\n\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\ttree.phase = \"userEvent\";\n\t\t\t\t\t\t\tswitch (event.type) {\n\t\t\t\t\t\t\t\tcase \"click\":\n\t\t\t\t\t\t\t\t\tctx.targetType = et.type;\n\t\t\t\t\t\t\t\t\tif (node.isPagingNode()) {\n\t\t\t\t\t\t\t\t\t\treturn (\n\t\t\t\t\t\t\t\t\t\t\ttree._triggerNodeEvent(\n\t\t\t\t\t\t\t\t\t\t\t\t\"clickPaging\",\n\t\t\t\t\t\t\t\t\t\t\t\tctx,\n\t\t\t\t\t\t\t\t\t\t\t\tevent\n\t\t\t\t\t\t\t\t\t\t\t) === true\n\t\t\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\treturn tree._triggerNodeEvent(\n\t\t\t\t\t\t\t\t\t\t\"click\",\n\t\t\t\t\t\t\t\t\t\tctx,\n\t\t\t\t\t\t\t\t\t\tevent\n\t\t\t\t\t\t\t\t\t) === false\n\t\t\t\t\t\t\t\t\t\t? false\n\t\t\t\t\t\t\t\t\t\t: tree._callHook(\"nodeClick\", ctx);\n\t\t\t\t\t\t\t\tcase \"dblclick\":\n\t\t\t\t\t\t\t\t\tctx.targetType = et.type;\n\t\t\t\t\t\t\t\t\treturn tree._triggerNodeEvent(\n\t\t\t\t\t\t\t\t\t\t\"dblclick\",\n\t\t\t\t\t\t\t\t\t\tctx,\n\t\t\t\t\t\t\t\t\t\tevent\n\t\t\t\t\t\t\t\t\t) === false\n\t\t\t\t\t\t\t\t\t\t? false\n\t\t\t\t\t\t\t\t\t\t: tree._callHook(\"nodeDblclick\", ctx);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} finally {\n\t\t\t\t\t\t\ttree.phase = prevPhase;\n\t\t\t\t\t\t}\n\t\t\t\t\t});\n\t\t\t},\n\t\t\t/** Return the active node or null.\n\t\t\t * @returns {FancytreeNode}\n\t\t\t */\n\t\t\tgetActiveNode: function() {\n\t\t\t\treturn this.tree.activeNode;\n\t\t\t},\n\t\t\t/** Return the matching node or null.\n\t\t\t * @param {string} key\n\t\t\t * @returns {FancytreeNode}\n\t\t\t */\n\t\t\tgetNodeByKey: function(key) {\n\t\t\t\treturn this.tree.getNodeByKey(key);\n\t\t\t},\n\t\t\t/** Return the invisible system root node.\n\t\t\t * @returns {FancytreeNode}\n\t\t\t */\n\t\t\tgetRootNode: function() {\n\t\t\t\treturn this.tree.rootNode;\n\t\t\t},\n\t\t\t/** Return the current tree instance.\n\t\t\t * @returns {Fancytree}\n\t\t\t */\n\t\t\tgetTree: function() {\n\t\t\t\treturn this.tree;\n\t\t\t},\n\t\t}\n\t);\n\n\t// $.ui.fancytree was created by the widget factory. Create a local shortcut:\n\tFT = $.ui.fancytree;\n\n\t/**\n\t * Static members in the `$.ui.fancytree` namespace.<br>\n\t * <br>\n\t * <pre class=\"sh_javascript sunlight-highlight-javascript\">// Access static members:\n\t * var node = $.ui.fancytree.getNode(element);\n\t * alert($.ui.fancytree.version);\n\t * </pre>\n\t *\n\t * @mixin Fancytree_Static\n\t */\n\t$.extend(\n\t\t$.ui.fancytree,\n\t\t/** @lends Fancytree_Static# */\n\t\t{\n\t\t\t/** @type {string} */\n\t\t\tversion: \"2.30.1\", // Set to semver by 'grunt release'\n\t\t\t/** @type {string} */\n\t\t\tbuildType: \"production\", // Set to 'production' by 'grunt build'\n\t\t\t/** @type {int} */\n\t\t\tdebugLevel: 3, // Set to 3 by 'grunt build'\n\t\t\t// Used by $.ui.fancytree.debug() and as default for tree.options.debugLevel\n\n\t\t\t_nextId: 1,\n\t\t\t_nextNodeKey: 1,\n\t\t\t_extensions: {},\n\t\t\t// focusTree: null,\n\n\t\t\t/** Expose class object as $.ui.fancytree._FancytreeClass */\n\t\t\t_FancytreeClass: Fancytree,\n\t\t\t/** Expose class object as $.ui.fancytree._FancytreeNodeClass */\n\t\t\t_FancytreeNodeClass: FancytreeNode,\n\t\t\t/* Feature checks to provide backwards compatibility */\n\t\t\tjquerySupports: {\n\t\t\t\t// http://jqueryui.com/upgrade-guide/1.9/#deprecated-offset-option-merged-into-my-and-at\n\t\t\t\tpositionMyOfs: isVersionAtLeast($.ui.version, 1, 9),\n\t\t\t},\n\t\t\t/** Throw an error if condition fails (debug method).\n\t\t\t * @param {boolean} cond\n\t\t\t * @param {string} msg\n\t\t\t */\n\t\t\tassert: function(cond, msg) {\n\t\t\t\treturn _assert(cond, msg);\n\t\t\t},\n\t\t\t/** Create a new Fancytree instance on a target element.\n\t\t\t *\n\t\t\t * @param {Element | jQueryObject | string} el Target DOM element or selector\n\t\t\t * @param {FancytreeOptions} [opts] Fancytree options\n\t\t\t * @returns {Fancytree} new tree instance\n\t\t\t * @example\n\t\t\t * var tree = $.ui.fancytree.createTree(\"#tree\", {\n\t\t\t *     source: {url: \"my/webservice\"}\n\t\t\t * }); // Create tree for this matching element\n\t\t\t *\n\t\t\t * @since 2.25\n\t\t\t */\n\t\t\tcreateTree: function(el, opts) {\n\t\t\t\tvar tree = $(el)\n\t\t\t\t\t.fancytree(opts)\n\t\t\t\t\t.fancytree(\"getTree\");\n\t\t\t\treturn tree;\n\t\t\t},\n\t\t\t/** Return a function that executes *fn* at most every *timeout* ms.\n\t\t\t * @param {integer} timeout\n\t\t\t * @param {function} fn\n\t\t\t * @param {boolean} [invokeAsap=false]\n\t\t\t * @param {any} [ctx]\n\t\t\t */\n\t\t\tdebounce: function(timeout, fn, invokeAsap, ctx) {\n\t\t\t\tvar timer;\n\t\t\t\tif (arguments.length === 3 && typeof invokeAsap !== \"boolean\") {\n\t\t\t\t\tctx = invokeAsap;\n\t\t\t\t\tinvokeAsap = false;\n\t\t\t\t}\n\t\t\t\treturn function() {\n\t\t\t\t\tvar args = arguments;\n\t\t\t\t\tctx = ctx || this;\n\t\t\t\t\tinvokeAsap && !timer && fn.apply(ctx, args);\n\t\t\t\t\tclearTimeout(timer);\n\t\t\t\t\ttimer = setTimeout(function() {\n\t\t\t\t\t\tinvokeAsap || fn.apply(ctx, args);\n\t\t\t\t\t\ttimer = null;\n\t\t\t\t\t}, timeout);\n\t\t\t\t};\n\t\t\t},\n\t\t\t/** Write message to console if debugLevel >= 4\n\t\t\t * @param {string} msg\n\t\t\t */\n\t\t\tdebug: function(msg) {\n\t\t\t\t/*jshint expr:true */\n\t\t\t\t$.ui.fancytree.debugLevel >= 4 &&\n\t\t\t\t\tconsoleApply(\"log\", arguments);\n\t\t\t},\n\t\t\t/** Write error message to console if debugLevel >= 1.\n\t\t\t * @param {string} msg\n\t\t\t */\n\t\t\terror: function(msg) {\n\t\t\t\t$.ui.fancytree.debugLevel >= 1 &&\n\t\t\t\t\tconsoleApply(\"error\", arguments);\n\t\t\t},\n\t\t\t/** Convert &lt;, &gt;, &amp;, &quot;, &#39;, &#x2F; to the equivalent entities.\n\t\t\t *\n\t\t\t * @param {string} s\n\t\t\t * @returns {string}\n\t\t\t */\n\t\t\tescapeHtml: function(s) {\n\t\t\t\treturn (\"\" + s).replace(REX_HTML, function(s) {\n\t\t\t\t\treturn ENTITY_MAP[s];\n\t\t\t\t});\n\t\t\t},\n\t\t\t/** Make jQuery.position() arguments backwards compatible, i.e. if\n\t\t\t * jQuery UI version <= 1.8, convert\n\t\t\t *   { my: \"left+3 center\", at: \"left bottom\", of: $target }\n\t\t\t * to\n\t\t\t *   { my: \"left center\", at: \"left bottom\", of: $target, offset: \"3  0\" }\n\t\t\t *\n\t\t\t * See http://jqueryui.com/upgrade-guide/1.9/#deprecated-offset-option-merged-into-my-and-at\n\t\t\t * and http://jsfiddle.net/mar10/6xtu9a4e/\n\t\t\t *\n\t\t\t * @param {object} opts\n\t\t\t * @returns {object} the (potentially modified) original opts hash object\n\t\t\t */\n\t\t\tfixPositionOptions: function(opts) {\n\t\t\t\tif (opts.offset || (\"\" + opts.my + opts.at).indexOf(\"%\") >= 0) {\n\t\t\t\t\t$.error(\n\t\t\t\t\t\t\"expected new position syntax (but '%' is not supported)\"\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\tif (!$.ui.fancytree.jquerySupports.positionMyOfs) {\n\t\t\t\t\tvar // parse 'left+3 center' into ['left+3 center', 'left', '+3', 'center', undefined]\n\t\t\t\t\t\tmyParts = /(\\w+)([+-]?\\d+)?\\s+(\\w+)([+-]?\\d+)?/.exec(\n\t\t\t\t\t\t\topts.my\n\t\t\t\t\t\t),\n\t\t\t\t\t\tatParts = /(\\w+)([+-]?\\d+)?\\s+(\\w+)([+-]?\\d+)?/.exec(\n\t\t\t\t\t\t\topts.at\n\t\t\t\t\t\t),\n\t\t\t\t\t\t// convert to numbers\n\t\t\t\t\t\tdx =\n\t\t\t\t\t\t\t(myParts[2] ? +myParts[2] : 0) +\n\t\t\t\t\t\t\t(atParts[2] ? +atParts[2] : 0),\n\t\t\t\t\t\tdy =\n\t\t\t\t\t\t\t(myParts[4] ? +myParts[4] : 0) +\n\t\t\t\t\t\t\t(atParts[4] ? +atParts[4] : 0);\n\n\t\t\t\t\topts = $.extend({}, opts, {\n\t\t\t\t\t\t// make a copy and overwrite\n\t\t\t\t\t\tmy: myParts[1] + \" \" + myParts[3],\n\t\t\t\t\t\tat: atParts[1] + \" \" + atParts[3],\n\t\t\t\t\t});\n\t\t\t\t\tif (dx || dy) {\n\t\t\t\t\t\topts.offset = \"\" + dx + \" \" + dy;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn opts;\n\t\t\t},\n\t\t\t/** Return a {node: FancytreeNode, type: TYPE} object for a mouse event.\n\t\t\t *\n\t\t\t * @param {Event} event Mouse event, e.g. click, ...\n\t\t\t * @returns {object} Return a {node: FancytreeNode, type: TYPE} object\n\t\t\t *     TYPE: 'title' | 'prefix' | 'expander' | 'checkbox' | 'icon' | undefined\n\t\t\t */\n\t\t\tgetEventTarget: function(event) {\n\t\t\t\tvar $target,\n\t\t\t\t\ttree,\n\t\t\t\t\ttcn = event && event.target ? event.target.className : \"\",\n\t\t\t\t\tres = { node: this.getNode(event.target), type: undefined };\n\t\t\t\t// We use a fast version of $(res.node).hasClass()\n\t\t\t\t// See http://jsperf.com/test-for-classname/2\n\t\t\t\tif (/\\bfancytree-title\\b/.test(tcn)) {\n\t\t\t\t\tres.type = \"title\";\n\t\t\t\t} else if (/\\bfancytree-expander\\b/.test(tcn)) {\n\t\t\t\t\tres.type =\n\t\t\t\t\t\tres.node.hasChildren() === false\n\t\t\t\t\t\t\t? \"prefix\"\n\t\t\t\t\t\t\t: \"expander\";\n\t\t\t\t\t// }else if( /\\bfancytree-checkbox\\b/.test(tcn) || /\\bfancytree-radio\\b/.test(tcn) ){\n\t\t\t\t} else if (/\\bfancytree-checkbox\\b/.test(tcn)) {\n\t\t\t\t\tres.type = \"checkbox\";\n\t\t\t\t} else if (/\\bfancytree(-custom)?-icon\\b/.test(tcn)) {\n\t\t\t\t\tres.type = \"icon\";\n\t\t\t\t} else if (/\\bfancytree-node\\b/.test(tcn)) {\n\t\t\t\t\t// Somewhere near the title\n\t\t\t\t\tres.type = \"title\";\n\t\t\t\t} else if (event && event.target) {\n\t\t\t\t\t$target = $(event.target);\n\t\t\t\t\tif ($target.is(\"ul[role=group]\")) {\n\t\t\t\t\t\t// #nnn: Clicking right to a node may hit the surrounding UL\n\t\t\t\t\t\ttree = res.node && res.node.tree;\n\t\t\t\t\t\t(tree || FT).debug(\"Ignoring click on outer UL.\");\n\t\t\t\t\t\tres.node = null;\n\t\t\t\t\t} else if ($target.closest(\".fancytree-title\").length) {\n\t\t\t\t\t\t// #228: clicking an embedded element inside a title\n\t\t\t\t\t\tres.type = \"title\";\n\t\t\t\t\t} else if ($target.closest(\".fancytree-checkbox\").length) {\n\t\t\t\t\t\t// E.g. <svg> inside checkbox span\n\t\t\t\t\t\tres.type = \"checkbox\";\n\t\t\t\t\t} else if ($target.closest(\".fancytree-expander\").length) {\n\t\t\t\t\t\tres.type = \"expander\";\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn res;\n\t\t\t},\n\t\t\t/** Return a string describing the affected node region for a mouse event.\n\t\t\t *\n\t\t\t * @param {Event} event Mouse event, e.g. click, mousemove, ...\n\t\t\t * @returns {string} 'title' | 'prefix' | 'expander' | 'checkbox' | 'icon' | undefined\n\t\t\t */\n\t\t\tgetEventTargetType: function(event) {\n\t\t\t\treturn this.getEventTarget(event).type;\n\t\t\t},\n\t\t\t/** Return a FancytreeNode instance from element, event, or jQuery object.\n\t\t\t *\n\t\t\t * @param {Element | jQueryObject | Event} el\n\t\t\t * @returns {FancytreeNode} matching node or null\n\t\t\t */\n\t\t\tgetNode: function(el) {\n\t\t\t\tif (el instanceof FancytreeNode) {\n\t\t\t\t\treturn el; // el already was a FancytreeNode\n\t\t\t\t} else if (el instanceof $) {\n\t\t\t\t\tel = el[0]; // el was a jQuery object: use the DOM element\n\t\t\t\t} else if (el.originalEvent !== undefined) {\n\t\t\t\t\tel = el.target; // el was an Event\n\t\t\t\t}\n\t\t\t\twhile (el) {\n\t\t\t\t\tif (el.ftnode) {\n\t\t\t\t\t\treturn el.ftnode;\n\t\t\t\t\t}\n\t\t\t\t\tel = el.parentNode;\n\t\t\t\t}\n\t\t\t\treturn null;\n\t\t\t},\n\t\t\t/** Return a Fancytree instance, from element, index, event, or jQueryObject.\n\t\t\t *\n\t\t\t * @param {Element | jQueryObject | Event | integer | string} [el]\n\t\t\t * @returns {Fancytree} matching tree or null\n\t\t\t * @example\n\t\t\t * $.ui.fancytree.getTree();   // Get first Fancytree instance on page\n\t\t\t * $.ui.fancytree.getTree(1);  // Get second Fancytree instance on page\n\t\t\t * $.ui.fancytree.getTree(\"#tree\"); // Get tree for this matching element\n\t\t\t *\n\t\t\t * @since 2.13\n\t\t\t */\n\t\t\tgetTree: function(el) {\n\t\t\t\tvar widget;\n\n\t\t\t\tif (el instanceof Fancytree) {\n\t\t\t\t\treturn el; // el already was a Fancytree\n\t\t\t\t}\n\t\t\t\tif (el === undefined) {\n\t\t\t\t\tel = 0; // get first tree\n\t\t\t\t}\n\t\t\t\tif (typeof el === \"number\") {\n\t\t\t\t\tel = $(\".fancytree-container\").eq(el); // el was an integer: return nth instance\n\t\t\t\t} else if (typeof el === \"string\") {\n\t\t\t\t\tel = $(el).eq(0); // el was a selector: use first match\n\t\t\t\t} else if (el.selector !== undefined) {\n\t\t\t\t\tel = el.eq(0); // el was a jQuery object: use the first DOM element\n\t\t\t\t} else if (el.originalEvent !== undefined) {\n\t\t\t\t\tel = $(el.target); // el was an Event\n\t\t\t\t}\n\t\t\t\tel = el.closest(\":ui-fancytree\");\n\t\t\t\twidget = el.data(\"ui-fancytree\") || el.data(\"fancytree\"); // the latter is required by jQuery <= 1.8\n\t\t\t\treturn widget ? widget.tree : null;\n\t\t\t},\n\t\t\t/** Return an option value that has a default, but may be overridden by a\n\t\t\t * callback or a node instance attribute.\n\t\t\t *\n\t\t\t * Evaluation sequence:<br>\n\t\t\t *\n\t\t\t * If tree.options.<optionName> is a callback that returns something, use that.<br>\n\t\t\t * Else if node.<optionName> is defined, use that.<br>\n\t\t\t * Else if tree.options.<optionName> is a value, use that.<br>\n\t\t\t * Else use `defaultValue`.\n\t\t\t *\n\t\t\t * @param {string} optionName name of the option property (on node and tree)\n\t\t\t * @param {FancytreeNode} node passed to the callback\n\t\t\t * @param {object} nodeObject where to look for the local option property, e.g. `node` or `node.data`\n\t\t\t * @param {object} treeOption where to look for the tree option, e.g. `tree.options` or `tree.options.dnd5`\n\t\t\t * @param {any} [defaultValue]\n\t\t\t * @returns {any}\n\t\t\t *\n\t\t\t * @example\n\t\t\t * // Check for node.foo, tree,options.foo(), and tree.options.foo:\n\t\t\t * $.ui.fancytree.evalOption(\"foo\", node, node, tree.options);\n\t\t\t * // Check for node.data.bar, tree,options.qux.bar(), and tree.options.qux.bar:\n\t\t\t * $.ui.fancytree.evalOption(\"bar\", node, node.data, tree.options.qux);\n\t\t\t *\n\t\t\t * @since 2.22\n\t\t\t */\n\t\t\tevalOption: function(\n\t\t\t\toptionName,\n\t\t\t\tnode,\n\t\t\t\tnodeObject,\n\t\t\t\ttreeOptions,\n\t\t\t\tdefaultValue\n\t\t\t) {\n\t\t\t\tvar ctx,\n\t\t\t\t\tres,\n\t\t\t\t\ttree = node.tree,\n\t\t\t\t\ttreeOpt = treeOptions[optionName],\n\t\t\t\t\tnodeOpt = nodeObject[optionName];\n\n\t\t\t\tif ($.isFunction(treeOpt)) {\n\t\t\t\t\tctx = {\n\t\t\t\t\t\tnode: node,\n\t\t\t\t\t\ttree: tree,\n\t\t\t\t\t\twidget: tree.widget,\n\t\t\t\t\t\toptions: tree.widget.options,\n\t\t\t\t\t\ttypeInfo: tree.types[node.type] || {},\n\t\t\t\t\t};\n\t\t\t\t\tres = treeOpt.call(tree, { type: optionName }, ctx);\n\t\t\t\t\tif (res == null) {\n\t\t\t\t\t\tres = nodeOpt;\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tres = nodeOpt != null ? nodeOpt : treeOpt;\n\t\t\t\t}\n\t\t\t\tif (res == null) {\n\t\t\t\t\tres = defaultValue; // no option set at all: return default\n\t\t\t\t}\n\t\t\t\treturn res;\n\t\t\t},\n\t\t\t/** Set expander, checkbox, or node icon, supporting string and object format.\n\t\t\t *\n\t\t\t * @param {Element | jQueryObject} span\n\t\t\t * @param {string} baseClass\n\t\t\t * @param {string | object} icon\n\t\t\t * @since 2.27\n\t\t\t */\n\t\t\tsetSpanIcon: function(span, baseClass, icon) {\n\t\t\t\tvar $span = $(span);\n\n\t\t\t\tif (typeof icon === \"string\") {\n\t\t\t\t\t$span.attr(\"class\", baseClass + \" \" + icon);\n\t\t\t\t} else {\n\t\t\t\t\t// support object syntax: { text: ligature, addClasse: classname }\n\t\t\t\t\tif (icon.text) {\n\t\t\t\t\t\t$span.text(\"\" + icon.text);\n\t\t\t\t\t} else if (icon.html) {\n\t\t\t\t\t\tspan.innerHTML = icon.html;\n\t\t\t\t\t}\n\t\t\t\t\t$span.attr(\n\t\t\t\t\t\t\"class\",\n\t\t\t\t\t\tbaseClass + \" \" + (icon.addClass || \"\")\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t},\n\t\t\t/** Convert a keydown or mouse event to a canonical string like 'ctrl+a',\n\t * 'ctrl+shift+f2', 'shift+leftdblclick'.\n\t *\n\t * This is especially handy for switch-statements in event handlers.\n\t *\n\t * @param {event}\n\t * @returns {string}\n\t *\n\t * @example\n\n\tswitch( $.ui.fancytree.eventToString(event) ) {\n\t\tcase \"-\":\n\t\t\ttree.nodeSetExpanded(ctx, false);\n\t\t\tbreak;\n\t\tcase \"shift+return\":\n\t\t\ttree.nodeSetActive(ctx, true);\n\t\t\tbreak;\n\t\tcase \"down\":\n\t\t\tres = node.navigate(event.which, activate);\n\t\t\tbreak;\n\t\tdefault:\n\t\t\thandled = false;\n\t}\n\tif( handled ){\n\t\tevent.preventDefault();\n\t}\n\t */\n\t\t\teventToString: function(event) {\n\t\t\t\t// Poor-man's hotkeys. See here for a complete implementation:\n\t\t\t\t//   https://github.com/jeresig/jquery.hotkeys\n\t\t\t\tvar which = event.which,\n\t\t\t\t\tet = event.type,\n\t\t\t\t\ts = [];\n\n\t\t\t\tif (event.altKey) {\n\t\t\t\t\ts.push(\"alt\");\n\t\t\t\t}\n\t\t\t\tif (event.ctrlKey) {\n\t\t\t\t\ts.push(\"ctrl\");\n\t\t\t\t}\n\t\t\t\tif (event.metaKey) {\n\t\t\t\t\ts.push(\"meta\");\n\t\t\t\t}\n\t\t\t\tif (event.shiftKey) {\n\t\t\t\t\ts.push(\"shift\");\n\t\t\t\t}\n\n\t\t\t\tif (et === \"click\" || et === \"dblclick\") {\n\t\t\t\t\ts.push(MOUSE_BUTTONS[event.button] + et);\n\t\t\t\t} else {\n\t\t\t\t\tif (!IGNORE_KEYCODES[which]) {\n\t\t\t\t\t\ts.push(\n\t\t\t\t\t\t\tSPECIAL_KEYCODES[which] ||\n\t\t\t\t\t\t\t\tString.fromCharCode(which).toLowerCase()\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn s.join(\"+\");\n\t\t\t},\n\t\t\t/** Write message to console if debugLevel >= 3\n\t\t\t * @param {string} msg\n\t\t\t */\n\t\t\tinfo: function(msg) {\n\t\t\t\t/*jshint expr:true */\n\t\t\t\t$.ui.fancytree.debugLevel >= 3 &&\n\t\t\t\t\tconsoleApply(\"info\", arguments);\n\t\t\t},\n\t\t\t/* @deprecated: use eventToString(event) instead.\n\t */\n\t\t\tkeyEventToString: function(event) {\n\t\t\t\tthis.warn(\n\t\t\t\t\t\"keyEventToString() is deprecated: use eventToString()\"\n\t\t\t\t);\n\t\t\t\treturn this.eventToString(event);\n\t\t\t},\n\t\t\t/** Return a wrapped handler method, that provides `this._super`.\n\t *\n\t * @example\n\t\t// Implement `opts.createNode` event to add the 'draggable' attribute\n\t\t$.ui.fancytree.overrideMethod(ctx.options, \"createNode\", function(event, data) {\n\t\t\t// Default processing if any\n\t\t\tthis._super.apply(this, arguments);\n\t\t\t// Add 'draggable' attribute\n\t\t\tdata.node.span.draggable = true;\n\t\t});\n\t *\n\t * @param {object} instance\n\t * @param {string} methodName\n\t * @param {function} handler\n\t * @param {object} [self] optional context\n\t */\n\t\t\toverrideMethod: function(instance, methodName, handler, self) {\n\t\t\t\tvar prevSuper,\n\t\t\t\t\t_super = instance[methodName] || $.noop;\n\n\t\t\t\tself = self || this;\n\n\t\t\t\tinstance[methodName] = function() {\n\t\t\t\t\ttry {\n\t\t\t\t\t\tprevSuper = self._super;\n\t\t\t\t\t\tself._super = _super;\n\t\t\t\t\t\treturn handler.apply(self, arguments);\n\t\t\t\t\t} finally {\n\t\t\t\t\t\tself._super = prevSuper;\n\t\t\t\t\t}\n\t\t\t\t};\n\t\t\t},\n\t\t\t/**\n\t\t\t * Parse tree data from HTML <ul> markup\n\t\t\t *\n\t\t\t * @param {jQueryObject} $ul\n\t\t\t * @returns {NodeData[]}\n\t\t\t */\n\t\t\tparseHtml: function($ul) {\n\t\t\t\t// TODO: understand this:\n\t\t\t\t/*jshint validthis:true */\n\t\t\t\tvar classes,\n\t\t\t\t\tclassName,\n\t\t\t\t\textraClasses,\n\t\t\t\t\ti,\n\t\t\t\t\tiPos,\n\t\t\t\t\tl,\n\t\t\t\t\ttmp,\n\t\t\t\t\ttmp2,\n\t\t\t\t\t$children = $ul.find(\">li\"),\n\t\t\t\t\tchildren = [];\n\n\t\t\t\t$children.each(function() {\n\t\t\t\t\tvar allData,\n\t\t\t\t\t\tlowerCaseAttr,\n\t\t\t\t\t\t$li = $(this),\n\t\t\t\t\t\t$liSpan = $li.find(\">span:first\", this),\n\t\t\t\t\t\t$liA = $liSpan.length ? null : $li.find(\">a:first\"),\n\t\t\t\t\t\td = { tooltip: null, data: {} };\n\n\t\t\t\t\tif ($liSpan.length) {\n\t\t\t\t\t\td.title = $liSpan.html();\n\t\t\t\t\t} else if ($liA && $liA.length) {\n\t\t\t\t\t\t// If a <li><a> tag is specified, use it literally and extract href/target.\n\t\t\t\t\t\td.title = $liA.html();\n\t\t\t\t\t\td.data.href = $liA.attr(\"href\");\n\t\t\t\t\t\td.data.target = $liA.attr(\"target\");\n\t\t\t\t\t\td.tooltip = $liA.attr(\"title\");\n\t\t\t\t\t} else {\n\t\t\t\t\t\t// If only a <li> tag is specified, use the trimmed string up to\n\t\t\t\t\t\t// the next child <ul> tag.\n\t\t\t\t\t\td.title = $li.html();\n\t\t\t\t\t\tiPos = d.title.search(/<ul/i);\n\t\t\t\t\t\tif (iPos >= 0) {\n\t\t\t\t\t\t\td.title = d.title.substring(0, iPos);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\td.title = $.trim(d.title);\n\n\t\t\t\t\t// Make sure all fields exist\n\t\t\t\t\tfor (i = 0, l = CLASS_ATTRS.length; i < l; i++) {\n\t\t\t\t\t\td[CLASS_ATTRS[i]] = undefined;\n\t\t\t\t\t}\n\t\t\t\t\t// Initialize to `true`, if class is set and collect extraClasses\n\t\t\t\t\tclasses = this.className.split(\" \");\n\t\t\t\t\textraClasses = [];\n\t\t\t\t\tfor (i = 0, l = classes.length; i < l; i++) {\n\t\t\t\t\t\tclassName = classes[i];\n\t\t\t\t\t\tif (CLASS_ATTR_MAP[className]) {\n\t\t\t\t\t\t\td[className] = true;\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\textraClasses.push(className);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\td.extraClasses = extraClasses.join(\" \");\n\n\t\t\t\t\t// Parse node options from ID, title and class attributes\n\t\t\t\t\ttmp = $li.attr(\"title\");\n\t\t\t\t\tif (tmp) {\n\t\t\t\t\t\td.tooltip = tmp; // overrides <a title='...'>\n\t\t\t\t\t}\n\t\t\t\t\ttmp = $li.attr(\"id\");\n\t\t\t\t\tif (tmp) {\n\t\t\t\t\t\td.key = tmp;\n\t\t\t\t\t}\n\t\t\t\t\t// Translate hideCheckbox -> checkbox:false\n\t\t\t\t\tif ($li.attr(\"hideCheckbox\")) {\n\t\t\t\t\t\td.checkbox = false;\n\t\t\t\t\t}\n\t\t\t\t\t// Add <li data-NAME='...'> as node.data.NAME\n\t\t\t\t\tallData = _getElementDataAsDict($li);\n\t\t\t\t\tif (allData && !$.isEmptyObject(allData)) {\n\t\t\t\t\t\t// #507: convert data-hidecheckbox (lower case) to hideCheckbox\n\t\t\t\t\t\tfor (lowerCaseAttr in NODE_ATTR_LOWERCASE_MAP) {\n\t\t\t\t\t\t\tif (allData.hasOwnProperty(lowerCaseAttr)) {\n\t\t\t\t\t\t\t\tallData[\n\t\t\t\t\t\t\t\t\tNODE_ATTR_LOWERCASE_MAP[lowerCaseAttr]\n\t\t\t\t\t\t\t\t] =\n\t\t\t\t\t\t\t\t\tallData[lowerCaseAttr];\n\t\t\t\t\t\t\t\tdelete allData[lowerCaseAttr];\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\t// #56: Allow to set special node.attributes from data-...\n\t\t\t\t\t\tfor (i = 0, l = NODE_ATTRS.length; i < l; i++) {\n\t\t\t\t\t\t\ttmp = NODE_ATTRS[i];\n\t\t\t\t\t\t\ttmp2 = allData[tmp];\n\t\t\t\t\t\t\tif (tmp2 != null) {\n\t\t\t\t\t\t\t\tdelete allData[tmp];\n\t\t\t\t\t\t\t\td[tmp] = tmp2;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\t// All other data-... goes to node.data...\n\t\t\t\t\t\t$.extend(d.data, allData);\n\t\t\t\t\t}\n\t\t\t\t\t// Recursive reading of child nodes, if LI tag contains an UL tag\n\t\t\t\t\t$ul = $li.find(\">ul:first\");\n\t\t\t\t\tif ($ul.length) {\n\t\t\t\t\t\td.children = $.ui.fancytree.parseHtml($ul);\n\t\t\t\t\t} else {\n\t\t\t\t\t\td.children = d.lazy ? undefined : null;\n\t\t\t\t\t}\n\t\t\t\t\tchildren.push(d);\n\t\t\t\t\t//            FT.debug(\"parse \", d, children);\n\t\t\t\t});\n\t\t\t\treturn children;\n\t\t\t},\n\t\t\t/** Add Fancytree extension definition to the list of globally available extensions.\n\t\t\t *\n\t\t\t * @param {object} definition\n\t\t\t */\n\t\t\tregisterExtension: function(definition) {\n\t\t\t\t_assert(\n\t\t\t\t\tdefinition.name != null,\n\t\t\t\t\t\"extensions must have a `name` property.\"\n\t\t\t\t);\n\t\t\t\t_assert(\n\t\t\t\t\tdefinition.version != null,\n\t\t\t\t\t\"extensions must have a `version` property.\"\n\t\t\t\t);\n\t\t\t\t$.ui.fancytree._extensions[definition.name] = definition;\n\t\t\t},\n\t\t\t/** Inverse of escapeHtml().\n\t\t\t *\n\t\t\t * @param {string} s\n\t\t\t * @returns {string}\n\t\t\t */\n\t\t\tunescapeHtml: function(s) {\n\t\t\t\tvar e = document.createElement(\"div\");\n\t\t\t\te.innerHTML = s;\n\t\t\t\treturn e.childNodes.length === 0\n\t\t\t\t\t? \"\"\n\t\t\t\t\t: e.childNodes[0].nodeValue;\n\t\t\t},\n\t\t\t/** Write warning message to console if debugLevel >= 2.\n\t\t\t * @param {string} msg\n\t\t\t */\n\t\t\twarn: function(msg) {\n\t\t\t\t$.ui.fancytree.debugLevel >= 2 &&\n\t\t\t\t\tconsoleApply(\"warn\", arguments);\n\t\t\t},\n\t\t}\n\t);\n\n\t// Value returned by `require('jquery.fancytree')`\n\treturn $.ui.fancytree;\n}); // End of closure\n","/*!\n * jquery.fancytree.edit.js\n *\n * Make node titles editable.\n * (Extension module for jquery.fancytree.js: https://github.com/mar10/fancytree/)\n *\n * Copyright (c) 2008-2018, Martin Wendt (http://wwWendt.de)\n *\n * Released under the MIT license\n * https://github.com/mar10/fancytree/wiki/LicenseInfo\n *\n * @version 2.30.1\n * @date 2018-11-13T18:58:18Z\n */\n\n(function(factory) {\n\tif (typeof define === \"function\" && define.amd) {\n\t\t// AMD. Register as an anonymous module.\n\t\tdefine([\"jquery\", \"./jquery.fancytree\"], factory);\n\t} else if (typeof module === \"object\" && module.exports) {\n\t\t// Node/CommonJS\n\t\trequire(\"./jquery.fancytree\");\n\t\tmodule.exports = factory(require(\"jquery\"));\n\t} else {\n\t\t// Browser globals\n\t\tfactory(jQuery);\n\t}\n})(function($) {\n\t\"use strict\";\n\n\t/*******************************************************************************\n\t * Private functions and variables\n\t */\n\n\tvar isMac = /Mac/.test(navigator.platform),\n\t\tescapeHtml = $.ui.fancytree.escapeHtml,\n\t\tunescapeHtml = $.ui.fancytree.unescapeHtml;\n\n\t/**\n\t * [ext-edit] Start inline editing of current node title.\n\t *\n\t * @alias FancytreeNode#editStart\n\t * @requires Fancytree\n\t */\n\t$.ui.fancytree._FancytreeNodeClass.prototype.editStart = function() {\n\t\tvar $input,\n\t\t\tnode = this,\n\t\t\ttree = this.tree,\n\t\t\tlocal = tree.ext.edit,\n\t\t\tinstOpts = tree.options.edit,\n\t\t\t$title = $(\".fancytree-title\", node.span),\n\t\t\teventData = {\n\t\t\t\tnode: node,\n\t\t\t\ttree: tree,\n\t\t\t\toptions: tree.options,\n\t\t\t\tisNew: $(node[tree.statusClassPropName]).hasClass(\n\t\t\t\t\t\"fancytree-edit-new\"\n\t\t\t\t),\n\t\t\t\torgTitle: node.title,\n\t\t\t\tinput: null,\n\t\t\t\tdirty: false,\n\t\t\t};\n\n\t\t// beforeEdit may want to modify the title before editing\n\t\tif (\n\t\t\tinstOpts.beforeEdit.call(\n\t\t\t\tnode,\n\t\t\t\t{ type: \"beforeEdit\" },\n\t\t\t\teventData\n\t\t\t) === false\n\t\t) {\n\t\t\treturn false;\n\t\t}\n\t\t$.ui.fancytree.assert(!local.currentNode, \"recursive edit\");\n\t\tlocal.currentNode = this;\n\t\tlocal.eventData = eventData;\n\n\t\t// Disable standard Fancytree mouse- and key handling\n\t\ttree.widget._unbind();\n\t\t// #116: ext-dnd prevents the blur event, so we have to catch outer clicks\n\t\t$(document).on(\"mousedown.fancytree-edit\", function(event) {\n\t\t\tif (!$(event.target).hasClass(\"fancytree-edit-input\")) {\n\t\t\t\tnode.editEnd(true, event);\n\t\t\t}\n\t\t});\n\n\t\t// Replace node with <input>\n\t\t$input = $(\"<input />\", {\n\t\t\tclass: \"fancytree-edit-input\",\n\t\t\ttype: \"text\",\n\t\t\tvalue: tree.options.escapeTitles\n\t\t\t\t? eventData.orgTitle\n\t\t\t\t: unescapeHtml(eventData.orgTitle),\n\t\t});\n\t\tlocal.eventData.input = $input;\n\t\tif (instOpts.adjustWidthOfs != null) {\n\t\t\t$input.width($title.width() + instOpts.adjustWidthOfs);\n\t\t}\n\t\tif (instOpts.inputCss != null) {\n\t\t\t$input.css(instOpts.inputCss);\n\t\t}\n\n\t\t$title.html($input);\n\n\t\t// Focus <input> and bind keyboard handler\n\t\t$input\n\t\t\t.focus()\n\t\t\t.change(function(event) {\n\t\t\t\t$input.addClass(\"fancytree-edit-dirty\");\n\t\t\t})\n\t\t\t.keydown(function(event) {\n\t\t\t\tswitch (event.which) {\n\t\t\t\t\tcase $.ui.keyCode.ESCAPE:\n\t\t\t\t\t\tnode.editEnd(false, event);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase $.ui.keyCode.ENTER:\n\t\t\t\t\t\tnode.editEnd(true, event);\n\t\t\t\t\t\treturn false; // so we don't start editmode on Mac\n\t\t\t\t}\n\t\t\t\tevent.stopPropagation();\n\t\t\t})\n\t\t\t.blur(function(event) {\n\t\t\t\treturn node.editEnd(true, event);\n\t\t\t});\n\n\t\tinstOpts.edit.call(node, { type: \"edit\" }, eventData);\n\t};\n\n\t/**\n\t * [ext-edit] Stop inline editing.\n\t * @param {Boolean} [applyChanges=false] false: cancel edit, true: save (if modified)\n\t * @alias FancytreeNode#editEnd\n\t * @requires jquery.fancytree.edit.js\n\t */\n\t$.ui.fancytree._FancytreeNodeClass.prototype.editEnd = function(\n\t\tapplyChanges,\n\t\t_event\n\t) {\n\t\tvar newVal,\n\t\t\tnode = this,\n\t\t\ttree = this.tree,\n\t\t\tlocal = tree.ext.edit,\n\t\t\teventData = local.eventData,\n\t\t\tinstOpts = tree.options.edit,\n\t\t\t$title = $(\".fancytree-title\", node.span),\n\t\t\t$input = $title.find(\"input.fancytree-edit-input\");\n\n\t\tif (instOpts.trim) {\n\t\t\t$input.val($.trim($input.val()));\n\t\t}\n\t\tnewVal = $input.val();\n\n\t\teventData.dirty = newVal !== node.title;\n\t\teventData.originalEvent = _event;\n\n\t\t// Find out, if saving is required\n\t\tif (applyChanges === false) {\n\t\t\t// If true/false was passed, honor this (except in rename mode, if unchanged)\n\t\t\teventData.save = false;\n\t\t} else if (eventData.isNew) {\n\t\t\t// In create mode, we save everything, except for empty text\n\t\t\teventData.save = newVal !== \"\";\n\t\t} else {\n\t\t\t// In rename mode, we save everyting, except for empty or unchanged text\n\t\t\teventData.save = eventData.dirty && newVal !== \"\";\n\t\t}\n\t\t// Allow to break (keep editor open), modify input, or re-define data.save\n\t\tif (\n\t\t\tinstOpts.beforeClose.call(\n\t\t\t\tnode,\n\t\t\t\t{ type: \"beforeClose\" },\n\t\t\t\teventData\n\t\t\t) === false\n\t\t) {\n\t\t\treturn false;\n\t\t}\n\t\tif (\n\t\t\teventData.save &&\n\t\t\tinstOpts.save.call(node, { type: \"save\" }, eventData) === false\n\t\t) {\n\t\t\treturn false;\n\t\t}\n\t\t$input.removeClass(\"fancytree-edit-dirty\").off();\n\t\t// Unbind outer-click handler\n\t\t$(document).off(\".fancytree-edit\");\n\n\t\tif (eventData.save) {\n\t\t\t// # 171: escape user input (not required if global escaping is on)\n\t\t\tnode.setTitle(\n\t\t\t\ttree.options.escapeTitles ? newVal : escapeHtml(newVal)\n\t\t\t);\n\t\t\tnode.setFocus();\n\t\t} else {\n\t\t\tif (eventData.isNew) {\n\t\t\t\tnode.remove();\n\t\t\t\tnode = eventData.node = null;\n\t\t\t\tlocal.relatedNode.setFocus();\n\t\t\t} else {\n\t\t\t\tnode.renderTitle();\n\t\t\t\tnode.setFocus();\n\t\t\t}\n\t\t}\n\t\tlocal.eventData = null;\n\t\tlocal.currentNode = null;\n\t\tlocal.relatedNode = null;\n\t\t// Re-enable mouse and keyboard handling\n\t\ttree.widget._bind();\n\t\t// Set keyboard focus, even if setFocus() claims 'nothing to do'\n\t\t$(tree.$container).focus();\n\t\teventData.input = null;\n\t\tinstOpts.close.call(node, { type: \"close\" }, eventData);\n\t\treturn true;\n\t};\n\n\t/**\n\t * [ext-edit] Create a new child or sibling node and start edit mode.\n\t *\n\t * @param {String} [mode='child'] 'before', 'after', or 'child'\n\t * @param {Object} [init] NodeData (or simple title string)\n\t * @alias FancytreeNode#editCreateNode\n\t * @requires jquery.fancytree.edit.js\n\t * @since 2.4\n\t */\n\t$.ui.fancytree._FancytreeNodeClass.prototype.editCreateNode = function(\n\t\tmode,\n\t\tinit\n\t) {\n\t\tvar newNode,\n\t\t\ttree = this.tree,\n\t\t\tself = this;\n\n\t\tmode = mode || \"child\";\n\t\tif (init == null) {\n\t\t\tinit = { title: \"\" };\n\t\t} else if (typeof init === \"string\") {\n\t\t\tinit = { title: init };\n\t\t} else {\n\t\t\t$.ui.fancytree.assert($.isPlainObject(init));\n\t\t}\n\t\t// Make sure node is expanded (and loaded) in 'child' mode\n\t\tif (\n\t\t\tmode === \"child\" &&\n\t\t\t!this.isExpanded() &&\n\t\t\tthis.hasChildren() !== false\n\t\t) {\n\t\t\tthis.setExpanded().done(function() {\n\t\t\t\tself.editCreateNode(mode, init);\n\t\t\t});\n\t\t\treturn;\n\t\t}\n\t\tnewNode = this.addNode(init, mode);\n\n\t\t// #644: Don't filter new nodes.\n\t\tnewNode.match = true;\n\t\t$(newNode[tree.statusClassPropName])\n\t\t\t.removeClass(\"fancytree-hide\")\n\t\t\t.addClass(\"fancytree-match\");\n\n\t\tnewNode.makeVisible(/*{noAnimation: true}*/).done(function() {\n\t\t\t$(newNode[tree.statusClassPropName]).addClass(\"fancytree-edit-new\");\n\t\t\tself.tree.ext.edit.relatedNode = self;\n\t\t\tnewNode.editStart();\n\t\t});\n\t};\n\n\t/**\n\t * [ext-edit] Check if any node in this tree  in edit mode.\n\t *\n\t * @returns {FancytreeNode | null}\n\t * @alias Fancytree#isEditing\n\t * @requires jquery.fancytree.edit.js\n\t */\n\t$.ui.fancytree._FancytreeClass.prototype.isEditing = function() {\n\t\treturn this.ext.edit ? this.ext.edit.currentNode : null;\n\t};\n\n\t/**\n\t * [ext-edit] Check if this node is in edit mode.\n\t * @returns {Boolean} true if node is currently beeing edited\n\t * @alias FancytreeNode#isEditing\n\t * @requires jquery.fancytree.edit.js\n\t */\n\t$.ui.fancytree._FancytreeNodeClass.prototype.isEditing = function() {\n\t\treturn this.tree.ext.edit\n\t\t\t? this.tree.ext.edit.currentNode === this\n\t\t\t: false;\n\t};\n\n\t/*******************************************************************************\n\t * Extension code\n\t */\n\t$.ui.fancytree.registerExtension({\n\t\tname: \"edit\",\n\t\tversion: \"2.30.1\",\n\t\t// Default options for this extension.\n\t\toptions: {\n\t\t\tadjustWidthOfs: 4, // null: don't adjust input size to content\n\t\t\tallowEmpty: false, // Prevent empty input\n\t\t\tinputCss: { minWidth: \"3em\" },\n\t\t\t// triggerCancel: [\"esc\", \"tab\", \"click\"],\n\t\t\ttriggerStart: [\"f2\", \"mac+enter\", \"shift+click\"],\n\t\t\ttrim: true, // Trim whitespace before save\n\t\t\t// Events:\n\t\t\tbeforeClose: $.noop, // Return false to prevent cancel/save (data.input is available)\n\t\t\tbeforeEdit: $.noop, // Return false to prevent edit mode\n\t\t\tclose: $.noop, // Editor was removed\n\t\t\tedit: $.noop, // Editor was opened (available as data.input)\n\t\t\t//\t\tkeypress: $.noop,    // Not yet implemented\n\t\t\tsave: $.noop, // Save data.input.val() or return false to keep editor open\n\t\t},\n\t\t// Local attributes\n\t\tcurrentNode: null,\n\n\t\ttreeInit: function(ctx) {\n\t\t\tthis._superApply(arguments);\n\t\t\tthis.$container.addClass(\"fancytree-ext-edit\");\n\t\t},\n\t\tnodeClick: function(ctx) {\n\t\t\tvar eventStr = $.ui.fancytree.eventToString(ctx.originalEvent),\n\t\t\t\ttriggerStart = ctx.options.edit.triggerStart;\n\n\t\t\tif (\n\t\t\t\teventStr === \"shift+click\" &&\n\t\t\t\t$.inArray(\"shift+click\", triggerStart) >= 0\n\t\t\t) {\n\t\t\t\tif (ctx.originalEvent.shiftKey) {\n\t\t\t\t\tctx.node.editStart();\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (\n\t\t\t\teventStr === \"click\" &&\n\t\t\t\t$.inArray(\"clickActive\", triggerStart) >= 0\n\t\t\t) {\n\t\t\t\t// Only when click was inside title text (not aynwhere else in the row)\n\t\t\t\tif (\n\t\t\t\t\tctx.node.isActive() &&\n\t\t\t\t\t!ctx.node.isEditing() &&\n\t\t\t\t\t$(ctx.originalEvent.target).hasClass(\"fancytree-title\")\n\t\t\t\t) {\n\t\t\t\t\tctx.node.editStart();\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn this._superApply(arguments);\n\t\t},\n\t\tnodeDblclick: function(ctx) {\n\t\t\tif ($.inArray(\"dblclick\", ctx.options.edit.triggerStart) >= 0) {\n\t\t\t\tctx.node.editStart();\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\treturn this._superApply(arguments);\n\t\t},\n\t\tnodeKeydown: function(ctx) {\n\t\t\tswitch (ctx.originalEvent.which) {\n\t\t\t\tcase 113: // [F2]\n\t\t\t\t\tif ($.inArray(\"f2\", ctx.options.edit.triggerStart) >= 0) {\n\t\t\t\t\t\tctx.node.editStart();\n\t\t\t\t\t\treturn false;\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\tcase $.ui.keyCode.ENTER:\n\t\t\t\t\tif (\n\t\t\t\t\t\t$.inArray(\"mac+enter\", ctx.options.edit.triggerStart) >=\n\t\t\t\t\t\t\t0 &&\n\t\t\t\t\t\tisMac\n\t\t\t\t\t) {\n\t\t\t\t\t\tctx.node.editStart();\n\t\t\t\t\t\treturn false;\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t\treturn this._superApply(arguments);\n\t\t},\n\t});\n\t// Value returned by `require('jquery.fancytree..')`\n\treturn $.ui.fancytree;\n}); // End of closure\n","/*!\n * jquery.fancytree.filter.js\n *\n * Remove or highlight tree nodes, based on a filter.\n * (Extension module for jquery.fancytree.js: https://github.com/mar10/fancytree/)\n *\n * Copyright (c) 2008-2018, Martin Wendt (http://wwWendt.de)\n *\n * Released under the MIT license\n * https://github.com/mar10/fancytree/wiki/LicenseInfo\n *\n * @version 2.30.1\n * @date 2018-11-13T18:58:18Z\n */\n\n(function(factory) {\n\tif (typeof define === \"function\" && define.amd) {\n\t\t// AMD. Register as an anonymous module.\n\t\tdefine([\"jquery\", \"./jquery.fancytree\"], factory);\n\t} else if (typeof module === \"object\" && module.exports) {\n\t\t// Node/CommonJS\n\t\trequire(\"./jquery.fancytree\");\n\t\tmodule.exports = factory(require(\"jquery\"));\n\t} else {\n\t\t// Browser globals\n\t\tfactory(jQuery);\n\t}\n})(function($) {\n\t\"use strict\";\n\n\t/*******************************************************************************\n\t * Private functions and variables\n\t */\n\n\tvar KeyNoData = \"__not_found__\",\n\t\tescapeHtml = $.ui.fancytree.escapeHtml;\n\n\tfunction _escapeRegex(str) {\n\t\t/*jshint regexdash:true */\n\t\treturn (str + \"\").replace(/([.?*+\\^\\$\\[\\]\\\\(){}|-])/g, \"\\\\$1\");\n\t}\n\n\tfunction extractHtmlText(s) {\n\t\tif (s.indexOf(\">\") >= 0) {\n\t\t\treturn $(\"<div/>\")\n\t\t\t\t.html(s)\n\t\t\t\t.text();\n\t\t}\n\t\treturn s;\n\t}\n\n\t$.ui.fancytree._FancytreeClass.prototype._applyFilterImpl = function(\n\t\tfilter,\n\t\tbranchMode,\n\t\t_opts\n\t) {\n\t\tvar match,\n\t\t\tstatusNode,\n\t\t\tre,\n\t\t\treHighlight,\n\t\t\ttemp,\n\t\t\tcount = 0,\n\t\t\ttreeOpts = this.options,\n\t\t\tescapeTitles = treeOpts.escapeTitles,\n\t\t\tprevAutoCollapse = treeOpts.autoCollapse,\n\t\t\topts = $.extend({}, treeOpts.filter, _opts),\n\t\t\thideMode = opts.mode === \"hide\",\n\t\t\tleavesOnly = !!opts.leavesOnly && !branchMode;\n\n\t\t// Default to 'match title substring (not case sensitive)'\n\t\tif (typeof filter === \"string\") {\n\t\t\tif (filter === \"\") {\n\t\t\t\tthis.warn(\n\t\t\t\t\t\"Fancytree passing an empty string as a filter is handled as clearFilter().\"\n\t\t\t\t);\n\t\t\t\tthis.clearFilter();\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tif (opts.fuzzy) {\n\t\t\t\t// See https://codereview.stackexchange.com/questions/23899/faster-javascript-fuzzy-string-matching-function/23905#23905\n\t\t\t\t// and http://www.quora.com/How-is-the-fuzzy-search-algorithm-in-Sublime-Text-designed\n\t\t\t\t// and http://www.dustindiaz.com/autocomplete-fuzzy-matching\n\t\t\t\tmatch = filter.split(\"\").reduce(function(a, b) {\n\t\t\t\t\treturn a + \"[^\" + b + \"]*\" + b;\n\t\t\t\t});\n\t\t\t} else {\n\t\t\t\tmatch = _escapeRegex(filter); // make sure a '.' is treated literally\n\t\t\t}\n\t\t\tre = new RegExp(\".*\" + match + \".*\", \"i\");\n\t\t\treHighlight = new RegExp(_escapeRegex(filter), \"gi\");\n\t\t\tfilter = function(node) {\n\t\t\t\tif (!node.title) {\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t\tvar text = escapeTitles\n\t\t\t\t\t\t? node.title\n\t\t\t\t\t\t: extractHtmlText(node.title),\n\t\t\t\t\tres = !!re.test(text);\n\n\t\t\t\tif (res && opts.highlight) {\n\t\t\t\t\tif (escapeTitles) {\n\t\t\t\t\t\t// #740: we must not apply the marks to escaped entity names, e.g. `&quot;`\n\t\t\t\t\t\t// Use some exotic characters to mark matches:\n\t\t\t\t\t\ttemp = text.replace(reHighlight, function(s) {\n\t\t\t\t\t\t\treturn \"\\uFFF7\" + s + \"\\uFFF8\";\n\t\t\t\t\t\t});\n\t\t\t\t\t\t// now we can escape the title...\n\t\t\t\t\t\tnode.titleWithHighlight = escapeHtml(temp)\n\t\t\t\t\t\t\t// ... and finally insert the desired `<mark>` tags\n\t\t\t\t\t\t\t.replace(/\\uFFF7/g, \"<mark>\")\n\t\t\t\t\t\t\t.replace(/\\uFFF8/g, \"</mark>\");\n\t\t\t\t\t} else {\n\t\t\t\t\t\tnode.titleWithHighlight = text.replace(\n\t\t\t\t\t\t\treHighlight,\n\t\t\t\t\t\t\tfunction(s) {\n\t\t\t\t\t\t\t\treturn \"<mark>\" + s + \"</mark>\";\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t\t// node.debug(\"filter\", escapeTitles, text, node.titleWithHighlight);\n\t\t\t\t}\n\t\t\t\treturn res;\n\t\t\t};\n\t\t}\n\n\t\tthis.enableFilter = true;\n\t\tthis.lastFilterArgs = arguments;\n\n\t\tthis.$div.addClass(\"fancytree-ext-filter\");\n\t\tif (hideMode) {\n\t\t\tthis.$div.addClass(\"fancytree-ext-filter-hide\");\n\t\t} else {\n\t\t\tthis.$div.addClass(\"fancytree-ext-filter-dimm\");\n\t\t}\n\t\tthis.$div.toggleClass(\n\t\t\t\"fancytree-ext-filter-hide-expanders\",\n\t\t\t!!opts.hideExpanders\n\t\t);\n\t\t// Reset current filter\n\t\tthis.visit(function(node) {\n\t\t\tdelete node.match;\n\t\t\tdelete node.titleWithHighlight;\n\t\t\tnode.subMatchCount = 0;\n\t\t});\n\t\tstatusNode = this.getRootNode()._findDirectChild(KeyNoData);\n\t\tif (statusNode) {\n\t\t\tstatusNode.remove();\n\t\t}\n\n\t\t// Adjust node.hide, .match, and .subMatchCount properties\n\t\ttreeOpts.autoCollapse = false; // #528\n\n\t\tthis.visit(function(node) {\n\t\t\tif (leavesOnly && node.children != null) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tvar res = filter(node),\n\t\t\t\tmatchedByBranch = false;\n\n\t\t\tif (res === \"skip\") {\n\t\t\t\tnode.visit(function(c) {\n\t\t\t\t\tc.match = false;\n\t\t\t\t}, true);\n\t\t\t\treturn \"skip\";\n\t\t\t}\n\t\t\tif (!res && (branchMode || res === \"branch\") && node.parent.match) {\n\t\t\t\tres = true;\n\t\t\t\tmatchedByBranch = true;\n\t\t\t}\n\t\t\tif (res) {\n\t\t\t\tcount++;\n\t\t\t\tnode.match = true;\n\t\t\t\tnode.visitParents(function(p) {\n\t\t\t\t\tp.subMatchCount += 1;\n\t\t\t\t\t// Expand match (unless this is no real match, but only a node in a matched branch)\n\t\t\t\t\tif (opts.autoExpand && !matchedByBranch && !p.expanded) {\n\t\t\t\t\t\tp.setExpanded(true, {\n\t\t\t\t\t\t\tnoAnimation: true,\n\t\t\t\t\t\t\tnoEvents: true,\n\t\t\t\t\t\t\tscrollIntoView: false,\n\t\t\t\t\t\t});\n\t\t\t\t\t\tp._filterAutoExpanded = true;\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t}\n\t\t});\n\t\ttreeOpts.autoCollapse = prevAutoCollapse;\n\n\t\tif (count === 0 && opts.nodata && hideMode) {\n\t\t\tstatusNode = opts.nodata;\n\t\t\tif ($.isFunction(statusNode)) {\n\t\t\t\tstatusNode = statusNode();\n\t\t\t}\n\t\t\tif (statusNode === true) {\n\t\t\t\tstatusNode = {};\n\t\t\t} else if (typeof statusNode === \"string\") {\n\t\t\t\tstatusNode = { title: statusNode };\n\t\t\t}\n\t\t\tstatusNode = $.extend(\n\t\t\t\t{\n\t\t\t\t\tstatusNodeType: \"nodata\",\n\t\t\t\t\tkey: KeyNoData,\n\t\t\t\t\ttitle: this.options.strings.noData,\n\t\t\t\t},\n\t\t\t\tstatusNode\n\t\t\t);\n\n\t\t\tthis.getRootNode().addNode(statusNode).match = true;\n\t\t}\n\t\t// Redraw whole tree\n\t\tthis.render();\n\t\treturn count;\n\t};\n\n\t/**\n\t * [ext-filter] Dimm or hide nodes.\n\t *\n\t * @param {function | string} filter\n\t * @param {boolean} [opts={autoExpand: false, leavesOnly: false}]\n\t * @returns {integer} count\n\t * @alias Fancytree#filterNodes\n\t * @requires jquery.fancytree.filter.js\n\t */\n\t$.ui.fancytree._FancytreeClass.prototype.filterNodes = function(\n\t\tfilter,\n\t\topts\n\t) {\n\t\tif (typeof opts === \"boolean\") {\n\t\t\topts = { leavesOnly: opts };\n\t\t\tthis.warn(\n\t\t\t\t\"Fancytree.filterNodes() leavesOnly option is deprecated since 2.9.0 / 2015-04-19. Use opts.leavesOnly instead.\"\n\t\t\t);\n\t\t}\n\t\treturn this._applyFilterImpl(filter, false, opts);\n\t};\n\n\t/**\n\t * @deprecated\n\t */\n\t$.ui.fancytree._FancytreeClass.prototype.applyFilter = function(filter) {\n\t\tthis.warn(\n\t\t\t\"Fancytree.applyFilter() is deprecated since 2.1.0 / 2014-05-29. Use .filterNodes() instead.\"\n\t\t);\n\t\treturn this.filterNodes.apply(this, arguments);\n\t};\n\n\t/**\n\t * [ext-filter] Dimm or hide whole branches.\n\t *\n\t * @param {function | string} filter\n\t * @param {boolean} [opts={autoExpand: false}]\n\t * @returns {integer} count\n\t * @alias Fancytree#filterBranches\n\t * @requires jquery.fancytree.filter.js\n\t */\n\t$.ui.fancytree._FancytreeClass.prototype.filterBranches = function(\n\t\tfilter,\n\t\topts\n\t) {\n\t\treturn this._applyFilterImpl(filter, true, opts);\n\t};\n\n\t/**\n\t * [ext-filter] Reset the filter.\n\t *\n\t * @alias Fancytree#clearFilter\n\t * @requires jquery.fancytree.filter.js\n\t */\n\t$.ui.fancytree._FancytreeClass.prototype.clearFilter = function() {\n\t\tvar $title,\n\t\t\tstatusNode = this.getRootNode()._findDirectChild(KeyNoData),\n\t\t\tescapeTitles = this.options.escapeTitles,\n\t\t\tenhanceTitle = this.options.enhanceTitle;\n\n\t\tif (statusNode) {\n\t\t\tstatusNode.remove();\n\t\t}\n\t\tthis.visit(function(node) {\n\t\t\tif (node.match && node.span) {\n\t\t\t\t// #491, #601\n\t\t\t\t$title = $(node.span).find(\">span.fancytree-title\");\n\t\t\t\tif (escapeTitles) {\n\t\t\t\t\t$title.text(node.title);\n\t\t\t\t} else {\n\t\t\t\t\t$title.html(node.title);\n\t\t\t\t}\n\t\t\t\tif (enhanceTitle) {\n\t\t\t\t\tenhanceTitle(\n\t\t\t\t\t\t{ type: \"enhanceTitle\" },\n\t\t\t\t\t\t{ node: node, $title: $title }\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t}\n\t\t\tdelete node.match;\n\t\t\tdelete node.subMatchCount;\n\t\t\tdelete node.titleWithHighlight;\n\t\t\tif (node.$subMatchBadge) {\n\t\t\t\tnode.$subMatchBadge.remove();\n\t\t\t\tdelete node.$subMatchBadge;\n\t\t\t}\n\t\t\tif (node._filterAutoExpanded && node.expanded) {\n\t\t\t\tnode.setExpanded(false, {\n\t\t\t\t\tnoAnimation: true,\n\t\t\t\t\tnoEvents: true,\n\t\t\t\t\tscrollIntoView: false,\n\t\t\t\t});\n\t\t\t}\n\t\t\tdelete node._filterAutoExpanded;\n\t\t});\n\t\tthis.enableFilter = false;\n\t\tthis.lastFilterArgs = null;\n\t\tthis.$div.removeClass(\n\t\t\t\"fancytree-ext-filter fancytree-ext-filter-dimm fancytree-ext-filter-hide\"\n\t\t);\n\t\tthis.render();\n\t};\n\n\t/**\n\t * [ext-filter] Return true if a filter is currently applied.\n\t *\n\t * @returns {Boolean}\n\t * @alias Fancytree#isFilterActive\n\t * @requires jquery.fancytree.filter.js\n\t * @since 2.13\n\t */\n\t$.ui.fancytree._FancytreeClass.prototype.isFilterActive = function() {\n\t\treturn !!this.enableFilter;\n\t};\n\n\t/**\n\t * [ext-filter] Return true if this node is matched by current filter (or no filter is active).\n\t *\n\t * @returns {Boolean}\n\t * @alias FancytreeNode#isMatched\n\t * @requires jquery.fancytree.filter.js\n\t * @since 2.13\n\t */\n\t$.ui.fancytree._FancytreeNodeClass.prototype.isMatched = function() {\n\t\treturn !(this.tree.enableFilter && !this.match);\n\t};\n\n\t/*******************************************************************************\n\t * Extension code\n\t */\n\t$.ui.fancytree.registerExtension({\n\t\tname: \"filter\",\n\t\tversion: \"2.30.1\",\n\t\t// Default options for this extension.\n\t\toptions: {\n\t\t\tautoApply: true, // Re-apply last filter if lazy data is loaded\n\t\t\tautoExpand: false, // Expand all branches that contain matches while filtered\n\t\t\tcounter: true, // Show a badge with number of matching child nodes near parent icons\n\t\t\tfuzzy: false, // Match single characters in order, e.g. 'fb' will match 'FooBar'\n\t\t\thideExpandedCounter: true, // Hide counter badge if parent is expanded\n\t\t\thideExpanders: false, // Hide expanders if all child nodes are hidden by filter\n\t\t\thighlight: true, // Highlight matches by wrapping inside <mark> tags\n\t\t\tleavesOnly: false, // Match end nodes only\n\t\t\tnodata: true, // Display a 'no data' status node if result is empty\n\t\t\tmode: \"dimm\", // Grayout unmatched nodes (pass \"hide\" to remove unmatched node instead)\n\t\t},\n\t\tnodeLoadChildren: function(ctx, source) {\n\t\t\treturn this._superApply(arguments).done(function() {\n\t\t\t\tif (\n\t\t\t\t\tctx.tree.enableFilter &&\n\t\t\t\t\tctx.tree.lastFilterArgs &&\n\t\t\t\t\tctx.options.filter.autoApply\n\t\t\t\t) {\n\t\t\t\t\tctx.tree._applyFilterImpl.apply(\n\t\t\t\t\t\tctx.tree,\n\t\t\t\t\t\tctx.tree.lastFilterArgs\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t});\n\t\t},\n\t\tnodeSetExpanded: function(ctx, flag, callOpts) {\n\t\t\tdelete ctx.node._filterAutoExpanded;\n\t\t\t// Make sure counter badge is displayed again, when node is beeing collapsed\n\t\t\tif (\n\t\t\t\t!flag &&\n\t\t\t\tctx.options.filter.hideExpandedCounter &&\n\t\t\t\tctx.node.$subMatchBadge\n\t\t\t) {\n\t\t\t\tctx.node.$subMatchBadge.show();\n\t\t\t}\n\t\t\treturn this._superApply(arguments);\n\t\t},\n\t\tnodeRenderStatus: function(ctx) {\n\t\t\t// Set classes for current status\n\t\t\tvar res,\n\t\t\t\tnode = ctx.node,\n\t\t\t\ttree = ctx.tree,\n\t\t\t\topts = ctx.options.filter,\n\t\t\t\t$title = $(node.span).find(\"span.fancytree-title\"),\n\t\t\t\t$span = $(node[tree.statusClassPropName]),\n\t\t\t\tenhanceTitle = ctx.options.enhanceTitle,\n\t\t\t\tescapeTitles = ctx.options.escapeTitles;\n\n\t\t\tres = this._super(ctx);\n\t\t\t// nothing to do, if node was not yet rendered\n\t\t\tif (!$span.length || !tree.enableFilter) {\n\t\t\t\treturn res;\n\t\t\t}\n\t\t\t$span\n\t\t\t\t.toggleClass(\"fancytree-match\", !!node.match)\n\t\t\t\t.toggleClass(\"fancytree-submatch\", !!node.subMatchCount)\n\t\t\t\t.toggleClass(\n\t\t\t\t\t\"fancytree-hide\",\n\t\t\t\t\t!(node.match || node.subMatchCount)\n\t\t\t\t);\n\t\t\t// Add/update counter badge\n\t\t\tif (\n\t\t\t\topts.counter &&\n\t\t\t\tnode.subMatchCount &&\n\t\t\t\t(!node.isExpanded() || !opts.hideExpandedCounter)\n\t\t\t) {\n\t\t\t\tif (!node.$subMatchBadge) {\n\t\t\t\t\tnode.$subMatchBadge = $(\n\t\t\t\t\t\t\"<span class='fancytree-childcounter'/>\"\n\t\t\t\t\t);\n\t\t\t\t\t$(\n\t\t\t\t\t\t\"span.fancytree-icon, span.fancytree-custom-icon\",\n\t\t\t\t\t\tnode.span\n\t\t\t\t\t).append(node.$subMatchBadge);\n\t\t\t\t}\n\t\t\t\tnode.$subMatchBadge.show().text(node.subMatchCount);\n\t\t\t} else if (node.$subMatchBadge) {\n\t\t\t\tnode.$subMatchBadge.hide();\n\t\t\t}\n\t\t\t// node.debug(\"nodeRenderStatus\", node.titleWithHighlight, node.title)\n\t\t\t// #601: also chek for $title.length, because we don't need to render\n\t\t\t// if node.span is null (i.e. not rendered)\n\t\t\tif (node.span && (!node.isEditing || !node.isEditing.call(node))) {\n\t\t\t\tif (node.titleWithHighlight) {\n\t\t\t\t\t$title.html(node.titleWithHighlight);\n\t\t\t\t} else if (escapeTitles) {\n\t\t\t\t\t$title.text(node.title);\n\t\t\t\t} else {\n\t\t\t\t\t$title.html(node.title);\n\t\t\t\t}\n\t\t\t\tif (enhanceTitle) {\n\t\t\t\t\tenhanceTitle(\n\t\t\t\t\t\t{ type: \"enhanceTitle\" },\n\t\t\t\t\t\t{ node: node, $title: $title }\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn res;\n\t\t},\n\t});\n\t// Value returned by `require('jquery.fancytree..')`\n\treturn $.ui.fancytree;\n}); // End of closure\n","'use strict'\n\nexports.byteLength = byteLength\nexports.toByteArray = toByteArray\nexports.fromByteArray = fromByteArray\n\nvar lookup = []\nvar revLookup = []\nvar Arr = typeof Uint8Array !== 'undefined' ? Uint8Array : Array\n\nvar code = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'\nfor (var i = 0, len = code.length; i < len; ++i) {\n  lookup[i] = code[i]\n  revLookup[code.charCodeAt(i)] = i\n}\n\n// Support decoding URL-safe base64 strings, as Node.js does.\n// See: https://en.wikipedia.org/wiki/Base64#URL_applications\nrevLookup['-'.charCodeAt(0)] = 62\nrevLookup['_'.charCodeAt(0)] = 63\n\nfunction getLens (b64) {\n  var len = b64.length\n\n  if (len % 4 > 0) {\n    throw new Error('Invalid string. Length must be a multiple of 4')\n  }\n\n  // Trim off extra bytes after placeholder bytes are found\n  // See: https://github.com/beatgammit/base64-js/issues/42\n  var validLen = b64.indexOf('=')\n  if (validLen === -1) validLen = len\n\n  var placeHoldersLen = validLen === len\n    ? 0\n    : 4 - (validLen % 4)\n\n  return [validLen, placeHoldersLen]\n}\n\n// base64 is 4/3 + up to two characters of the original data\nfunction byteLength (b64) {\n  var lens = getLens(b64)\n  var validLen = lens[0]\n  var placeHoldersLen = lens[1]\n  return ((validLen + placeHoldersLen) * 3 / 4) - placeHoldersLen\n}\n\nfunction _byteLength (b64, validLen, placeHoldersLen) {\n  return ((validLen + placeHoldersLen) * 3 / 4) - placeHoldersLen\n}\n\nfunction toByteArray (b64) {\n  var tmp\n  var lens = getLens(b64)\n  var validLen = lens[0]\n  var placeHoldersLen = lens[1]\n\n  var arr = new Arr(_byteLength(b64, validLen, placeHoldersLen))\n\n  var curByte = 0\n\n  // if there are placeholders, only get up to the last complete 4 chars\n  var len = placeHoldersLen > 0\n    ? validLen - 4\n    : validLen\n\n  for (var i = 0; i < len; i += 4) {\n    tmp =\n      (revLookup[b64.charCodeAt(i)] << 18) |\n      (revLookup[b64.charCodeAt(i + 1)] << 12) |\n      (revLookup[b64.charCodeAt(i + 2)] << 6) |\n      revLookup[b64.charCodeAt(i + 3)]\n    arr[curByte++] = (tmp >> 16) & 0xFF\n    arr[curByte++] = (tmp >> 8) & 0xFF\n    arr[curByte++] = tmp & 0xFF\n  }\n\n  if (placeHoldersLen === 2) {\n    tmp =\n      (revLookup[b64.charCodeAt(i)] << 2) |\n      (revLookup[b64.charCodeAt(i + 1)] >> 4)\n    arr[curByte++] = tmp & 0xFF\n  }\n\n  if (placeHoldersLen === 1) {\n    tmp =\n      (revLookup[b64.charCodeAt(i)] << 10) |\n      (revLookup[b64.charCodeAt(i + 1)] << 4) |\n      (revLookup[b64.charCodeAt(i + 2)] >> 2)\n    arr[curByte++] = (tmp >> 8) & 0xFF\n    arr[curByte++] = tmp & 0xFF\n  }\n\n  return arr\n}\n\nfunction tripletToBase64 (num) {\n  return lookup[num >> 18 & 0x3F] +\n    lookup[num >> 12 & 0x3F] +\n    lookup[num >> 6 & 0x3F] +\n    lookup[num & 0x3F]\n}\n\nfunction encodeChunk (uint8, start, end) {\n  var tmp\n  var output = []\n  for (var i = start; i < end; i += 3) {\n    tmp =\n      ((uint8[i] << 16) & 0xFF0000) +\n      ((uint8[i + 1] << 8) & 0xFF00) +\n      (uint8[i + 2] & 0xFF)\n    output.push(tripletToBase64(tmp))\n  }\n  return output.join('')\n}\n\nfunction fromByteArray (uint8) {\n  var tmp\n  var len = uint8.length\n  var extraBytes = len % 3 // if we have 1 byte left, pad 2 bytes\n  var parts = []\n  var maxChunkLength = 16383 // must be multiple of 3\n\n  // go through the array every three bytes, we'll deal with trailing stuff later\n  for (var i = 0, len2 = len - extraBytes; i < len2; i += maxChunkLength) {\n    parts.push(encodeChunk(\n      uint8, i, (i + maxChunkLength) > len2 ? len2 : (i + maxChunkLength)\n    ))\n  }\n\n  // pad the end with zeros, but make sure to not forget the extra bytes\n  if (extraBytes === 1) {\n    tmp = uint8[len - 1]\n    parts.push(\n      lookup[tmp >> 2] +\n      lookup[(tmp << 4) & 0x3F] +\n      '=='\n    )\n  } else if (extraBytes === 2) {\n    tmp = (uint8[len - 2] << 8) + uint8[len - 1]\n    parts.push(\n      lookup[tmp >> 10] +\n      lookup[(tmp >> 4) & 0x3F] +\n      lookup[(tmp << 2) & 0x3F] +\n      '='\n    )\n  }\n\n  return parts.join('')\n}\n","exports.read = function (buffer, offset, isLE, mLen, nBytes) {\n  var e, m\n  var eLen = (nBytes * 8) - mLen - 1\n  var eMax = (1 << eLen) - 1\n  var eBias = eMax >> 1\n  var nBits = -7\n  var i = isLE ? (nBytes - 1) : 0\n  var d = isLE ? -1 : 1\n  var s = buffer[offset + i]\n\n  i += d\n\n  e = s & ((1 << (-nBits)) - 1)\n  s >>= (-nBits)\n  nBits += eLen\n  for (; nBits > 0; e = (e * 256) + buffer[offset + i], i += d, nBits -= 8) {}\n\n  m = e & ((1 << (-nBits)) - 1)\n  e >>= (-nBits)\n  nBits += mLen\n  for (; nBits > 0; m = (m * 256) + buffer[offset + i], i += d, nBits -= 8) {}\n\n  if (e === 0) {\n    e = 1 - eBias\n  } else if (e === eMax) {\n    return m ? NaN : ((s ? -1 : 1) * Infinity)\n  } else {\n    m = m + Math.pow(2, mLen)\n    e = e - eBias\n  }\n  return (s ? -1 : 1) * m * Math.pow(2, e - mLen)\n}\n\nexports.write = function (buffer, value, offset, isLE, mLen, nBytes) {\n  var e, m, c\n  var eLen = (nBytes * 8) - mLen - 1\n  var eMax = (1 << eLen) - 1\n  var eBias = eMax >> 1\n  var rt = (mLen === 23 ? Math.pow(2, -24) - Math.pow(2, -77) : 0)\n  var i = isLE ? 0 : (nBytes - 1)\n  var d = isLE ? 1 : -1\n  var s = value < 0 || (value === 0 && 1 / value < 0) ? 1 : 0\n\n  value = Math.abs(value)\n\n  if (isNaN(value) || value === Infinity) {\n    m = isNaN(value) ? 1 : 0\n    e = eMax\n  } else {\n    e = Math.floor(Math.log(value) / Math.LN2)\n    if (value * (c = Math.pow(2, -e)) < 1) {\n      e--\n      c *= 2\n    }\n    if (e + eBias >= 1) {\n      value += rt / c\n    } else {\n      value += rt * Math.pow(2, 1 - eBias)\n    }\n    if (value * c >= 2) {\n      e++\n      c /= 2\n    }\n\n    if (e + eBias >= eMax) {\n      m = 0\n      e = eMax\n    } else if (e + eBias >= 1) {\n      m = ((value * c) - 1) * Math.pow(2, mLen)\n      e = e + eBias\n    } else {\n      m = value * Math.pow(2, eBias - 1) * Math.pow(2, mLen)\n      e = 0\n    }\n  }\n\n  for (; mLen >= 8; buffer[offset + i] = m & 0xff, i += d, m /= 256, mLen -= 8) {}\n\n  e = (e << mLen) | m\n  eLen += mLen\n  for (; eLen > 0; buffer[offset + i] = e & 0xff, i += d, e /= 256, eLen -= 8) {}\n\n  buffer[offset + i - d] |= s * 128\n}\n","var toString = {}.toString;\n\nmodule.exports = Array.isArray || function (arr) {\n  return toString.call(arr) == '[object Array]';\n};\n","/*!\n * The buffer module from node.js, for the browser.\n *\n * @author   Feross Aboukhadijeh <feross@feross.org> <http://feross.org>\n * @license  MIT\n */\n/* eslint-disable no-proto */\n\n'use strict'\n\nvar base64 = require('base64-js')\nvar ieee754 = require('ieee754')\nvar isArray = require('isarray')\n\nexports.Buffer = Buffer\nexports.SlowBuffer = SlowBuffer\nexports.INSPECT_MAX_BYTES = 50\n\n/**\n * If `Buffer.TYPED_ARRAY_SUPPORT`:\n *   === true    Use Uint8Array implementation (fastest)\n *   === false   Use Object implementation (most compatible, even IE6)\n *\n * Browsers that support typed arrays are IE 10+, Firefox 4+, Chrome 7+, Safari 5.1+,\n * Opera 11.6+, iOS 4.2+.\n *\n * Due to various browser bugs, sometimes the Object implementation will be used even\n * when the browser supports typed arrays.\n *\n * Note:\n *\n *   - Firefox 4-29 lacks support for adding new properties to `Uint8Array` instances,\n *     See: https://bugzilla.mozilla.org/show_bug.cgi?id=695438.\n *\n *   - Chrome 9-10 is missing the `TypedArray.prototype.subarray` function.\n *\n *   - IE10 has a broken `TypedArray.prototype.subarray` function which returns arrays of\n *     incorrect length in some situations.\n\n * We detect these buggy browsers and set `Buffer.TYPED_ARRAY_SUPPORT` to `false` so they\n * get the Object implementation, which is slower but behaves correctly.\n */\nBuffer.TYPED_ARRAY_SUPPORT = global.TYPED_ARRAY_SUPPORT !== undefined\n  ? global.TYPED_ARRAY_SUPPORT\n  : typedArraySupport()\n\n/*\n * Export kMaxLength after typed array support is determined.\n */\nexports.kMaxLength = kMaxLength()\n\nfunction typedArraySupport () {\n  try {\n    var arr = new Uint8Array(1)\n    arr.__proto__ = {__proto__: Uint8Array.prototype, foo: function () { return 42 }}\n    return arr.foo() === 42 && // typed array instances can be augmented\n        typeof arr.subarray === 'function' && // chrome 9-10 lack `subarray`\n        arr.subarray(1, 1).byteLength === 0 // ie10 has broken `subarray`\n  } catch (e) {\n    return false\n  }\n}\n\nfunction kMaxLength () {\n  return Buffer.TYPED_ARRAY_SUPPORT\n    ? 0x7fffffff\n    : 0x3fffffff\n}\n\nfunction createBuffer (that, length) {\n  if (kMaxLength() < length) {\n    throw new RangeError('Invalid typed array length')\n  }\n  if (Buffer.TYPED_ARRAY_SUPPORT) {\n    // Return an augmented `Uint8Array` instance, for best performance\n    that = new Uint8Array(length)\n    that.__proto__ = Buffer.prototype\n  } else {\n    // Fallback: Return an object instance of the Buffer class\n    if (that === null) {\n      that = new Buffer(length)\n    }\n    that.length = length\n  }\n\n  return that\n}\n\n/**\n * The Buffer constructor returns instances of `Uint8Array` that have their\n * prototype changed to `Buffer.prototype`. Furthermore, `Buffer` is a subclass of\n * `Uint8Array`, so the returned instances will have all the node `Buffer` methods\n * and the `Uint8Array` methods. Square bracket notation works as expected -- it\n * returns a single octet.\n *\n * The `Uint8Array` prototype remains unmodified.\n */\n\nfunction Buffer (arg, encodingOrOffset, length) {\n  if (!Buffer.TYPED_ARRAY_SUPPORT && !(this instanceof Buffer)) {\n    return new Buffer(arg, encodingOrOffset, length)\n  }\n\n  // Common case.\n  if (typeof arg === 'number') {\n    if (typeof encodingOrOffset === 'string') {\n      throw new Error(\n        'If encoding is specified then the first argument must be a string'\n      )\n    }\n    return allocUnsafe(this, arg)\n  }\n  return from(this, arg, encodingOrOffset, length)\n}\n\nBuffer.poolSize = 8192 // not used by this implementation\n\n// TODO: Legacy, not needed anymore. Remove in next major version.\nBuffer._augment = function (arr) {\n  arr.__proto__ = Buffer.prototype\n  return arr\n}\n\nfunction from (that, value, encodingOrOffset, length) {\n  if (typeof value === 'number') {\n    throw new TypeError('\"value\" argument must not be a number')\n  }\n\n  if (typeof ArrayBuffer !== 'undefined' && value instanceof ArrayBuffer) {\n    return fromArrayBuffer(that, value, encodingOrOffset, length)\n  }\n\n  if (typeof value === 'string') {\n    return fromString(that, value, encodingOrOffset)\n  }\n\n  return fromObject(that, value)\n}\n\n/**\n * Functionally equivalent to Buffer(arg, encoding) but throws a TypeError\n * if value is a number.\n * Buffer.from(str[, encoding])\n * Buffer.from(array)\n * Buffer.from(buffer)\n * Buffer.from(arrayBuffer[, byteOffset[, length]])\n **/\nBuffer.from = function (value, encodingOrOffset, length) {\n  return from(null, value, encodingOrOffset, length)\n}\n\nif (Buffer.TYPED_ARRAY_SUPPORT) {\n  Buffer.prototype.__proto__ = Uint8Array.prototype\n  Buffer.__proto__ = Uint8Array\n  if (typeof Symbol !== 'undefined' && Symbol.species &&\n      Buffer[Symbol.species] === Buffer) {\n    // Fix subarray() in ES2016. See: https://github.com/feross/buffer/pull/97\n    Object.defineProperty(Buffer, Symbol.species, {\n      value: null,\n      configurable: true\n    })\n  }\n}\n\nfunction assertSize (size) {\n  if (typeof size !== 'number') {\n    throw new TypeError('\"size\" argument must be a number')\n  } else if (size < 0) {\n    throw new RangeError('\"size\" argument must not be negative')\n  }\n}\n\nfunction alloc (that, size, fill, encoding) {\n  assertSize(size)\n  if (size <= 0) {\n    return createBuffer(that, size)\n  }\n  if (fill !== undefined) {\n    // Only pay attention to encoding if it's a string. This\n    // prevents accidentally sending in a number that would\n    // be interpretted as a start offset.\n    return typeof encoding === 'string'\n      ? createBuffer(that, size).fill(fill, encoding)\n      : createBuffer(that, size).fill(fill)\n  }\n  return createBuffer(that, size)\n}\n\n/**\n * Creates a new filled Buffer instance.\n * alloc(size[, fill[, encoding]])\n **/\nBuffer.alloc = function (size, fill, encoding) {\n  return alloc(null, size, fill, encoding)\n}\n\nfunction allocUnsafe (that, size) {\n  assertSize(size)\n  that = createBuffer(that, size < 0 ? 0 : checked(size) | 0)\n  if (!Buffer.TYPED_ARRAY_SUPPORT) {\n    for (var i = 0; i < size; ++i) {\n      that[i] = 0\n    }\n  }\n  return that\n}\n\n/**\n * Equivalent to Buffer(num), by default creates a non-zero-filled Buffer instance.\n * */\nBuffer.allocUnsafe = function (size) {\n  return allocUnsafe(null, size)\n}\n/**\n * Equivalent to SlowBuffer(num), by default creates a non-zero-filled Buffer instance.\n */\nBuffer.allocUnsafeSlow = function (size) {\n  return allocUnsafe(null, size)\n}\n\nfunction fromString (that, string, encoding) {\n  if (typeof encoding !== 'string' || encoding === '') {\n    encoding = 'utf8'\n  }\n\n  if (!Buffer.isEncoding(encoding)) {\n    throw new TypeError('\"encoding\" must be a valid string encoding')\n  }\n\n  var length = byteLength(string, encoding) | 0\n  that = createBuffer(that, length)\n\n  var actual = that.write(string, encoding)\n\n  if (actual !== length) {\n    // Writing a hex string, for example, that contains invalid characters will\n    // cause everything after the first invalid character to be ignored. (e.g.\n    // 'abxxcd' will be treated as 'ab')\n    that = that.slice(0, actual)\n  }\n\n  return that\n}\n\nfunction fromArrayLike (that, array) {\n  var length = array.length < 0 ? 0 : checked(array.length) | 0\n  that = createBuffer(that, length)\n  for (var i = 0; i < length; i += 1) {\n    that[i] = array[i] & 255\n  }\n  return that\n}\n\nfunction fromArrayBuffer (that, array, byteOffset, length) {\n  array.byteLength // this throws if `array` is not a valid ArrayBuffer\n\n  if (byteOffset < 0 || array.byteLength < byteOffset) {\n    throw new RangeError('\\'offset\\' is out of bounds')\n  }\n\n  if (array.byteLength < byteOffset + (length || 0)) {\n    throw new RangeError('\\'length\\' is out of bounds')\n  }\n\n  if (byteOffset === undefined && length === undefined) {\n    array = new Uint8Array(array)\n  } else if (length === undefined) {\n    array = new Uint8Array(array, byteOffset)\n  } else {\n    array = new Uint8Array(array, byteOffset, length)\n  }\n\n  if (Buffer.TYPED_ARRAY_SUPPORT) {\n    // Return an augmented `Uint8Array` instance, for best performance\n    that = array\n    that.__proto__ = Buffer.prototype\n  } else {\n    // Fallback: Return an object instance of the Buffer class\n    that = fromArrayLike(that, array)\n  }\n  return that\n}\n\nfunction fromObject (that, obj) {\n  if (Buffer.isBuffer(obj)) {\n    var len = checked(obj.length) | 0\n    that = createBuffer(that, len)\n\n    if (that.length === 0) {\n      return that\n    }\n\n    obj.copy(that, 0, 0, len)\n    return that\n  }\n\n  if (obj) {\n    if ((typeof ArrayBuffer !== 'undefined' &&\n        obj.buffer instanceof ArrayBuffer) || 'length' in obj) {\n      if (typeof obj.length !== 'number' || isnan(obj.length)) {\n        return createBuffer(that, 0)\n      }\n      return fromArrayLike(that, obj)\n    }\n\n    if (obj.type === 'Buffer' && isArray(obj.data)) {\n      return fromArrayLike(that, obj.data)\n    }\n  }\n\n  throw new TypeError('First argument must be a string, Buffer, ArrayBuffer, Array, or array-like object.')\n}\n\nfunction checked (length) {\n  // Note: cannot use `length < kMaxLength()` here because that fails when\n  // length is NaN (which is otherwise coerced to zero.)\n  if (length >= kMaxLength()) {\n    throw new RangeError('Attempt to allocate Buffer larger than maximum ' +\n                         'size: 0x' + kMaxLength().toString(16) + ' bytes')\n  }\n  return length | 0\n}\n\nfunction SlowBuffer (length) {\n  if (+length != length) { // eslint-disable-line eqeqeq\n    length = 0\n  }\n  return Buffer.alloc(+length)\n}\n\nBuffer.isBuffer = function isBuffer (b) {\n  return !!(b != null && b._isBuffer)\n}\n\nBuffer.compare = function compare (a, b) {\n  if (!Buffer.isBuffer(a) || !Buffer.isBuffer(b)) {\n    throw new TypeError('Arguments must be Buffers')\n  }\n\n  if (a === b) return 0\n\n  var x = a.length\n  var y = b.length\n\n  for (var i = 0, len = Math.min(x, y); i < len; ++i) {\n    if (a[i] !== b[i]) {\n      x = a[i]\n      y = b[i]\n      break\n    }\n  }\n\n  if (x < y) return -1\n  if (y < x) return 1\n  return 0\n}\n\nBuffer.isEncoding = function isEncoding (encoding) {\n  switch (String(encoding).toLowerCase()) {\n    case 'hex':\n    case 'utf8':\n    case 'utf-8':\n    case 'ascii':\n    case 'latin1':\n    case 'binary':\n    case 'base64':\n    case 'ucs2':\n    case 'ucs-2':\n    case 'utf16le':\n    case 'utf-16le':\n      return true\n    default:\n      return false\n  }\n}\n\nBuffer.concat = function concat (list, length) {\n  if (!isArray(list)) {\n    throw new TypeError('\"list\" argument must be an Array of Buffers')\n  }\n\n  if (list.length === 0) {\n    return Buffer.alloc(0)\n  }\n\n  var i\n  if (length === undefined) {\n    length = 0\n    for (i = 0; i < list.length; ++i) {\n      length += list[i].length\n    }\n  }\n\n  var buffer = Buffer.allocUnsafe(length)\n  var pos = 0\n  for (i = 0; i < list.length; ++i) {\n    var buf = list[i]\n    if (!Buffer.isBuffer(buf)) {\n      throw new TypeError('\"list\" argument must be an Array of Buffers')\n    }\n    buf.copy(buffer, pos)\n    pos += buf.length\n  }\n  return buffer\n}\n\nfunction byteLength (string, encoding) {\n  if (Buffer.isBuffer(string)) {\n    return string.length\n  }\n  if (typeof ArrayBuffer !== 'undefined' && typeof ArrayBuffer.isView === 'function' &&\n      (ArrayBuffer.isView(string) || string instanceof ArrayBuffer)) {\n    return string.byteLength\n  }\n  if (typeof string !== 'string') {\n    string = '' + string\n  }\n\n  var len = string.length\n  if (len === 0) return 0\n\n  // Use a for loop to avoid recursion\n  var loweredCase = false\n  for (;;) {\n    switch (encoding) {\n      case 'ascii':\n      case 'latin1':\n      case 'binary':\n        return len\n      case 'utf8':\n      case 'utf-8':\n      case undefined:\n        return utf8ToBytes(string).length\n      case 'ucs2':\n      case 'ucs-2':\n      case 'utf16le':\n      case 'utf-16le':\n        return len * 2\n      case 'hex':\n        return len >>> 1\n      case 'base64':\n        return base64ToBytes(string).length\n      default:\n        if (loweredCase) return utf8ToBytes(string).length // assume utf8\n        encoding = ('' + encoding).toLowerCase()\n        loweredCase = true\n    }\n  }\n}\nBuffer.byteLength = byteLength\n\nfunction slowToString (encoding, start, end) {\n  var loweredCase = false\n\n  // No need to verify that \"this.length <= MAX_UINT32\" since it's a read-only\n  // property of a typed array.\n\n  // This behaves neither like String nor Uint8Array in that we set start/end\n  // to their upper/lower bounds if the value passed is out of range.\n  // undefined is handled specially as per ECMA-262 6th Edition,\n  // Section 13.3.3.7 Runtime Semantics: KeyedBindingInitialization.\n  if (start === undefined || start < 0) {\n    start = 0\n  }\n  // Return early if start > this.length. Done here to prevent potential uint32\n  // coercion fail below.\n  if (start > this.length) {\n    return ''\n  }\n\n  if (end === undefined || end > this.length) {\n    end = this.length\n  }\n\n  if (end <= 0) {\n    return ''\n  }\n\n  // Force coersion to uint32. This will also coerce falsey/NaN values to 0.\n  end >>>= 0\n  start >>>= 0\n\n  if (end <= start) {\n    return ''\n  }\n\n  if (!encoding) encoding = 'utf8'\n\n  while (true) {\n    switch (encoding) {\n      case 'hex':\n        return hexSlice(this, start, end)\n\n      case 'utf8':\n      case 'utf-8':\n        return utf8Slice(this, start, end)\n\n      case 'ascii':\n        return asciiSlice(this, start, end)\n\n      case 'latin1':\n      case 'binary':\n        return latin1Slice(this, start, end)\n\n      case 'base64':\n        return base64Slice(this, start, end)\n\n      case 'ucs2':\n      case 'ucs-2':\n      case 'utf16le':\n      case 'utf-16le':\n        return utf16leSlice(this, start, end)\n\n      default:\n        if (loweredCase) throw new TypeError('Unknown encoding: ' + encoding)\n        encoding = (encoding + '').toLowerCase()\n        loweredCase = true\n    }\n  }\n}\n\n// The property is used by `Buffer.isBuffer` and `is-buffer` (in Safari 5-7) to detect\n// Buffer instances.\nBuffer.prototype._isBuffer = true\n\nfunction swap (b, n, m) {\n  var i = b[n]\n  b[n] = b[m]\n  b[m] = i\n}\n\nBuffer.prototype.swap16 = function swap16 () {\n  var len = this.length\n  if (len % 2 !== 0) {\n    throw new RangeError('Buffer size must be a multiple of 16-bits')\n  }\n  for (var i = 0; i < len; i += 2) {\n    swap(this, i, i + 1)\n  }\n  return this\n}\n\nBuffer.prototype.swap32 = function swap32 () {\n  var len = this.length\n  if (len % 4 !== 0) {\n    throw new RangeError('Buffer size must be a multiple of 32-bits')\n  }\n  for (var i = 0; i < len; i += 4) {\n    swap(this, i, i + 3)\n    swap(this, i + 1, i + 2)\n  }\n  return this\n}\n\nBuffer.prototype.swap64 = function swap64 () {\n  var len = this.length\n  if (len % 8 !== 0) {\n    throw new RangeError('Buffer size must be a multiple of 64-bits')\n  }\n  for (var i = 0; i < len; i += 8) {\n    swap(this, i, i + 7)\n    swap(this, i + 1, i + 6)\n    swap(this, i + 2, i + 5)\n    swap(this, i + 3, i + 4)\n  }\n  return this\n}\n\nBuffer.prototype.toString = function toString () {\n  var length = this.length | 0\n  if (length === 0) return ''\n  if (arguments.length === 0) return utf8Slice(this, 0, length)\n  return slowToString.apply(this, arguments)\n}\n\nBuffer.prototype.equals = function equals (b) {\n  if (!Buffer.isBuffer(b)) throw new TypeError('Argument must be a Buffer')\n  if (this === b) return true\n  return Buffer.compare(this, b) === 0\n}\n\nBuffer.prototype.inspect = function inspect () {\n  var str = ''\n  var max = exports.INSPECT_MAX_BYTES\n  if (this.length > 0) {\n    str = this.toString('hex', 0, max).match(/.{2}/g).join(' ')\n    if (this.length > max) str += ' ... '\n  }\n  return '<Buffer ' + str + '>'\n}\n\nBuffer.prototype.compare = function compare (target, start, end, thisStart, thisEnd) {\n  if (!Buffer.isBuffer(target)) {\n    throw new TypeError('Argument must be a Buffer')\n  }\n\n  if (start === undefined) {\n    start = 0\n  }\n  if (end === undefined) {\n    end = target ? target.length : 0\n  }\n  if (thisStart === undefined) {\n    thisStart = 0\n  }\n  if (thisEnd === undefined) {\n    thisEnd = this.length\n  }\n\n  if (start < 0 || end > target.length || thisStart < 0 || thisEnd > this.length) {\n    throw new RangeError('out of range index')\n  }\n\n  if (thisStart >= thisEnd && start >= end) {\n    return 0\n  }\n  if (thisStart >= thisEnd) {\n    return -1\n  }\n  if (start >= end) {\n    return 1\n  }\n\n  start >>>= 0\n  end >>>= 0\n  thisStart >>>= 0\n  thisEnd >>>= 0\n\n  if (this === target) return 0\n\n  var x = thisEnd - thisStart\n  var y = end - start\n  var len = Math.min(x, y)\n\n  var thisCopy = this.slice(thisStart, thisEnd)\n  var targetCopy = target.slice(start, end)\n\n  for (var i = 0; i < len; ++i) {\n    if (thisCopy[i] !== targetCopy[i]) {\n      x = thisCopy[i]\n      y = targetCopy[i]\n      break\n    }\n  }\n\n  if (x < y) return -1\n  if (y < x) return 1\n  return 0\n}\n\n// Finds either the first index of `val` in `buffer` at offset >= `byteOffset`,\n// OR the last index of `val` in `buffer` at offset <= `byteOffset`.\n//\n// Arguments:\n// - buffer - a Buffer to search\n// - val - a string, Buffer, or number\n// - byteOffset - an index into `buffer`; will be clamped to an int32\n// - encoding - an optional encoding, relevant is val is a string\n// - dir - true for indexOf, false for lastIndexOf\nfunction bidirectionalIndexOf (buffer, val, byteOffset, encoding, dir) {\n  // Empty buffer means no match\n  if (buffer.length === 0) return -1\n\n  // Normalize byteOffset\n  if (typeof byteOffset === 'string') {\n    encoding = byteOffset\n    byteOffset = 0\n  } else if (byteOffset > 0x7fffffff) {\n    byteOffset = 0x7fffffff\n  } else if (byteOffset < -0x80000000) {\n    byteOffset = -0x80000000\n  }\n  byteOffset = +byteOffset  // Coerce to Number.\n  if (isNaN(byteOffset)) {\n    // byteOffset: it it's undefined, null, NaN, \"foo\", etc, search whole buffer\n    byteOffset = dir ? 0 : (buffer.length - 1)\n  }\n\n  // Normalize byteOffset: negative offsets start from the end of the buffer\n  if (byteOffset < 0) byteOffset = buffer.length + byteOffset\n  if (byteOffset >= buffer.length) {\n    if (dir) return -1\n    else byteOffset = buffer.length - 1\n  } else if (byteOffset < 0) {\n    if (dir) byteOffset = 0\n    else return -1\n  }\n\n  // Normalize val\n  if (typeof val === 'string') {\n    val = Buffer.from(val, encoding)\n  }\n\n  // Finally, search either indexOf (if dir is true) or lastIndexOf\n  if (Buffer.isBuffer(val)) {\n    // Special case: looking for empty string/buffer always fails\n    if (val.length === 0) {\n      return -1\n    }\n    return arrayIndexOf(buffer, val, byteOffset, encoding, dir)\n  } else if (typeof val === 'number') {\n    val = val & 0xFF // Search for a byte value [0-255]\n    if (Buffer.TYPED_ARRAY_SUPPORT &&\n        typeof Uint8Array.prototype.indexOf === 'function') {\n      if (dir) {\n        return Uint8Array.prototype.indexOf.call(buffer, val, byteOffset)\n      } else {\n        return Uint8Array.prototype.lastIndexOf.call(buffer, val, byteOffset)\n      }\n    }\n    return arrayIndexOf(buffer, [ val ], byteOffset, encoding, dir)\n  }\n\n  throw new TypeError('val must be string, number or Buffer')\n}\n\nfunction arrayIndexOf (arr, val, byteOffset, encoding, dir) {\n  var indexSize = 1\n  var arrLength = arr.length\n  var valLength = val.length\n\n  if (encoding !== undefined) {\n    encoding = String(encoding).toLowerCase()\n    if (encoding === 'ucs2' || encoding === 'ucs-2' ||\n        encoding === 'utf16le' || encoding === 'utf-16le') {\n      if (arr.length < 2 || val.length < 2) {\n        return -1\n      }\n      indexSize = 2\n      arrLength /= 2\n      valLength /= 2\n      byteOffset /= 2\n    }\n  }\n\n  function read (buf, i) {\n    if (indexSize === 1) {\n      return buf[i]\n    } else {\n      return buf.readUInt16BE(i * indexSize)\n    }\n  }\n\n  var i\n  if (dir) {\n    var foundIndex = -1\n    for (i = byteOffset; i < arrLength; i++) {\n      if (read(arr, i) === read(val, foundIndex === -1 ? 0 : i - foundIndex)) {\n        if (foundIndex === -1) foundIndex = i\n        if (i - foundIndex + 1 === valLength) return foundIndex * indexSize\n      } else {\n        if (foundIndex !== -1) i -= i - foundIndex\n        foundIndex = -1\n      }\n    }\n  } else {\n    if (byteOffset + valLength > arrLength) byteOffset = arrLength - valLength\n    for (i = byteOffset; i >= 0; i--) {\n      var found = true\n      for (var j = 0; j < valLength; j++) {\n        if (read(arr, i + j) !== read(val, j)) {\n          found = false\n          break\n        }\n      }\n      if (found) return i\n    }\n  }\n\n  return -1\n}\n\nBuffer.prototype.includes = function includes (val, byteOffset, encoding) {\n  return this.indexOf(val, byteOffset, encoding) !== -1\n}\n\nBuffer.prototype.indexOf = function indexOf (val, byteOffset, encoding) {\n  return bidirectionalIndexOf(this, val, byteOffset, encoding, true)\n}\n\nBuffer.prototype.lastIndexOf = function lastIndexOf (val, byteOffset, encoding) {\n  return bidirectionalIndexOf(this, val, byteOffset, encoding, false)\n}\n\nfunction hexWrite (buf, string, offset, length) {\n  offset = Number(offset) || 0\n  var remaining = buf.length - offset\n  if (!length) {\n    length = remaining\n  } else {\n    length = Number(length)\n    if (length > remaining) {\n      length = remaining\n    }\n  }\n\n  // must be an even number of digits\n  var strLen = string.length\n  if (strLen % 2 !== 0) throw new TypeError('Invalid hex string')\n\n  if (length > strLen / 2) {\n    length = strLen / 2\n  }\n  for (var i = 0; i < length; ++i) {\n    var parsed = parseInt(string.substr(i * 2, 2), 16)\n    if (isNaN(parsed)) return i\n    buf[offset + i] = parsed\n  }\n  return i\n}\n\nfunction utf8Write (buf, string, offset, length) {\n  return blitBuffer(utf8ToBytes(string, buf.length - offset), buf, offset, length)\n}\n\nfunction asciiWrite (buf, string, offset, length) {\n  return blitBuffer(asciiToBytes(string), buf, offset, length)\n}\n\nfunction latin1Write (buf, string, offset, length) {\n  return asciiWrite(buf, string, offset, length)\n}\n\nfunction base64Write (buf, string, offset, length) {\n  return blitBuffer(base64ToBytes(string), buf, offset, length)\n}\n\nfunction ucs2Write (buf, string, offset, length) {\n  return blitBuffer(utf16leToBytes(string, buf.length - offset), buf, offset, length)\n}\n\nBuffer.prototype.write = function write (string, offset, length, encoding) {\n  // Buffer#write(string)\n  if (offset === undefined) {\n    encoding = 'utf8'\n    length = this.length\n    offset = 0\n  // Buffer#write(string, encoding)\n  } else if (length === undefined && typeof offset === 'string') {\n    encoding = offset\n    length = this.length\n    offset = 0\n  // Buffer#write(string, offset[, length][, encoding])\n  } else if (isFinite(offset)) {\n    offset = offset | 0\n    if (isFinite(length)) {\n      length = length | 0\n      if (encoding === undefined) encoding = 'utf8'\n    } else {\n      encoding = length\n      length = undefined\n    }\n  // legacy write(string, encoding, offset, length) - remove in v0.13\n  } else {\n    throw new Error(\n      'Buffer.write(string, encoding, offset[, length]) is no longer supported'\n    )\n  }\n\n  var remaining = this.length - offset\n  if (length === undefined || length > remaining) length = remaining\n\n  if ((string.length > 0 && (length < 0 || offset < 0)) || offset > this.length) {\n    throw new RangeError('Attempt to write outside buffer bounds')\n  }\n\n  if (!encoding) encoding = 'utf8'\n\n  var loweredCase = false\n  for (;;) {\n    switch (encoding) {\n      case 'hex':\n        return hexWrite(this, string, offset, length)\n\n      case 'utf8':\n      case 'utf-8':\n        return utf8Write(this, string, offset, length)\n\n      case 'ascii':\n        return asciiWrite(this, string, offset, length)\n\n      case 'latin1':\n      case 'binary':\n        return latin1Write(this, string, offset, length)\n\n      case 'base64':\n        // Warning: maxLength not taken into account in base64Write\n        return base64Write(this, string, offset, length)\n\n      case 'ucs2':\n      case 'ucs-2':\n      case 'utf16le':\n      case 'utf-16le':\n        return ucs2Write(this, string, offset, length)\n\n      default:\n        if (loweredCase) throw new TypeError('Unknown encoding: ' + encoding)\n        encoding = ('' + encoding).toLowerCase()\n        loweredCase = true\n    }\n  }\n}\n\nBuffer.prototype.toJSON = function toJSON () {\n  return {\n    type: 'Buffer',\n    data: Array.prototype.slice.call(this._arr || this, 0)\n  }\n}\n\nfunction base64Slice (buf, start, end) {\n  if (start === 0 && end === buf.length) {\n    return base64.fromByteArray(buf)\n  } else {\n    return base64.fromByteArray(buf.slice(start, end))\n  }\n}\n\nfunction utf8Slice (buf, start, end) {\n  end = Math.min(buf.length, end)\n  var res = []\n\n  var i = start\n  while (i < end) {\n    var firstByte = buf[i]\n    var codePoint = null\n    var bytesPerSequence = (firstByte > 0xEF) ? 4\n      : (firstByte > 0xDF) ? 3\n      : (firstByte > 0xBF) ? 2\n      : 1\n\n    if (i + bytesPerSequence <= end) {\n      var secondByte, thirdByte, fourthByte, tempCodePoint\n\n      switch (bytesPerSequence) {\n        case 1:\n          if (firstByte < 0x80) {\n            codePoint = firstByte\n          }\n          break\n        case 2:\n          secondByte = buf[i + 1]\n          if ((secondByte & 0xC0) === 0x80) {\n            tempCodePoint = (firstByte & 0x1F) << 0x6 | (secondByte & 0x3F)\n            if (tempCodePoint > 0x7F) {\n              codePoint = tempCodePoint\n            }\n          }\n          break\n        case 3:\n          secondByte = buf[i + 1]\n          thirdByte = buf[i + 2]\n          if ((secondByte & 0xC0) === 0x80 && (thirdByte & 0xC0) === 0x80) {\n            tempCodePoint = (firstByte & 0xF) << 0xC | (secondByte & 0x3F) << 0x6 | (thirdByte & 0x3F)\n            if (tempCodePoint > 0x7FF && (tempCodePoint < 0xD800 || tempCodePoint > 0xDFFF)) {\n              codePoint = tempCodePoint\n            }\n          }\n          break\n        case 4:\n          secondByte = buf[i + 1]\n          thirdByte = buf[i + 2]\n          fourthByte = buf[i + 3]\n          if ((secondByte & 0xC0) === 0x80 && (thirdByte & 0xC0) === 0x80 && (fourthByte & 0xC0) === 0x80) {\n            tempCodePoint = (firstByte & 0xF) << 0x12 | (secondByte & 0x3F) << 0xC | (thirdByte & 0x3F) << 0x6 | (fourthByte & 0x3F)\n            if (tempCodePoint > 0xFFFF && tempCodePoint < 0x110000) {\n              codePoint = tempCodePoint\n            }\n          }\n      }\n    }\n\n    if (codePoint === null) {\n      // we did not generate a valid codePoint so insert a\n      // replacement char (U+FFFD) and advance only 1 byte\n      codePoint = 0xFFFD\n      bytesPerSequence = 1\n    } else if (codePoint > 0xFFFF) {\n      // encode to utf16 (surrogate pair dance)\n      codePoint -= 0x10000\n      res.push(codePoint >>> 10 & 0x3FF | 0xD800)\n      codePoint = 0xDC00 | codePoint & 0x3FF\n    }\n\n    res.push(codePoint)\n    i += bytesPerSequence\n  }\n\n  return decodeCodePointsArray(res)\n}\n\n// Based on http://stackoverflow.com/a/22747272/680742, the browser with\n// the lowest limit is Chrome, with 0x10000 args.\n// We go 1 magnitude less, for safety\nvar MAX_ARGUMENTS_LENGTH = 0x1000\n\nfunction decodeCodePointsArray (codePoints) {\n  var len = codePoints.length\n  if (len <= MAX_ARGUMENTS_LENGTH) {\n    return String.fromCharCode.apply(String, codePoints) // avoid extra slice()\n  }\n\n  // Decode in chunks to avoid \"call stack size exceeded\".\n  var res = ''\n  var i = 0\n  while (i < len) {\n    res += String.fromCharCode.apply(\n      String,\n      codePoints.slice(i, i += MAX_ARGUMENTS_LENGTH)\n    )\n  }\n  return res\n}\n\nfunction asciiSlice (buf, start, end) {\n  var ret = ''\n  end = Math.min(buf.length, end)\n\n  for (var i = start; i < end; ++i) {\n    ret += String.fromCharCode(buf[i] & 0x7F)\n  }\n  return ret\n}\n\nfunction latin1Slice (buf, start, end) {\n  var ret = ''\n  end = Math.min(buf.length, end)\n\n  for (var i = start; i < end; ++i) {\n    ret += String.fromCharCode(buf[i])\n  }\n  return ret\n}\n\nfunction hexSlice (buf, start, end) {\n  var len = buf.length\n\n  if (!start || start < 0) start = 0\n  if (!end || end < 0 || end > len) end = len\n\n  var out = ''\n  for (var i = start; i < end; ++i) {\n    out += toHex(buf[i])\n  }\n  return out\n}\n\nfunction utf16leSlice (buf, start, end) {\n  var bytes = buf.slice(start, end)\n  var res = ''\n  for (var i = 0; i < bytes.length; i += 2) {\n    res += String.fromCharCode(bytes[i] + bytes[i + 1] * 256)\n  }\n  return res\n}\n\nBuffer.prototype.slice = function slice (start, end) {\n  var len = this.length\n  start = ~~start\n  end = end === undefined ? len : ~~end\n\n  if (start < 0) {\n    start += len\n    if (start < 0) start = 0\n  } else if (start > len) {\n    start = len\n  }\n\n  if (end < 0) {\n    end += len\n    if (end < 0) end = 0\n  } else if (end > len) {\n    end = len\n  }\n\n  if (end < start) end = start\n\n  var newBuf\n  if (Buffer.TYPED_ARRAY_SUPPORT) {\n    newBuf = this.subarray(start, end)\n    newBuf.__proto__ = Buffer.prototype\n  } else {\n    var sliceLen = end - start\n    newBuf = new Buffer(sliceLen, undefined)\n    for (var i = 0; i < sliceLen; ++i) {\n      newBuf[i] = this[i + start]\n    }\n  }\n\n  return newBuf\n}\n\n/*\n * Need to make sure that buffer isn't trying to write out of bounds.\n */\nfunction checkOffset (offset, ext, length) {\n  if ((offset % 1) !== 0 || offset < 0) throw new RangeError('offset is not uint')\n  if (offset + ext > length) throw new RangeError('Trying to access beyond buffer length')\n}\n\nBuffer.prototype.readUIntLE = function readUIntLE (offset, byteLength, noAssert) {\n  offset = offset | 0\n  byteLength = byteLength | 0\n  if (!noAssert) checkOffset(offset, byteLength, this.length)\n\n  var val = this[offset]\n  var mul = 1\n  var i = 0\n  while (++i < byteLength && (mul *= 0x100)) {\n    val += this[offset + i] * mul\n  }\n\n  return val\n}\n\nBuffer.prototype.readUIntBE = function readUIntBE (offset, byteLength, noAssert) {\n  offset = offset | 0\n  byteLength = byteLength | 0\n  if (!noAssert) {\n    checkOffset(offset, byteLength, this.length)\n  }\n\n  var val = this[offset + --byteLength]\n  var mul = 1\n  while (byteLength > 0 && (mul *= 0x100)) {\n    val += this[offset + --byteLength] * mul\n  }\n\n  return val\n}\n\nBuffer.prototype.readUInt8 = function readUInt8 (offset, noAssert) {\n  if (!noAssert) checkOffset(offset, 1, this.length)\n  return this[offset]\n}\n\nBuffer.prototype.readUInt16LE = function readUInt16LE (offset, noAssert) {\n  if (!noAssert) checkOffset(offset, 2, this.length)\n  return this[offset] | (this[offset + 1] << 8)\n}\n\nBuffer.prototype.readUInt16BE = function readUInt16BE (offset, noAssert) {\n  if (!noAssert) checkOffset(offset, 2, this.length)\n  return (this[offset] << 8) | this[offset + 1]\n}\n\nBuffer.prototype.readUInt32LE = function readUInt32LE (offset, noAssert) {\n  if (!noAssert) checkOffset(offset, 4, this.length)\n\n  return ((this[offset]) |\n      (this[offset + 1] << 8) |\n      (this[offset + 2] << 16)) +\n      (this[offset + 3] * 0x1000000)\n}\n\nBuffer.prototype.readUInt32BE = function readUInt32BE (offset, noAssert) {\n  if (!noAssert) checkOffset(offset, 4, this.length)\n\n  return (this[offset] * 0x1000000) +\n    ((this[offset + 1] << 16) |\n    (this[offset + 2] << 8) |\n    this[offset + 3])\n}\n\nBuffer.prototype.readIntLE = function readIntLE (offset, byteLength, noAssert) {\n  offset = offset | 0\n  byteLength = byteLength | 0\n  if (!noAssert) checkOffset(offset, byteLength, this.length)\n\n  var val = this[offset]\n  var mul = 1\n  var i = 0\n  while (++i < byteLength && (mul *= 0x100)) {\n    val += this[offset + i] * mul\n  }\n  mul *= 0x80\n\n  if (val >= mul) val -= Math.pow(2, 8 * byteLength)\n\n  return val\n}\n\nBuffer.prototype.readIntBE = function readIntBE (offset, byteLength, noAssert) {\n  offset = offset | 0\n  byteLength = byteLength | 0\n  if (!noAssert) checkOffset(offset, byteLength, this.length)\n\n  var i = byteLength\n  var mul = 1\n  var val = this[offset + --i]\n  while (i > 0 && (mul *= 0x100)) {\n    val += this[offset + --i] * mul\n  }\n  mul *= 0x80\n\n  if (val >= mul) val -= Math.pow(2, 8 * byteLength)\n\n  return val\n}\n\nBuffer.prototype.readInt8 = function readInt8 (offset, noAssert) {\n  if (!noAssert) checkOffset(offset, 1, this.length)\n  if (!(this[offset] & 0x80)) return (this[offset])\n  return ((0xff - this[offset] + 1) * -1)\n}\n\nBuffer.prototype.readInt16LE = function readInt16LE (offset, noAssert) {\n  if (!noAssert) checkOffset(offset, 2, this.length)\n  var val = this[offset] | (this[offset + 1] << 8)\n  return (val & 0x8000) ? val | 0xFFFF0000 : val\n}\n\nBuffer.prototype.readInt16BE = function readInt16BE (offset, noAssert) {\n  if (!noAssert) checkOffset(offset, 2, this.length)\n  var val = this[offset + 1] | (this[offset] << 8)\n  return (val & 0x8000) ? val | 0xFFFF0000 : val\n}\n\nBuffer.prototype.readInt32LE = function readInt32LE (offset, noAssert) {\n  if (!noAssert) checkOffset(offset, 4, this.length)\n\n  return (this[offset]) |\n    (this[offset + 1] << 8) |\n    (this[offset + 2] << 16) |\n    (this[offset + 3] << 24)\n}\n\nBuffer.prototype.readInt32BE = function readInt32BE (offset, noAssert) {\n  if (!noAssert) checkOffset(offset, 4, this.length)\n\n  return (this[offset] << 24) |\n    (this[offset + 1] << 16) |\n    (this[offset + 2] << 8) |\n    (this[offset + 3])\n}\n\nBuffer.prototype.readFloatLE = function readFloatLE (offset, noAssert) {\n  if (!noAssert) checkOffset(offset, 4, this.length)\n  return ieee754.read(this, offset, true, 23, 4)\n}\n\nBuffer.prototype.readFloatBE = function readFloatBE (offset, noAssert) {\n  if (!noAssert) checkOffset(offset, 4, this.length)\n  return ieee754.read(this, offset, false, 23, 4)\n}\n\nBuffer.prototype.readDoubleLE = function readDoubleLE (offset, noAssert) {\n  if (!noAssert) checkOffset(offset, 8, this.length)\n  return ieee754.read(this, offset, true, 52, 8)\n}\n\nBuffer.prototype.readDoubleBE = function readDoubleBE (offset, noAssert) {\n  if (!noAssert) checkOffset(offset, 8, this.length)\n  return ieee754.read(this, offset, false, 52, 8)\n}\n\nfunction checkInt (buf, value, offset, ext, max, min) {\n  if (!Buffer.isBuffer(buf)) throw new TypeError('\"buffer\" argument must be a Buffer instance')\n  if (value > max || value < min) throw new RangeError('\"value\" argument is out of bounds')\n  if (offset + ext > buf.length) throw new RangeError('Index out of range')\n}\n\nBuffer.prototype.writeUIntLE = function writeUIntLE (value, offset, byteLength, noAssert) {\n  value = +value\n  offset = offset | 0\n  byteLength = byteLength | 0\n  if (!noAssert) {\n    var maxBytes = Math.pow(2, 8 * byteLength) - 1\n    checkInt(this, value, offset, byteLength, maxBytes, 0)\n  }\n\n  var mul = 1\n  var i = 0\n  this[offset] = value & 0xFF\n  while (++i < byteLength && (mul *= 0x100)) {\n    this[offset + i] = (value / mul) & 0xFF\n  }\n\n  return offset + byteLength\n}\n\nBuffer.prototype.writeUIntBE = function writeUIntBE (value, offset, byteLength, noAssert) {\n  value = +value\n  offset = offset | 0\n  byteLength = byteLength | 0\n  if (!noAssert) {\n    var maxBytes = Math.pow(2, 8 * byteLength) - 1\n    checkInt(this, value, offset, byteLength, maxBytes, 0)\n  }\n\n  var i = byteLength - 1\n  var mul = 1\n  this[offset + i] = value & 0xFF\n  while (--i >= 0 && (mul *= 0x100)) {\n    this[offset + i] = (value / mul) & 0xFF\n  }\n\n  return offset + byteLength\n}\n\nBuffer.prototype.writeUInt8 = function writeUInt8 (value, offset, noAssert) {\n  value = +value\n  offset = offset | 0\n  if (!noAssert) checkInt(this, value, offset, 1, 0xff, 0)\n  if (!Buffer.TYPED_ARRAY_SUPPORT) value = Math.floor(value)\n  this[offset] = (value & 0xff)\n  return offset + 1\n}\n\nfunction objectWriteUInt16 (buf, value, offset, littleEndian) {\n  if (value < 0) value = 0xffff + value + 1\n  for (var i = 0, j = Math.min(buf.length - offset, 2); i < j; ++i) {\n    buf[offset + i] = (value & (0xff << (8 * (littleEndian ? i : 1 - i)))) >>>\n      (littleEndian ? i : 1 - i) * 8\n  }\n}\n\nBuffer.prototype.writeUInt16LE = function writeUInt16LE (value, offset, noAssert) {\n  value = +value\n  offset = offset | 0\n  if (!noAssert) checkInt(this, value, offset, 2, 0xffff, 0)\n  if (Buffer.TYPED_ARRAY_SUPPORT) {\n    this[offset] = (value & 0xff)\n    this[offset + 1] = (value >>> 8)\n  } else {\n    objectWriteUInt16(this, value, offset, true)\n  }\n  return offset + 2\n}\n\nBuffer.prototype.writeUInt16BE = function writeUInt16BE (value, offset, noAssert) {\n  value = +value\n  offset = offset | 0\n  if (!noAssert) checkInt(this, value, offset, 2, 0xffff, 0)\n  if (Buffer.TYPED_ARRAY_SUPPORT) {\n    this[offset] = (value >>> 8)\n    this[offset + 1] = (value & 0xff)\n  } else {\n    objectWriteUInt16(this, value, offset, false)\n  }\n  return offset + 2\n}\n\nfunction objectWriteUInt32 (buf, value, offset, littleEndian) {\n  if (value < 0) value = 0xffffffff + value + 1\n  for (var i = 0, j = Math.min(buf.length - offset, 4); i < j; ++i) {\n    buf[offset + i] = (value >>> (littleEndian ? i : 3 - i) * 8) & 0xff\n  }\n}\n\nBuffer.prototype.writeUInt32LE = function writeUInt32LE (value, offset, noAssert) {\n  value = +value\n  offset = offset | 0\n  if (!noAssert) checkInt(this, value, offset, 4, 0xffffffff, 0)\n  if (Buffer.TYPED_ARRAY_SUPPORT) {\n    this[offset + 3] = (value >>> 24)\n    this[offset + 2] = (value >>> 16)\n    this[offset + 1] = (value >>> 8)\n    this[offset] = (value & 0xff)\n  } else {\n    objectWriteUInt32(this, value, offset, true)\n  }\n  return offset + 4\n}\n\nBuffer.prototype.writeUInt32BE = function writeUInt32BE (value, offset, noAssert) {\n  value = +value\n  offset = offset | 0\n  if (!noAssert) checkInt(this, value, offset, 4, 0xffffffff, 0)\n  if (Buffer.TYPED_ARRAY_SUPPORT) {\n    this[offset] = (value >>> 24)\n    this[offset + 1] = (value >>> 16)\n    this[offset + 2] = (value >>> 8)\n    this[offset + 3] = (value & 0xff)\n  } else {\n    objectWriteUInt32(this, value, offset, false)\n  }\n  return offset + 4\n}\n\nBuffer.prototype.writeIntLE = function writeIntLE (value, offset, byteLength, noAssert) {\n  value = +value\n  offset = offset | 0\n  if (!noAssert) {\n    var limit = Math.pow(2, 8 * byteLength - 1)\n\n    checkInt(this, value, offset, byteLength, limit - 1, -limit)\n  }\n\n  var i = 0\n  var mul = 1\n  var sub = 0\n  this[offset] = value & 0xFF\n  while (++i < byteLength && (mul *= 0x100)) {\n    if (value < 0 && sub === 0 && this[offset + i - 1] !== 0) {\n      sub = 1\n    }\n    this[offset + i] = ((value / mul) >> 0) - sub & 0xFF\n  }\n\n  return offset + byteLength\n}\n\nBuffer.prototype.writeIntBE = function writeIntBE (value, offset, byteLength, noAssert) {\n  value = +value\n  offset = offset | 0\n  if (!noAssert) {\n    var limit = Math.pow(2, 8 * byteLength - 1)\n\n    checkInt(this, value, offset, byteLength, limit - 1, -limit)\n  }\n\n  var i = byteLength - 1\n  var mul = 1\n  var sub = 0\n  this[offset + i] = value & 0xFF\n  while (--i >= 0 && (mul *= 0x100)) {\n    if (value < 0 && sub === 0 && this[offset + i + 1] !== 0) {\n      sub = 1\n    }\n    this[offset + i] = ((value / mul) >> 0) - sub & 0xFF\n  }\n\n  return offset + byteLength\n}\n\nBuffer.prototype.writeInt8 = function writeInt8 (value, offset, noAssert) {\n  value = +value\n  offset = offset | 0\n  if (!noAssert) checkInt(this, value, offset, 1, 0x7f, -0x80)\n  if (!Buffer.TYPED_ARRAY_SUPPORT) value = Math.floor(value)\n  if (value < 0) value = 0xff + value + 1\n  this[offset] = (value & 0xff)\n  return offset + 1\n}\n\nBuffer.prototype.writeInt16LE = function writeInt16LE (value, offset, noAssert) {\n  value = +value\n  offset = offset | 0\n  if (!noAssert) checkInt(this, value, offset, 2, 0x7fff, -0x8000)\n  if (Buffer.TYPED_ARRAY_SUPPORT) {\n    this[offset] = (value & 0xff)\n    this[offset + 1] = (value >>> 8)\n  } else {\n    objectWriteUInt16(this, value, offset, true)\n  }\n  return offset + 2\n}\n\nBuffer.prototype.writeInt16BE = function writeInt16BE (value, offset, noAssert) {\n  value = +value\n  offset = offset | 0\n  if (!noAssert) checkInt(this, value, offset, 2, 0x7fff, -0x8000)\n  if (Buffer.TYPED_ARRAY_SUPPORT) {\n    this[offset] = (value >>> 8)\n    this[offset + 1] = (value & 0xff)\n  } else {\n    objectWriteUInt16(this, value, offset, false)\n  }\n  return offset + 2\n}\n\nBuffer.prototype.writeInt32LE = function writeInt32LE (value, offset, noAssert) {\n  value = +value\n  offset = offset | 0\n  if (!noAssert) checkInt(this, value, offset, 4, 0x7fffffff, -0x80000000)\n  if (Buffer.TYPED_ARRAY_SUPPORT) {\n    this[offset] = (value & 0xff)\n    this[offset + 1] = (value >>> 8)\n    this[offset + 2] = (value >>> 16)\n    this[offset + 3] = (value >>> 24)\n  } else {\n    objectWriteUInt32(this, value, offset, true)\n  }\n  return offset + 4\n}\n\nBuffer.prototype.writeInt32BE = function writeInt32BE (value, offset, noAssert) {\n  value = +value\n  offset = offset | 0\n  if (!noAssert) checkInt(this, value, offset, 4, 0x7fffffff, -0x80000000)\n  if (value < 0) value = 0xffffffff + value + 1\n  if (Buffer.TYPED_ARRAY_SUPPORT) {\n    this[offset] = (value >>> 24)\n    this[offset + 1] = (value >>> 16)\n    this[offset + 2] = (value >>> 8)\n    this[offset + 3] = (value & 0xff)\n  } else {\n    objectWriteUInt32(this, value, offset, false)\n  }\n  return offset + 4\n}\n\nfunction checkIEEE754 (buf, value, offset, ext, max, min) {\n  if (offset + ext > buf.length) throw new RangeError('Index out of range')\n  if (offset < 0) throw new RangeError('Index out of range')\n}\n\nfunction writeFloat (buf, value, offset, littleEndian, noAssert) {\n  if (!noAssert) {\n    checkIEEE754(buf, value, offset, 4, 3.4028234663852886e+38, -3.4028234663852886e+38)\n  }\n  ieee754.write(buf, value, offset, littleEndian, 23, 4)\n  return offset + 4\n}\n\nBuffer.prototype.writeFloatLE = function writeFloatLE (value, offset, noAssert) {\n  return writeFloat(this, value, offset, true, noAssert)\n}\n\nBuffer.prototype.writeFloatBE = function writeFloatBE (value, offset, noAssert) {\n  return writeFloat(this, value, offset, false, noAssert)\n}\n\nfunction writeDouble (buf, value, offset, littleEndian, noAssert) {\n  if (!noAssert) {\n    checkIEEE754(buf, value, offset, 8, 1.7976931348623157E+308, -1.7976931348623157E+308)\n  }\n  ieee754.write(buf, value, offset, littleEndian, 52, 8)\n  return offset + 8\n}\n\nBuffer.prototype.writeDoubleLE = function writeDoubleLE (value, offset, noAssert) {\n  return writeDouble(this, value, offset, true, noAssert)\n}\n\nBuffer.prototype.writeDoubleBE = function writeDoubleBE (value, offset, noAssert) {\n  return writeDouble(this, value, offset, false, noAssert)\n}\n\n// copy(targetBuffer, targetStart=0, sourceStart=0, sourceEnd=buffer.length)\nBuffer.prototype.copy = function copy (target, targetStart, start, end) {\n  if (!start) start = 0\n  if (!end && end !== 0) end = this.length\n  if (targetStart >= target.length) targetStart = target.length\n  if (!targetStart) targetStart = 0\n  if (end > 0 && end < start) end = start\n\n  // Copy 0 bytes; we're done\n  if (end === start) return 0\n  if (target.length === 0 || this.length === 0) return 0\n\n  // Fatal error conditions\n  if (targetStart < 0) {\n    throw new RangeError('targetStart out of bounds')\n  }\n  if (start < 0 || start >= this.length) throw new RangeError('sourceStart out of bounds')\n  if (end < 0) throw new RangeError('sourceEnd out of bounds')\n\n  // Are we oob?\n  if (end > this.length) end = this.length\n  if (target.length - targetStart < end - start) {\n    end = target.length - targetStart + start\n  }\n\n  var len = end - start\n  var i\n\n  if (this === target && start < targetStart && targetStart < end) {\n    // descending copy from end\n    for (i = len - 1; i >= 0; --i) {\n      target[i + targetStart] = this[i + start]\n    }\n  } else if (len < 1000 || !Buffer.TYPED_ARRAY_SUPPORT) {\n    // ascending copy from start\n    for (i = 0; i < len; ++i) {\n      target[i + targetStart] = this[i + start]\n    }\n  } else {\n    Uint8Array.prototype.set.call(\n      target,\n      this.subarray(start, start + len),\n      targetStart\n    )\n  }\n\n  return len\n}\n\n// Usage:\n//    buffer.fill(number[, offset[, end]])\n//    buffer.fill(buffer[, offset[, end]])\n//    buffer.fill(string[, offset[, end]][, encoding])\nBuffer.prototype.fill = function fill (val, start, end, encoding) {\n  // Handle string cases:\n  if (typeof val === 'string') {\n    if (typeof start === 'string') {\n      encoding = start\n      start = 0\n      end = this.length\n    } else if (typeof end === 'string') {\n      encoding = end\n      end = this.length\n    }\n    if (val.length === 1) {\n      var code = val.charCodeAt(0)\n      if (code < 256) {\n        val = code\n      }\n    }\n    if (encoding !== undefined && typeof encoding !== 'string') {\n      throw new TypeError('encoding must be a string')\n    }\n    if (typeof encoding === 'string' && !Buffer.isEncoding(encoding)) {\n      throw new TypeError('Unknown encoding: ' + encoding)\n    }\n  } else if (typeof val === 'number') {\n    val = val & 255\n  }\n\n  // Invalid ranges are not set to a default, so can range check early.\n  if (start < 0 || this.length < start || this.length < end) {\n    throw new RangeError('Out of range index')\n  }\n\n  if (end <= start) {\n    return this\n  }\n\n  start = start >>> 0\n  end = end === undefined ? this.length : end >>> 0\n\n  if (!val) val = 0\n\n  var i\n  if (typeof val === 'number') {\n    for (i = start; i < end; ++i) {\n      this[i] = val\n    }\n  } else {\n    var bytes = Buffer.isBuffer(val)\n      ? val\n      : utf8ToBytes(new Buffer(val, encoding).toString())\n    var len = bytes.length\n    for (i = 0; i < end - start; ++i) {\n      this[i + start] = bytes[i % len]\n    }\n  }\n\n  return this\n}\n\n// HELPER FUNCTIONS\n// ================\n\nvar INVALID_BASE64_RE = /[^+\\/0-9A-Za-z-_]/g\n\nfunction base64clean (str) {\n  // Node strips out invalid characters like \\n and \\t from the string, base64-js does not\n  str = stringtrim(str).replace(INVALID_BASE64_RE, '')\n  // Node converts strings with length < 2 to ''\n  if (str.length < 2) return ''\n  // Node allows for non-padded base64 strings (missing trailing ===), base64-js does not\n  while (str.length % 4 !== 0) {\n    str = str + '='\n  }\n  return str\n}\n\nfunction stringtrim (str) {\n  if (str.trim) return str.trim()\n  return str.replace(/^\\s+|\\s+$/g, '')\n}\n\nfunction toHex (n) {\n  if (n < 16) return '0' + n.toString(16)\n  return n.toString(16)\n}\n\nfunction utf8ToBytes (string, units) {\n  units = units || Infinity\n  var codePoint\n  var length = string.length\n  var leadSurrogate = null\n  var bytes = []\n\n  for (var i = 0; i < length; ++i) {\n    codePoint = string.charCodeAt(i)\n\n    // is surrogate component\n    if (codePoint > 0xD7FF && codePoint < 0xE000) {\n      // last char was a lead\n      if (!leadSurrogate) {\n        // no lead yet\n        if (codePoint > 0xDBFF) {\n          // unexpected trail\n          if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD)\n          continue\n        } else if (i + 1 === length) {\n          // unpaired lead\n          if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD)\n          continue\n        }\n\n        // valid lead\n        leadSurrogate = codePoint\n\n        continue\n      }\n\n      // 2 leads in a row\n      if (codePoint < 0xDC00) {\n        if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD)\n        leadSurrogate = codePoint\n        continue\n      }\n\n      // valid surrogate pair\n      codePoint = (leadSurrogate - 0xD800 << 10 | codePoint - 0xDC00) + 0x10000\n    } else if (leadSurrogate) {\n      // valid bmp char, but last char was a lead\n      if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD)\n    }\n\n    leadSurrogate = null\n\n    // encode utf8\n    if (codePoint < 0x80) {\n      if ((units -= 1) < 0) break\n      bytes.push(codePoint)\n    } else if (codePoint < 0x800) {\n      if ((units -= 2) < 0) break\n      bytes.push(\n        codePoint >> 0x6 | 0xC0,\n        codePoint & 0x3F | 0x80\n      )\n    } else if (codePoint < 0x10000) {\n      if ((units -= 3) < 0) break\n      bytes.push(\n        codePoint >> 0xC | 0xE0,\n        codePoint >> 0x6 & 0x3F | 0x80,\n        codePoint & 0x3F | 0x80\n      )\n    } else if (codePoint < 0x110000) {\n      if ((units -= 4) < 0) break\n      bytes.push(\n        codePoint >> 0x12 | 0xF0,\n        codePoint >> 0xC & 0x3F | 0x80,\n        codePoint >> 0x6 & 0x3F | 0x80,\n        codePoint & 0x3F | 0x80\n      )\n    } else {\n      throw new Error('Invalid code point')\n    }\n  }\n\n  return bytes\n}\n\nfunction asciiToBytes (str) {\n  var byteArray = []\n  for (var i = 0; i < str.length; ++i) {\n    // Node's code seems to be doing this and not & 0x7F..\n    byteArray.push(str.charCodeAt(i) & 0xFF)\n  }\n  return byteArray\n}\n\nfunction utf16leToBytes (str, units) {\n  var c, hi, lo\n  var byteArray = []\n  for (var i = 0; i < str.length; ++i) {\n    if ((units -= 2) < 0) break\n\n    c = str.charCodeAt(i)\n    hi = c >> 8\n    lo = c % 256\n    byteArray.push(lo)\n    byteArray.push(hi)\n  }\n\n  return byteArray\n}\n\nfunction base64ToBytes (str) {\n  return base64.toByteArray(base64clean(str))\n}\n\nfunction blitBuffer (src, dst, offset, length) {\n  for (var i = 0; i < length; ++i) {\n    if ((i + offset >= dst.length) || (i >= src.length)) break\n    dst[i + offset] = src[i]\n  }\n  return i\n}\n\nfunction isnan (val) {\n  return val !== val // eslint-disable-line no-self-compare\n}\n","/* build: `node build.js modules=ALL exclude=gestures,accessors requirejs minifier=uglifyjs` */\n/*! Fabric.js Copyright 2008-2015, Printio (Juriy Zaytsev, Maxim Chernyak) */\n\nvar fabric = fabric || { version: '2.4.3' };\nif (typeof exports !== 'undefined') {\n  exports.fabric = fabric;\n}\n/* _AMD_START_ */\nelse if (typeof define === 'function' && define.amd) {\n  define([], function() { return fabric; });\n}\n/* _AMD_END_ */\nif (typeof document !== 'undefined' && typeof window !== 'undefined') {\n  fabric.document = document;\n  fabric.window = window;\n}\nelse {\n  // assume we're running under node.js when document/window are not present\n  fabric.document = require('jsdom')\n    .jsdom(\n      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      });\n  fabric.jsdomImplForWrapper = require('jsdom/lib/jsdom/living/generated/utils').implForWrapper;\n  fabric.nodeCanvas = require('jsdom/lib/jsdom/utils').Canvas;\n  fabric.window = fabric.document.defaultView;\n  DOMParser = require('xmldom').DOMParser;\n}\n\n/**\n * True when in environment that supports touch events\n * @type boolean\n */\nfabric.isTouchSupported = 'ontouchstart' in fabric.window;\n\n/**\n * True when in environment that's probably Node.js\n * @type boolean\n */\nfabric.isLikelyNode = typeof Buffer !== 'undefined' &&\n                      typeof window === 'undefined';\n\n/* _FROM_SVG_START_ */\n/**\n * Attributes parsed from all SVG elements\n * @type array\n */\nfabric.SHARED_ATTRIBUTES = [\n  'display',\n  'transform',\n  'fill', 'fill-opacity', 'fill-rule',\n  'opacity',\n  'stroke', 'stroke-dasharray', 'stroke-linecap',\n  'stroke-linejoin', 'stroke-miterlimit',\n  'stroke-opacity', 'stroke-width',\n  'id', 'paint-order',\n  'instantiated_by_use', 'clip-path'\n];\n/* _FROM_SVG_END_ */\n\n/**\n * Pixel per Inch as a default value set to 96. Can be changed for more realistic conversion.\n */\nfabric.DPI = 96;\nfabric.reNum = '(?:[-+]?(?:\\\\d+|\\\\d*\\\\.\\\\d+)(?:e[-+]?\\\\d+)?)';\nfabric.fontPaths = { };\nfabric.iMatrix = [1, 0, 0, 1, 0, 0];\nfabric.canvasModule = 'canvas';\n\n/**\n * Pixel limit for cache canvases. 1Mpx , 4Mpx should be fine.\n * @since 1.7.14\n * @type Number\n * @default\n */\nfabric.perfLimitSizeTotal = 2097152;\n\n/**\n * Pixel limit for cache canvases width or height. IE fixes the maximum at 5000\n * @since 1.7.14\n * @type Number\n * @default\n */\nfabric.maxCacheSideLimit = 4096;\n\n/**\n * Lowest pixel limit for cache canvases, set at 256PX\n * @since 1.7.14\n * @type Number\n * @default\n */\nfabric.minCacheSideLimit = 256;\n\n/**\n * Cache Object for widths of chars in text rendering.\n */\nfabric.charWidthsCache = { };\n\n/**\n * if webgl is enabled and available, textureSize will determine the size\n * of the canvas backend\n * @since 2.0.0\n * @type Number\n * @default\n */\nfabric.textureSize = 2048;\n\n/**\n * Enable webgl for filtering picture is available\n * A filtering backend will be initialized, this will both take memory and\n * time since a default 2048x2048 canvas will be created for the gl context\n * @since 2.0.0\n * @type Boolean\n * @default\n */\nfabric.enableGLFiltering = true;\n\n/**\n * Device Pixel Ratio\n * @see https://developer.apple.com/library/safari/documentation/AudioVideo/Conceptual/HTML-canvas-guide/SettingUptheCanvas/SettingUptheCanvas.html\n */\nfabric.devicePixelRatio = fabric.window.devicePixelRatio ||\n                          fabric.window.webkitDevicePixelRatio ||\n                          fabric.window.mozDevicePixelRatio ||\n                          1;\n/**\n * Browser-specific constant to adjust CanvasRenderingContext2D.shadowBlur value,\n * which is unitless and not rendered equally across browsers.\n *\n * Values that work quite well (as of October 2017) are:\n * - Chrome: 1.5\n * - Edge: 1.75\n * - Firefox: 0.9\n * - Safari: 0.95\n *\n * @since 2.0.0\n * @type Number\n * @default 1\n */\nfabric.browserShadowBlurConstant = 1;\n\n/**\n * This object contains the result of arc to beizer conversion for faster retrieving if the same arc needs to be converted again.\n * It was an internal variable, is accessible since version 2.3.4\n */\nfabric.arcToSegmentsCache = { };\n\n/**\n * This object keeps the results of the boundsOfCurve calculation mapped by the joined arguments necessary to calculate it.\n * It does speed up calculation, if you parse and add always the same paths, but in case of heavy usage of freedrawing\n * you do not get any speed benefit and you get a big object in memory.\n * The object was a private variable before, while now is appended to the lib so that you have access to it and you\n * can eventually clear it.\n * It was an internal variable, is accessible since version 2.3.4\n */\nfabric.boundsOfCurveCache = { };\n\n/**\n * If disabled boundsOfCurveCache is not used. For apps that make heavy usage of pencil drawing probably disabling it is better\n * @default true\n */\nfabric.cachesBoundsOfCurve = true;\n\nfabric.initFilterBackend = function() {\n  if (fabric.enableGLFiltering && fabric.isWebglSupported && fabric.isWebglSupported(fabric.textureSize)) {\n    console.log('max texture size: ' + fabric.maxTextureSize);\n    return (new fabric.WebglFilterBackend({ tileSize: fabric.textureSize }));\n  }\n  else if (fabric.Canvas2dFilterBackend) {\n    return (new fabric.Canvas2dFilterBackend());\n  }\n};\n\n\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\n(function() {\n\n  /**\n   * @private\n   * @param {String} eventName\n   * @param {Function} handler\n   */\n  function _removeEventListener(eventName, handler) {\n    if (!this.__eventListeners[eventName]) {\n      return;\n    }\n    var eventListener = this.__eventListeners[eventName];\n    if (handler) {\n      eventListener[eventListener.indexOf(handler)] = false;\n    }\n    else {\n      fabric.util.array.fill(eventListener, false);\n    }\n  }\n\n  /**\n   * Observes specified event\n   * @deprecated `observe` deprecated since 0.8.34 (use `on` instead)\n   * @memberOf fabric.Observable\n   * @alias on\n   * @param {String|Object} eventName Event name (eg. 'after:render') or object with key/value pairs (eg. {'after:render': handler, 'selection:cleared': handler})\n   * @param {Function} handler Function that receives a notification when an event of the specified type occurs\n   * @return {Self} thisArg\n   * @chainable\n   */\n  function observe(eventName, handler) {\n    if (!this.__eventListeners) {\n      this.__eventListeners = { };\n    }\n    // one object with key/value pairs was passed\n    if (arguments.length === 1) {\n      for (var prop in eventName) {\n        this.on(prop, eventName[prop]);\n      }\n    }\n    else {\n      if (!this.__eventListeners[eventName]) {\n        this.__eventListeners[eventName] = [];\n      }\n      this.__eventListeners[eventName].push(handler);\n    }\n    return this;\n  }\n\n  /**\n   * Stops event observing for a particular event handler. Calling this method\n   * without arguments removes all handlers for all events\n   * @deprecated `stopObserving` deprecated since 0.8.34 (use `off` instead)\n   * @memberOf fabric.Observable\n   * @alias off\n   * @param {String|Object} eventName Event name (eg. 'after:render') or object with key/value pairs (eg. {'after:render': handler, 'selection:cleared': handler})\n   * @param {Function} handler Function to be deleted from EventListeners\n   * @return {Self} thisArg\n   * @chainable\n   */\n  function stopObserving(eventName, handler) {\n    if (!this.__eventListeners) {\n      return;\n    }\n\n    // remove all key/value pairs (event name -> event handler)\n    if (arguments.length === 0) {\n      for (eventName in this.__eventListeners) {\n        _removeEventListener.call(this, eventName);\n      }\n    }\n    // one object with key/value pairs was passed\n    else if (arguments.length === 1 && typeof arguments[0] === 'object') {\n      for (var prop in eventName) {\n        _removeEventListener.call(this, prop, eventName[prop]);\n      }\n    }\n    else {\n      _removeEventListener.call(this, eventName, handler);\n    }\n    return this;\n  }\n\n  /**\n   * Fires event with an optional options object\n   * @deprecated `fire` deprecated since 1.0.7 (use `trigger` instead)\n   * @memberOf fabric.Observable\n   * @alias trigger\n   * @param {String} eventName Event name to fire\n   * @param {Object} [options] Options object\n   * @return {Self} thisArg\n   * @chainable\n   */\n  function fire(eventName, options) {\n    if (!this.__eventListeners) {\n      return;\n    }\n\n    var listenersForEvent = this.__eventListeners[eventName];\n    if (!listenersForEvent) {\n      return;\n    }\n\n    for (var i = 0, len = listenersForEvent.length; i < len; i++) {\n      listenersForEvent[i] && listenersForEvent[i].call(this, options || { });\n    }\n    this.__eventListeners[eventName] = listenersForEvent.filter(function(value) {\n      return value !== false;\n    });\n    return this;\n  }\n\n  /**\n   * @namespace fabric.Observable\n   * @tutorial {@link http://fabricjs.com/fabric-intro-part-2#events}\n   * @see {@link http://fabricjs.com/events|Events demo}\n   */\n  fabric.Observable = {\n    observe: observe,\n    stopObserving: stopObserving,\n    fire: fire,\n\n    on: observe,\n    off: stopObserving,\n    trigger: fire\n  };\n})();\n\n\n/**\n * @namespace fabric.Collection\n */\nfabric.Collection = {\n\n  _objects: [],\n\n  /**\n   * Adds objects to collection, Canvas or Group, then renders canvas\n   * (if `renderOnAddRemove` is not `false`).\n   * in case of Group no changes to bounding box are made.\n   * Objects should be instances of (or inherit from) fabric.Object\n   * Use of this function is highly discouraged for groups.\n   * you can add a bunch of objects with the add method but then you NEED\n   * to run a addWithUpdate call for the Group class or position/bbox will be wrong.\n   * @param {...fabric.Object} object Zero or more fabric instances\n   * @return {Self} thisArg\n   * @chainable\n   */\n  add: function () {\n    this._objects.push.apply(this._objects, arguments);\n    if (this._onObjectAdded) {\n      for (var i = 0, length = arguments.length; i < length; i++) {\n        this._onObjectAdded(arguments[i]);\n      }\n    }\n    this.renderOnAddRemove && this.requestRenderAll();\n    return this;\n  },\n\n  /**\n   * Inserts an object into collection at specified index, then renders canvas (if `renderOnAddRemove` is not `false`)\n   * An object should be an instance of (or inherit from) fabric.Object\n   * Use of this function is highly discouraged for groups.\n   * you can add a bunch of objects with the insertAt method but then you NEED\n   * to run a addWithUpdate call for the Group class or position/bbox will be wrong.\n   * @param {Object} object Object to insert\n   * @param {Number} index Index to insert object at\n   * @param {Boolean} nonSplicing When `true`, no splicing (shifting) of objects occurs\n   * @return {Self} thisArg\n   * @chainable\n   */\n  insertAt: function (object, index, nonSplicing) {\n    var objects = this._objects;\n    if (nonSplicing) {\n      objects[index] = object;\n    }\n    else {\n      objects.splice(index, 0, object);\n    }\n    this._onObjectAdded && this._onObjectAdded(object);\n    this.renderOnAddRemove && this.requestRenderAll();\n    return this;\n  },\n\n  /**\n   * Removes objects from a collection, then renders canvas (if `renderOnAddRemove` is not `false`)\n   * @param {...fabric.Object} object Zero or more fabric instances\n   * @return {Self} thisArg\n   * @chainable\n   */\n  remove: function() {\n    var objects = this._objects,\n        index, somethingRemoved = false;\n\n    for (var i = 0, length = arguments.length; i < length; i++) {\n      index = objects.indexOf(arguments[i]);\n\n      // only call onObjectRemoved if an object was actually removed\n      if (index !== -1) {\n        somethingRemoved = true;\n        objects.splice(index, 1);\n        this._onObjectRemoved && this._onObjectRemoved(arguments[i]);\n      }\n    }\n\n    this.renderOnAddRemove && somethingRemoved && this.requestRenderAll();\n    return this;\n  },\n\n  /**\n   * Executes given function for each object in this group\n   * @param {Function} callback\n   *                   Callback invoked with current object as first argument,\n   *                   index - as second and an array of all objects - as third.\n   *                   Callback is invoked in a context of Global Object (e.g. `window`)\n   *                   when no `context` argument is given\n   *\n   * @param {Object} context Context (aka thisObject)\n   * @return {Self} thisArg\n   * @chainable\n   */\n  forEachObject: function(callback, context) {\n    var objects = this.getObjects();\n    for (var i = 0, len = objects.length; i < len; i++) {\n      callback.call(context, objects[i], i, objects);\n    }\n    return this;\n  },\n\n  /**\n   * Returns an array of children objects of this instance\n   * Type parameter introduced in 1.3.10\n   * since 2.3.5 this method return always a COPY of the array;\n   * @param {String} [type] When specified, only objects of this type are returned\n   * @return {Array}\n   */\n  getObjects: function(type) {\n    if (typeof type === 'undefined') {\n      return this._objects.concat();\n    }\n    return this._objects.filter(function(o) {\n      return o.type === type;\n    });\n  },\n\n  /**\n   * Returns object at specified index\n   * @param {Number} index\n   * @return {Self} thisArg\n   */\n  item: function (index) {\n    return this._objects[index];\n  },\n\n  /**\n   * Returns true if collection contains no objects\n   * @return {Boolean} true if collection is empty\n   */\n  isEmpty: function () {\n    return this._objects.length === 0;\n  },\n\n  /**\n   * Returns a size of a collection (i.e: length of an array containing its objects)\n   * @return {Number} Collection size\n   */\n  size: function() {\n    return this._objects.length;\n  },\n\n  /**\n   * Returns true if collection contains an object\n   * @param {Object} object Object to check against\n   * @return {Boolean} `true` if collection contains an object\n   */\n  contains: function(object) {\n    return this._objects.indexOf(object) > -1;\n  },\n\n  /**\n   * Returns number representation of a collection complexity\n   * @return {Number} complexity\n   */\n  complexity: function () {\n    return this._objects.reduce(function (memo, current) {\n      memo += current.complexity ? current.complexity() : 0;\n      return memo;\n    }, 0);\n  }\n};\n\n\n/**\n * @namespace fabric.CommonMethods\n */\nfabric.CommonMethods = {\n\n  /**\n   * Sets object's properties from options\n   * @param {Object} [options] Options object\n   */\n  _setOptions: function(options) {\n    for (var prop in options) {\n      this.set(prop, options[prop]);\n    }\n  },\n\n  /**\n   * @private\n   * @param {Object} [filler] Options object\n   * @param {String} [property] property to set the Gradient to\n   */\n  _initGradient: function(filler, property) {\n    if (filler && filler.colorStops && !(filler instanceof fabric.Gradient)) {\n      this.set(property, new fabric.Gradient(filler));\n    }\n  },\n\n  /**\n   * @private\n   * @param {Object} [filler] Options object\n   * @param {String} [property] property to set the Pattern to\n   * @param {Function} [callback] callback to invoke after pattern load\n   */\n  _initPattern: function(filler, property, callback) {\n    if (filler && filler.source && !(filler instanceof fabric.Pattern)) {\n      this.set(property, new fabric.Pattern(filler, callback));\n    }\n    else {\n      callback && callback();\n    }\n  },\n\n  /**\n   * @private\n   * @param {Object} [options] Options object\n   */\n  _initClipping: function(options) {\n    if (!options.clipTo || typeof options.clipTo !== 'string') {\n      return;\n    }\n\n    var functionBody = fabric.util.getFunctionBody(options.clipTo);\n    if (typeof functionBody !== 'undefined') {\n      this.clipTo = new Function('ctx', functionBody);\n    }\n  },\n\n  /**\n   * @private\n   */\n  _setObject: function(obj) {\n    for (var prop in obj) {\n      this._set(prop, obj[prop]);\n    }\n  },\n\n  /**\n   * Sets property to a given value. When changing position/dimension -related properties (left, top, scale, angle, etc.) `set` does not update position of object's borders/controls. If you need to update those, call `setCoords()`.\n   * @param {String|Object} key Property name or object (if object, iterate over the object properties)\n   * @param {Object|Function} value Property value (if function, the value is passed into it and its return value is used as a new one)\n   * @return {fabric.Object} thisArg\n   * @chainable\n   */\n  set: function(key, value) {\n    if (typeof key === 'object') {\n      this._setObject(key);\n    }\n    else {\n      if (typeof value === 'function' && key !== 'clipTo') {\n        this._set(key, value(this.get(key)));\n      }\n      else {\n        this._set(key, value);\n      }\n    }\n    return this;\n  },\n\n  _set: function(key, value) {\n    this[key] = value;\n  },\n\n  /**\n   * Toggles specified property from `true` to `false` or from `false` to `true`\n   * @param {String} property Property to toggle\n   * @return {fabric.Object} thisArg\n   * @chainable\n   */\n  toggle: function(property) {\n    var value = this.get(property);\n    if (typeof value === 'boolean') {\n      this.set(property, !value);\n    }\n    return this;\n  },\n\n  /**\n   * Basic getter\n   * @param {String} property Property name\n   * @return {*} value of a property\n   */\n  get: function(property) {\n    return this[property];\n  }\n};\n\n\n(function(global) {\n\n  var sqrt = Math.sqrt,\n      atan2 = Math.atan2,\n      pow = Math.pow,\n      abs = Math.abs,\n      PiBy180 = Math.PI / 180,\n      PiBy2 = Math.PI / 2;\n\n  /**\n   * @namespace fabric.util\n   */\n  fabric.util = {\n\n    /**\n     * Calculate the cos of an angle, avoiding returning floats for known results\n     * @static\n     * @memberOf fabric.util\n     * @param {Number} angle the angle in radians or in degree\n     * @return {Number}\n     */\n    cos: function(angle) {\n      if (angle === 0) { return 1; }\n      if (angle < 0) {\n        // cos(a) = cos(-a)\n        angle = -angle;\n      }\n      var angleSlice = angle / PiBy2;\n      switch (angleSlice) {\n        case 1: case 3: return 0;\n        case 2: return -1;\n      }\n      return Math.cos(angle);\n    },\n\n    /**\n     * Calculate the sin of an angle, avoiding returning floats for known results\n     * @static\n     * @memberOf fabric.util\n     * @param {Number} angle the angle in radians or in degree\n     * @return {Number}\n     */\n    sin: function(angle) {\n      if (angle === 0) { return 0; }\n      var angleSlice = angle / PiBy2, sign = 1;\n      if (angle < 0) {\n        // sin(-a) = -sin(a)\n        sign = -1;\n      }\n      switch (angleSlice) {\n        case 1: return sign;\n        case 2: return 0;\n        case 3: return -sign;\n      }\n      return Math.sin(angle);\n    },\n\n    /**\n     * Removes value from an array.\n     * Presence of value (and its position in an array) is determined via `Array.prototype.indexOf`\n     * @static\n     * @memberOf fabric.util\n     * @param {Array} array\n     * @param {*} value\n     * @return {Array} original array\n     */\n    removeFromArray: function(array, value) {\n      var idx = array.indexOf(value);\n      if (idx !== -1) {\n        array.splice(idx, 1);\n      }\n      return array;\n    },\n\n    /**\n     * Returns random number between 2 specified ones.\n     * @static\n     * @memberOf fabric.util\n     * @param {Number} min lower limit\n     * @param {Number} max upper limit\n     * @return {Number} random value (between min and max)\n     */\n    getRandomInt: function(min, max) {\n      return Math.floor(Math.random() * (max - min + 1)) + min;\n    },\n\n    /**\n     * Transforms degrees to radians.\n     * @static\n     * @memberOf fabric.util\n     * @param {Number} degrees value in degrees\n     * @return {Number} value in radians\n     */\n    degreesToRadians: function(degrees) {\n      return degrees * PiBy180;\n    },\n\n    /**\n     * Transforms radians to degrees.\n     * @static\n     * @memberOf fabric.util\n     * @param {Number} radians value in radians\n     * @return {Number} value in degrees\n     */\n    radiansToDegrees: function(radians) {\n      return radians / PiBy180;\n    },\n\n    /**\n     * Rotates `point` around `origin` with `radians`\n     * @static\n     * @memberOf fabric.util\n     * @param {fabric.Point} point The point to rotate\n     * @param {fabric.Point} origin The origin of the rotation\n     * @param {Number} radians The radians of the angle for the rotation\n     * @return {fabric.Point} The new rotated point\n     */\n    rotatePoint: function(point, origin, radians) {\n      point.subtractEquals(origin);\n      var v = fabric.util.rotateVector(point, radians);\n      return new fabric.Point(v.x, v.y).addEquals(origin);\n    },\n\n    /**\n     * Rotates `vector` with `radians`\n     * @static\n     * @memberOf fabric.util\n     * @param {Object} vector The vector to rotate (x and y)\n     * @param {Number} radians The radians of the angle for the rotation\n     * @return {Object} The new rotated point\n     */\n    rotateVector: function(vector, radians) {\n      var sin = fabric.util.sin(radians),\n          cos = fabric.util.cos(radians),\n          rx = vector.x * cos - vector.y * sin,\n          ry = vector.x * sin + vector.y * cos;\n      return {\n        x: rx,\n        y: ry\n      };\n    },\n\n    /**\n     * Apply transform t to point p\n     * @static\n     * @memberOf fabric.util\n     * @param  {fabric.Point} p The point to transform\n     * @param  {Array} t The transform\n     * @param  {Boolean} [ignoreOffset] Indicates that the offset should not be applied\n     * @return {fabric.Point} The transformed point\n     */\n    transformPoint: function(p, t, ignoreOffset) {\n      if (ignoreOffset) {\n        return new fabric.Point(\n          t[0] * p.x + t[2] * p.y,\n          t[1] * p.x + t[3] * p.y\n        );\n      }\n      return new fabric.Point(\n        t[0] * p.x + t[2] * p.y + t[4],\n        t[1] * p.x + t[3] * p.y + t[5]\n      );\n    },\n\n    /**\n     * Returns coordinates of points's bounding rectangle (left, top, width, height)\n     * @param {Array} points 4 points array\n     * @return {Object} Object with left, top, width, height properties\n     */\n    makeBoundingBoxFromPoints: function(points) {\n      var xPoints = [points[0].x, points[1].x, points[2].x, points[3].x],\n          minX = fabric.util.array.min(xPoints),\n          maxX = fabric.util.array.max(xPoints),\n          width = maxX - minX,\n          yPoints = [points[0].y, points[1].y, points[2].y, points[3].y],\n          minY = fabric.util.array.min(yPoints),\n          maxY = fabric.util.array.max(yPoints),\n          height = maxY - minY;\n\n      return {\n        left: minX,\n        top: minY,\n        width: width,\n        height: height\n      };\n    },\n\n    /**\n     * Invert transformation t\n     * @static\n     * @memberOf fabric.util\n     * @param {Array} t The transform\n     * @return {Array} The inverted transform\n     */\n    invertTransform: function(t) {\n      var a = 1 / (t[0] * t[3] - t[1] * t[2]),\n          r = [a * t[3], -a * t[1], -a * t[2], a * t[0]],\n          o = fabric.util.transformPoint({ x: t[4], y: t[5] }, r, true);\n      r[4] = -o.x;\n      r[5] = -o.y;\n      return r;\n    },\n\n    /**\n     * A wrapper around Number#toFixed, which contrary to native method returns number, not string.\n     * @static\n     * @memberOf fabric.util\n     * @param {Number|String} number number to operate on\n     * @param {Number} fractionDigits number of fraction digits to \"leave\"\n     * @return {Number}\n     */\n    toFixed: function(number, fractionDigits) {\n      return parseFloat(Number(number).toFixed(fractionDigits));\n    },\n\n    /**\n     * Converts from attribute value to pixel value if applicable.\n     * Returns converted pixels or original value not converted.\n     * @param {Number|String} value number to operate on\n     * @param {Number} fontSize\n     * @return {Number|String}\n     */\n    parseUnit: function(value, fontSize) {\n      var unit = /\\D{0,2}$/.exec(value),\n          number = parseFloat(value);\n      if (!fontSize) {\n        fontSize = fabric.Text.DEFAULT_SVG_FONT_SIZE;\n      }\n      switch (unit[0]) {\n        case 'mm':\n          return number * fabric.DPI / 25.4;\n\n        case 'cm':\n          return number * fabric.DPI / 2.54;\n\n        case 'in':\n          return number * fabric.DPI;\n\n        case 'pt':\n          return number * fabric.DPI / 72; // or * 4 / 3\n\n        case 'pc':\n          return number * fabric.DPI / 72 * 12; // or * 16\n\n        case 'em':\n          return number * fontSize;\n\n        default:\n          return number;\n      }\n    },\n\n    /**\n     * Function which always returns `false`.\n     * @static\n     * @memberOf fabric.util\n     * @return {Boolean}\n     */\n    falseFunction: function() {\n      return false;\n    },\n\n    /**\n     * Returns klass \"Class\" object of given namespace\n     * @memberOf fabric.util\n     * @param {String} type Type of object (eg. 'circle')\n     * @param {String} namespace Namespace to get klass \"Class\" object from\n     * @return {Object} klass \"Class\"\n     */\n    getKlass: function(type, namespace) {\n      // capitalize first letter only\n      type = fabric.util.string.camelize(type.charAt(0).toUpperCase() + type.slice(1));\n      return fabric.util.resolveNamespace(namespace)[type];\n    },\n\n    /**\n     * Returns array of attributes for given svg that fabric parses\n     * @memberOf fabric.util\n     * @param {String} type Type of svg element (eg. 'circle')\n     * @return {Array} string names of supported attributes\n     */\n    getSvgAttributes: function(type) {\n      var attributes = [\n        'instantiated_by_use',\n        'style',\n        'id',\n        'class'\n      ];\n      switch (type) {\n        case 'linearGradient':\n          attributes = attributes.concat(['x1', 'y1', 'x2', 'y2', 'gradientUnits', 'gradientTransform']);\n          break;\n        case 'radialGradient':\n          attributes = attributes.concat(['gradientUnits', 'gradientTransform', 'cx', 'cy', 'r', 'fx', 'fy', 'fr']);\n          break;\n        case 'stop':\n          attributes = attributes.concat(['offset', 'stop-color', 'stop-opacity']);\n          break;\n      }\n      return attributes;\n    },\n\n    /**\n     * Returns object of given namespace\n     * @memberOf fabric.util\n     * @param {String} namespace Namespace string e.g. 'fabric.Image.filter' or 'fabric'\n     * @return {Object} Object for given namespace (default fabric)\n     */\n    resolveNamespace: function(namespace) {\n      if (!namespace) {\n        return fabric;\n      }\n\n      var parts = namespace.split('.'),\n          len = parts.length, i,\n          obj = global || fabric.window;\n\n      for (i = 0; i < len; ++i) {\n        obj = obj[parts[i]];\n      }\n\n      return obj;\n    },\n\n    /**\n     * Loads image element from given url and passes it to a callback\n     * @memberOf fabric.util\n     * @param {String} url URL representing an image\n     * @param {Function} callback Callback; invoked with loaded image\n     * @param {*} [context] Context to invoke callback in\n     * @param {Object} [crossOrigin] crossOrigin value to set image element to\n     */\n    loadImage: function(url, callback, context, crossOrigin) {\n      if (!url) {\n        callback && callback.call(context, url);\n        return;\n      }\n\n      var img = fabric.util.createImage();\n\n      /** @ignore */\n      var onLoadCallback = function () {\n        callback && callback.call(context, img);\n        img = img.onload = img.onerror = null;\n      };\n\n      img.onload = onLoadCallback;\n      /** @ignore */\n      img.onerror = function() {\n        fabric.log('Error loading ' + img.src);\n        callback && callback.call(context, null, true);\n        img = img.onload = img.onerror = null;\n      };\n\n      // data-urls appear to be buggy with crossOrigin\n      // https://github.com/kangax/fabric.js/commit/d0abb90f1cd5c5ef9d2a94d3fb21a22330da3e0a#commitcomment-4513767\n      // see https://code.google.com/p/chromium/issues/detail?id=315152\n      //     https://bugzilla.mozilla.org/show_bug.cgi?id=935069\n      if (url.indexOf('data') !== 0 && crossOrigin) {\n        img.crossOrigin = crossOrigin;\n      }\n\n      // IE10 / IE11-Fix: SVG contents from data: URI\n      // will only be available if the IMG is present\n      // in the DOM (and visible)\n      if (url.substring(0,14) === 'data:image/svg') {\n        img.onload = null;\n        fabric.util.loadImageInDom(img, onLoadCallback);\n      }\n\n      img.src = url;\n    },\n\n    /**\n     * Attaches SVG image with data: URL to the dom\n     * @memberOf fabric.util\n     * @param {Object} img Image object with data:image/svg src\n     * @param {Function} callback Callback; invoked with loaded image\n     * @return {Object} DOM element (div containing the SVG image)\n     */\n    loadImageInDom: function(img, onLoadCallback) {\n      var div = fabric.document.createElement('div');\n      div.style.width = div.style.height = '1px';\n      div.style.left = div.style.top = '-100%';\n      div.style.position = 'absolute';\n      div.appendChild(img);\n      fabric.document.querySelector('body').appendChild(div);\n      /**\n       * Wrap in function to:\n       *   1. Call existing callback\n       *   2. Cleanup DOM\n       */\n      img.onload = function () {\n        onLoadCallback();\n        div.parentNode.removeChild(div);\n        div = null;\n      };\n    },\n\n    /**\n     * Creates corresponding fabric instances from their object representations\n     * @static\n     * @memberOf fabric.util\n     * @param {Array} objects Objects to enliven\n     * @param {Function} callback Callback to invoke when all objects are created\n     * @param {String} namespace Namespace to get klass \"Class\" object from\n     * @param {Function} reviver Method for further parsing of object elements,\n     * called after each fabric object created.\n     */\n    enlivenObjects: function(objects, callback, namespace, reviver) {\n      objects = objects || [];\n\n      function onLoaded() {\n        if (++numLoadedObjects === numTotalObjects) {\n          callback && callback(enlivenedObjects);\n        }\n      }\n\n      var enlivenedObjects = [],\n          numLoadedObjects = 0,\n          numTotalObjects = objects.length;\n\n      if (!numTotalObjects) {\n        callback && callback(enlivenedObjects);\n        return;\n      }\n\n      objects.forEach(function (o, index) {\n        // if sparse array\n        if (!o || !o.type) {\n          onLoaded();\n          return;\n        }\n        var klass = fabric.util.getKlass(o.type, namespace);\n        klass.fromObject(o, function (obj, error) {\n          error || (enlivenedObjects[index] = obj);\n          reviver && reviver(o, obj, error);\n          onLoaded();\n        });\n      });\n    },\n\n    /**\n     * Create and wait for loading of patterns\n     * @static\n     * @memberOf fabric.util\n     * @param {Array} patterns Objects to enliven\n     * @param {Function} callback Callback to invoke when all objects are created\n     * called after each fabric object created.\n     */\n    enlivenPatterns: function(patterns, callback) {\n      patterns = patterns || [];\n\n      function onLoaded() {\n        if (++numLoadedPatterns === numPatterns) {\n          callback && callback(enlivenedPatterns);\n        }\n      }\n\n      var enlivenedPatterns = [],\n          numLoadedPatterns = 0,\n          numPatterns = patterns.length;\n\n      if (!numPatterns) {\n        callback && callback(enlivenedPatterns);\n        return;\n      }\n\n      patterns.forEach(function (p, index) {\n        if (p && p.source) {\n          new fabric.Pattern(p, function(pattern) {\n            enlivenedPatterns[index] = pattern;\n            onLoaded();\n          });\n        }\n        else {\n          enlivenedPatterns[index] = p;\n          onLoaded();\n        }\n      });\n    },\n\n    /**\n     * Groups SVG elements (usually those retrieved from SVG document)\n     * @static\n     * @memberOf fabric.util\n     * @param {Array} elements SVG elements to group\n     * @param {Object} [options] Options object\n     * @param {String} path Value to set sourcePath to\n     * @return {fabric.Object|fabric.Group}\n     */\n    groupSVGElements: function(elements, options, path) {\n      var object;\n      if (elements && elements.length === 1) {\n        return elements[0];\n      }\n      if (options) {\n        if (options.width && options.height) {\n          options.centerPoint = {\n            x: options.width / 2,\n            y: options.height / 2\n          };\n        }\n        else {\n          delete options.width;\n          delete options.height;\n        }\n      }\n      object = new fabric.Group(elements, options);\n      if (typeof path !== 'undefined') {\n        object.sourcePath = path;\n      }\n      return object;\n    },\n\n    /**\n     * Populates an object with properties of another object\n     * @static\n     * @memberOf fabric.util\n     * @param {Object} source Source object\n     * @param {Object} destination Destination object\n     * @return {Array} properties Properties names to include\n     */\n    populateWithProperties: function(source, destination, properties) {\n      if (properties && Object.prototype.toString.call(properties) === '[object Array]') {\n        for (var i = 0, len = properties.length; i < len; i++) {\n          if (properties[i] in source) {\n            destination[properties[i]] = source[properties[i]];\n          }\n        }\n      }\n    },\n\n    /**\n     * Draws a dashed line between two points\n     *\n     * This method is used to draw dashed line around selection area.\n     * See <a href=\"http://stackoverflow.com/questions/4576724/dotted-stroke-in-canvas\">dotted stroke in canvas</a>\n     *\n     * @param {CanvasRenderingContext2D} ctx context\n     * @param {Number} x  start x coordinate\n     * @param {Number} y start y coordinate\n     * @param {Number} x2 end x coordinate\n     * @param {Number} y2 end y coordinate\n     * @param {Array} da dash array pattern\n     */\n    drawDashedLine: function(ctx, x, y, x2, y2, da) {\n      var dx = x2 - x,\n          dy = y2 - y,\n          len = sqrt(dx * dx + dy * dy),\n          rot = atan2(dy, dx),\n          dc = da.length,\n          di = 0,\n          draw = true;\n\n      ctx.save();\n      ctx.translate(x, y);\n      ctx.moveTo(0, 0);\n      ctx.rotate(rot);\n\n      x = 0;\n      while (len > x) {\n        x += da[di++ % dc];\n        if (x > len) {\n          x = len;\n        }\n        ctx[draw ? 'lineTo' : 'moveTo'](x, 0);\n        draw = !draw;\n      }\n\n      ctx.restore();\n    },\n\n    /**\n     * Creates canvas element\n     * @static\n     * @memberOf fabric.util\n     * @return {CanvasElement} initialized canvas element\n     */\n    createCanvasElement: function() {\n      return fabric.document.createElement('canvas');\n    },\n\n    /**\n     * Creates a canvas element that is a copy of another and is also painted\n     * @static\n     * @memberOf fabric.util\n     * @return {CanvasElement} initialized canvas element\n     */\n    copyCanvasElement: function(canvas) {\n      var newCanvas = fabric.util.createCanvasElement();\n      newCanvas.width = canvas.width;\n      newCanvas.height = canvas.height;\n      newCanvas.getContext('2d').drawImage(canvas, 0, 0);\n      return newCanvas;\n    },\n\n    /**\n     * Creates image element (works on client and node)\n     * @static\n     * @memberOf fabric.util\n     * @return {HTMLImageElement} HTML image element\n     */\n    createImage: function() {\n      return fabric.document.createElement('img');\n    },\n\n    /**\n     * @static\n     * @memberOf fabric.util\n     * @deprecated since 2.0.0\n     * @param {fabric.Object} receiver Object implementing `clipTo` method\n     * @param {CanvasRenderingContext2D} ctx Context to clip\n     */\n    clipContext: function(receiver, ctx) {\n      ctx.save();\n      ctx.beginPath();\n      receiver.clipTo(ctx);\n      ctx.clip();\n    },\n\n    /**\n     * Multiply matrix A by matrix B to nest transformations\n     * @static\n     * @memberOf fabric.util\n     * @param  {Array} a First transformMatrix\n     * @param  {Array} b Second transformMatrix\n     * @param  {Boolean} is2x2 flag to multiply matrices as 2x2 matrices\n     * @return {Array} The product of the two transform matrices\n     */\n    multiplyTransformMatrices: function(a, b, is2x2) {\n      // Matrix multiply a * b\n      return [\n        a[0] * b[0] + a[2] * b[1],\n        a[1] * b[0] + a[3] * b[1],\n        a[0] * b[2] + a[2] * b[3],\n        a[1] * b[2] + a[3] * b[3],\n        is2x2 ? 0 : a[0] * b[4] + a[2] * b[5] + a[4],\n        is2x2 ? 0 : a[1] * b[4] + a[3] * b[5] + a[5]\n      ];\n    },\n\n    /**\n     * Decomposes standard 2x2 matrix into transform componentes\n     * @static\n     * @memberOf fabric.util\n     * @param  {Array} a transformMatrix\n     * @return {Object} Components of transform\n     */\n    qrDecompose: function(a) {\n      var angle = atan2(a[1], a[0]),\n          denom = pow(a[0], 2) + pow(a[1], 2),\n          scaleX = sqrt(denom),\n          scaleY = (a[0] * a[3] - a[2] * a [1]) / scaleX,\n          skewX = atan2(a[0] * a[2] + a[1] * a [3], denom);\n      return {\n        angle: angle  / PiBy180,\n        scaleX: scaleX,\n        scaleY: scaleY,\n        skewX: skewX / PiBy180,\n        skewY: 0,\n        translateX: a[4],\n        translateY: a[5]\n      };\n    },\n\n    customTransformMatrix: function(scaleX, scaleY, skewX) {\n      var skewMatrixX = [1, 0, abs(Math.tan(skewX * PiBy180)), 1],\n          scaleMatrix = [abs(scaleX), 0, 0, abs(scaleY)];\n      return fabric.util.multiplyTransformMatrices(scaleMatrix, skewMatrixX, true);\n    },\n\n    /**\n     * reset an object transform state to neutral. Top and left are not accounted for\n     * @static\n     * @memberOf fabric.util\n     * @param  {fabric.Object} target object to transform\n     */\n    resetObjectTransform: function (target) {\n      target.scaleX = 1;\n      target.scaleY = 1;\n      target.skewX = 0;\n      target.skewY = 0;\n      target.flipX = false;\n      target.flipY = false;\n      target.rotate(0);\n    },\n\n    /**\n     * Extract Object transform values\n     * @static\n     * @memberOf fabric.util\n     * @param  {fabric.Object} target object to read from\n     * @return {Object} Components of transform\n     */\n    saveObjectTransform: function (target) {\n      return {\n        scaleX: target.scaleX,\n        scaleY: target.scaleY,\n        skewX: target.skewX,\n        skewY: target.skewY,\n        angle: target.angle,\n        left: target.left,\n        flipX: target.flipX,\n        flipY: target.flipY,\n        top: target.top\n      };\n    },\n\n    /**\n     * Returns string representation of function body\n     * @param {Function} fn Function to get body of\n     * @return {String} Function body\n     */\n    getFunctionBody: function(fn) {\n      return (String(fn).match(/function[^{]*\\{([\\s\\S]*)\\}/) || {})[1];\n    },\n\n    /**\n     * Returns true if context has transparent pixel\n     * at specified location (taking tolerance into account)\n     * @param {CanvasRenderingContext2D} ctx context\n     * @param {Number} x x coordinate\n     * @param {Number} y y coordinate\n     * @param {Number} tolerance Tolerance\n     */\n    isTransparent: function(ctx, x, y, tolerance) {\n\n      // If tolerance is > 0 adjust start coords to take into account.\n      // If moves off Canvas fix to 0\n      if (tolerance > 0) {\n        if (x > tolerance) {\n          x -= tolerance;\n        }\n        else {\n          x = 0;\n        }\n        if (y > tolerance) {\n          y -= tolerance;\n        }\n        else {\n          y = 0;\n        }\n      }\n\n      var _isTransparent = true, i, temp,\n          imageData = ctx.getImageData(x, y, (tolerance * 2) || 1, (tolerance * 2) || 1),\n          l = imageData.data.length;\n\n      // Split image data - for tolerance > 1, pixelDataSize = 4;\n      for (i = 3; i < l; i += 4) {\n        temp = imageData.data[i];\n        _isTransparent = temp <= 0;\n        if (_isTransparent === false) {\n          break; // Stop if colour found\n        }\n      }\n\n      imageData = null;\n\n      return _isTransparent;\n    },\n\n    /**\n     * Parse preserveAspectRatio attribute from element\n     * @param {string} attribute to be parsed\n     * @return {Object} an object containing align and meetOrSlice attribute\n     */\n    parsePreserveAspectRatioAttribute: function(attribute) {\n      var meetOrSlice = 'meet', alignX = 'Mid', alignY = 'Mid',\n          aspectRatioAttrs = attribute.split(' '), align;\n\n      if (aspectRatioAttrs && aspectRatioAttrs.length) {\n        meetOrSlice = aspectRatioAttrs.pop();\n        if (meetOrSlice !== 'meet' && meetOrSlice !== 'slice') {\n          align = meetOrSlice;\n          meetOrSlice = 'meet';\n        }\n        else if (aspectRatioAttrs.length) {\n          align = aspectRatioAttrs.pop();\n        }\n      }\n      //divide align in alignX and alignY\n      alignX = align !== 'none' ? align.slice(1, 4) : 'none';\n      alignY = align !== 'none' ? align.slice(5, 8) : 'none';\n      return {\n        meetOrSlice: meetOrSlice,\n        alignX: alignX,\n        alignY: alignY\n      };\n    },\n\n    /**\n     * Clear char widths cache for the given font family or all the cache if no\n     * fontFamily is specified.\n     * Use it if you know you are loading fonts in a lazy way and you are not waiting\n     * for custom fonts to load properly when adding text objects to the canvas.\n     * If a text object is added when its own font is not loaded yet, you will get wrong\n     * measurement and so wrong bounding boxes.\n     * After the font cache is cleared, either change the textObject text content or call\n     * initDimensions() to trigger a recalculation\n     * @memberOf fabric.util\n     * @param {String} [fontFamily] font family to clear\n     */\n    clearFabricFontCache: function(fontFamily) {\n      fontFamily = (fontFamily || '').toLowerCase();\n      if (!fontFamily) {\n        fabric.charWidthsCache = { };\n      }\n      else if (fabric.charWidthsCache[fontFamily]) {\n        delete fabric.charWidthsCache[fontFamily];\n      }\n    },\n\n    /**\n     * Given current aspect ratio, determines the max width and height that can\n     * respect the total allowed area for the cache.\n     * @memberOf fabric.util\n     * @param {Number} ar aspect ratio\n     * @param {Number} maximumArea Maximum area you want to achieve\n     * @return {Object.x} Limited dimensions by X\n     * @return {Object.y} Limited dimensions by Y\n     */\n    limitDimsByArea: function(ar, maximumArea) {\n      var roughWidth = Math.sqrt(maximumArea * ar),\n          perfLimitSizeY = Math.floor(maximumArea / roughWidth);\n      return { x: Math.floor(roughWidth), y: perfLimitSizeY };\n    },\n\n    capValue: function(min, value, max) {\n      return Math.max(min, Math.min(value, max));\n    },\n\n    findScaleToFit: function(source, destination) {\n      return Math.min(destination.width / source.width, destination.height / source.height);\n    },\n\n    findScaleToCover: function(source, destination) {\n      return Math.max(destination.width / source.width, destination.height / source.height);\n    }\n  };\n})(typeof exports !== 'undefined' ? exports : this);\n\n\n(function() {\n\n  var _join = Array.prototype.join;\n\n  /* Adapted from http://dxr.mozilla.org/mozilla-central/source/content/svg/content/src/nsSVGPathDataParser.cpp\n   * by Andrea Bogazzi code is under MPL. if you don't have a copy of the license you can take it here\n   * http://mozilla.org/MPL/2.0/\n   */\n  function arcToSegments(toX, toY, rx, ry, large, sweep, rotateX) {\n    var argsString = _join.call(arguments);\n    if (fabric.arcToSegmentsCache[argsString]) {\n      return fabric.arcToSegmentsCache[argsString];\n    }\n\n    var PI = Math.PI, th = rotateX * PI / 180,\n        sinTh = fabric.util.sin(th),\n        cosTh = fabric.util.cos(th),\n        fromX = 0, fromY = 0;\n\n    rx = Math.abs(rx);\n    ry = Math.abs(ry);\n\n    var px = -cosTh * toX * 0.5 - sinTh * toY * 0.5,\n        py = -cosTh * toY * 0.5 + sinTh * toX * 0.5,\n        rx2 = rx * rx, ry2 = ry * ry, py2 = py * py, px2 = px * px,\n        pl = rx2 * ry2 - rx2 * py2 - ry2 * px2,\n        root = 0;\n\n    if (pl < 0) {\n      var s = Math.sqrt(1 - pl / (rx2 * ry2));\n      rx *= s;\n      ry *= s;\n    }\n    else {\n      root = (large === sweep ? -1.0 : 1.0) *\n              Math.sqrt( pl / (rx2 * py2 + ry2 * px2));\n    }\n\n    var cx = root * rx * py / ry,\n        cy = -root * ry * px / rx,\n        cx1 = cosTh * cx - sinTh * cy + toX * 0.5,\n        cy1 = sinTh * cx + cosTh * cy + toY * 0.5,\n        mTheta = calcVectorAngle(1, 0, (px - cx) / rx, (py - cy) / ry),\n        dtheta = calcVectorAngle((px - cx) / rx, (py - cy) / ry, (-px - cx) / rx, (-py - cy) / ry);\n\n    if (sweep === 0 && dtheta > 0) {\n      dtheta -= 2 * PI;\n    }\n    else if (sweep === 1 && dtheta < 0) {\n      dtheta += 2 * PI;\n    }\n\n    // Convert into cubic bezier segments <= 90deg\n    var segments = Math.ceil(Math.abs(dtheta / PI * 2)),\n        result = [], mDelta = dtheta / segments,\n        mT = 8 / 3 * Math.sin(mDelta / 4) * Math.sin(mDelta / 4) / Math.sin(mDelta / 2),\n        th3 = mTheta + mDelta;\n\n    for (var i = 0; i < segments; i++) {\n      result[i] = segmentToBezier(mTheta, th3, cosTh, sinTh, rx, ry, cx1, cy1, mT, fromX, fromY);\n      fromX = result[i][4];\n      fromY = result[i][5];\n      mTheta = th3;\n      th3 += mDelta;\n    }\n    fabric.arcToSegmentsCache[argsString] = result;\n    return result;\n  }\n\n  function segmentToBezier(th2, th3, cosTh, sinTh, rx, ry, cx1, cy1, mT, fromX, fromY) {\n    var costh2 = fabric.util.cos(th2),\n        sinth2 = fabric.util.sin(th2),\n        costh3 = fabric.util.cos(th3),\n        sinth3 = fabric.util.sin(th3),\n        toX = cosTh * rx * costh3 - sinTh * ry * sinth3 + cx1,\n        toY = sinTh * rx * costh3 + cosTh * ry * sinth3 + cy1,\n        cp1X = fromX + mT * ( -cosTh * rx * sinth2 - sinTh * ry * costh2),\n        cp1Y = fromY + mT * ( -sinTh * rx * sinth2 + cosTh * ry * costh2),\n        cp2X = toX + mT * ( cosTh * rx * sinth3 + sinTh * ry * costh3),\n        cp2Y = toY + mT * ( sinTh * rx * sinth3 - cosTh * ry * costh3);\n\n    return [\n      cp1X, cp1Y,\n      cp2X, cp2Y,\n      toX, toY\n    ];\n  }\n\n  /*\n   * Private\n   */\n  function calcVectorAngle(ux, uy, vx, vy) {\n    var ta = Math.atan2(uy, ux),\n        tb = Math.atan2(vy, vx);\n    if (tb >= ta) {\n      return tb - ta;\n    }\n    else {\n      return 2 * Math.PI - (ta - tb);\n    }\n  }\n\n  /**\n   * Draws arc\n   * @param {CanvasRenderingContext2D} ctx\n   * @param {Number} fx\n   * @param {Number} fy\n   * @param {Array} coords\n   */\n  fabric.util.drawArc = function(ctx, fx, fy, coords) {\n    var rx = coords[0],\n        ry = coords[1],\n        rot = coords[2],\n        large = coords[3],\n        sweep = coords[4],\n        tx = coords[5],\n        ty = coords[6],\n        segs = [[], [], [], []],\n        segsNorm = arcToSegments(tx - fx, ty - fy, rx, ry, large, sweep, rot);\n\n    for (var i = 0, len = segsNorm.length; i < len; i++) {\n      segs[i][0] = segsNorm[i][0] + fx;\n      segs[i][1] = segsNorm[i][1] + fy;\n      segs[i][2] = segsNorm[i][2] + fx;\n      segs[i][3] = segsNorm[i][3] + fy;\n      segs[i][4] = segsNorm[i][4] + fx;\n      segs[i][5] = segsNorm[i][5] + fy;\n      ctx.bezierCurveTo.apply(ctx, segs[i]);\n    }\n  };\n\n  /**\n   * Calculate bounding box of a elliptic-arc\n   * @param {Number} fx start point of arc\n   * @param {Number} fy\n   * @param {Number} rx horizontal radius\n   * @param {Number} ry vertical radius\n   * @param {Number} rot angle of horizontal axe\n   * @param {Number} large 1 or 0, whatever the arc is the big or the small on the 2 points\n   * @param {Number} sweep 1 or 0, 1 clockwise or counterclockwise direction\n   * @param {Number} tx end point of arc\n   * @param {Number} ty\n   */\n  fabric.util.getBoundsOfArc = function(fx, fy, rx, ry, rot, large, sweep, tx, ty) {\n\n    var fromX = 0, fromY = 0, bound, bounds = [],\n        segs = arcToSegments(tx - fx, ty - fy, rx, ry, large, sweep, rot);\n\n    for (var i = 0, len = segs.length; i < len; i++) {\n      bound = getBoundsOfCurve(fromX, fromY, segs[i][0], segs[i][1], segs[i][2], segs[i][3], segs[i][4], segs[i][5]);\n      bounds.push({ x: bound[0].x + fx, y: bound[0].y + fy });\n      bounds.push({ x: bound[1].x + fx, y: bound[1].y + fy });\n      fromX = segs[i][4];\n      fromY = segs[i][5];\n    }\n    return bounds;\n  };\n\n  /**\n   * Calculate bounding box of a beziercurve\n   * @param {Number} x0 starting point\n   * @param {Number} y0\n   * @param {Number} x1 first control point\n   * @param {Number} y1\n   * @param {Number} x2 secondo control point\n   * @param {Number} y2\n   * @param {Number} x3 end of beizer\n   * @param {Number} y3\n   */\n  // taken from http://jsbin.com/ivomiq/56/edit  no credits available for that.\n  function getBoundsOfCurve(x0, y0, x1, y1, x2, y2, x3, y3) {\n    var argsString;\n    if (fabric.cachesBoundsOfCurve) {\n      argsString = _join.call(arguments);\n      if (fabric.boundsOfCurveCache[argsString]) {\n        return fabric.boundsOfCurveCache[argsString];\n      }\n    }\n\n    var sqrt = Math.sqrt,\n        min = Math.min, max = Math.max,\n        abs = Math.abs, tvalues = [],\n        bounds = [[], []],\n        a, b, c, t, t1, t2, b2ac, sqrtb2ac;\n\n    b = 6 * x0 - 12 * x1 + 6 * x2;\n    a = -3 * x0 + 9 * x1 - 9 * x2 + 3 * x3;\n    c = 3 * x1 - 3 * x0;\n\n    for (var i = 0; i < 2; ++i) {\n      if (i > 0) {\n        b = 6 * y0 - 12 * y1 + 6 * y2;\n        a = -3 * y0 + 9 * y1 - 9 * y2 + 3 * y3;\n        c = 3 * y1 - 3 * y0;\n      }\n\n      if (abs(a) < 1e-12) {\n        if (abs(b) < 1e-12) {\n          continue;\n        }\n        t = -c / b;\n        if (0 < t && t < 1) {\n          tvalues.push(t);\n        }\n        continue;\n      }\n      b2ac = b * b - 4 * c * a;\n      if (b2ac < 0) {\n        continue;\n      }\n      sqrtb2ac = sqrt(b2ac);\n      t1 = (-b + sqrtb2ac) / (2 * a);\n      if (0 < t1 && t1 < 1) {\n        tvalues.push(t1);\n      }\n      t2 = (-b - sqrtb2ac) / (2 * a);\n      if (0 < t2 && t2 < 1) {\n        tvalues.push(t2);\n      }\n    }\n\n    var x, y, j = tvalues.length, jlen = j, mt;\n    while (j--) {\n      t = tvalues[j];\n      mt = 1 - t;\n      x = (mt * mt * mt * x0) + (3 * mt * mt * t * x1) + (3 * mt * t * t * x2) + (t * t * t * x3);\n      bounds[0][j] = x;\n\n      y = (mt * mt * mt * y0) + (3 * mt * mt * t * y1) + (3 * mt * t * t * y2) + (t * t * t * y3);\n      bounds[1][j] = y;\n    }\n\n    bounds[0][jlen] = x0;\n    bounds[1][jlen] = y0;\n    bounds[0][jlen + 1] = x3;\n    bounds[1][jlen + 1] = y3;\n    var result = [\n      {\n        x: min.apply(null, bounds[0]),\n        y: min.apply(null, bounds[1])\n      },\n      {\n        x: max.apply(null, bounds[0]),\n        y: max.apply(null, bounds[1])\n      }\n    ];\n    if (fabric.cachesBoundsOfCurve) {\n      fabric.boundsOfCurveCache[argsString] = result;\n    }\n    return result;\n  }\n\n  fabric.util.getBoundsOfCurve = getBoundsOfCurve;\n\n})();\n\n\n(function() {\n\n  var slice = Array.prototype.slice;\n\n  /**\n   * Invokes method on all items in a given array\n   * @memberOf fabric.util.array\n   * @param {Array} array Array to iterate over\n   * @param {String} method Name of a method to invoke\n   * @return {Array}\n   */\n  function invoke(array, method) {\n    var args = slice.call(arguments, 2), result = [];\n    for (var i = 0, len = array.length; i < len; i++) {\n      result[i] = args.length ? array[i][method].apply(array[i], args) : array[i][method].call(array[i]);\n    }\n    return result;\n  }\n\n  /**\n   * Finds maximum value in array (not necessarily \"first\" one)\n   * @memberOf fabric.util.array\n   * @param {Array} array Array to iterate over\n   * @param {String} byProperty\n   * @return {*}\n   */\n  function max(array, byProperty) {\n    return find(array, byProperty, function(value1, value2) {\n      return value1 >= value2;\n    });\n  }\n\n  /**\n   * Finds minimum value in array (not necessarily \"first\" one)\n   * @memberOf fabric.util.array\n   * @param {Array} array Array to iterate over\n   * @param {String} byProperty\n   * @return {*}\n   */\n  function min(array, byProperty) {\n    return find(array, byProperty, function(value1, value2) {\n      return value1 < value2;\n    });\n  }\n\n  /**\n   * @private\n   */\n  function fill(array, value) {\n    var k = array.length;\n    while (k--) {\n      array[k] = value;\n    }\n    return array;\n  }\n\n  /**\n   * @private\n   */\n  function find(array, byProperty, condition) {\n    if (!array || array.length === 0) {\n      return;\n    }\n\n    var i = array.length - 1,\n        result = byProperty ? array[i][byProperty] : array[i];\n    if (byProperty) {\n      while (i--) {\n        if (condition(array[i][byProperty], result)) {\n          result = array[i][byProperty];\n        }\n      }\n    }\n    else {\n      while (i--) {\n        if (condition(array[i], result)) {\n          result = array[i];\n        }\n      }\n    }\n    return result;\n  }\n\n  /**\n   * @namespace fabric.util.array\n   */\n  fabric.util.array = {\n    fill: fill,\n    invoke: invoke,\n    min: min,\n    max: max\n  };\n\n})();\n\n\n(function() {\n  /**\n   * Copies all enumerable properties of one js object to another\n   * Does not clone or extend fabric.Object subclasses.\n   * @memberOf fabric.util.object\n   * @param {Object} destination Where to copy to\n   * @param {Object} source Where to copy from\n   * @return {Object}\n   */\n\n  function extend(destination, source, deep) {\n    // JScript DontEnum bug is not taken care of\n    // the deep clone is for internal use, is not meant to avoid\n    // javascript traps or cloning html element or self referenced objects.\n    if (deep) {\n      if (!fabric.isLikelyNode && source instanceof Element) {\n        // avoid cloning deep images, canvases,\n        destination = source;\n      }\n      else if (source instanceof Array) {\n        destination = [];\n        for (var i = 0, len = source.length; i < len; i++) {\n          destination[i] = extend({ }, source[i], deep);\n        }\n      }\n      else if (source && typeof source === 'object') {\n        for (var property in source) {\n          if (source.hasOwnProperty(property)) {\n            destination[property] = extend({ }, source[property], deep);\n          }\n        }\n      }\n      else {\n        // this sounds odd for an extend but is ok for recursive use\n        destination = source;\n      }\n    }\n    else {\n      for (var property in source) {\n        destination[property] = source[property];\n      }\n    }\n    return destination;\n  }\n\n  /**\n   * Creates an empty object and copies all enumerable properties of another object to it\n   * @memberOf fabric.util.object\n   * TODO: this function return an empty object if you try to clone null\n   * @param {Object} object Object to clone\n   * @return {Object}\n   */\n  function clone(object, deep) {\n    return extend({ }, object, deep);\n  }\n\n  /** @namespace fabric.util.object */\n  fabric.util.object = {\n    extend: extend,\n    clone: clone\n  };\n  fabric.util.object.extend(fabric.util, fabric.Observable);\n})();\n\n\n(function() {\n\n  /**\n   * Camelizes a string\n   * @memberOf fabric.util.string\n   * @param {String} string String to camelize\n   * @return {String} Camelized version of a string\n   */\n  function camelize(string) {\n    return string.replace(/-+(.)?/g, function(match, character) {\n      return character ? character.toUpperCase() : '';\n    });\n  }\n\n  /**\n   * Capitalizes a string\n   * @memberOf fabric.util.string\n   * @param {String} string String to capitalize\n   * @param {Boolean} [firstLetterOnly] If true only first letter is capitalized\n   * and other letters stay untouched, if false first letter is capitalized\n   * and other letters are converted to lowercase.\n   * @return {String} Capitalized version of a string\n   */\n  function capitalize(string, firstLetterOnly) {\n    return string.charAt(0).toUpperCase() +\n      (firstLetterOnly ? string.slice(1) : string.slice(1).toLowerCase());\n  }\n\n  /**\n   * Escapes XML in a string\n   * @memberOf fabric.util.string\n   * @param {String} string String to escape\n   * @return {String} Escaped version of a string\n   */\n  function escapeXml(string) {\n    return string.replace(/&/g, '&amp;')\n      .replace(/\"/g, '&quot;')\n      .replace(/'/g, '&apos;')\n      .replace(/</g, '&lt;')\n      .replace(/>/g, '&gt;');\n  }\n\n  /**\n   * Divide a string in the user perceived single units\n   * @memberOf fabric.util.string\n   * @param {String} textstring String to escape\n   * @return {Array} array containing the graphemes\n   */\n  function graphemeSplit(textstring) {\n    var i = 0, chr, graphemes = [];\n    for (i = 0, chr; i < textstring.length; i++) {\n      if ((chr = getWholeChar(textstring, i)) === false) {\n        continue;\n      }\n      graphemes.push(chr);\n    }\n    return graphemes;\n  }\n\n  // taken from mdn in the charAt doc page.\n  function getWholeChar(str, i) {\n    var code = str.charCodeAt(i);\n\n    if (isNaN(code)) {\n      return ''; // Position not found\n    }\n    if (code < 0xD800 || code > 0xDFFF) {\n      return str.charAt(i);\n    }\n\n    // High surrogate (could change last hex to 0xDB7F to treat high private\n    // surrogates as single characters)\n    if (0xD800 <= code && code <= 0xDBFF) {\n      if (str.length <= (i + 1)) {\n        throw 'High surrogate without following low surrogate';\n      }\n      var next = str.charCodeAt(i + 1);\n      if (0xDC00 > next || next > 0xDFFF) {\n        throw 'High surrogate without following low surrogate';\n      }\n      return str.charAt(i) + str.charAt(i + 1);\n    }\n    // Low surrogate (0xDC00 <= code && code <= 0xDFFF)\n    if (i === 0) {\n      throw 'Low surrogate without preceding high surrogate';\n    }\n    var prev = str.charCodeAt(i - 1);\n\n    // (could change last hex to 0xDB7F to treat high private\n    // surrogates as single characters)\n    if (0xD800 > prev || prev > 0xDBFF) {\n      throw 'Low surrogate without preceding high surrogate';\n    }\n    // We can pass over low surrogates now as the second component\n    // in a pair which we have already processed\n    return false;\n  }\n\n\n  /**\n   * String utilities\n   * @namespace fabric.util.string\n   */\n  fabric.util.string = {\n    camelize: camelize,\n    capitalize: capitalize,\n    escapeXml: escapeXml,\n    graphemeSplit: graphemeSplit\n  };\n})();\n\n\n(function() {\n\n  var slice = Array.prototype.slice, emptyFunction = function() { },\n\n      IS_DONTENUM_BUGGY = (function() {\n        for (var p in { toString: 1 }) {\n          if (p === 'toString') {\n            return false;\n          }\n        }\n        return true;\n      })(),\n\n      /** @ignore */\n      addMethods = function(klass, source, parent) {\n        for (var property in source) {\n\n          if (property in klass.prototype &&\n              typeof klass.prototype[property] === 'function' &&\n              (source[property] + '').indexOf('callSuper') > -1) {\n\n            klass.prototype[property] = (function(property) {\n              return function() {\n\n                var superclass = this.constructor.superclass;\n                this.constructor.superclass = parent;\n                var returnValue = source[property].apply(this, arguments);\n                this.constructor.superclass = superclass;\n\n                if (property !== 'initialize') {\n                  return returnValue;\n                }\n              };\n            })(property);\n          }\n          else {\n            klass.prototype[property] = source[property];\n          }\n\n          if (IS_DONTENUM_BUGGY) {\n            if (source.toString !== Object.prototype.toString) {\n              klass.prototype.toString = source.toString;\n            }\n            if (source.valueOf !== Object.prototype.valueOf) {\n              klass.prototype.valueOf = source.valueOf;\n            }\n          }\n        }\n      };\n\n  function Subclass() { }\n\n  function callSuper(methodName) {\n    var parentMethod = null,\n        _this = this;\n\n    // climb prototype chain to find method not equal to callee's method\n    while (_this.constructor.superclass) {\n      var superClassMethod = _this.constructor.superclass.prototype[methodName];\n      if (_this[methodName] !== superClassMethod) {\n        parentMethod = superClassMethod;\n        break;\n      }\n      // eslint-disable-next-line\n      _this = _this.constructor.superclass.prototype;\n    }\n\n    if (!parentMethod) {\n      return console.log('tried to callSuper ' + methodName + ', method not found in prototype chain', this);\n    }\n\n    return (arguments.length > 1)\n      ? parentMethod.apply(this, slice.call(arguments, 1))\n      : parentMethod.call(this);\n  }\n\n  /**\n   * Helper for creation of \"classes\".\n   * @memberOf fabric.util\n   * @param {Function} [parent] optional \"Class\" to inherit from\n   * @param {Object} [properties] Properties shared by all instances of this class\n   *                  (be careful modifying objects defined here as this would affect all instances)\n   */\n  function createClass() {\n    var parent = null,\n        properties = slice.call(arguments, 0);\n\n    if (typeof properties[0] === 'function') {\n      parent = properties.shift();\n    }\n    function klass() {\n      this.initialize.apply(this, arguments);\n    }\n\n    klass.superclass = parent;\n    klass.subclasses = [];\n\n    if (parent) {\n      Subclass.prototype = parent.prototype;\n      klass.prototype = new Subclass();\n      parent.subclasses.push(klass);\n    }\n    for (var i = 0, length = properties.length; i < length; i++) {\n      addMethods(klass, properties[i], parent);\n    }\n    if (!klass.prototype.initialize) {\n      klass.prototype.initialize = emptyFunction;\n    }\n    klass.prototype.constructor = klass;\n    klass.prototype.callSuper = callSuper;\n    return klass;\n  }\n\n  fabric.util.createClass = createClass;\n})();\n\n\n(function () {\n\n  var unknown = 'unknown';\n\n  /* EVENT HANDLING */\n\n  function areHostMethods(object) {\n    var methodNames = Array.prototype.slice.call(arguments, 1),\n        t, i, len = methodNames.length;\n    for (i = 0; i < len; i++) {\n      t = typeof object[methodNames[i]];\n      if (!(/^(?:function|object|unknown)$/).test(t)) {\n        return false;\n      }\n    }\n    return true;\n  }\n\n  /** @ignore */\n  var getElement,\n      setElement,\n      getUniqueId = (function () {\n        var uid = 0;\n        return function (element) {\n          return element.__uniqueID || (element.__uniqueID = 'uniqueID__' + uid++);\n        };\n      })();\n\n  (function () {\n    var elements = { };\n    /** @ignore */\n    getElement = function (uid) {\n      return elements[uid];\n    };\n    /** @ignore */\n    setElement = function (uid, element) {\n      elements[uid] = element;\n    };\n  })();\n\n  function createListener(uid, handler) {\n    return {\n      handler: handler,\n      wrappedHandler: createWrappedHandler(uid, handler)\n    };\n  }\n\n  function createWrappedHandler(uid, handler) {\n    return function (e) {\n      handler.call(getElement(uid), e || fabric.window.event);\n    };\n  }\n\n  function createDispatcher(uid, eventName) {\n    return function (e) {\n      if (handlers[uid] && handlers[uid][eventName]) {\n        var handlersForEvent = handlers[uid][eventName];\n        for (var i = 0, len = handlersForEvent.length; i < len; i++) {\n          handlersForEvent[i].call(this, e || fabric.window.event);\n        }\n      }\n    };\n  }\n\n  var shouldUseAddListenerRemoveListener = (\n        areHostMethods(fabric.document.documentElement, 'addEventListener', 'removeEventListener') &&\n        areHostMethods(fabric.window, 'addEventListener', 'removeEventListener')),\n\n      shouldUseAttachEventDetachEvent = (\n        areHostMethods(fabric.document.documentElement, 'attachEvent', 'detachEvent') &&\n        areHostMethods(fabric.window, 'attachEvent', 'detachEvent')),\n\n      // IE branch\n      listeners = { },\n\n      // DOM L0 branch\n      handlers = { },\n\n      addListener, removeListener;\n\n  if (shouldUseAddListenerRemoveListener) {\n    /** @ignore */\n    addListener = function (element, eventName, handler, options) {\n      // since ie10 or ie9 can use addEventListener but they do not support options, i need to check\n      element && element.addEventListener(eventName, handler, shouldUseAttachEventDetachEvent ? false : options);\n    };\n    /** @ignore */\n    removeListener = function (element, eventName, handler, options) {\n      element && element.removeEventListener(eventName, handler, shouldUseAttachEventDetachEvent ? false : options);\n    };\n  }\n\n  else if (shouldUseAttachEventDetachEvent) {\n    /** @ignore */\n    addListener = function (element, eventName, handler) {\n      if (!element) {\n        return;\n      }\n      var uid = getUniqueId(element);\n      setElement(uid, element);\n      if (!listeners[uid]) {\n        listeners[uid] = { };\n      }\n      if (!listeners[uid][eventName]) {\n        listeners[uid][eventName] = [];\n\n      }\n      var listener = createListener(uid, handler);\n      listeners[uid][eventName].push(listener);\n      element.attachEvent('on' + eventName, listener.wrappedHandler);\n    };\n    /** @ignore */\n    removeListener = function (element, eventName, handler) {\n      if (!element) {\n        return;\n      }\n      var uid = getUniqueId(element), listener;\n      if (listeners[uid] && listeners[uid][eventName]) {\n        for (var i = 0, len = listeners[uid][eventName].length; i < len; i++) {\n          listener = listeners[uid][eventName][i];\n          if (listener && listener.handler === handler) {\n            element.detachEvent('on' + eventName, listener.wrappedHandler);\n            listeners[uid][eventName][i] = null;\n          }\n        }\n      }\n    };\n  }\n  else {\n    /** @ignore */\n    addListener = function (element, eventName, handler) {\n      if (!element) {\n        return;\n      }\n      var uid = getUniqueId(element);\n      if (!handlers[uid]) {\n        handlers[uid] = { };\n      }\n      if (!handlers[uid][eventName]) {\n        handlers[uid][eventName] = [];\n        var existingHandler = element['on' + eventName];\n        if (existingHandler) {\n          handlers[uid][eventName].push(existingHandler);\n        }\n        element['on' + eventName] = createDispatcher(uid, eventName);\n      }\n      handlers[uid][eventName].push(handler);\n    };\n    /** @ignore */\n    removeListener = function (element, eventName, handler) {\n      if (!element) {\n        return;\n      }\n      var uid = getUniqueId(element);\n      if (handlers[uid] && handlers[uid][eventName]) {\n        var handlersForEvent = handlers[uid][eventName];\n        for (var i = 0, len = handlersForEvent.length; i < len; i++) {\n          if (handlersForEvent[i] === handler) {\n            handlersForEvent.splice(i, 1);\n          }\n        }\n      }\n    };\n  }\n\n  /**\n   * Adds an event listener to an element\n   * @function\n   * @memberOf fabric.util\n   * @param {HTMLElement} element\n   * @param {String} eventName\n   * @param {Function} handler\n   */\n  fabric.util.addListener = addListener;\n\n  /**\n   * Removes an event listener from an element\n   * @function\n   * @memberOf fabric.util\n   * @param {HTMLElement} element\n   * @param {String} eventName\n   * @param {Function} handler\n   */\n  fabric.util.removeListener = removeListener;\n\n  /**\n   * Cross-browser wrapper for getting event's coordinates\n   * @memberOf fabric.util\n   * @param {Event} event Event object\n   */\n  function getPointer(event) {\n    event || (event = fabric.window.event);\n\n    var element = event.target ||\n                  (typeof event.srcElement !== unknown ? event.srcElement : null),\n\n        scroll = fabric.util.getScrollLeftTop(element);\n    return {\n      x: pointerX(event) + scroll.left,\n      y: pointerY(event) + scroll.top\n    };\n  }\n\n  var pointerX = function(event) {\n        return event.clientX;\n      },\n\n      pointerY = function(event) {\n        return event.clientY;\n      };\n\n  function _getPointer(event, pageProp, clientProp) {\n    var touchProp = event.type === 'touchend' ? 'changedTouches' : 'touches';\n    var pointer, eventTouchProp = event[touchProp];\n\n    if (eventTouchProp && eventTouchProp[0]) {\n      pointer = eventTouchProp[0][clientProp];\n    }\n\n    if (typeof pointer === 'undefined') {\n      pointer = event[clientProp];\n    }\n\n    return pointer;\n  }\n\n  if (fabric.isTouchSupported) {\n    pointerX = function(event) {\n      return _getPointer(event, 'pageX', 'clientX');\n    };\n    pointerY = function(event) {\n      return _getPointer(event, 'pageY', 'clientY');\n    };\n  }\n\n  fabric.util.getPointer = getPointer;\n\n})();\n\n\n(function () {\n\n  /**\n   * Cross-browser wrapper for setting element's style\n   * @memberOf fabric.util\n   * @param {HTMLElement} element\n   * @param {Object} styles\n   * @return {HTMLElement} Element that was passed as a first argument\n   */\n  function setStyle(element, styles) {\n    var elementStyle = element.style;\n    if (!elementStyle) {\n      return element;\n    }\n    if (typeof styles === 'string') {\n      element.style.cssText += ';' + styles;\n      return styles.indexOf('opacity') > -1\n        ? setOpacity(element, styles.match(/opacity:\\s*(\\d?\\.?\\d*)/)[1])\n        : element;\n    }\n    for (var property in styles) {\n      if (property === 'opacity') {\n        setOpacity(element, styles[property]);\n      }\n      else {\n        var normalizedProperty = (property === 'float' || property === 'cssFloat')\n          ? (typeof elementStyle.styleFloat === 'undefined' ? 'cssFloat' : 'styleFloat')\n          : property;\n        elementStyle[normalizedProperty] = styles[property];\n      }\n    }\n    return element;\n  }\n\n  var parseEl = fabric.document.createElement('div'),\n      supportsOpacity = typeof parseEl.style.opacity === 'string',\n      supportsFilters = typeof parseEl.style.filter === 'string',\n      reOpacity = /alpha\\s*\\(\\s*opacity\\s*=\\s*([^\\)]+)\\)/,\n\n      /** @ignore */\n      setOpacity = function (element) { return element; };\n\n  if (supportsOpacity) {\n    /** @ignore */\n    setOpacity = function(element, value) {\n      element.style.opacity = value;\n      return element;\n    };\n  }\n  else if (supportsFilters) {\n    /** @ignore */\n    setOpacity = function(element, value) {\n      var es = element.style;\n      if (element.currentStyle && !element.currentStyle.hasLayout) {\n        es.zoom = 1;\n      }\n      if (reOpacity.test(es.filter)) {\n        value = value >= 0.9999 ? '' : ('alpha(opacity=' + (value * 100) + ')');\n        es.filter = es.filter.replace(reOpacity, value);\n      }\n      else {\n        es.filter += ' alpha(opacity=' + (value * 100) + ')';\n      }\n      return element;\n    };\n  }\n\n  fabric.util.setStyle = setStyle;\n\n})();\n\n\n(function() {\n\n  var _slice = Array.prototype.slice;\n\n  /**\n   * Takes id and returns an element with that id (if one exists in a document)\n   * @memberOf fabric.util\n   * @param {String|HTMLElement} id\n   * @return {HTMLElement|null}\n   */\n  function getById(id) {\n    return typeof id === 'string' ? fabric.document.getElementById(id) : id;\n  }\n\n  var sliceCanConvertNodelists,\n      /**\n       * Converts an array-like object (e.g. arguments or NodeList) to an array\n       * @memberOf fabric.util\n       * @param {Object} arrayLike\n       * @return {Array}\n       */\n      toArray = function(arrayLike) {\n        return _slice.call(arrayLike, 0);\n      };\n\n  try {\n    sliceCanConvertNodelists = toArray(fabric.document.childNodes) instanceof Array;\n  }\n  catch (err) { }\n\n  if (!sliceCanConvertNodelists) {\n    toArray = function(arrayLike) {\n      var arr = new Array(arrayLike.length), i = arrayLike.length;\n      while (i--) {\n        arr[i] = arrayLike[i];\n      }\n      return arr;\n    };\n  }\n\n  /**\n   * Creates specified element with specified attributes\n   * @memberOf fabric.util\n   * @param {String} tagName Type of an element to create\n   * @param {Object} [attributes] Attributes to set on an element\n   * @return {HTMLElement} Newly created element\n   */\n  function makeElement(tagName, attributes) {\n    var el = fabric.document.createElement(tagName);\n    for (var prop in attributes) {\n      if (prop === 'class') {\n        el.className = attributes[prop];\n      }\n      else if (prop === 'for') {\n        el.htmlFor = attributes[prop];\n      }\n      else {\n        el.setAttribute(prop, attributes[prop]);\n      }\n    }\n    return el;\n  }\n\n  /**\n   * Adds class to an element\n   * @memberOf fabric.util\n   * @param {HTMLElement} element Element to add class to\n   * @param {String} className Class to add to an element\n   */\n  function addClass(element, className) {\n    if (element && (' ' + element.className + ' ').indexOf(' ' + className + ' ') === -1) {\n      element.className += (element.className ? ' ' : '') + className;\n    }\n  }\n\n  /**\n   * Wraps element with another element\n   * @memberOf fabric.util\n   * @param {HTMLElement} element Element to wrap\n   * @param {HTMLElement|String} wrapper Element to wrap with\n   * @param {Object} [attributes] Attributes to set on a wrapper\n   * @return {HTMLElement} wrapper\n   */\n  function wrapElement(element, wrapper, attributes) {\n    if (typeof wrapper === 'string') {\n      wrapper = makeElement(wrapper, attributes);\n    }\n    if (element.parentNode) {\n      element.parentNode.replaceChild(wrapper, element);\n    }\n    wrapper.appendChild(element);\n    return wrapper;\n  }\n\n  /**\n   * Returns element scroll offsets\n   * @memberOf fabric.util\n   * @param {HTMLElement} element Element to operate on\n   * @return {Object} Object with left/top values\n   */\n  function getScrollLeftTop(element) {\n\n    var left = 0,\n        top = 0,\n        docElement = fabric.document.documentElement,\n        body = fabric.document.body || {\n          scrollLeft: 0, scrollTop: 0\n        };\n\n    // While loop checks (and then sets element to) .parentNode OR .host\n    //  to account for ShadowDOM. We still want to traverse up out of ShadowDOM,\n    //  but the .parentNode of a root ShadowDOM node will always be null, instead\n    //  it should be accessed through .host. See http://stackoverflow.com/a/24765528/4383938\n    while (element && (element.parentNode || element.host)) {\n\n      // Set element to element parent, or 'host' in case of ShadowDOM\n      element = element.parentNode || element.host;\n\n      if (element === fabric.document) {\n        left = body.scrollLeft || docElement.scrollLeft || 0;\n        top = body.scrollTop ||  docElement.scrollTop || 0;\n      }\n      else {\n        left += element.scrollLeft || 0;\n        top += element.scrollTop || 0;\n      }\n\n      if (element.nodeType === 1 && element.style.position === 'fixed') {\n        break;\n      }\n    }\n\n    return { left: left, top: top };\n  }\n\n  /**\n   * Returns offset for a given element\n   * @function\n   * @memberOf fabric.util\n   * @param {HTMLElement} element Element to get offset for\n   * @return {Object} Object with \"left\" and \"top\" properties\n   */\n  function getElementOffset(element) {\n    var docElem,\n        doc = element && element.ownerDocument,\n        box = { left: 0, top: 0 },\n        offset = { left: 0, top: 0 },\n        scrollLeftTop,\n        offsetAttributes = {\n          borderLeftWidth: 'left',\n          borderTopWidth:  'top',\n          paddingLeft:     'left',\n          paddingTop:      'top'\n        };\n\n    if (!doc) {\n      return offset;\n    }\n\n    for (var attr in offsetAttributes) {\n      offset[offsetAttributes[attr]] += parseInt(getElementStyle(element, attr), 10) || 0;\n    }\n\n    docElem = doc.documentElement;\n    if ( typeof element.getBoundingClientRect !== 'undefined' ) {\n      box = element.getBoundingClientRect();\n    }\n\n    scrollLeftTop = getScrollLeftTop(element);\n\n    return {\n      left: box.left + scrollLeftTop.left - (docElem.clientLeft || 0) + offset.left,\n      top: box.top + scrollLeftTop.top - (docElem.clientTop || 0)  + offset.top\n    };\n  }\n\n  /**\n   * Returns style attribute value of a given element\n   * @memberOf fabric.util\n   * @param {HTMLElement} element Element to get style attribute for\n   * @param {String} attr Style attribute to get for element\n   * @return {String} Style attribute value of the given element.\n   */\n  var getElementStyle;\n  if (fabric.document.defaultView && fabric.document.defaultView.getComputedStyle) {\n    getElementStyle = function(element, attr) {\n      var style = fabric.document.defaultView.getComputedStyle(element, null);\n      return style ? style[attr] : undefined;\n    };\n  }\n  else {\n    getElementStyle = function(element, attr) {\n      var value = element.style[attr];\n      if (!value && element.currentStyle) {\n        value = element.currentStyle[attr];\n      }\n      return value;\n    };\n  }\n\n  (function () {\n    var style = fabric.document.documentElement.style,\n        selectProp = 'userSelect' in style\n          ? 'userSelect'\n          : 'MozUserSelect' in style\n            ? 'MozUserSelect'\n            : 'WebkitUserSelect' in style\n              ? 'WebkitUserSelect'\n              : 'KhtmlUserSelect' in style\n                ? 'KhtmlUserSelect'\n                : '';\n\n    /**\n     * Makes element unselectable\n     * @memberOf fabric.util\n     * @param {HTMLElement} element Element to make unselectable\n     * @return {HTMLElement} Element that was passed in\n     */\n    function makeElementUnselectable(element) {\n      if (typeof element.onselectstart !== 'undefined') {\n        element.onselectstart = fabric.util.falseFunction;\n      }\n      if (selectProp) {\n        element.style[selectProp] = 'none';\n      }\n      else if (typeof element.unselectable === 'string') {\n        element.unselectable = 'on';\n      }\n      return element;\n    }\n\n    /**\n     * Makes element selectable\n     * @memberOf fabric.util\n     * @param {HTMLElement} element Element to make selectable\n     * @return {HTMLElement} Element that was passed in\n     */\n    function makeElementSelectable(element) {\n      if (typeof element.onselectstart !== 'undefined') {\n        element.onselectstart = null;\n      }\n      if (selectProp) {\n        element.style[selectProp] = '';\n      }\n      else if (typeof element.unselectable === 'string') {\n        element.unselectable = '';\n      }\n      return element;\n    }\n\n    fabric.util.makeElementUnselectable = makeElementUnselectable;\n    fabric.util.makeElementSelectable = makeElementSelectable;\n  })();\n\n  (function() {\n\n    /**\n     * Inserts a script element with a given url into a document; invokes callback, when that script is finished loading\n     * @memberOf fabric.util\n     * @param {String} url URL of a script to load\n     * @param {Function} callback Callback to execute when script is finished loading\n     */\n    function getScript(url, callback) {\n      var headEl = fabric.document.getElementsByTagName('head')[0],\n          scriptEl = fabric.document.createElement('script'),\n          loading = true;\n\n      /** @ignore */\n      scriptEl.onload = /** @ignore */ scriptEl.onreadystatechange = function(e) {\n        if (loading) {\n          if (typeof this.readyState === 'string' &&\n              this.readyState !== 'loaded' &&\n              this.readyState !== 'complete') {\n            return;\n          }\n          loading = false;\n          callback(e || fabric.window.event);\n          scriptEl = scriptEl.onload = scriptEl.onreadystatechange = null;\n        }\n      };\n      scriptEl.src = url;\n      headEl.appendChild(scriptEl);\n      // causes issue in Opera\n      // headEl.removeChild(scriptEl);\n    }\n\n    fabric.util.getScript = getScript;\n  })();\n\n  function getNodeCanvas(element) {\n    var impl = fabric.jsdomImplForWrapper(element);\n    return impl._canvas || impl._image;\n  };\n\n  function cleanUpJsdomNode(element) {\n    if (!fabric.isLikelyNode) {\n      return;\n    }\n    var impl = fabric.jsdomImplForWrapper(element);\n    if (impl) {\n      impl._image = null;\n      impl._canvas = null;\n      // unsure if necessary\n      impl._currentSrc = null;\n      impl._attributes = null;\n      impl._classList = null;\n    }\n  }\n\n  fabric.util.getById = getById;\n  fabric.util.toArray = toArray;\n  fabric.util.makeElement = makeElement;\n  fabric.util.addClass = addClass;\n  fabric.util.wrapElement = wrapElement;\n  fabric.util.getScrollLeftTop = getScrollLeftTop;\n  fabric.util.getElementOffset = getElementOffset;\n  fabric.util.getElementStyle = getElementStyle;\n  fabric.util.getNodeCanvas = getNodeCanvas;\n  fabric.util.cleanUpJsdomNode = cleanUpJsdomNode;\n\n})();\n\n\n(function() {\n\n  function addParamToUrl(url, param) {\n    return url + (/\\?/.test(url) ? '&' : '?') + param;\n  }\n\n  function emptyFn() { }\n\n  /**\n   * Cross-browser abstraction for sending XMLHttpRequest\n   * @memberOf fabric.util\n   * @param {String} url URL to send XMLHttpRequest to\n   * @param {Object} [options] Options object\n   * @param {String} [options.method=\"GET\"]\n   * @param {String} [options.parameters] parameters to append to url in GET or in body\n   * @param {String} [options.body] body to send with POST or PUT request\n   * @param {Function} options.onComplete Callback to invoke when request is completed\n   * @return {XMLHttpRequest} request\n   */\n  function request(url, options) {\n    options || (options = { });\n\n    var method = options.method ? options.method.toUpperCase() : 'GET',\n        onComplete = options.onComplete || function() { },\n        xhr = new fabric.window.XMLHttpRequest(),\n        body = options.body || options.parameters;\n\n    /** @ignore */\n    xhr.onreadystatechange = function() {\n      if (xhr.readyState === 4) {\n        onComplete(xhr);\n        xhr.onreadystatechange = emptyFn;\n      }\n    };\n\n    if (method === 'GET') {\n      body = null;\n      if (typeof options.parameters === 'string') {\n        url = addParamToUrl(url, options.parameters);\n      }\n    }\n\n    xhr.open(method, url, true);\n\n    if (method === 'POST' || method === 'PUT') {\n      xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');\n    }\n\n    xhr.send(body);\n    return xhr;\n  }\n\n  fabric.util.request = request;\n})();\n\n\n/**\n * Wrapper around `console.log` (when available)\n * @param {*} [values] Values to log\n */\nfabric.log = function() { };\n\n/**\n * Wrapper around `console.warn` (when available)\n * @param {*} [values] Values to log as a warning\n */\nfabric.warn = function() { };\n\n/* eslint-disable */\nif (typeof console !== 'undefined') {\n\n  ['log', 'warn'].forEach(function(methodName) {\n\n    if (typeof console[methodName] !== 'undefined' &&\n        typeof console[methodName].apply === 'function') {\n\n      fabric[methodName] = function() {\n        return console[methodName].apply(console, arguments);\n      };\n    }\n  });\n}\n/* eslint-enable */\n\n\n(function() {\n\n  function noop() {\n    return false;\n  }\n\n  /**\n   * Changes value from one to another within certain period of time, invoking callbacks as value is being changed.\n   * @memberOf fabric.util\n   * @param {Object} [options] Animation options\n   * @param {Function} [options.onChange] Callback; invoked on every value change\n   * @param {Function} [options.onComplete] Callback; invoked when value change is completed\n   * @param {Number} [options.startValue=0] Starting value\n   * @param {Number} [options.endValue=100] Ending value\n   * @param {Number} [options.byValue=100] Value to modify the property by\n   * @param {Function} [options.easing] Easing function\n   * @param {Number} [options.duration=500] Duration of change (in ms)\n   */\n  function animate(options) {\n\n    requestAnimFrame(function(timestamp) {\n      options || (options = { });\n\n      var start = timestamp || +new Date(),\n          duration = options.duration || 500,\n          finish = start + duration, time,\n          onChange = options.onChange || noop,\n          abort = options.abort || noop,\n          onComplete = options.onComplete || noop,\n          easing = options.easing || function(t, b, c, d) {return -c * Math.cos(t / d * (Math.PI / 2)) + c + b;},\n          startValue = 'startValue' in options ? options.startValue : 0,\n          endValue = 'endValue' in options ? options.endValue : 100,\n          byValue = options.byValue || endValue - startValue;\n\n      options.onStart && options.onStart();\n\n      (function tick(ticktime) {\n        if (abort()) {\n          onComplete(endValue, 1, 1);\n          return;\n        }\n        time = ticktime || +new Date();\n        var currentTime = time > finish ? duration : (time - start),\n            timePerc = currentTime / duration,\n            current = easing(currentTime, startValue, byValue, duration),\n            valuePerc = Math.abs((current - startValue) / byValue);\n        onChange(current, valuePerc, timePerc);\n        if (time > finish) {\n          options.onComplete && options.onComplete();\n          return;\n        }\n        requestAnimFrame(tick);\n      })(start);\n    });\n\n  }\n\n  var _requestAnimFrame = fabric.window.requestAnimationFrame       ||\n                          fabric.window.webkitRequestAnimationFrame ||\n                          fabric.window.mozRequestAnimationFrame    ||\n                          fabric.window.oRequestAnimationFrame      ||\n                          fabric.window.msRequestAnimationFrame     ||\n                          function(callback) {\n                            return fabric.window.setTimeout(callback, 1000 / 60);\n                          };\n\n  var _cancelAnimFrame = fabric.window.cancelAnimationFrame || fabric.window.clearTimeout;\n\n  /**\n   * requestAnimationFrame polyfill based on http://paulirish.com/2011/requestanimationframe-for-smart-animating/\n   * In order to get a precise start time, `requestAnimFrame` should be called as an entry into the method\n   * @memberOf fabric.util\n   * @param {Function} callback Callback to invoke\n   * @param {DOMElement} element optional Element to associate with animation\n   */\n  function requestAnimFrame() {\n    return _requestAnimFrame.apply(fabric.window, arguments);\n  }\n\n  function cancelAnimFrame() {\n    return _cancelAnimFrame.apply(fabric.window, arguments);\n  }\n\n  fabric.util.animate = animate;\n  fabric.util.requestAnimFrame = requestAnimFrame;\n  fabric.util.cancelAnimFrame = cancelAnimFrame;\n})();\n\n\n(function() {\n  // Calculate an in-between color. Returns a \"rgba()\" string.\n  // Credit: Edwin Martin <edwin@bitstorm.org>\n  //         http://www.bitstorm.org/jquery/color-animation/jquery.animate-colors.js\n  function calculateColor(begin, end, pos) {\n    var color = 'rgba('\n        + parseInt((begin[0] + pos * (end[0] - begin[0])), 10) + ','\n        + parseInt((begin[1] + pos * (end[1] - begin[1])), 10) + ','\n        + parseInt((begin[2] + pos * (end[2] - begin[2])), 10);\n\n    color += ',' + (begin && end ? parseFloat(begin[3] + pos * (end[3] - begin[3])) : 1);\n    color += ')';\n    return color;\n  }\n\n  /**\n   * Changes the color from one to another within certain period of time, invoking callbacks as value is being changed.\n   * @memberOf fabric.util\n   * @param {String} fromColor The starting color in hex or rgb(a) format.\n   * @param {String} toColor The starting color in hex or rgb(a) format.\n   * @param {Number} [duration] Duration of change (in ms).\n   * @param {Object} [options] Animation options\n   * @param {Function} [options.onChange] Callback; invoked on every value change\n   * @param {Function} [options.onComplete] Callback; invoked when value change is completed\n   * @param {Function} [options.colorEasing] Easing function. Note that this function only take two arguments (currentTime, duration). Thus the regular animation easing functions cannot be used.\n   */\n  function animateColor(fromColor, toColor, duration, options) {\n    var startColor = new fabric.Color(fromColor).getSource(),\n        endColor = new fabric.Color(toColor).getSource();\n\n    options = options || {};\n\n    fabric.util.animate(fabric.util.object.extend(options, {\n      duration: duration || 500,\n      startValue: startColor,\n      endValue: endColor,\n      byValue: endColor,\n      easing: function (currentTime, startValue, byValue, duration) {\n        var posValue = options.colorEasing\n          ? options.colorEasing(currentTime, duration)\n          : 1 - Math.cos(currentTime / duration * (Math.PI / 2));\n        return calculateColor(startValue, byValue, posValue);\n      }\n    }));\n  }\n\n  fabric.util.animateColor = animateColor;\n\n})();\n\n\n(function() {\n\n  function normalize(a, c, p, s) {\n    if (a < Math.abs(c)) {\n      a = c;\n      s = p / 4;\n    }\n    else {\n      //handle the 0/0 case:\n      if (c === 0 && a === 0) {\n        s = p / (2 * Math.PI) * Math.asin(1);\n      }\n      else {\n        s = p / (2 * Math.PI) * Math.asin(c / a);\n      }\n    }\n    return { a: a, c: c, p: p, s: s };\n  }\n\n  function elastic(opts, t, d) {\n    return opts.a *\n      Math.pow(2, 10 * (t -= 1)) *\n      Math.sin( (t * d - opts.s) * (2 * Math.PI) / opts.p );\n  }\n\n  /**\n   * Cubic easing out\n   * @memberOf fabric.util.ease\n   */\n  function easeOutCubic(t, b, c, d) {\n    return c * ((t = t / d - 1) * t * t + 1) + b;\n  }\n\n  /**\n   * Cubic easing in and out\n   * @memberOf fabric.util.ease\n   */\n  function easeInOutCubic(t, b, c, d) {\n    t /= d / 2;\n    if (t < 1) {\n      return c / 2 * t * t * t + b;\n    }\n    return c / 2 * ((t -= 2) * t * t + 2) + b;\n  }\n\n  /**\n   * Quartic easing in\n   * @memberOf fabric.util.ease\n   */\n  function easeInQuart(t, b, c, d) {\n    return c * (t /= d) * t * t * t + b;\n  }\n\n  /**\n   * Quartic easing out\n   * @memberOf fabric.util.ease\n   */\n  function easeOutQuart(t, b, c, d) {\n    return -c * ((t = t / d - 1) * t * t * t - 1) + b;\n  }\n\n  /**\n   * Quartic easing in and out\n   * @memberOf fabric.util.ease\n   */\n  function easeInOutQuart(t, b, c, d) {\n    t /= d / 2;\n    if (t < 1) {\n      return c / 2 * t * t * t * t + b;\n    }\n    return -c / 2 * ((t -= 2) * t * t * t - 2) + b;\n  }\n\n  /**\n   * Quintic easing in\n   * @memberOf fabric.util.ease\n   */\n  function easeInQuint(t, b, c, d) {\n    return c * (t /= d) * t * t * t * t + b;\n  }\n\n  /**\n   * Quintic easing out\n   * @memberOf fabric.util.ease\n   */\n  function easeOutQuint(t, b, c, d) {\n    return c * ((t = t / d - 1) * t * t * t * t + 1) + b;\n  }\n\n  /**\n   * Quintic easing in and out\n   * @memberOf fabric.util.ease\n   */\n  function easeInOutQuint(t, b, c, d) {\n    t /= d / 2;\n    if (t < 1) {\n      return c / 2 * t * t * t * t * t + b;\n    }\n    return c / 2 * ((t -= 2) * t * t * t * t + 2) + b;\n  }\n\n  /**\n   * Sinusoidal easing in\n   * @memberOf fabric.util.ease\n   */\n  function easeInSine(t, b, c, d) {\n    return -c * Math.cos(t / d * (Math.PI / 2)) + c + b;\n  }\n\n  /**\n   * Sinusoidal easing out\n   * @memberOf fabric.util.ease\n   */\n  function easeOutSine(t, b, c, d) {\n    return c * Math.sin(t / d * (Math.PI / 2)) + b;\n  }\n\n  /**\n   * Sinusoidal easing in and out\n   * @memberOf fabric.util.ease\n   */\n  function easeInOutSine(t, b, c, d) {\n    return -c / 2 * (Math.cos(Math.PI * t / d) - 1) + b;\n  }\n\n  /**\n   * Exponential easing in\n   * @memberOf fabric.util.ease\n   */\n  function easeInExpo(t, b, c, d) {\n    return (t === 0) ? b : c * Math.pow(2, 10 * (t / d - 1)) + b;\n  }\n\n  /**\n   * Exponential easing out\n   * @memberOf fabric.util.ease\n   */\n  function easeOutExpo(t, b, c, d) {\n    return (t === d) ? b + c : c * (-Math.pow(2, -10 * t / d) + 1) + b;\n  }\n\n  /**\n   * Exponential easing in and out\n   * @memberOf fabric.util.ease\n   */\n  function easeInOutExpo(t, b, c, d) {\n    if (t === 0) {\n      return b;\n    }\n    if (t === d) {\n      return b + c;\n    }\n    t /= d / 2;\n    if (t < 1) {\n      return c / 2 * Math.pow(2, 10 * (t - 1)) + b;\n    }\n    return c / 2 * (-Math.pow(2, -10 * --t) + 2) + b;\n  }\n\n  /**\n   * Circular easing in\n   * @memberOf fabric.util.ease\n   */\n  function easeInCirc(t, b, c, d) {\n    return -c * (Math.sqrt(1 - (t /= d) * t) - 1) + b;\n  }\n\n  /**\n   * Circular easing out\n   * @memberOf fabric.util.ease\n   */\n  function easeOutCirc(t, b, c, d) {\n    return c * Math.sqrt(1 - (t = t / d - 1) * t) + b;\n  }\n\n  /**\n   * Circular easing in and out\n   * @memberOf fabric.util.ease\n   */\n  function easeInOutCirc(t, b, c, d) {\n    t /= d / 2;\n    if (t < 1) {\n      return -c / 2 * (Math.sqrt(1 - t * t) - 1) + b;\n    }\n    return c / 2 * (Math.sqrt(1 - (t -= 2) * t) + 1) + b;\n  }\n\n  /**\n   * Elastic easing in\n   * @memberOf fabric.util.ease\n   */\n  function easeInElastic(t, b, c, d) {\n    var s = 1.70158, p = 0, a = c;\n    if (t === 0) {\n      return b;\n    }\n    t /= d;\n    if (t === 1) {\n      return b + c;\n    }\n    if (!p) {\n      p = d * 0.3;\n    }\n    var opts = normalize(a, c, p, s);\n    return -elastic(opts, t, d) + b;\n  }\n\n  /**\n   * Elastic easing out\n   * @memberOf fabric.util.ease\n   */\n  function easeOutElastic(t, b, c, d) {\n    var s = 1.70158, p = 0, a = c;\n    if (t === 0) {\n      return b;\n    }\n    t /= d;\n    if (t === 1) {\n      return b + c;\n    }\n    if (!p) {\n      p = d * 0.3;\n    }\n    var opts = normalize(a, c, p, s);\n    return opts.a * Math.pow(2, -10 * t) * Math.sin((t * d - opts.s) * (2 * Math.PI) / opts.p ) + opts.c + b;\n  }\n\n  /**\n   * Elastic easing in and out\n   * @memberOf fabric.util.ease\n   */\n  function easeInOutElastic(t, b, c, d) {\n    var s = 1.70158, p = 0, a = c;\n    if (t === 0) {\n      return b;\n    }\n    t /= d / 2;\n    if (t === 2) {\n      return b + c;\n    }\n    if (!p) {\n      p = d * (0.3 * 1.5);\n    }\n    var opts = normalize(a, c, p, s);\n    if (t < 1) {\n      return -0.5 * elastic(opts, t, d) + b;\n    }\n    return opts.a * Math.pow(2, -10 * (t -= 1)) *\n      Math.sin((t * d - opts.s) * (2 * Math.PI) / opts.p ) * 0.5 + opts.c + b;\n  }\n\n  /**\n   * Backwards easing in\n   * @memberOf fabric.util.ease\n   */\n  function easeInBack(t, b, c, d, s) {\n    if (s === undefined) {\n      s = 1.70158;\n    }\n    return c * (t /= d) * t * ((s + 1) * t - s) + b;\n  }\n\n  /**\n   * Backwards easing out\n   * @memberOf fabric.util.ease\n   */\n  function easeOutBack(t, b, c, d, s) {\n    if (s === undefined) {\n      s = 1.70158;\n    }\n    return c * ((t = t / d - 1) * t * ((s + 1) * t + s) + 1) + b;\n  }\n\n  /**\n   * Backwards easing in and out\n   * @memberOf fabric.util.ease\n   */\n  function easeInOutBack(t, b, c, d, s) {\n    if (s === undefined) {\n      s = 1.70158;\n    }\n    t /= d / 2;\n    if (t < 1) {\n      return c / 2 * (t * t * (((s *= (1.525)) + 1) * t - s)) + b;\n    }\n    return c / 2 * ((t -= 2) * t * (((s *= (1.525)) + 1) * t + s) + 2) + b;\n  }\n\n  /**\n   * Bouncing easing in\n   * @memberOf fabric.util.ease\n   */\n  function easeInBounce(t, b, c, d) {\n    return c - easeOutBounce (d - t, 0, c, d) + b;\n  }\n\n  /**\n   * Bouncing easing out\n   * @memberOf fabric.util.ease\n   */\n  function easeOutBounce(t, b, c, d) {\n    if ((t /= d) < (1 / 2.75)) {\n      return c * (7.5625 * t * t) + b;\n    }\n    else if (t < (2 / 2.75)) {\n      return c * (7.5625 * (t -= (1.5 / 2.75)) * t + 0.75) + b;\n    }\n    else if (t < (2.5 / 2.75)) {\n      return c * (7.5625 * (t -= (2.25 / 2.75)) * t + 0.9375) + b;\n    }\n    else {\n      return c * (7.5625 * (t -= (2.625 / 2.75)) * t + 0.984375) + b;\n    }\n  }\n\n  /**\n   * Bouncing easing in and out\n   * @memberOf fabric.util.ease\n   */\n  function easeInOutBounce(t, b, c, d) {\n    if (t < d / 2) {\n      return easeInBounce (t * 2, 0, c, d) * 0.5 + b;\n    }\n    return easeOutBounce(t * 2 - d, 0, c, d) * 0.5 + c * 0.5 + b;\n  }\n\n  /**\n   * Easing functions\n   * See <a href=\"http://gizma.com/easing/\">Easing Equations by Robert Penner</a>\n   * @namespace fabric.util.ease\n   */\n  fabric.util.ease = {\n\n    /**\n     * Quadratic easing in\n     * @memberOf fabric.util.ease\n     */\n    easeInQuad: function(t, b, c, d) {\n      return c * (t /= d) * t + b;\n    },\n\n    /**\n     * Quadratic easing out\n     * @memberOf fabric.util.ease\n     */\n    easeOutQuad: function(t, b, c, d) {\n      return -c * (t /= d) * (t - 2) + b;\n    },\n\n    /**\n     * Quadratic easing in and out\n     * @memberOf fabric.util.ease\n     */\n    easeInOutQuad: function(t, b, c, d) {\n      t /= (d / 2);\n      if (t < 1) {\n        return c / 2 * t * t + b;\n      }\n      return -c / 2 * ((--t) * (t - 2) - 1) + b;\n    },\n\n    /**\n     * Cubic easing in\n     * @memberOf fabric.util.ease\n     */\n    easeInCubic: function(t, b, c, d) {\n      return c * (t /= d) * t * t + b;\n    },\n\n    easeOutCubic: easeOutCubic,\n    easeInOutCubic: easeInOutCubic,\n    easeInQuart: easeInQuart,\n    easeOutQuart: easeOutQuart,\n    easeInOutQuart: easeInOutQuart,\n    easeInQuint: easeInQuint,\n    easeOutQuint: easeOutQuint,\n    easeInOutQuint: easeInOutQuint,\n    easeInSine: easeInSine,\n    easeOutSine: easeOutSine,\n    easeInOutSine: easeInOutSine,\n    easeInExpo: easeInExpo,\n    easeOutExpo: easeOutExpo,\n    easeInOutExpo: easeInOutExpo,\n    easeInCirc: easeInCirc,\n    easeOutCirc: easeOutCirc,\n    easeInOutCirc: easeInOutCirc,\n    easeInElastic: easeInElastic,\n    easeOutElastic: easeOutElastic,\n    easeInOutElastic: easeInOutElastic,\n    easeInBack: easeInBack,\n    easeOutBack: easeOutBack,\n    easeInOutBack: easeInOutBack,\n    easeInBounce: easeInBounce,\n    easeOutBounce: easeOutBounce,\n    easeInOutBounce: easeInOutBounce\n  };\n\n})();\n\n\n(function(global) {\n\n  'use strict';\n\n  /**\n   * @name fabric\n   * @namespace\n   */\n\n  var fabric = global.fabric || (global.fabric = { }),\n      extend = fabric.util.object.extend,\n      clone = fabric.util.object.clone,\n      toFixed = fabric.util.toFixed,\n      parseUnit = fabric.util.parseUnit,\n      multiplyTransformMatrices = fabric.util.multiplyTransformMatrices,\n\n      svgValidTagNames = ['path', 'circle', 'polygon', 'polyline', 'ellipse', 'rect', 'line',\n        'image', 'text'],\n      svgViewBoxElements = ['symbol', 'image', 'marker', 'pattern', 'view', 'svg'],\n      svgInvalidAncestors = ['pattern', 'defs', 'symbol', 'metadata', 'clipPath', 'mask', 'desc'],\n      svgValidParents = ['symbol', 'g', 'a', 'svg', 'clipPath', 'defs'],\n\n      attributesMap = {\n        cx:                   'left',\n        x:                    'left',\n        r:                    'radius',\n        cy:                   'top',\n        y:                    'top',\n        display:              'visible',\n        visibility:           'visible',\n        transform:            'transformMatrix',\n        'fill-opacity':       'fillOpacity',\n        'fill-rule':          'fillRule',\n        'font-family':        'fontFamily',\n        'font-size':          'fontSize',\n        'font-style':         'fontStyle',\n        'font-weight':        'fontWeight',\n        'letter-spacing':     'charSpacing',\n        'paint-order':        'paintFirst',\n        'stroke-dasharray':   'strokeDashArray',\n        'stroke-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      },\n\n      colorAttributes = {\n        stroke: 'strokeOpacity',\n        fill:   'fillOpacity'\n      };\n\n  fabric.svgValidTagNamesRegEx = getSvgRegex(svgValidTagNames);\n  fabric.svgViewBoxElementsRegEx = getSvgRegex(svgViewBoxElements);\n  fabric.svgInvalidAncestorsRegEx = getSvgRegex(svgInvalidAncestors);\n  fabric.svgValidParentsRegEx = getSvgRegex(svgValidParents);\n\n  fabric.cssRules = { };\n  fabric.gradientDefs = { };\n  fabric.clipPaths = { };\n\n  function normalizeAttr(attr) {\n    // transform attribute names\n    if (attr in attributesMap) {\n      return attributesMap[attr];\n    }\n    return attr;\n  }\n\n  function normalizeValue(attr, value, parentAttributes, fontSize) {\n    var isArray = Object.prototype.toString.call(value) === '[object Array]',\n        parsed;\n\n    if ((attr === 'fill' || attr === 'stroke') && value === 'none') {\n      value = '';\n    }\n    else if (attr === 'strokeDashArray') {\n      if (value === 'none') {\n        value = null;\n      }\n      else {\n        value = value.replace(/,/g, ' ').split(/\\s+/).map(function(n) {\n          return parseFloat(n);\n        });\n      }\n    }\n    else if (attr === 'transformMatrix') {\n      if (parentAttributes && parentAttributes.transformMatrix) {\n        value = multiplyTransformMatrices(\n          parentAttributes.transformMatrix, fabric.parseTransformAttribute(value));\n      }\n      else {\n        value = fabric.parseTransformAttribute(value);\n      }\n    }\n    else if (attr === 'visible') {\n      value = value !== 'none' && value !== 'hidden';\n      // display=none on parent element always takes precedence over child element\n      if (parentAttributes && parentAttributes.visible === false) {\n        value = false;\n      }\n    }\n    else if (attr === 'opacity') {\n      value = parseFloat(value);\n      if (parentAttributes && typeof parentAttributes.opacity !== 'undefined') {\n        value *= parentAttributes.opacity;\n      }\n    }\n    else if (attr === 'textAnchor' /* text-anchor */) {\n      value = value === 'start' ? 'left' : value === 'end' ? 'right' : 'center';\n    }\n    else if (attr === 'charSpacing') {\n      // parseUnit returns px and we convert it to em\n      parsed = parseUnit(value, fontSize) / fontSize * 1000;\n    }\n    else if (attr === 'paintFirst') {\n      var fillIndex = value.indexOf('fill');\n      var strokeIndex = value.indexOf('stroke');\n      var value = 'fill';\n      if (fillIndex > -1 && strokeIndex > -1 && strokeIndex < fillIndex) {\n        value = 'stroke';\n      }\n      else if (fillIndex === -1 && strokeIndex > -1) {\n        value = 'stroke';\n      }\n    }\n    else {\n      parsed = isArray ? value.map(parseUnit) : parseUnit(value, fontSize);\n    }\n\n    return (!isArray && isNaN(parsed) ? value : parsed);\n  }\n\n  /**\n    * @private\n    */\n  function getSvgRegex(arr) {\n    return new RegExp('^(' + arr.join('|') + ')\\\\b', 'i');\n  }\n\n  /**\n   * @private\n   * @param {Object} attributes Array of attributes to parse\n   */\n  function _setStrokeFillOpacity(attributes) {\n    for (var attr in colorAttributes) {\n\n      if (typeof attributes[colorAttributes[attr]] === 'undefined' || attributes[attr] === '') {\n        continue;\n      }\n\n      if (typeof attributes[attr] === 'undefined') {\n        if (!fabric.Object.prototype[attr]) {\n          continue;\n        }\n        attributes[attr] = fabric.Object.prototype[attr];\n      }\n\n      if (attributes[attr].indexOf('url(') === 0) {\n        continue;\n      }\n\n      var color = new fabric.Color(attributes[attr]);\n      attributes[attr] = color.setAlpha(toFixed(color.getAlpha() * attributes[colorAttributes[attr]], 2)).toRgba();\n    }\n    return attributes;\n  }\n\n  /**\n   * @private\n   */\n  function _getMultipleNodes(doc, nodeNames) {\n    var nodeName, nodeArray = [], nodeList, i, len;\n    for (i = 0, len = nodeNames.length; i < len; i++) {\n      nodeName = nodeNames[i];\n      nodeList = doc.getElementsByTagName(nodeName);\n      nodeArray = nodeArray.concat(Array.prototype.slice.call(nodeList));\n    }\n    return nodeArray;\n  }\n\n  /**\n   * Parses \"transform\" attribute, returning an array of values\n   * @static\n   * @function\n   * @memberOf fabric\n   * @param {String} attributeValue String containing attribute value\n   * @return {Array} Array of 6 elements representing transformation matrix\n   */\n  fabric.parseTransformAttribute = (function() {\n    function rotateMatrix(matrix, args) {\n      var cos = fabric.util.cos(args[0]), sin = fabric.util.sin(args[0]),\n          x = 0, y = 0;\n      if (args.length === 3) {\n        x = args[1];\n        y = args[2];\n      }\n\n      matrix[0] = cos;\n      matrix[1] = sin;\n      matrix[2] = -sin;\n      matrix[3] = cos;\n      matrix[4] = x - (cos * x - sin * y);\n      matrix[5] = y - (sin * x + cos * y);\n    }\n\n    function scaleMatrix(matrix, args) {\n      var multiplierX = args[0],\n          multiplierY = (args.length === 2) ? args[1] : args[0];\n\n      matrix[0] = multiplierX;\n      matrix[3] = multiplierY;\n    }\n\n    function skewMatrix(matrix, args, pos) {\n      matrix[pos] = Math.tan(fabric.util.degreesToRadians(args[0]));\n    }\n\n    function translateMatrix(matrix, args) {\n      matrix[4] = args[0];\n      if (args.length === 2) {\n        matrix[5] = args[1];\n      }\n    }\n\n    // identity matrix\n    var iMatrix = [\n          1, // a\n          0, // b\n          0, // c\n          1, // d\n          0, // e\n          0  // f\n        ],\n\n        // == begin transform regexp\n        number = fabric.reNum,\n\n        commaWsp = '(?:\\\\s+,?\\\\s*|,\\\\s*)',\n\n        skewX = '(?:(skewX)\\\\s*\\\\(\\\\s*(' + number + ')\\\\s*\\\\))',\n\n        skewY = '(?:(skewY)\\\\s*\\\\(\\\\s*(' + number + ')\\\\s*\\\\))',\n\n        rotate = '(?:(rotate)\\\\s*\\\\(\\\\s*(' + number + ')(?:' +\n                    commaWsp + '(' + number + ')' +\n                    commaWsp + '(' + number + '))?\\\\s*\\\\))',\n\n        scale = '(?:(scale)\\\\s*\\\\(\\\\s*(' + number + ')(?:' +\n                    commaWsp + '(' + number + '))?\\\\s*\\\\))',\n\n        translate = '(?:(translate)\\\\s*\\\\(\\\\s*(' + number + ')(?:' +\n                    commaWsp + '(' + number + '))?\\\\s*\\\\))',\n\n        matrix = '(?:(matrix)\\\\s*\\\\(\\\\s*' +\n                  '(' + number + ')' + commaWsp +\n                  '(' + number + ')' + commaWsp +\n                  '(' + number + ')' + commaWsp +\n                  '(' + number + ')' + commaWsp +\n                  '(' + number + ')' + commaWsp +\n                  '(' + number + ')' +\n                  '\\\\s*\\\\))',\n\n        transform = '(?:' +\n                    matrix + '|' +\n                    translate + '|' +\n                    scale + '|' +\n                    rotate + '|' +\n                    skewX + '|' +\n                    skewY +\n                    ')',\n\n        transforms = '(?:' + transform + '(?:' + commaWsp + '*' + transform + ')*' + ')',\n\n        transformList = '^\\\\s*(?:' + transforms + '?)\\\\s*$',\n\n        // http://www.w3.org/TR/SVG/coords.html#TransformAttribute\n        reTransformList = new RegExp(transformList),\n        // == end transform regexp\n\n        reTransform = new RegExp(transform, 'g');\n\n    return function(attributeValue) {\n\n      // start with identity matrix\n      var matrix = iMatrix.concat(),\n          matrices = [];\n\n      // return if no argument was given or\n      // an argument does not match transform attribute regexp\n      if (!attributeValue || (attributeValue && !reTransformList.test(attributeValue))) {\n        return matrix;\n      }\n\n      attributeValue.replace(reTransform, function(match) {\n\n        var m = new RegExp(transform).exec(match).filter(function (match) {\n              // match !== '' && match != null\n              return (!!match);\n            }),\n            operation = m[1],\n            args = m.slice(2).map(parseFloat);\n\n        switch (operation) {\n          case 'translate':\n            translateMatrix(matrix, args);\n            break;\n          case 'rotate':\n            args[0] = fabric.util.degreesToRadians(args[0]);\n            rotateMatrix(matrix, args);\n            break;\n          case 'scale':\n            scaleMatrix(matrix, args);\n            break;\n          case 'skewX':\n            skewMatrix(matrix, args, 2);\n            break;\n          case 'skewY':\n            skewMatrix(matrix, args, 1);\n            break;\n          case 'matrix':\n            matrix = args;\n            break;\n        }\n\n        // snapshot current matrix into matrices array\n        matrices.push(matrix.concat());\n        // reset\n        matrix = iMatrix.concat();\n      });\n\n      var combinedMatrix = matrices[0];\n      while (matrices.length > 1) {\n        matrices.shift();\n        combinedMatrix = fabric.util.multiplyTransformMatrices(combinedMatrix, matrices[0]);\n      }\n      return combinedMatrix;\n    };\n  })();\n\n  /**\n   * @private\n   */\n  function parseStyleString(style, oStyle) {\n    var attr, value;\n    style.replace(/;\\s*$/, '').split(';').forEach(function (chunk) {\n      var pair = chunk.split(':');\n\n      attr = pair[0].trim().toLowerCase();\n      value =  pair[1].trim();\n\n      oStyle[attr] = value;\n    });\n  }\n\n  /**\n   * @private\n   */\n  function parseStyleObject(style, oStyle) {\n    var attr, value;\n    for (var prop in style) {\n      if (typeof style[prop] === 'undefined') {\n        continue;\n      }\n\n      attr = prop.toLowerCase();\n      value = style[prop];\n\n      oStyle[attr] = value;\n    }\n  }\n\n  /**\n   * @private\n   */\n  function getGlobalStylesForElement(element, svgUid) {\n    var styles = { };\n    for (var rule in fabric.cssRules[svgUid]) {\n      if (elementMatchesRule(element, rule.split(' '))) {\n        for (var property in fabric.cssRules[svgUid][rule]) {\n          styles[property] = fabric.cssRules[svgUid][rule][property];\n        }\n      }\n    }\n    return styles;\n  }\n\n  /**\n   * @private\n   */\n  function elementMatchesRule(element, selectors) {\n    var firstMatching, parentMatching = true;\n    //start from rightmost selector.\n    firstMatching = selectorMatches(element, selectors.pop());\n    if (firstMatching && selectors.length) {\n      parentMatching = doesSomeParentMatch(element, selectors);\n    }\n    return firstMatching && parentMatching && (selectors.length === 0);\n  }\n\n  function doesSomeParentMatch(element, selectors) {\n    var selector, parentMatching = true;\n    while (element.parentNode && element.parentNode.nodeType === 1 && selectors.length) {\n      if (parentMatching) {\n        selector = selectors.pop();\n      }\n      element = element.parentNode;\n      parentMatching = selectorMatches(element, selector);\n    }\n    return selectors.length === 0;\n  }\n\n  /**\n   * @private\n   */\n  function selectorMatches(element, selector) {\n    var nodeName = element.nodeName,\n        classNames = element.getAttribute('class'),\n        id = element.getAttribute('id'), matcher, i;\n    // i check if a selector matches slicing away part from it.\n    // if i get empty string i should match\n    matcher = new RegExp('^' + nodeName, 'i');\n    selector = selector.replace(matcher, '');\n    if (id && selector.length) {\n      matcher = new RegExp('#' + id + '(?![a-zA-Z\\\\-]+)', 'i');\n      selector = selector.replace(matcher, '');\n    }\n    if (classNames && selector.length) {\n      classNames = classNames.split(' ');\n      for (i = classNames.length; i--;) {\n        matcher = new RegExp('\\\\.' + classNames[i] + '(?![a-zA-Z\\\\-]+)', 'i');\n        selector = selector.replace(matcher, '');\n      }\n    }\n    return selector.length === 0;\n  }\n\n  /**\n   * @private\n   * to support IE8 missing getElementById on SVGdocument\n   */\n  function elementById(doc, id) {\n    var el;\n    doc.getElementById && (el = doc.getElementById(id));\n    if (el) {\n      return el;\n    }\n    var node, i, len, nodelist = doc.getElementsByTagName('*');\n    for (i = 0, len = nodelist.length; i < len; i++) {\n      node = nodelist[i];\n      if (id === node.getAttribute('id')) {\n        return node;\n      }\n    }\n  }\n\n  /**\n   * @private\n   */\n  function parseUseDirectives(doc) {\n    var nodelist = _getMultipleNodes(doc, ['use', 'svg:use']), i = 0;\n    while (nodelist.length && i < nodelist.length) {\n      var el = nodelist[i],\n          xlink = (el.getAttribute('xlink:href') || el.getAttribute('href')).substr(1),\n          x = el.getAttribute('x') || 0,\n          y = el.getAttribute('y') || 0,\n          el2 = elementById(doc, xlink).cloneNode(true),\n          currentTrans = (el2.getAttribute('transform') || '') + ' translate(' + x + ', ' + y + ')',\n          parentNode, oldLength = nodelist.length, attr, j, attrs, len;\n\n      applyViewboxTransform(el2);\n      if (/^svg$/i.test(el2.nodeName)) {\n        var el3 = el2.ownerDocument.createElement('g');\n        for (j = 0, attrs = el2.attributes, len = attrs.length; j < len; j++) {\n          attr = attrs.item(j);\n          el3.setAttribute(attr.nodeName, attr.nodeValue);\n        }\n        // el2.firstChild != null\n        while (el2.firstChild) {\n          el3.appendChild(el2.firstChild);\n        }\n        el2 = el3;\n      }\n\n      for (j = 0, attrs = el.attributes, len = attrs.length; j < len; j++) {\n        attr = attrs.item(j);\n        if (attr.nodeName === 'x' || attr.nodeName === 'y' ||\n          attr.nodeName === 'xlink:href' || attr.nodeName === 'href') {\n          continue;\n        }\n\n        if (attr.nodeName === 'transform') {\n          currentTrans = attr.nodeValue + ' ' + currentTrans;\n        }\n        else {\n          el2.setAttribute(attr.nodeName, attr.nodeValue);\n        }\n      }\n\n      el2.setAttribute('transform', currentTrans);\n      el2.setAttribute('instantiated_by_use', '1');\n      el2.removeAttribute('id');\n      parentNode = el.parentNode;\n      parentNode.replaceChild(el2, el);\n      // some browsers do not shorten nodelist after replaceChild (IE8)\n      if (nodelist.length === oldLength) {\n        i++;\n      }\n    }\n  }\n\n  // http://www.w3.org/TR/SVG/coords.html#ViewBoxAttribute\n  // matches, e.g.: +14.56e-12, etc.\n  var reViewBoxAttrValue = new RegExp(\n    '^' +\n    '\\\\s*(' + fabric.reNum + '+)\\\\s*,?' +\n    '\\\\s*(' + fabric.reNum + '+)\\\\s*,?' +\n    '\\\\s*(' + fabric.reNum + '+)\\\\s*,?' +\n    '\\\\s*(' + fabric.reNum + '+)\\\\s*' +\n    '$'\n  );\n\n  /**\n   * Add a <g> element that envelop all child elements and makes the viewbox transformMatrix descend on all elements\n   */\n  function applyViewboxTransform(element) {\n\n    var viewBoxAttr = element.getAttribute('viewBox'),\n        scaleX = 1,\n        scaleY = 1,\n        minX = 0,\n        minY = 0,\n        viewBoxWidth, viewBoxHeight, matrix, el,\n        widthAttr = element.getAttribute('width'),\n        heightAttr = element.getAttribute('height'),\n        x = element.getAttribute('x') || 0,\n        y = element.getAttribute('y') || 0,\n        preserveAspectRatio = element.getAttribute('preserveAspectRatio') || '',\n        missingViewBox = (!viewBoxAttr || !fabric.svgViewBoxElementsRegEx.test(element.nodeName)\n                           || !(viewBoxAttr = viewBoxAttr.match(reViewBoxAttrValue))),\n        missingDimAttr = (!widthAttr || !heightAttr || widthAttr === '100%' || heightAttr === '100%'),\n        toBeParsed = missingViewBox && missingDimAttr,\n        parsedDim = { }, translateMatrix = '', widthDiff = 0, heightDiff = 0;\n\n    parsedDim.width = 0;\n    parsedDim.height = 0;\n    parsedDim.toBeParsed = toBeParsed;\n\n    if (toBeParsed) {\n      return parsedDim;\n    }\n\n    if (missingViewBox) {\n      parsedDim.width = parseUnit(widthAttr);\n      parsedDim.height = parseUnit(heightAttr);\n      return parsedDim;\n    }\n\n    minX = -parseFloat(viewBoxAttr[1]);\n    minY = -parseFloat(viewBoxAttr[2]);\n    viewBoxWidth = parseFloat(viewBoxAttr[3]);\n    viewBoxHeight = parseFloat(viewBoxAttr[4]);\n\n    if (!missingDimAttr) {\n      parsedDim.width = parseUnit(widthAttr);\n      parsedDim.height = parseUnit(heightAttr);\n      scaleX = parsedDim.width / viewBoxWidth;\n      scaleY = parsedDim.height / viewBoxHeight;\n    }\n    else {\n      parsedDim.width = viewBoxWidth;\n      parsedDim.height = viewBoxHeight;\n    }\n\n    // default is to preserve aspect ratio\n    preserveAspectRatio = fabric.util.parsePreserveAspectRatioAttribute(preserveAspectRatio);\n    if (preserveAspectRatio.alignX !== 'none') {\n      //translate all container for the effect of Mid, Min, Max\n      if (preserveAspectRatio.meetOrSlice === 'meet') {\n        scaleY = scaleX = (scaleX > scaleY ? scaleY : scaleX);\n        // calculate additional translation to move the viewbox\n      }\n      if (preserveAspectRatio.meetOrSlice === 'slice') {\n        scaleY = scaleX = (scaleX > scaleY ? scaleX : scaleY);\n        // calculate additional translation to move the viewbox\n      }\n      widthDiff = parsedDim.width - viewBoxWidth * scaleX;\n      heightDiff = parsedDim.height - viewBoxHeight * scaleX;\n      if (preserveAspectRatio.alignX === 'Mid') {\n        widthDiff /= 2;\n      }\n      if (preserveAspectRatio.alignY === 'Mid') {\n        heightDiff /= 2;\n      }\n      if (preserveAspectRatio.alignX === 'Min') {\n        widthDiff = 0;\n      }\n      if (preserveAspectRatio.alignY === 'Min') {\n        heightDiff = 0;\n      }\n    }\n\n    if (scaleX === 1 && scaleY === 1 && minX === 0 && minY === 0 && x === 0 && y === 0) {\n      return parsedDim;\n    }\n\n    if (x || y) {\n      translateMatrix = ' translate(' + parseUnit(x) + ' ' + parseUnit(y) + ') ';\n    }\n\n    matrix = translateMatrix + ' matrix(' + scaleX +\n                  ' 0' +\n                  ' 0 ' +\n                  scaleY + ' ' +\n                  (minX * scaleX + widthDiff) + ' ' +\n                  (minY * scaleY + heightDiff) + ') ';\n    parsedDim.viewboxTransform = fabric.parseTransformAttribute(matrix);\n    if (element.nodeName === 'svg') {\n      el = element.ownerDocument.createElement('g');\n      // element.firstChild != null\n      while (element.firstChild) {\n        el.appendChild(element.firstChild);\n      }\n      element.appendChild(el);\n    }\n    else {\n      el = element;\n      matrix = el.getAttribute('transform') + matrix;\n    }\n    el.setAttribute('transform', matrix);\n    return parsedDim;\n  }\n\n  function hasAncestorWithNodeName(element, nodeName) {\n    while (element && (element = element.parentNode)) {\n      if (element.nodeName && nodeName.test(element.nodeName.replace('svg:', ''))\n        && !element.getAttribute('instantiated_by_use')) {\n        return true;\n      }\n    }\n    return false;\n  }\n\n  /**\n   * Parses an SVG document, converts it to an array of corresponding fabric.* instances and passes them to a callback\n   * @static\n   * @function\n   * @memberOf fabric\n   * @param {SVGDocument} doc SVG document to parse\n   * @param {Function} callback Callback to call when parsing is finished;\n   * It's being passed an array of elements (parsed from a document).\n   * @param {Function} [reviver] Method for further parsing of SVG elements, called after each fabric object created.\n   * @param {Object} [parsingOptions] options for parsing document\n   * @param {String} [parsingOptions.crossOrigin] crossOrigin settings\n   */\n  fabric.parseSVGDocument = function(doc, callback, reviver, parsingOptions) {\n    if (!doc) {\n      return;\n    }\n\n    parseUseDirectives(doc);\n\n    var svgUid =  fabric.Object.__uid++, i, len,\n        options = applyViewboxTransform(doc),\n        descendants = fabric.util.toArray(doc.getElementsByTagName('*'));\n    options.crossOrigin = parsingOptions && parsingOptions.crossOrigin;\n    options.svgUid = svgUid;\n\n    if (descendants.length === 0 && fabric.isLikelyNode) {\n      // we're likely in node, where \"o3-xml\" library fails to gEBTN(\"*\")\n      // https://github.com/ajaxorg/node-o3-xml/issues/21\n      descendants = doc.selectNodes('//*[name(.)!=\"svg\"]');\n      var arr = [];\n      for (i = 0, len = descendants.length; i < len; i++) {\n        arr[i] = descendants[i];\n      }\n      descendants = arr;\n    }\n\n    var elements = descendants.filter(function(el) {\n      applyViewboxTransform(el);\n      return fabric.svgValidTagNamesRegEx.test(el.nodeName.replace('svg:', '')) &&\n            !hasAncestorWithNodeName(el, fabric.svgInvalidAncestorsRegEx); // http://www.w3.org/TR/SVG/struct.html#DefsElement\n    });\n\n    if (!elements || (elements && !elements.length)) {\n      callback && callback([], {});\n      return;\n    }\n    var clipPaths = { };\n    descendants.filter(function(el) {\n      return el.nodeName.replace('svg:', '') === 'clipPath';\n    }).forEach(function(el) {\n      var id = el.getAttribute('id');\n      clipPaths[id] = fabric.util.toArray(el.getElementsByTagName('*')).filter(function(el) {\n        return fabric.svgValidTagNamesRegEx.test(el.nodeName.replace('svg:', ''));\n      });\n    });\n    fabric.gradientDefs[svgUid] = fabric.getGradientDefs(doc);\n    fabric.cssRules[svgUid] = fabric.getCSSRules(doc);\n    fabric.clipPaths[svgUid] = clipPaths;\n    // Precedence of rules:   style > class > attribute\n    fabric.parseElements(elements, function(instances, elements) {\n      if (callback) {\n        callback(instances, options, elements, descendants);\n        delete fabric.gradientDefs[svgUid];\n        delete fabric.cssRules[svgUid];\n        delete fabric.clipPaths[svgUid];\n      }\n    }, clone(options), reviver, parsingOptions);\n  };\n\n  var reFontDeclaration = new RegExp(\n    '(normal|italic)?\\\\s*(normal|small-caps)?\\\\s*' +\n    '(normal|bold|bolder|lighter|100|200|300|400|500|600|700|800|900)?\\\\s*(' +\n      fabric.reNum +\n    '(?:px|cm|mm|em|pt|pc|in)*)(?:\\\\/(normal|' + fabric.reNum + '))?\\\\s+(.*)');\n\n  extend(fabric, {\n    /**\n     * Parses a short font declaration, building adding its properties to a style object\n     * @static\n     * @function\n     * @memberOf fabric\n     * @param {String} value font declaration\n     * @param {Object} oStyle definition\n     */\n    parseFontDeclaration: function(value, oStyle) {\n      var match = value.match(reFontDeclaration);\n\n      if (!match) {\n        return;\n      }\n      var fontStyle = match[1],\n          // font variant is not used\n          // fontVariant = match[2],\n          fontWeight = match[3],\n          fontSize = match[4],\n          lineHeight = match[5],\n          fontFamily = match[6];\n\n      if (fontStyle) {\n        oStyle.fontStyle = fontStyle;\n      }\n      if (fontWeight) {\n        oStyle.fontWeight = isNaN(parseFloat(fontWeight)) ? fontWeight : parseFloat(fontWeight);\n      }\n      if (fontSize) {\n        oStyle.fontSize = parseUnit(fontSize);\n      }\n      if (fontFamily) {\n        oStyle.fontFamily = fontFamily;\n      }\n      if (lineHeight) {\n        oStyle.lineHeight = lineHeight === 'normal' ? 1 : lineHeight;\n      }\n    },\n\n    /**\n     * Parses an SVG document, returning all of the gradient declarations found in it\n     * @static\n     * @function\n     * @memberOf fabric\n     * @param {SVGDocument} doc SVG document to parse\n     * @return {Object} Gradient definitions; key corresponds to element id, value -- to gradient definition element\n     */\n    getGradientDefs: function(doc) {\n      var tagArray = [\n            'linearGradient',\n            'radialGradient',\n            'svg:linearGradient',\n            'svg:radialGradient'],\n          elList = _getMultipleNodes(doc, tagArray),\n          el, j = 0, id, xlink,\n          gradientDefs = { }, idsToXlinkMap = { };\n      j = elList.length;\n\n      while (j--) {\n        el = elList[j];\n        xlink = el.getAttribute('xlink:href');\n        id = el.getAttribute('id');\n        if (xlink) {\n          idsToXlinkMap[id] = xlink.substr(1);\n        }\n        gradientDefs[id] = el;\n      }\n\n      for (id in idsToXlinkMap) {\n        var el2 = gradientDefs[idsToXlinkMap[id]].cloneNode(true);\n        el = gradientDefs[id];\n        while (el2.firstChild) {\n          el.appendChild(el2.firstChild);\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(element, attributes, svgUid) {\n\n      if (!element) {\n        return;\n      }\n\n      var value,\n          parentAttributes = { },\n          fontSize;\n\n      if (typeof svgUid === 'undefined') {\n        svgUid = element.getAttribute('svgUid');\n      }\n      // if there's a parent container (`g` or `a` or `symbol` node), parse its attributes recursively upwards\n      if (element.parentNode && fabric.svgValidParentsRegEx.test(element.parentNode.nodeName)) {\n        parentAttributes = fabric.parseAttributes(element.parentNode, attributes, svgUid);\n      }\n\n      var ownAttributes = attributes.reduce(function(memo, attr) {\n        value = element.getAttribute(attr);\n        if (value) { // eslint-disable-line\n          memo[attr] = value;\n        }\n        return memo;\n      }, { });\n      // add values parsed from style, which take precedence over attributes\n      // (see: http://www.w3.org/TR/SVG/styling.html#UsingPresentationAttributes)\n      ownAttributes = extend(ownAttributes,\n        extend(getGlobalStylesForElement(element, svgUid), fabric.parseStyleAttribute(element)));\n\n      fontSize = (parentAttributes && parentAttributes.fontSize ) ||\n                   ownAttributes['font-size'] || fabric.Text.DEFAULT_SVG_FONT_SIZE;\n\n      var normalizedAttr, normalizedValue, normalizedStyle = {};\n      for (var attr in ownAttributes) {\n        normalizedAttr = normalizeAttr(attr);\n        normalizedValue = normalizeValue(normalizedAttr, ownAttributes[attr], parentAttributes, fontSize);\n        normalizedStyle[normalizedAttr] = normalizedValue;\n      }\n      if (normalizedStyle && normalizedStyle.font) {\n        fabric.parseFontDeclaration(normalizedStyle.font, normalizedStyle);\n      }\n      var mergedAttrs = extend(parentAttributes, normalizedStyle);\n      return fabric.svgValidParentsRegEx.test(element.nodeName) ? mergedAttrs : _setStrokeFillOpacity(mergedAttrs);\n    },\n\n    /**\n     * Transforms an array of svg elements to corresponding fabric.* instances\n     * @static\n     * @memberOf fabric\n     * @param {Array} elements Array of elements to parse\n     * @param {Function} callback Being passed an array of fabric instances (transformed from SVG elements)\n     * @param {Object} [options] Options object\n     * @param {Function} [reviver] Method for further parsing of SVG elements, called after each fabric object created.\n     */\n    parseElements: function(elements, callback, options, reviver, parsingOptions) {\n      new fabric.ElementsParser(elements, callback, options, reviver, parsingOptions).parse();\n    },\n\n    /**\n     * Parses \"style\" attribute, retuning an object with values\n     * @static\n     * @memberOf fabric\n     * @param {SVGElement} element Element to parse\n     * @return {Object} Objects with values parsed from style attribute of an element\n     */\n    parseStyleAttribute: function(element) {\n      var oStyle = { },\n          style = element.getAttribute('style');\n\n      if (!style) {\n        return oStyle;\n      }\n\n      if (typeof style === 'string') {\n        parseStyleString(style, oStyle);\n      }\n      else {\n        parseStyleObject(style, oStyle);\n      }\n\n      return oStyle;\n    },\n\n    /**\n     * Parses \"points\" attribute, returning an array of values\n     * @static\n     * @memberOf fabric\n     * @param {String} points points attribute string\n     * @return {Array} array of points\n     */\n    parsePointsAttribute: function(points) {\n\n      // points attribute is required and must not be empty\n      if (!points) {\n        return null;\n      }\n\n      // replace commas with whitespace and remove bookending whitespace\n      points = points.replace(/,/g, ' ').trim();\n\n      points = points.split(/\\s+/);\n      var parsedPoints = [], i, len;\n\n      for (i = 0, len = points.length; i < len; i += 2) {\n        parsedPoints.push({\n          x: parseFloat(points[i]),\n          y: parseFloat(points[i + 1])\n        });\n      }\n\n      // odd number of points is an error\n      // if (parsedPoints.length % 2 !== 0) {\n      //   return null;\n      // }\n\n      return parsedPoints;\n    },\n\n    /**\n     * Returns CSS rules for a given SVG document\n     * @static\n     * @function\n     * @memberOf fabric\n     * @param {SVGDocument} doc SVG document to parse\n     * @return {Object} CSS rules of this document\n     */\n    getCSSRules: function(doc) {\n      var styles = doc.getElementsByTagName('style'), i, len,\n          allRules = { }, rules;\n\n      // very crude parsing of style contents\n      for (i = 0, len = styles.length; i < len; i++) {\n        // IE9 doesn't support textContent, but provides text instead.\n        var styleContents = styles[i].textContent || styles[i].text;\n\n        // remove comments\n        styleContents = styleContents.replace(/\\/\\*[\\s\\S]*?\\*\\//g, '');\n        if (styleContents.trim() === '') {\n          continue;\n        }\n        rules = styleContents.match(/[^{]*\\{[\\s\\S]*?\\}/g);\n        rules = rules.map(function(rule) { return rule.trim(); });\n        // eslint-disable-next-line no-loop-func\n        rules.forEach(function(rule) {\n\n          var match = rule.match(/([\\s\\S]*?)\\s*\\{([^}]*)\\}/),\n              ruleObj = { }, declaration = match[2].trim(),\n              propertyValuePairs = declaration.replace(/;$/, '').split(/\\s*;\\s*/);\n\n          for (i = 0, len = propertyValuePairs.length; i < len; i++) {\n            var pair = propertyValuePairs[i].split(/\\s*:\\s*/),\n                property = pair[0],\n                value = pair[1];\n            ruleObj[property] = value;\n          }\n          rule = match[1];\n          rule.split(',').forEach(function(_rule) {\n            _rule = _rule.replace(/^svg/i, '').trim();\n            if (_rule === '') {\n              return;\n            }\n            if (allRules[_rule]) {\n              fabric.util.object.extend(allRules[_rule], ruleObj);\n            }\n            else {\n              allRules[_rule] = fabric.util.object.clone(ruleObj);\n            }\n          });\n        });\n      }\n      return allRules;\n    },\n\n    /**\n     * Takes url corresponding to an SVG document, and parses it into a set of fabric objects.\n     * Note that SVG is fetched via XMLHttpRequest, so it needs to conform to SOP (Same Origin Policy)\n     * @memberOf fabric\n     * @param {String} url\n     * @param {Function} callback\n     * @param {Function} [reviver] Method for further parsing of SVG elements, called after each fabric object created.\n     * @param {Object} [options] Object containing options for parsing\n     * @param {String} [options.crossOrigin] crossOrigin crossOrigin setting to use for external resources\n     */\n    loadSVGFromURL: function(url, callback, reviver, options) {\n\n      url = url.replace(/^\\n\\s*/, '').trim();\n      new fabric.util.request(url, {\n        method: 'get',\n        onComplete: onComplete\n      });\n\n      function onComplete(r) {\n\n        var xml = r.responseXML;\n        if (xml && !xml.documentElement && fabric.window.ActiveXObject && r.responseText) {\n          xml = new ActiveXObject('Microsoft.XMLDOM');\n          xml.async = 'false';\n          //IE chokes on DOCTYPE\n          xml.loadXML(r.responseText.replace(/<!DOCTYPE[\\s\\S]*?(\\[[\\s\\S]*\\])*?>/i, ''));\n        }\n        if (!xml || !xml.documentElement) {\n          callback && callback(null);\n          return false;\n        }\n\n        fabric.parseSVGDocument(xml.documentElement, function (results, _options, elements, allElements) {\n          callback && callback(results, _options, elements, allElements);\n        }, reviver, options);\n      }\n    },\n\n    /**\n     * Takes string corresponding to an SVG document, and parses it into a set of fabric objects\n     * @memberOf fabric\n     * @param {String} string\n     * @param {Function} callback\n     * @param {Function} [reviver] Method for further parsing of SVG elements, called after each fabric object created.\n     * @param {Object} [options] Object containing options for parsing\n     * @param {String} [options.crossOrigin] crossOrigin crossOrigin setting to use for external resources\n     */\n    loadSVGFromString: function(string, callback, reviver, options) {\n      string = string.trim();\n      var doc;\n      if (typeof DOMParser !== 'undefined') {\n        var parser = new DOMParser();\n        if (parser && parser.parseFromString) {\n          doc = parser.parseFromString(string, 'text/xml');\n        }\n      }\n      else if (fabric.window.ActiveXObject) {\n        doc = new ActiveXObject('Microsoft.XMLDOM');\n        doc.async = 'false';\n        // IE chokes on DOCTYPE\n        doc.loadXML(string.replace(/<!DOCTYPE[\\s\\S]*?(\\[[\\s\\S]*\\])*?>/i, ''));\n      }\n\n      fabric.parseSVGDocument(doc.documentElement, function (results, _options, elements, allElements) {\n        callback(results, _options, elements, allElements);\n      }, reviver, options);\n    }\n  });\n\n})(typeof exports !== 'undefined' ? exports : this);\n\n\nfabric.ElementsParser = function(elements, callback, options, reviver, parsingOptions) {\n  this.elements = elements;\n  this.callback = callback;\n  this.options = options;\n  this.reviver = reviver;\n  this.svgUid = (options && options.svgUid) || 0;\n  this.parsingOptions = parsingOptions;\n  this.regexUrl = /^url\\(['\"]?#([^'\"]+)['\"]?\\)/g;\n};\n\n(function(proto) {\n  proto.parse = function() {\n    this.instances = new Array(this.elements.length);\n    this.numElements = this.elements.length;\n    this.createObjects();\n  };\n\n  proto.createObjects = function() {\n    var _this = this;\n    this.elements.forEach(function(element, i) {\n      element.setAttribute('svgUid', _this.svgUid);\n      _this.createObject(element, i);\n    });\n  };\n\n  proto.findTag = function(el) {\n    return fabric[fabric.util.string.capitalize(el.tagName.replace('svg:', ''))];\n  };\n\n  proto.createObject = function(el, index) {\n    var klass = this.findTag(el);\n    if (klass && klass.fromElement) {\n      try {\n        klass.fromElement(el, this.createCallback(index, el), this.options);\n      }\n      catch (err) {\n        fabric.log(err);\n      }\n    }\n    else {\n      this.checkIfDone();\n    }\n  };\n\n  proto.createCallback = function(index, el) {\n    var _this = this;\n    return function(obj) {\n      var _options;\n      _this.resolveGradient(obj, 'fill');\n      _this.resolveGradient(obj, 'stroke');\n      if (obj instanceof fabric.Image) {\n        _options = obj.parsePreserveAspectRatioAttribute(el);\n      }\n      obj._removeTransformMatrix(_options);\n      _this.resolveClipPath(obj);\n      _this.reviver && _this.reviver(el, obj);\n      _this.instances[index] = obj;\n      _this.checkIfDone();\n    };\n  };\n\n  proto.extractPropertyDefinition = function(obj, property, storage) {\n    var value = obj[property];\n    if (!(/^url\\(/).test(value)) {\n      return;\n    }\n    var id = this.regexUrl.exec(value)[1];\n    this.regexUrl.lastIndex = 0;\n    return fabric[storage][this.svgUid][id];\n  };\n\n  proto.resolveGradient = function(obj, property) {\n    var gradientDef = this.extractPropertyDefinition(obj, property, 'gradientDefs');\n    if (gradientDef) {\n      obj.set(property, fabric.Gradient.fromElement(gradientDef, obj));\n    }\n  };\n\n  proto.createClipPathCallback = function(obj, container) {\n    return function(_newObj) {\n      _newObj._removeTransformMatrix();\n      _newObj.fillRule = _newObj.clipRule;\n      container.push(_newObj);\n    };\n  };\n\n  proto.resolveClipPath = function(obj) {\n    var clipPath = this.extractPropertyDefinition(obj, 'clipPath', 'clipPaths'),\n        element, klass, objTransformInv, container, gTransform, options;\n    if (clipPath) {\n      container = [];\n      objTransformInv = fabric.util.invertTransform(obj.calcTransformMatrix());\n      for (var i = 0; i < clipPath.length; i++) {\n        element = clipPath[i];\n        klass = this.findTag(element);\n        klass.fromElement(\n          element,\n          this.createClipPathCallback(obj, container),\n          this.options\n        );\n      }\n      if (container.length === 1) {\n        clipPath = container[0];\n      }\n      else {\n        clipPath = new fabric.Group(container);\n      }\n      gTransform = fabric.util.multiplyTransformMatrices(\n        objTransformInv,\n        clipPath.calcTransformMatrix()\n      );\n      var options = fabric.util.qrDecompose(gTransform);\n      clipPath.flipX = false;\n      clipPath.flipY = false;\n      clipPath.set('scaleX', options.scaleX);\n      clipPath.set('scaleY', options.scaleY);\n      clipPath.angle = options.angle;\n      clipPath.skewX = options.skewX;\n      clipPath.skewY = 0;\n      clipPath.setPositionByOrigin({ x: options.translateX, y: options.translateY }, 'center', 'center');\n      obj.clipPath = clipPath;\n    }\n  };\n\n  proto.checkIfDone = function() {\n    if (--this.numElements === 0) {\n      this.instances = this.instances.filter(function(el) {\n        // eslint-disable-next-line no-eq-null, eqeqeq\n        return el != null;\n      });\n      this.callback(this.instances, this.elements);\n    }\n  };\n})(fabric.ElementsParser.prototype);\n\n\n(function(global) {\n\n  'use strict';\n\n  /* Adaptation of work of Kevin Lindsey (kevin@kevlindev.com) */\n\n  var fabric = global.fabric || (global.fabric = { });\n\n  if (fabric.Point) {\n    fabric.warn('fabric.Point is already defined');\n    return;\n  }\n\n  fabric.Point = Point;\n\n  /**\n   * Point class\n   * @class fabric.Point\n   * @memberOf fabric\n   * @constructor\n   * @param {Number} x\n   * @param {Number} y\n   * @return {fabric.Point} thisArg\n   */\n  function Point(x, y) {\n    this.x = x;\n    this.y = y;\n  }\n\n  Point.prototype = /** @lends fabric.Point.prototype */ {\n\n    type: 'point',\n\n    constructor: Point,\n\n    /**\n     * Adds another point to this one and returns another one\n     * @param {fabric.Point} that\n     * @return {fabric.Point} new Point instance with added values\n     */\n    add: function (that) {\n      return new Point(this.x + that.x, this.y + that.y);\n    },\n\n    /**\n     * Adds another point to this one\n     * @param {fabric.Point} that\n     * @return {fabric.Point} thisArg\n     * @chainable\n     */\n    addEquals: function (that) {\n      this.x += that.x;\n      this.y += that.y;\n      return this;\n    },\n\n    /**\n     * Adds value to this point and returns a new one\n     * @param {Number} scalar\n     * @return {fabric.Point} new Point with added value\n     */\n    scalarAdd: function (scalar) {\n      return new Point(this.x + scalar, this.y + scalar);\n    },\n\n    /**\n     * Adds value to this point\n     * @param {Number} scalar\n     * @return {fabric.Point} thisArg\n     * @chainable\n     */\n    scalarAddEquals: function (scalar) {\n      this.x += scalar;\n      this.y += scalar;\n      return this;\n    },\n\n    /**\n     * Subtracts another point from this point and returns a new one\n     * @param {fabric.Point} that\n     * @return {fabric.Point} new Point object with subtracted values\n     */\n    subtract: function (that) {\n      return new Point(this.x - that.x, this.y - that.y);\n    },\n\n    /**\n     * Subtracts another point from this point\n     * @param {fabric.Point} that\n     * @return {fabric.Point} thisArg\n     * @chainable\n     */\n    subtractEquals: function (that) {\n      this.x -= that.x;\n      this.y -= that.y;\n      return this;\n    },\n\n    /**\n     * Subtracts value from this point and returns a new one\n     * @param {Number} scalar\n     * @return {fabric.Point}\n     */\n    scalarSubtract: function (scalar) {\n      return new Point(this.x - scalar, this.y - scalar);\n    },\n\n    /**\n     * Subtracts value from this point\n     * @param {Number} scalar\n     * @return {fabric.Point} thisArg\n     * @chainable\n     */\n    scalarSubtractEquals: function (scalar) {\n      this.x -= scalar;\n      this.y -= scalar;\n      return this;\n    },\n\n    /**\n     * Multiplies this point by a value and returns a new one\n     * TODO: rename in scalarMultiply in 2.0\n     * @param {Number} scalar\n     * @return {fabric.Point}\n     */\n    multiply: function (scalar) {\n      return new Point(this.x * scalar, this.y * scalar);\n    },\n\n    /**\n     * Multiplies this point by a value\n     * TODO: rename in scalarMultiplyEquals in 2.0\n     * @param {Number} scalar\n     * @return {fabric.Point} thisArg\n     * @chainable\n     */\n    multiplyEquals: function (scalar) {\n      this.x *= scalar;\n      this.y *= scalar;\n      return this;\n    },\n\n    /**\n     * Divides this point by a value and returns a new one\n     * TODO: rename in scalarDivide in 2.0\n     * @param {Number} scalar\n     * @return {fabric.Point}\n     */\n    divide: function (scalar) {\n      return new Point(this.x / scalar, this.y / scalar);\n    },\n\n    /**\n     * Divides this point by a value\n     * TODO: rename in scalarDivideEquals in 2.0\n     * @param {Number} scalar\n     * @return {fabric.Point} thisArg\n     * @chainable\n     */\n    divideEquals: function (scalar) {\n      this.x /= scalar;\n      this.y /= scalar;\n      return this;\n    },\n\n    /**\n     * Returns true if this point is equal to another one\n     * @param {fabric.Point} that\n     * @return {Boolean}\n     */\n    eq: function (that) {\n      return (this.x === that.x && this.y === that.y);\n    },\n\n    /**\n     * Returns true if this point is less than another one\n     * @param {fabric.Point} that\n     * @return {Boolean}\n     */\n    lt: function (that) {\n      return (this.x < that.x && this.y < that.y);\n    },\n\n    /**\n     * Returns true if this point is less than or equal to another one\n     * @param {fabric.Point} that\n     * @return {Boolean}\n     */\n    lte: function (that) {\n      return (this.x <= that.x && this.y <= that.y);\n    },\n\n    /**\n\n     * Returns true if this point is greater another one\n     * @param {fabric.Point} that\n     * @return {Boolean}\n     */\n    gt: function (that) {\n      return (this.x > that.x && this.y > that.y);\n    },\n\n    /**\n     * Returns true if this point is greater than or equal to another one\n     * @param {fabric.Point} that\n     * @return {Boolean}\n     */\n    gte: function (that) {\n      return (this.x >= that.x && this.y >= that.y);\n    },\n\n    /**\n     * Returns new point which is the result of linear interpolation with this one and another one\n     * @param {fabric.Point} that\n     * @param {Number} t , position of interpolation, between 0 and 1 default 0.5\n     * @return {fabric.Point}\n     */\n    lerp: function (that, t) {\n      if (typeof t === 'undefined') {\n        t = 0.5;\n      }\n      t = Math.max(Math.min(1, t), 0);\n      return new Point(this.x + (that.x - this.x) * t, this.y + (that.y - this.y) * t);\n    },\n\n    /**\n     * Returns distance from this point and another one\n     * @param {fabric.Point} that\n     * @return {Number}\n     */\n    distanceFrom: function (that) {\n      var dx = this.x - that.x,\n          dy = this.y - that.y;\n      return Math.sqrt(dx * dx + dy * dy);\n    },\n\n    /**\n     * Returns the point between this point and another one\n     * @param {fabric.Point} that\n     * @return {fabric.Point}\n     */\n    midPointFrom: function (that) {\n      return this.lerp(that);\n    },\n\n    /**\n     * Returns a new point which is the min of this and another one\n     * @param {fabric.Point} that\n     * @return {fabric.Point}\n     */\n    min: function (that) {\n      return new Point(Math.min(this.x, that.x), Math.min(this.y, that.y));\n    },\n\n    /**\n     * Returns a new point which is the max of this and another one\n     * @param {fabric.Point} that\n     * @return {fabric.Point}\n     */\n    max: function (that) {\n      return new Point(Math.max(this.x, that.x), Math.max(this.y, that.y));\n    },\n\n    /**\n     * Returns string representation of this point\n     * @return {String}\n     */\n    toString: function () {\n      return this.x + ',' + this.y;\n    },\n\n    /**\n     * Sets x/y of this point\n     * @param {Number} x\n     * @param {Number} y\n     * @chainable\n     */\n    setXY: function (x, y) {\n      this.x = x;\n      this.y = y;\n      return this;\n    },\n\n    /**\n     * Sets x of this point\n     * @param {Number} x\n     * @chainable\n     */\n    setX: function (x) {\n      this.x = x;\n      return this;\n    },\n\n    /**\n     * Sets y of this point\n     * @param {Number} y\n     * @chainable\n     */\n    setY: function (y) {\n      this.y = y;\n      return this;\n    },\n\n    /**\n     * Sets x/y of this point from another point\n     * @param {fabric.Point} that\n     * @chainable\n     */\n    setFromPoint: function (that) {\n      this.x = that.x;\n      this.y = that.y;\n      return this;\n    },\n\n    /**\n     * Swaps x/y of this point and another point\n     * @param {fabric.Point} that\n     */\n    swap: function (that) {\n      var x = this.x,\n          y = this.y;\n      this.x = that.x;\n      this.y = that.y;\n      that.x = x;\n      that.y = y;\n    },\n\n    /**\n     * return a cloned instance of the point\n     * @return {fabric.Point}\n     */\n    clone: function () {\n      return new Point(this.x, this.y);\n    }\n  };\n\n})(typeof exports !== 'undefined' ? exports : this);\n\n\n(function(global) {\n\n  'use strict';\n\n  /* Adaptation of work of Kevin Lindsey (kevin@kevlindev.com) */\n  var fabric = global.fabric || (global.fabric = { });\n\n  if (fabric.Intersection) {\n    fabric.warn('fabric.Intersection is already defined');\n    return;\n  }\n\n  /**\n   * Intersection class\n   * @class fabric.Intersection\n   * @memberOf fabric\n   * @constructor\n   */\n  function Intersection(status) {\n    this.status = status;\n    this.points = [];\n  }\n\n  fabric.Intersection = Intersection;\n\n  fabric.Intersection.prototype = /** @lends fabric.Intersection.prototype */ {\n\n    constructor: Intersection,\n\n    /**\n     * Appends a point to intersection\n     * @param {fabric.Point} point\n     * @return {fabric.Intersection} thisArg\n     * @chainable\n     */\n    appendPoint: function (point) {\n      this.points.push(point);\n      return this;\n    },\n\n    /**\n     * Appends points to intersection\n     * @param {Array} points\n     * @return {fabric.Intersection} thisArg\n     * @chainable\n     */\n    appendPoints: function (points) {\n      this.points = this.points.concat(points);\n      return this;\n    }\n  };\n\n  /**\n   * Checks if one line intersects another\n   * TODO: rename in intersectSegmentSegment\n   * @static\n   * @param {fabric.Point} a1\n   * @param {fabric.Point} a2\n   * @param {fabric.Point} b1\n   * @param {fabric.Point} b2\n   * @return {fabric.Intersection}\n   */\n  fabric.Intersection.intersectLineLine = function (a1, a2, b1, b2) {\n    var result,\n        uaT = (b2.x - b1.x) * (a1.y - b1.y) - (b2.y - b1.y) * (a1.x - b1.x),\n        ubT = (a2.x - a1.x) * (a1.y - b1.y) - (a2.y - a1.y) * (a1.x - b1.x),\n        uB = (b2.y - b1.y) * (a2.x - a1.x) - (b2.x - b1.x) * (a2.y - a1.y);\n    if (uB !== 0) {\n      var ua = uaT / uB,\n          ub = ubT / uB;\n      if (0 <= ua && ua <= 1 && 0 <= ub && ub <= 1) {\n        result = new Intersection('Intersection');\n        result.appendPoint(new fabric.Point(a1.x + ua * (a2.x - a1.x), a1.y + ua * (a2.y - a1.y)));\n      }\n      else {\n        result = new Intersection();\n      }\n    }\n    else {\n      if (uaT === 0 || ubT === 0) {\n        result = new Intersection('Coincident');\n      }\n      else {\n        result = new Intersection('Parallel');\n      }\n    }\n    return result;\n  };\n\n  /**\n   * Checks if line intersects polygon\n   * TODO: rename in intersectSegmentPolygon\n   * fix detection of coincident\n   * @static\n   * @param {fabric.Point} a1\n   * @param {fabric.Point} a2\n   * @param {Array} points\n   * @return {fabric.Intersection}\n   */\n  fabric.Intersection.intersectLinePolygon = function(a1, a2, points) {\n    var result = new Intersection(),\n        length = points.length,\n        b1, b2, inter, i;\n\n    for (i = 0; i < length; i++) {\n      b1 = points[i];\n      b2 = points[(i + 1) % length];\n      inter = Intersection.intersectLineLine(a1, a2, b1, b2);\n\n      result.appendPoints(inter.points);\n    }\n    if (result.points.length > 0) {\n      result.status = 'Intersection';\n    }\n    return result;\n  };\n\n  /**\n   * Checks if polygon intersects another polygon\n   * @static\n   * @param {Array} points1\n   * @param {Array} points2\n   * @return {fabric.Intersection}\n   */\n  fabric.Intersection.intersectPolygonPolygon = function (points1, points2) {\n    var result = new Intersection(),\n        length = points1.length, i;\n\n    for (i = 0; i < length; i++) {\n      var a1 = points1[i],\n          a2 = points1[(i + 1) % length],\n          inter = Intersection.intersectLinePolygon(a1, a2, points2);\n\n      result.appendPoints(inter.points);\n    }\n    if (result.points.length > 0) {\n      result.status = 'Intersection';\n    }\n    return result;\n  };\n\n  /**\n   * Checks if polygon intersects rectangle\n   * @static\n   * @param {Array} points\n   * @param {fabric.Point} r1\n   * @param {fabric.Point} r2\n   * @return {fabric.Intersection}\n   */\n  fabric.Intersection.intersectPolygonRectangle = function (points, r1, r2) {\n    var min = r1.min(r2),\n        max = r1.max(r2),\n        topRight = new fabric.Point(max.x, min.y),\n        bottomLeft = new fabric.Point(min.x, max.y),\n        inter1 = Intersection.intersectLinePolygon(min, topRight, points),\n        inter2 = Intersection.intersectLinePolygon(topRight, max, points),\n        inter3 = Intersection.intersectLinePolygon(max, bottomLeft, points),\n        inter4 = Intersection.intersectLinePolygon(bottomLeft, min, points),\n        result = new Intersection();\n\n    result.appendPoints(inter1.points);\n    result.appendPoints(inter2.points);\n    result.appendPoints(inter3.points);\n    result.appendPoints(inter4.points);\n\n    if (result.points.length > 0) {\n      result.status = 'Intersection';\n    }\n    return result;\n  };\n\n})(typeof exports !== 'undefined' ? exports : this);\n\n\n(function(global) {\n\n  'use strict';\n\n  var fabric = global.fabric || (global.fabric = { });\n\n  if (fabric.Color) {\n    fabric.warn('fabric.Color is already defined.');\n    return;\n  }\n\n  /**\n   * Color class\n   * The purpose of {@link fabric.Color} is to abstract and encapsulate common color operations;\n   * {@link fabric.Color} is a constructor and creates instances of {@link fabric.Color} objects.\n   *\n   * @class fabric.Color\n   * @param {String} color optional in hex or rgb(a) or hsl format or from known color list\n   * @return {fabric.Color} thisArg\n   * @tutorial {@link http://fabricjs.com/fabric-intro-part-2/#colors}\n   */\n  function Color(color) {\n    if (!color) {\n      this.setSource([0, 0, 0, 1]);\n    }\n    else {\n      this._tryParsingColor(color);\n    }\n  }\n\n  fabric.Color = Color;\n\n  fabric.Color.prototype = /** @lends fabric.Color.prototype */ {\n\n    /**\n     * @private\n     * @param {String|Array} color Color value to parse\n     */\n    _tryParsingColor: function(color) {\n      var source;\n\n      if (color in Color.colorNameMap) {\n        color = Color.colorNameMap[color];\n      }\n\n      if (color === 'transparent') {\n        source = [255, 255, 255, 0];\n      }\n\n      if (!source) {\n        source = Color.sourceFromHex(color);\n      }\n      if (!source) {\n        source = Color.sourceFromRgb(color);\n      }\n      if (!source) {\n        source = Color.sourceFromHsl(color);\n      }\n      if (!source) {\n        //if color is not recognize let's make black as canvas does\n        source = [0, 0, 0, 1];\n      }\n      if (source) {\n        this.setSource(source);\n      }\n    },\n\n    /**\n     * Adapted from <a href=\"https://rawgithub.com/mjijackson/mjijackson.github.com/master/2008/02/rgb-to-hsl-and-rgb-to-hsv-color-model-conversion-algorithms-in-javascript.html\">https://github.com/mjijackson</a>\n     * @private\n     * @param {Number} r Red color value\n     * @param {Number} g Green color value\n     * @param {Number} b Blue color value\n     * @return {Array} Hsl color\n     */\n    _rgbToHsl: function(r, g, b) {\n      r /= 255; g /= 255; b /= 255;\n\n      var h, s, l,\n          max = fabric.util.array.max([r, g, b]),\n          min = fabric.util.array.min([r, g, b]);\n\n      l = (max + min) / 2;\n\n      if (max === min) {\n        h = s = 0; // achromatic\n      }\n      else {\n        var d = max - min;\n        s = l > 0.5 ? d / (2 - max - min) : d / (max + min);\n        switch (max) {\n          case r:\n            h = (g - b) / d + (g < b ? 6 : 0);\n            break;\n          case g:\n            h = (b - r) / d + 2;\n            break;\n          case b:\n            h = (r - g) / d + 4;\n            break;\n        }\n        h /= 6;\n      }\n\n      return [\n        Math.round(h * 360),\n        Math.round(s * 100),\n        Math.round(l * 100)\n      ];\n    },\n\n    /**\n     * Returns source of this color (where source is an array representation; ex: [200, 200, 100, 1])\n     * @return {Array}\n     */\n    getSource: function() {\n      return this._source;\n    },\n\n    /**\n     * Sets source of this color (where source is an array representation; ex: [200, 200, 100, 1])\n     * @param {Array} source\n     */\n    setSource: function(source) {\n      this._source = source;\n    },\n\n    /**\n     * Returns color representation in RGB format\n     * @return {String} ex: rgb(0-255,0-255,0-255)\n     */\n    toRgb: function() {\n      var source = this.getSource();\n      return 'rgb(' + source[0] + ',' + source[1] + ',' + source[2] + ')';\n    },\n\n    /**\n     * Returns color representation in RGBA format\n     * @return {String} ex: rgba(0-255,0-255,0-255,0-1)\n     */\n    toRgba: function() {\n      var source = this.getSource();\n      return 'rgba(' + source[0] + ',' + source[1] + ',' + source[2] + ',' + source[3] + ')';\n    },\n\n    /**\n     * Returns color representation in HSL format\n     * @return {String} ex: hsl(0-360,0%-100%,0%-100%)\n     */\n    toHsl: function() {\n      var source = this.getSource(),\n          hsl = this._rgbToHsl(source[0], source[1], source[2]);\n\n      return 'hsl(' + hsl[0] + ',' + hsl[1] + '%,' + hsl[2] + '%)';\n    },\n\n    /**\n     * Returns color representation in HSLA format\n     * @return {String} ex: hsla(0-360,0%-100%,0%-100%,0-1)\n     */\n    toHsla: function() {\n      var source = this.getSource(),\n          hsl = this._rgbToHsl(source[0], source[1], source[2]);\n\n      return 'hsla(' + hsl[0] + ',' + hsl[1] + '%,' + hsl[2] + '%,' + source[3] + ')';\n    },\n\n    /**\n     * Returns color representation in HEX format\n     * @return {String} ex: FF5555\n     */\n    toHex: function() {\n      var source = this.getSource(), r, g, b;\n\n      r = source[0].toString(16);\n      r = (r.length === 1) ? ('0' + r) : r;\n\n      g = source[1].toString(16);\n      g = (g.length === 1) ? ('0' + g) : g;\n\n      b = source[2].toString(16);\n      b = (b.length === 1) ? ('0' + b) : b;\n\n      return r.toUpperCase() + g.toUpperCase() + b.toUpperCase();\n    },\n\n    /**\n     * Returns color representation in HEXA format\n     * @return {String} ex: FF5555CC\n     */\n    toHexa: function() {\n      var source = this.getSource(), a;\n\n      a = Math.round(source[3] * 255);\n      a = a.toString(16);\n      a = (a.length === 1) ? ('0' + a) : a;\n\n      return this.toHex() + a.toUpperCase();\n    },\n\n    /**\n     * Gets value of alpha channel for this color\n     * @return {Number} 0-1\n     */\n    getAlpha: function() {\n      return this.getSource()[3];\n    },\n\n    /**\n     * Sets value of alpha channel for this color\n     * @param {Number} alpha Alpha value 0-1\n     * @return {fabric.Color} thisArg\n     */\n    setAlpha: function(alpha) {\n      var source = this.getSource();\n      source[3] = alpha;\n      this.setSource(source);\n      return this;\n    },\n\n    /**\n     * Transforms color to its grayscale representation\n     * @return {fabric.Color} thisArg\n     */\n    toGrayscale: function() {\n      var source = this.getSource(),\n          average = parseInt((source[0] * 0.3 + source[1] * 0.59 + source[2] * 0.11).toFixed(0), 10),\n          currentAlpha = source[3];\n      this.setSource([average, average, average, currentAlpha]);\n      return this;\n    },\n\n    /**\n     * Transforms color to its black and white representation\n     * @param {Number} threshold\n     * @return {fabric.Color} thisArg\n     */\n    toBlackWhite: function(threshold) {\n      var source = this.getSource(),\n          average = (source[0] * 0.3 + source[1] * 0.59 + source[2] * 0.11).toFixed(0),\n          currentAlpha = source[3];\n\n      threshold = threshold || 127;\n\n      average = (Number(average) < Number(threshold)) ? 0 : 255;\n      this.setSource([average, average, average, currentAlpha]);\n      return this;\n    },\n\n    /**\n     * Overlays color with another color\n     * @param {String|fabric.Color} otherColor\n     * @return {fabric.Color} thisArg\n     */\n    overlayWith: function(otherColor) {\n      if (!(otherColor instanceof Color)) {\n        otherColor = new Color(otherColor);\n      }\n\n      var result = [],\n          alpha = this.getAlpha(),\n          otherAlpha = 0.5,\n          source = this.getSource(),\n          otherSource = otherColor.getSource(), i;\n\n      for (i = 0; i < 3; i++) {\n        result.push(Math.round((source[i] * (1 - otherAlpha)) + (otherSource[i] * otherAlpha)));\n      }\n\n      result[3] = alpha;\n      this.setSource(result);\n      return this;\n    }\n  };\n\n  /**\n   * Regex matching color in RGB or RGBA formats (ex: rgb(0, 0, 0), rgba(255, 100, 10, 0.5), rgba( 255 , 100 , 10 , 0.5 ), rgb(1,1,1), rgba(100%, 60%, 10%, 0.5))\n   * @static\n   * @field\n   * @memberOf fabric.Color\n   */\n  // eslint-disable-next-line max-len\n  fabric.Color.reRGBa = /^rgba?\\(\\s*(\\d{1,3}(?:\\.\\d+)?\\%?)\\s*,\\s*(\\d{1,3}(?:\\.\\d+)?\\%?)\\s*,\\s*(\\d{1,3}(?:\\.\\d+)?\\%?)\\s*(?:\\s*,\\s*((?:\\d*\\.?\\d+)?)\\s*)?\\)$/i;\n\n  /**\n   * Regex matching color in HSL or HSLA formats (ex: hsl(200, 80%, 10%), hsla(300, 50%, 80%, 0.5), hsla( 300 , 50% , 80% , 0.5 ))\n   * @static\n   * @field\n   * @memberOf fabric.Color\n   */\n  fabric.Color.reHSLa = /^hsla?\\(\\s*(\\d{1,3})\\s*,\\s*(\\d{1,3}\\%)\\s*,\\s*(\\d{1,3}\\%)\\s*(?:\\s*,\\s*(\\d+(?:\\.\\d+)?)\\s*)?\\)$/i;\n\n  /**\n   * Regex matching color in HEX format (ex: #FF5544CC, #FF5555, 010155, aff)\n   * @static\n   * @field\n   * @memberOf fabric.Color\n   */\n  fabric.Color.reHex = /^#?([0-9a-f]{8}|[0-9a-f]{6}|[0-9a-f]{4}|[0-9a-f]{3})$/i;\n\n  /**\n   * Map of the 148 color names with HEX code\n   * @static\n   * @field\n   * @memberOf fabric.Color\n   * @see: https://www.w3.org/TR/css3-color/#svg-color\n   */\n  fabric.Color.colorNameMap = {\n    aliceblue:            '#F0F8FF',\n    antiquewhite:         '#FAEBD7',\n    aqua:                 '#00FFFF',\n    aquamarine:           '#7FFFD4',\n    azure:                '#F0FFFF',\n    beige:                '#F5F5DC',\n    bisque:               '#FFE4C4',\n    black:                '#000000',\n    blanchedalmond:       '#FFEBCD',\n    blue:                 '#0000FF',\n    blueviolet:           '#8A2BE2',\n    brown:                '#A52A2A',\n    burlywood:            '#DEB887',\n    cadetblue:            '#5F9EA0',\n    chartreuse:           '#7FFF00',\n    chocolate:            '#D2691E',\n    coral:                '#FF7F50',\n    cornflowerblue:       '#6495ED',\n    cornsilk:             '#FFF8DC',\n    crimson:              '#DC143C',\n    cyan:                 '#00FFFF',\n    darkblue:             '#00008B',\n    darkcyan:             '#008B8B',\n    darkgoldenrod:        '#B8860B',\n    darkgray:             '#A9A9A9',\n    darkgrey:             '#A9A9A9',\n    darkgreen:            '#006400',\n    darkkhaki:            '#BDB76B',\n    darkmagenta:          '#8B008B',\n    darkolivegreen:       '#556B2F',\n    darkorange:           '#FF8C00',\n    darkorchid:           '#9932CC',\n    darkred:              '#8B0000',\n    darksalmon:           '#E9967A',\n    darkseagreen:         '#8FBC8F',\n    darkslateblue:        '#483D8B',\n    darkslategray:        '#2F4F4F',\n    darkslategrey:        '#2F4F4F',\n    darkturquoise:        '#00CED1',\n    darkviolet:           '#9400D3',\n    deeppink:             '#FF1493',\n    deepskyblue:          '#00BFFF',\n    dimgray:              '#696969',\n    dimgrey:              '#696969',\n    dodgerblue:           '#1E90FF',\n    firebrick:            '#B22222',\n    floralwhite:          '#FFFAF0',\n    forestgreen:          '#228B22',\n    fuchsia:              '#FF00FF',\n    gainsboro:            '#DCDCDC',\n    ghostwhite:           '#F8F8FF',\n    gold:                 '#FFD700',\n    goldenrod:            '#DAA520',\n    gray:                 '#808080',\n    grey:                 '#808080',\n    green:                '#008000',\n    greenyellow:          '#ADFF2F',\n    honeydew:             '#F0FFF0',\n    hotpink:              '#FF69B4',\n    indianred:            '#CD5C5C',\n    indigo:               '#4B0082',\n    ivory:                '#FFFFF0',\n    khaki:                '#F0E68C',\n    lavender:             '#E6E6FA',\n    lavenderblush:        '#FFF0F5',\n    lawngreen:            '#7CFC00',\n    lemonchiffon:         '#FFFACD',\n    lightblue:            '#ADD8E6',\n    lightcoral:           '#F08080',\n    lightcyan:            '#E0FFFF',\n    lightgoldenrodyellow: '#FAFAD2',\n    lightgray:            '#D3D3D3',\n    lightgrey:            '#D3D3D3',\n    lightgreen:           '#90EE90',\n    lightpink:            '#FFB6C1',\n    lightsalmon:          '#FFA07A',\n    lightseagreen:        '#20B2AA',\n    lightskyblue:         '#87CEFA',\n    lightslategray:       '#778899',\n    lightslategrey:       '#778899',\n    lightsteelblue:       '#B0C4DE',\n    lightyellow:          '#FFFFE0',\n    lime:                 '#00FF00',\n    limegreen:            '#32CD32',\n    linen:                '#FAF0E6',\n    magenta:              '#FF00FF',\n    maroon:               '#800000',\n    mediumaquamarine:     '#66CDAA',\n    mediumblue:           '#0000CD',\n    mediumorchid:         '#BA55D3',\n    mediumpurple:         '#9370DB',\n    mediumseagreen:       '#3CB371',\n    mediumslateblue:      '#7B68EE',\n    mediumspringgreen:    '#00FA9A',\n    mediumturquoise:      '#48D1CC',\n    mediumvioletred:      '#C71585',\n    midnightblue:         '#191970',\n    mintcream:            '#F5FFFA',\n    mistyrose:            '#FFE4E1',\n    moccasin:             '#FFE4B5',\n    navajowhite:          '#FFDEAD',\n    navy:                 '#000080',\n    oldlace:              '#FDF5E6',\n    olive:                '#808000',\n    olivedrab:            '#6B8E23',\n    orange:               '#FFA500',\n    orangered:            '#FF4500',\n    orchid:               '#DA70D6',\n    palegoldenrod:        '#EEE8AA',\n    palegreen:            '#98FB98',\n    paleturquoise:        '#AFEEEE',\n    palevioletred:        '#DB7093',\n    papayawhip:           '#FFEFD5',\n    peachpuff:            '#FFDAB9',\n    peru:                 '#CD853F',\n    pink:                 '#FFC0CB',\n    plum:                 '#DDA0DD',\n    powderblue:           '#B0E0E6',\n    purple:               '#800080',\n    rebeccapurple:        '#663399',\n    red:                  '#FF0000',\n    rosybrown:            '#BC8F8F',\n    royalblue:            '#4169E1',\n    saddlebrown:          '#8B4513',\n    salmon:               '#FA8072',\n    sandybrown:           '#F4A460',\n    seagreen:             '#2E8B57',\n    seashell:             '#FFF5EE',\n    sienna:               '#A0522D',\n    silver:               '#C0C0C0',\n    skyblue:              '#87CEEB',\n    slateblue:            '#6A5ACD',\n    slategray:            '#708090',\n    slategrey:            '#708090',\n    snow:                 '#FFFAFA',\n    springgreen:          '#00FF7F',\n    steelblue:            '#4682B4',\n    tan:                  '#D2B48C',\n    teal:                 '#008080',\n    thistle:              '#D8BFD8',\n    tomato:               '#FF6347',\n    turquoise:            '#40E0D0',\n    violet:               '#EE82EE',\n    wheat:                '#F5DEB3',\n    white:                '#FFFFFF',\n    whitesmoke:           '#F5F5F5',\n    yellow:               '#FFFF00',\n    yellowgreen:          '#9ACD32'\n  };\n\n  /**\n   * @private\n   * @param {Number} p\n   * @param {Number} q\n   * @param {Number} t\n   * @return {Number}\n   */\n  function hue2rgb(p, q, t) {\n    if (t < 0) {\n      t += 1;\n    }\n    if (t > 1) {\n      t -= 1;\n    }\n    if (t < 1 / 6) {\n      return p + (q - p) * 6 * t;\n    }\n    if (t < 1 / 2) {\n      return q;\n    }\n    if (t < 2 / 3) {\n      return p + (q - p) * (2 / 3 - t) * 6;\n    }\n    return p;\n  }\n\n  /**\n   * Returns new color object, when given a color in RGB format\n   * @memberOf fabric.Color\n   * @param {String} color Color value ex: rgb(0-255,0-255,0-255)\n   * @return {fabric.Color}\n   */\n  fabric.Color.fromRgb = function(color) {\n    return Color.fromSource(Color.sourceFromRgb(color));\n  };\n\n  /**\n   * Returns array representation (ex: [100, 100, 200, 1]) of a color that's in RGB or RGBA format\n   * @memberOf fabric.Color\n   * @param {String} color Color value ex: rgb(0-255,0-255,0-255), rgb(0%-100%,0%-100%,0%-100%)\n   * @return {Array} source\n   */\n  fabric.Color.sourceFromRgb = function(color) {\n    var match = color.match(Color.reRGBa);\n    if (match) {\n      var r = parseInt(match[1], 10) / (/%$/.test(match[1]) ? 100 : 1) * (/%$/.test(match[1]) ? 255 : 1),\n          g = parseInt(match[2], 10) / (/%$/.test(match[2]) ? 100 : 1) * (/%$/.test(match[2]) ? 255 : 1),\n          b = parseInt(match[3], 10) / (/%$/.test(match[3]) ? 100 : 1) * (/%$/.test(match[3]) ? 255 : 1);\n\n      return [\n        parseInt(r, 10),\n        parseInt(g, 10),\n        parseInt(b, 10),\n        match[4] ? parseFloat(match[4]) : 1\n      ];\n    }\n  };\n\n  /**\n   * Returns new color object, when given a color in RGBA format\n   * @static\n   * @function\n   * @memberOf fabric.Color\n   * @param {String} color\n   * @return {fabric.Color}\n   */\n  fabric.Color.fromRgba = Color.fromRgb;\n\n  /**\n   * Returns new color object, when given a color in HSL format\n   * @param {String} color Color value ex: hsl(0-260,0%-100%,0%-100%)\n   * @memberOf fabric.Color\n   * @return {fabric.Color}\n   */\n  fabric.Color.fromHsl = function(color) {\n    return Color.fromSource(Color.sourceFromHsl(color));\n  };\n\n  /**\n   * Returns array representation (ex: [100, 100, 200, 1]) of a color that's in HSL or HSLA format.\n   * Adapted from <a href=\"https://rawgithub.com/mjijackson/mjijackson.github.com/master/2008/02/rgb-to-hsl-and-rgb-to-hsv-color-model-conversion-algorithms-in-javascript.html\">https://github.com/mjijackson</a>\n   * @memberOf fabric.Color\n   * @param {String} color Color value ex: hsl(0-360,0%-100%,0%-100%) or hsla(0-360,0%-100%,0%-100%, 0-1)\n   * @return {Array} source\n   * @see http://http://www.w3.org/TR/css3-color/#hsl-color\n   */\n  fabric.Color.sourceFromHsl = function(color) {\n    var match = color.match(Color.reHSLa);\n    if (!match) {\n      return;\n    }\n\n    var h = (((parseFloat(match[1]) % 360) + 360) % 360) / 360,\n        s = parseFloat(match[2]) / (/%$/.test(match[2]) ? 100 : 1),\n        l = parseFloat(match[3]) / (/%$/.test(match[3]) ? 100 : 1),\n        r, g, b;\n\n    if (s === 0) {\n      r = g = b = l;\n    }\n    else {\n      var q = l <= 0.5 ? l * (s + 1) : l + s - l * s,\n          p = l * 2 - q;\n\n      r = hue2rgb(p, q, h + 1 / 3);\n      g = hue2rgb(p, q, h);\n      b = hue2rgb(p, q, h - 1 / 3);\n    }\n\n    return [\n      Math.round(r * 255),\n      Math.round(g * 255),\n      Math.round(b * 255),\n      match[4] ? parseFloat(match[4]) : 1\n    ];\n  };\n\n  /**\n   * Returns new color object, when given a color in HSLA format\n   * @static\n   * @function\n   * @memberOf fabric.Color\n   * @param {String} color\n   * @return {fabric.Color}\n   */\n  fabric.Color.fromHsla = Color.fromHsl;\n\n  /**\n   * Returns new color object, when given a color in HEX format\n   * @static\n   * @memberOf fabric.Color\n   * @param {String} color Color value ex: FF5555\n   * @return {fabric.Color}\n   */\n  fabric.Color.fromHex = function(color) {\n    return Color.fromSource(Color.sourceFromHex(color));\n  };\n\n  /**\n   * Returns array representation (ex: [100, 100, 200, 1]) of a color that's in HEX format\n   * @static\n   * @memberOf fabric.Color\n   * @param {String} color ex: FF5555 or FF5544CC (RGBa)\n   * @return {Array} source\n   */\n  fabric.Color.sourceFromHex = function(color) {\n    if (color.match(Color.reHex)) {\n      var value = color.slice(color.indexOf('#') + 1),\n          isShortNotation = (value.length === 3 || value.length === 4),\n          isRGBa = (value.length === 8 || value.length === 4),\n          r = isShortNotation ? (value.charAt(0) + value.charAt(0)) : value.substring(0, 2),\n          g = isShortNotation ? (value.charAt(1) + value.charAt(1)) : value.substring(2, 4),\n          b = isShortNotation ? (value.charAt(2) + value.charAt(2)) : value.substring(4, 6),\n          a = isRGBa ? (isShortNotation ? (value.charAt(3) + value.charAt(3)) : value.substring(6, 8)) : 'FF';\n\n      return [\n        parseInt(r, 16),\n        parseInt(g, 16),\n        parseInt(b, 16),\n        parseFloat((parseInt(a, 16) / 255).toFixed(2))\n      ];\n    }\n  };\n\n  /**\n   * Returns new color object, when given color in array representation (ex: [200, 100, 100, 0.5])\n   * @static\n   * @memberOf fabric.Color\n   * @param {Array} source\n   * @return {fabric.Color}\n   */\n  fabric.Color.fromSource = function(source) {\n    var oColor = new Color();\n    oColor.setSource(source);\n    return oColor;\n  };\n\n})(typeof exports !== 'undefined' ? exports : this);\n\n\n(function() {\n\n  /* _FROM_SVG_START_ */\n  function getColorStop(el) {\n    var style = el.getAttribute('style'),\n        offset = el.getAttribute('offset') || 0,\n        color, colorAlpha, opacity, i;\n\n    // convert percents to absolute values\n    offset = parseFloat(offset) / (/%$/.test(offset) ? 100 : 1);\n    offset = offset < 0 ? 0 : offset > 1 ? 1 : offset;\n    if (style) {\n      var keyValuePairs = style.split(/\\s*;\\s*/);\n\n      if (keyValuePairs[keyValuePairs.length - 1] === '') {\n        keyValuePairs.pop();\n      }\n\n      for (i = keyValuePairs.length; i--; ) {\n\n        var split = keyValuePairs[i].split(/\\s*:\\s*/),\n            key = split[0].trim(),\n            value = split[1].trim();\n\n        if (key === 'stop-color') {\n          color = value;\n        }\n        else if (key === 'stop-opacity') {\n          opacity = value;\n        }\n      }\n    }\n\n    if (!color) {\n      color = el.getAttribute('stop-color') || 'rgb(0,0,0)';\n    }\n    if (!opacity) {\n      opacity = el.getAttribute('stop-opacity');\n    }\n\n    color = new fabric.Color(color);\n    colorAlpha = color.getAlpha();\n    opacity = isNaN(parseFloat(opacity)) ? 1 : parseFloat(opacity);\n    opacity *= colorAlpha;\n\n    return {\n      offset: offset,\n      color: color.toRgb(),\n      opacity: opacity\n    };\n  }\n\n  function getLinearCoords(el) {\n    return {\n      x1: el.getAttribute('x1') || 0,\n      y1: el.getAttribute('y1') || 0,\n      x2: el.getAttribute('x2') || '100%',\n      y2: el.getAttribute('y2') || 0\n    };\n  }\n\n  function getRadialCoords(el) {\n    return {\n      x1: el.getAttribute('fx') || el.getAttribute('cx') || '50%',\n      y1: el.getAttribute('fy') || el.getAttribute('cy') || '50%',\n      r1: 0,\n      x2: el.getAttribute('cx') || '50%',\n      y2: el.getAttribute('cy') || '50%',\n      r2: el.getAttribute('r') || '50%'\n    };\n  }\n  /* _FROM_SVG_END_ */\n\n  var clone = fabric.util.object.clone;\n\n  /**\n   * Gradient class\n   * @class fabric.Gradient\n   * @tutorial {@link http://fabricjs.com/fabric-intro-part-2#gradients}\n   * @see {@link fabric.Gradient#initialize} for constructor definition\n   */\n  fabric.Gradient = fabric.util.createClass(/** @lends fabric.Gradient.prototype */ {\n\n    /**\n     * Horizontal offset for aligning gradients coming from SVG when outside pathgroups\n     * @type Number\n     * @default 0\n     */\n    offsetX: 0,\n\n    /**\n     * Vertical offset for aligning gradients coming from SVG when outside pathgroups\n     * @type Number\n     * @default 0\n     */\n    offsetY: 0,\n\n    /**\n     * Constructor\n     * @param {Object} [options] Options object with type, coords, gradientUnits and colorStops\n     * @return {fabric.Gradient} thisArg\n     */\n    initialize: function(options) {\n      options || (options = { });\n\n      var coords = { };\n\n      this.id = fabric.Object.__uid++;\n      this.type = options.type || 'linear';\n\n      coords = {\n        x1: options.coords.x1 || 0,\n        y1: options.coords.y1 || 0,\n        x2: options.coords.x2 || 0,\n        y2: options.coords.y2 || 0\n      };\n\n      if (this.type === 'radial') {\n        coords.r1 = options.coords.r1 || 0;\n        coords.r2 = options.coords.r2 || 0;\n      }\n      this.coords = coords;\n      this.colorStops = options.colorStops.slice();\n      if (options.gradientTransform) {\n        this.gradientTransform = options.gradientTransform;\n      }\n      this.offsetX = options.offsetX || this.offsetX;\n      this.offsetY = options.offsetY || this.offsetY;\n    },\n\n    /**\n     * Adds another colorStop\n     * @param {Object} colorStop Object with offset and color\n     * @return {fabric.Gradient} thisArg\n     */\n    addColorStop: function(colorStops) {\n      for (var position in colorStops) {\n        var color = new fabric.Color(colorStops[position]);\n        this.colorStops.push({\n          offset: parseFloat(position),\n          color: color.toRgb(),\n          opacity: color.getAlpha()\n        });\n      }\n      return this;\n    },\n\n    /**\n     * Returns object representation of a gradient\n     * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output\n     * @return {Object}\n     */\n    toObject: function(propertiesToInclude) {\n      var object = {\n        type: this.type,\n        coords: this.coords,\n        colorStops: this.colorStops,\n        offsetX: this.offsetX,\n        offsetY: this.offsetY,\n        gradientTransform: this.gradientTransform ? this.gradientTransform.concat() : this.gradientTransform\n      };\n      fabric.util.populateWithProperties(this, object, propertiesToInclude);\n\n      return object;\n    },\n\n    /* _TO_SVG_START_ */\n    /**\n     * Returns SVG representation of an gradient\n     * @param {Object} object Object to create a gradient for\n     * @return {String} SVG representation of an gradient (linear/radial)\n     */\n    toSVG: function(object) {\n      var coords = clone(this.coords, true), i, len,\n          markup, commonAttributes, colorStops = clone(this.colorStops, true),\n          needsSwap = coords.r1 > coords.r2,\n          offsetX = object.width / 2, offsetY = object.height / 2;\n      // colorStops must be sorted ascending\n      colorStops.sort(function(a, b) {\n        return a.offset - b.offset;\n      });\n      if (object.type === 'path') {\n        offsetX -= object.pathOffset.x;\n        offsetY -= object.pathOffset.y;\n      }\n      for (var prop in coords) {\n        if (prop === 'x1' || prop === 'x2') {\n          coords[prop] += this.offsetX - offsetX;\n        }\n        else if (prop === 'y1' || prop === 'y2') {\n          coords[prop] += this.offsetY - offsetY;\n        }\n      }\n\n      commonAttributes = 'id=\"SVGID_' + this.id +\n                     '\" gradientUnits=\"userSpaceOnUse\"';\n      if (this.gradientTransform) {\n        commonAttributes += ' gradientTransform=\"matrix(' + this.gradientTransform.join(' ') + ')\" ';\n      }\n      if (this.type === 'linear') {\n        markup = [\n          '<linearGradient ',\n          commonAttributes,\n          ' x1=\"', coords.x1,\n          '\" y1=\"', coords.y1,\n          '\" x2=\"', coords.x2,\n          '\" y2=\"', coords.y2,\n          '\">\\n'\n        ];\n      }\n      else if (this.type === 'radial') {\n        // svg radial gradient has just 1 radius. the biggest.\n        markup = [\n          '<radialGradient ',\n          commonAttributes,\n          ' cx=\"', needsSwap ? coords.x1 : coords.x2,\n          '\" cy=\"', needsSwap ? coords.y1 : coords.y2,\n          '\" r=\"', needsSwap ? coords.r1 : coords.r2,\n          '\" fx=\"', needsSwap ? coords.x2 : coords.x1,\n          '\" fy=\"', needsSwap ? coords.y2 : coords.y1,\n          '\">\\n'\n        ];\n      }\n\n      if (this.type === 'radial') {\n        if (needsSwap) {\n          // svg goes from internal to external radius. if radius are inverted, swap color stops.\n          colorStops = colorStops.concat();\n          colorStops.reverse();\n          for (i = 0, len = colorStops.length; i < len; i++) {\n            colorStops[i].offset = 1 - colorStops[i].offset;\n          }\n        }\n        var minRadius = Math.min(coords.r1, coords.r2);\n        if (minRadius > 0) {\n          // i have to shift all colorStops and add new one in 0.\n          var maxRadius = Math.max(coords.r1, coords.r2),\n              percentageShift = minRadius / maxRadius;\n          for (i = 0, len = colorStops.length; i < len; i++) {\n            colorStops[i].offset += percentageShift * (1 - colorStops[i].offset);\n          }\n        }\n      }\n\n      for (i = 0, len = colorStops.length; i < len; i++) {\n        var colorStop = colorStops[i];\n        markup.push(\n          '<stop ',\n          'offset=\"', (colorStop.offset * 100) + '%',\n          '\" style=\"stop-color:', colorStop.color,\n          (typeof colorStop.opacity !== 'undefined' ? ';stop-opacity: ' + colorStop.opacity : ';'),\n          '\"/>\\n'\n        );\n      }\n\n      markup.push((this.type === 'linear' ? '</linearGradient>\\n' : '</radialGradient>\\n'));\n\n      return markup.join('');\n    },\n    /* _TO_SVG_END_ */\n\n    /**\n     * Returns an instance of CanvasGradient\n     * @param {CanvasRenderingContext2D} ctx Context to render on\n     * @return {CanvasGradient}\n     */\n    toLive: function(ctx) {\n      var gradient, coords = fabric.util.object.clone(this.coords), i, len;\n\n      if (!this.type) {\n        return;\n      }\n\n      if (this.type === 'linear') {\n        gradient = ctx.createLinearGradient(\n          coords.x1, coords.y1, coords.x2, coords.y2);\n      }\n      else if (this.type === 'radial') {\n        gradient = ctx.createRadialGradient(\n          coords.x1, coords.y1, coords.r1, coords.x2, coords.y2, coords.r2);\n      }\n\n      for (i = 0, len = this.colorStops.length; i < len; i++) {\n        var color = this.colorStops[i].color,\n            opacity = this.colorStops[i].opacity,\n            offset = this.colorStops[i].offset;\n\n        if (typeof opacity !== 'undefined') {\n          color = new fabric.Color(color).setAlpha(opacity).toRgba();\n        }\n        gradient.addColorStop(offset, color);\n      }\n\n      return gradient;\n    }\n  });\n\n  fabric.util.object.extend(fabric.Gradient, {\n\n    /* _FROM_SVG_START_ */\n    /**\n     * Returns {@link fabric.Gradient} instance from an SVG element\n     * @static\n     * @memberOf fabric.Gradient\n     * @param {SVGGradientElement} el SVG gradient element\n     * @param {fabric.Object} instance\n     * @return {fabric.Gradient} Gradient instance\n     * @see http://www.w3.org/TR/SVG/pservers.html#LinearGradientElement\n     * @see http://www.w3.org/TR/SVG/pservers.html#RadialGradientElement\n     */\n    fromElement: function(el, instance) {\n      /**\n       *  @example:\n       *\n       *  <linearGradient id=\"linearGrad1\">\n       *    <stop offset=\"0%\" stop-color=\"white\"/>\n       *    <stop offset=\"100%\" stop-color=\"black\"/>\n       *  </linearGradient>\n       *\n       *  OR\n       *\n       *  <linearGradient id=\"linearGrad2\">\n       *    <stop offset=\"0\" style=\"stop-color:rgb(255,255,255)\"/>\n       *    <stop offset=\"1\" style=\"stop-color:rgb(0,0,0)\"/>\n       *  </linearGradient>\n       *\n       *  OR\n       *\n       *  <radialGradient id=\"radialGrad1\">\n       *    <stop offset=\"0%\" stop-color=\"white\" stop-opacity=\"1\" />\n       *    <stop offset=\"50%\" stop-color=\"black\" stop-opacity=\"0.5\" />\n       *    <stop offset=\"100%\" stop-color=\"white\" stop-opacity=\"1\" />\n       *  </radialGradient>\n       *\n       *  OR\n       *\n       *  <radialGradient id=\"radialGrad2\">\n       *    <stop offset=\"0\" stop-color=\"rgb(255,255,255)\" />\n       *    <stop offset=\"0.5\" stop-color=\"rgb(0,0,0)\" />\n       *    <stop offset=\"1\" stop-color=\"rgb(255,255,255)\" />\n       *  </radialGradient>\n       *\n       */\n\n      var colorStopEls = el.getElementsByTagName('stop'),\n          type,\n          gradientUnits = el.getAttribute('gradientUnits') || 'objectBoundingBox',\n          gradientTransform = el.getAttribute('gradientTransform'),\n          colorStops = [],\n          coords, ellipseMatrix, i;\n\n      if (el.nodeName === 'linearGradient' || el.nodeName === 'LINEARGRADIENT') {\n        type = 'linear';\n      }\n      else {\n        type = 'radial';\n      }\n\n      if (type === 'linear') {\n        coords = getLinearCoords(el);\n      }\n      else if (type === 'radial') {\n        coords = getRadialCoords(el);\n      }\n\n      for (i = colorStopEls.length; i--; ) {\n        colorStops.push(getColorStop(colorStopEls[i]));\n      }\n\n      ellipseMatrix = _convertPercentUnitsToValues(instance, coords, gradientUnits);\n\n      var gradient = new fabric.Gradient({\n        type: type,\n        coords: coords,\n        colorStops: colorStops,\n        offsetX: -instance.left,\n        offsetY: -instance.top\n      });\n\n      if (gradientTransform || ellipseMatrix !== '') {\n        gradient.gradientTransform = fabric.parseTransformAttribute((gradientTransform || '') + ellipseMatrix);\n      }\n\n      return gradient;\n    },\n    /* _FROM_SVG_END_ */\n\n    /**\n     * Returns {@link fabric.Gradient} instance from its object representation\n     * @static\n     * @memberOf fabric.Gradient\n     * @param {Object} obj\n     * @param {Object} [options] Options object\n     */\n    forObject: function(obj, options) {\n      options || (options = { });\n      _convertPercentUnitsToValues(obj, options.coords, 'userSpaceOnUse');\n      return new fabric.Gradient(options);\n    }\n  });\n\n  /**\n   * @private\n   */\n  function _convertPercentUnitsToValues(object, options, gradientUnits) {\n    var propValue, addFactor = 0, multFactor = 1, ellipseMatrix = '';\n    for (var prop in options) {\n      if (options[prop] === 'Infinity') {\n        options[prop] = 1;\n      }\n      else if (options[prop] === '-Infinity') {\n        options[prop] = 0;\n      }\n      propValue = parseFloat(options[prop], 10);\n      if (typeof options[prop] === 'string' && /^(\\d+\\.\\d+)%|(\\d+)%$/.test(options[prop])) {\n        multFactor = 0.01;\n      }\n      else {\n        multFactor = 1;\n      }\n      if (prop === 'x1' || prop === 'x2' || prop === 'r2') {\n        multFactor *= gradientUnits === 'objectBoundingBox' ? object.width : 1;\n        addFactor = gradientUnits === 'objectBoundingBox' ? object.left || 0 : 0;\n      }\n      else if (prop === 'y1' || prop === 'y2') {\n        multFactor *= gradientUnits === 'objectBoundingBox' ? object.height : 1;\n        addFactor = gradientUnits === 'objectBoundingBox' ? object.top || 0 : 0;\n      }\n      options[prop] = propValue * multFactor + addFactor;\n    }\n    if (object.type === 'ellipse' &&\n        options.r2 !== null &&\n        gradientUnits === 'objectBoundingBox' &&\n        object.rx !== object.ry) {\n\n      var scaleFactor = object.ry / object.rx;\n      ellipseMatrix = ' scale(1, ' + scaleFactor + ')';\n      if (options.y1) {\n        options.y1 /= scaleFactor;\n      }\n      if (options.y2) {\n        options.y2 /= scaleFactor;\n      }\n    }\n    return ellipseMatrix;\n  }\n})();\n\n\n(function() {\n\n  'use strict';\n\n  var toFixed = fabric.util.toFixed;\n\n  /**\n   * Pattern class\n   * @class fabric.Pattern\n   * @see {@link http://fabricjs.com/patterns|Pattern demo}\n   * @see {@link http://fabricjs.com/dynamic-patterns|DynamicPattern demo}\n   * @see {@link fabric.Pattern#initialize} for constructor definition\n   */\n\n\n  fabric.Pattern = fabric.util.createClass(/** @lends fabric.Pattern.prototype */ {\n\n    /**\n     * Repeat property of a pattern (one of repeat, repeat-x, repeat-y or no-repeat)\n     * @type String\n     * @default\n     */\n    repeat: 'repeat',\n\n    /**\n     * Pattern horizontal offset from object's left/top corner\n     * @type Number\n     * @default\n     */\n    offsetX: 0,\n\n    /**\n     * Pattern vertical offset from object's left/top corner\n     * @type Number\n     * @default\n     */\n    offsetY: 0,\n\n    /**\n     * crossOrigin value (one of \"\", \"anonymous\", \"use-credentials\")\n     * @see https://developer.mozilla.org/en-US/docs/HTML/CORS_settings_attributes\n     * @type String\n     * @default\n     */\n    crossOrigin: '',\n\n    /**\n     * transform matrix to change the pattern, imported from svgs.\n     * @type Array\n     * @default\n     */\n    patternTransform: null,\n\n    /**\n     * Constructor\n     * @param {Object} [options] Options object\n     * @param {Function} [callback] function to invoke after callback init.\n     * @return {fabric.Pattern} thisArg\n     */\n    initialize: function(options, callback) {\n      options || (options = { });\n\n      this.id = fabric.Object.__uid++;\n      this.setOptions(options);\n      if (!options.source || (options.source && typeof options.source !== 'string')) {\n        callback && callback(this);\n        return;\n      }\n      // function string\n      if (typeof fabric.util.getFunctionBody(options.source) !== 'undefined') {\n        this.source = new Function(fabric.util.getFunctionBody(options.source));\n        callback && callback(this);\n      }\n      else {\n        // img src string\n        var _this = this;\n        this.source = fabric.util.createImage();\n        fabric.util.loadImage(options.source, function(img) {\n          _this.source = img;\n          callback && callback(_this);\n        }, null, this.crossOrigin);\n      }\n    },\n\n    /**\n     * Returns object representation of a pattern\n     * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output\n     * @return {Object} Object representation of a pattern instance\n     */\n    toObject: function(propertiesToInclude) {\n      var NUM_FRACTION_DIGITS = fabric.Object.NUM_FRACTION_DIGITS,\n          source, object;\n\n      // callback\n      if (typeof this.source === 'function') {\n        source = String(this.source);\n      }\n      // <img> element\n      else if (typeof this.source.src === 'string') {\n        source = this.source.src;\n      }\n      // <canvas> element\n      else if (typeof this.source === 'object' && this.source.toDataURL) {\n        source = this.source.toDataURL();\n      }\n\n      object = {\n        type: 'pattern',\n        source: source,\n        repeat: this.repeat,\n        crossOrigin: this.crossOrigin,\n        offsetX: toFixed(this.offsetX, NUM_FRACTION_DIGITS),\n        offsetY: toFixed(this.offsetY, NUM_FRACTION_DIGITS),\n        patternTransform: this.patternTransform ? this.patternTransform.concat() : null\n      };\n      fabric.util.populateWithProperties(this, object, propertiesToInclude);\n\n      return object;\n    },\n\n    /* _TO_SVG_START_ */\n    /**\n     * Returns SVG representation of a pattern\n     * @param {fabric.Object} object\n     * @return {String} SVG representation of a pattern\n     */\n    toSVG: function(object) {\n      var patternSource = typeof this.source === 'function' ? this.source() : this.source,\n          patternWidth = patternSource.width / object.width,\n          patternHeight = patternSource.height / object.height,\n          patternOffsetX = this.offsetX / object.width,\n          patternOffsetY = this.offsetY / object.height,\n          patternImgSrc = '';\n      if (this.repeat === 'repeat-x' || this.repeat === 'no-repeat') {\n        patternHeight = 1;\n        if (patternOffsetY) {\n          patternHeight += Math.abs(patternOffsetY);\n        }\n      }\n      if (this.repeat === 'repeat-y' || this.repeat === 'no-repeat') {\n        patternWidth = 1;\n        if (patternOffsetX) {\n          patternWidth += Math.abs(patternOffsetX);\n        }\n\n      }\n      if (patternSource.src) {\n        patternImgSrc = patternSource.src;\n      }\n      else if (patternSource.toDataURL) {\n        patternImgSrc = patternSource.toDataURL();\n      }\n\n      return '<pattern id=\"SVGID_' + this.id +\n                    '\" x=\"' + patternOffsetX +\n                    '\" y=\"' + patternOffsetY +\n                    '\" width=\"' + patternWidth +\n                    '\" height=\"' + patternHeight + '\">\\n' +\n               '<image x=\"0\" y=\"0\"' +\n                      ' width=\"' + patternSource.width +\n                      '\" height=\"' + patternSource.height +\n                      '\" xlink:href=\"' + patternImgSrc +\n               '\"></image>\\n' +\n             '</pattern>\\n';\n    },\n    /* _TO_SVG_END_ */\n\n    setOptions: function(options) {\n      for (var prop in options) {\n        this[prop] = options[prop];\n      }\n    },\n\n    /**\n     * Returns an instance of CanvasPattern\n     * @param {CanvasRenderingContext2D} ctx Context to create pattern\n     * @return {CanvasPattern}\n     */\n    toLive: function(ctx) {\n      var source = typeof this.source === 'function' ? this.source() : this.source;\n\n      // if the image failed to load, return, and allow rest to continue loading\n      if (!source) {\n        return '';\n      }\n\n      // if an image\n      if (typeof source.src !== 'undefined') {\n        if (!source.complete) {\n          return '';\n        }\n        if (source.naturalWidth === 0 || source.naturalHeight === 0) {\n          return '';\n        }\n      }\n      return ctx.createPattern(source, this.repeat);\n    }\n  });\n})();\n\n\n(function(global) {\n\n  'use strict';\n\n  var fabric = global.fabric || (global.fabric = { }),\n      toFixed = fabric.util.toFixed;\n\n  if (fabric.Shadow) {\n    fabric.warn('fabric.Shadow is already defined.');\n    return;\n  }\n\n  /**\n   * Shadow class\n   * @class fabric.Shadow\n   * @see {@link http://fabricjs.com/shadows|Shadow demo}\n   * @see {@link fabric.Shadow#initialize} for constructor definition\n   */\n  fabric.Shadow = fabric.util.createClass(/** @lends fabric.Shadow.prototype */ {\n\n    /**\n     * Shadow color\n     * @type String\n     * @default\n     */\n    color: 'rgb(0,0,0)',\n\n    /**\n     * Shadow blur\n     * @type Number\n     */\n    blur: 0,\n\n    /**\n     * Shadow horizontal offset\n     * @type Number\n     * @default\n     */\n    offsetX: 0,\n\n    /**\n     * Shadow vertical offset\n     * @type Number\n     * @default\n     */\n    offsetY: 0,\n\n    /**\n     * Whether the shadow should affect stroke operations\n     * @type Boolean\n     * @default\n     */\n    affectStroke: false,\n\n    /**\n     * Indicates whether toObject should include default values\n     * @type Boolean\n     * @default\n     */\n    includeDefaultValues: true,\n\n    /**\n     * Constructor\n     * @param {Object|String} [options] Options object with any of color, blur, offsetX, offsetY properties or string (e.g. \"rgba(0,0,0,0.2) 2px 2px 10px\")\n     * @return {fabric.Shadow} thisArg\n     */\n    initialize: function(options) {\n\n      if (typeof options === 'string') {\n        options = this._parseShadow(options);\n      }\n\n      for (var prop in options) {\n        this[prop] = options[prop];\n      }\n\n      this.id = fabric.Object.__uid++;\n    },\n\n    /**\n     * @private\n     * @param {String} shadow Shadow value to parse\n     * @return {Object} Shadow object with color, offsetX, offsetY and blur\n     */\n    _parseShadow: function(shadow) {\n      var shadowStr = shadow.trim(),\n          offsetsAndBlur = fabric.Shadow.reOffsetsAndBlur.exec(shadowStr) || [],\n          color = shadowStr.replace(fabric.Shadow.reOffsetsAndBlur, '') || 'rgb(0,0,0)';\n\n      return {\n        color: color.trim(),\n        offsetX: parseInt(offsetsAndBlur[1], 10) || 0,\n        offsetY: parseInt(offsetsAndBlur[2], 10) || 0,\n        blur: parseInt(offsetsAndBlur[3], 10) || 0\n      };\n    },\n\n    /**\n     * Returns a string representation of an instance\n     * @see http://www.w3.org/TR/css-text-decor-3/#text-shadow\n     * @return {String} Returns CSS3 text-shadow declaration\n     */\n    toString: function() {\n      return [this.offsetX, this.offsetY, this.blur, this.color].join('px ');\n    },\n\n    /* _TO_SVG_START_ */\n    /**\n     * Returns SVG representation of a shadow\n     * @param {fabric.Object} object\n     * @return {String} SVG representation of a shadow\n     */\n    toSVG: function(object) {\n      var fBoxX = 40, fBoxY = 40, NUM_FRACTION_DIGITS = fabric.Object.NUM_FRACTION_DIGITS,\n          offset = fabric.util.rotateVector(\n            { x: this.offsetX, y: this.offsetY },\n            fabric.util.degreesToRadians(-object.angle)),\n          BLUR_BOX = 20, color = new fabric.Color(this.color);\n\n      if (object.width && object.height) {\n        //http://www.w3.org/TR/SVG/filters.html#FilterEffectsRegion\n        // we add some extra space to filter box to contain the blur ( 20 )\n        fBoxX = toFixed((Math.abs(offset.x) + this.blur) / object.width, NUM_FRACTION_DIGITS) * 100 + BLUR_BOX;\n        fBoxY = toFixed((Math.abs(offset.y) + this.blur) / object.height, NUM_FRACTION_DIGITS) * 100 + BLUR_BOX;\n      }\n      if (object.flipX) {\n        offset.x *= -1;\n      }\n      if (object.flipY) {\n        offset.y *= -1;\n      }\n\n      return (\n        '<filter id=\"SVGID_' + this.id + '\" y=\"-' + fBoxY + '%\" height=\"' + (100 + 2 * fBoxY) + '%\" ' +\n          'x=\"-' + fBoxX + '%\" width=\"' + (100 + 2 * fBoxX) + '%\" ' + '>\\n' +\n          '\\t<feGaussianBlur in=\"SourceAlpha\" stdDeviation=\"' +\n            toFixed(this.blur ? this.blur / 2 : 0, NUM_FRACTION_DIGITS) + '\"></feGaussianBlur>\\n' +\n          '\\t<feOffset dx=\"' + toFixed(offset.x, NUM_FRACTION_DIGITS) +\n          '\" dy=\"' + toFixed(offset.y, NUM_FRACTION_DIGITS) + '\" result=\"oBlur\" ></feOffset>\\n' +\n          '\\t<feFlood flood-color=\"' + color.toRgb() + '\" flood-opacity=\"' + color.getAlpha() + '\"/>\\n' +\n          '\\t<feComposite in2=\"oBlur\" operator=\"in\" />\\n' +\n          '\\t<feMerge>\\n' +\n            '\\t\\t<feMergeNode></feMergeNode>\\n' +\n            '\\t\\t<feMergeNode in=\"SourceGraphic\"></feMergeNode>\\n' +\n          '\\t</feMerge>\\n' +\n        '</filter>\\n');\n    },\n    /* _TO_SVG_END_ */\n\n    /**\n     * Returns object representation of a shadow\n     * @return {Object} Object representation of a shadow instance\n     */\n    toObject: function() {\n      if (this.includeDefaultValues) {\n        return {\n          color: this.color,\n          blur: this.blur,\n          offsetX: this.offsetX,\n          offsetY: this.offsetY,\n          affectStroke: this.affectStroke\n        };\n      }\n      var obj = { }, proto = fabric.Shadow.prototype;\n\n      ['color', 'blur', 'offsetX', 'offsetY', 'affectStroke'].forEach(function(prop) {\n        if (this[prop] !== proto[prop]) {\n          obj[prop] = this[prop];\n        }\n      }, this);\n\n      return obj;\n    }\n  });\n\n  /**\n   * Regex matching shadow offsetX, offsetY and blur (ex: \"2px 2px 10px rgba(0,0,0,0.2)\", \"rgb(0,255,0) 2px 2px\")\n   * @static\n   * @field\n   * @memberOf fabric.Shadow\n   */\n  // eslint-disable-next-line max-len\n  fabric.Shadow.reOffsetsAndBlur = /(?:\\s|^)(-?\\d+(?:px)?(?:\\s?|$))?(-?\\d+(?:px)?(?:\\s?|$))?(\\d+(?:px)?)?(?:\\s?|$)(?:$|\\s)/;\n\n})(typeof exports !== 'undefined' ? exports : this);\n\n\n(function () {\n\n  'use strict';\n\n  if (fabric.StaticCanvas) {\n    fabric.warn('fabric.StaticCanvas is already defined.');\n    return;\n  }\n\n  // aliases for faster resolution\n  var extend = fabric.util.object.extend,\n      getElementOffset = fabric.util.getElementOffset,\n      removeFromArray = fabric.util.removeFromArray,\n      toFixed = fabric.util.toFixed,\n      transformPoint = fabric.util.transformPoint,\n      invertTransform = fabric.util.invertTransform,\n      getNodeCanvas = fabric.util.getNodeCanvas,\n      createCanvasElement = fabric.util.createCanvasElement,\n\n      CANVAS_INIT_ERROR = new Error('Could not initialize `canvas` element');\n\n  /**\n   * Static canvas class\n   * @class fabric.StaticCanvas\n   * @mixes fabric.Collection\n   * @mixes fabric.Observable\n   * @see {@link http://fabricjs.com/static_canvas|StaticCanvas demo}\n   * @see {@link fabric.StaticCanvas#initialize} for constructor definition\n   * @fires before:render\n   * @fires after:render\n   * @fires canvas:cleared\n   * @fires object:added\n   * @fires object:removed\n   */\n  fabric.StaticCanvas = fabric.util.createClass(fabric.CommonMethods, /** @lends fabric.StaticCanvas.prototype */ {\n\n    /**\n     * Constructor\n     * @param {HTMLElement | String} el &lt;canvas> element to initialize instance on\n     * @param {Object} [options] Options object\n     * @return {Object} thisArg\n     */\n    initialize: function(el, options) {\n      options || (options = { });\n      this.renderAndResetBound = this.renderAndReset.bind(this);\n      this.requestRenderAllBound = this.requestRenderAll.bind(this);\n      this._initStatic(el, options);\n    },\n\n    /**\n     * Background color of canvas instance.\n     * Should be set via {@link fabric.StaticCanvas#setBackgroundColor}.\n     * @type {(String|fabric.Pattern)}\n     * @default\n     */\n    backgroundColor: '',\n\n    /**\n     * Background image of canvas instance.\n     * Should be set via {@link fabric.StaticCanvas#setBackgroundImage}.\n     * <b>Backwards incompatibility note:</b> The \"backgroundImageOpacity\"\n     * and \"backgroundImageStretch\" properties are deprecated since 1.3.9.\n     * Use {@link fabric.Image#opacity}, {@link fabric.Image#width} and {@link fabric.Image#height}.\n     * since 2.4.0 image caching is active, please when putting an image as background, add to the\n     * canvas property a reference to the canvas it is on. Otherwise the image cannot detect the zoom\n     * vale. As an alternative you can disable image objectCaching\n     * @type fabric.Image\n     * @default\n     */\n    backgroundImage: null,\n\n    /**\n     * Overlay color of canvas instance.\n     * Should be set via {@link fabric.StaticCanvas#setOverlayColor}\n     * @since 1.3.9\n     * @type {(String|fabric.Pattern)}\n     * @default\n     */\n    overlayColor: '',\n\n    /**\n     * Overlay image of canvas instance.\n     * Should be set via {@link fabric.StaticCanvas#setOverlayImage}.\n     * <b>Backwards incompatibility note:</b> The \"overlayImageLeft\"\n     * and \"overlayImageTop\" properties are deprecated since 1.3.9.\n     * Use {@link fabric.Image#left} and {@link fabric.Image#top}.\n     * since 2.4.0 image caching is active, please when putting an image as overlay, add to the\n     * canvas property a reference to the canvas it is on. Otherwise the image cannot detect the zoom\n     * vale. As an alternative you can disable image objectCaching\n     * @type fabric.Image\n     * @default\n     */\n    overlayImage: null,\n\n    /**\n     * Indicates whether toObject/toDatalessObject should include default values\n     * @type Boolean\n     * @default\n     */\n    includeDefaultValues: true,\n\n    /**\n     * Indicates whether objects' state should be saved\n     * @type Boolean\n     * @default\n     */\n    stateful: false,\n\n    /**\n     * Indicates whether {@link fabric.Collection.add}, {@link fabric.Collection.insertAt} and {@link fabric.Collection.remove},\n     * {@link fabric.StaticCanvas.moveTo}, {@link fabric.StaticCanvas.clear} and many more, should also re-render canvas.\n     * Disabling this option will not give a performance boost when adding/removing a lot of objects to/from canvas at once\n     * since the renders are quequed and executed one per frame.\n     * Disabling is suggested anyway and managing the renders of the app manually is not a big effort ( canvas.requestRenderAll() )\n     * Left default to true to do not break documentation and old app, fiddles.\n     * @type Boolean\n     * @default\n     */\n    renderOnAddRemove: true,\n\n    /**\n     * Function that determines clipping of entire canvas area\n     * Being passed context as first argument.\n     * If you are using code minification, ctx argument can be minified/manglied you should use\n     * as a workaround `var ctx = arguments[0];` in the function;\n     * See clipping canvas area in {@link https://github.com/kangax/fabric.js/wiki/FAQ}\n     * @deprecated since 2.0.0\n     * @type Function\n     * @default\n     */\n    clipTo: null,\n\n    /**\n     * Indicates whether object controls (borders/controls) are rendered above overlay image\n     * @type Boolean\n     * @default\n     */\n    controlsAboveOverlay: false,\n\n    /**\n     * Indicates whether the browser can be scrolled when using a touchscreen and dragging on the canvas\n     * @type Boolean\n     * @default\n     */\n    allowTouchScrolling: false,\n\n    /**\n     * Indicates whether this canvas will use image smoothing, this is on by default in browsers\n     * @type Boolean\n     * @default\n     */\n    imageSmoothingEnabled: true,\n\n    /**\n     * The transformation (in the format of Canvas transform) which focuses the viewport\n     * @type Array\n     * @default\n     */\n    viewportTransform: fabric.iMatrix.concat(),\n\n    /**\n     * if set to false background image is not affected by viewport transform\n     * @since 1.6.3\n     * @type Boolean\n     * @default\n     */\n    backgroundVpt: true,\n\n    /**\n     * if set to false overlya image is not affected by viewport transform\n     * @since 1.6.3\n     * @type Boolean\n     * @default\n     */\n    overlayVpt: true,\n\n    /**\n     * Callback; invoked right before object is about to be scaled/rotated\n     * @deprecated since 2.3.0\n     * Use before:transform event\n     */\n    onBeforeScaleRotate: function () {\n      /* NOOP */\n    },\n\n    /**\n     * When true, canvas is scaled by devicePixelRatio for better rendering on retina screens\n     * @type Boolean\n     * @default\n     */\n    enableRetinaScaling: true,\n\n    /**\n     * Describe canvas element extension over design\n     * properties are tl,tr,bl,br.\n     * if canvas is not zoomed/panned those points are the four corner of canvas\n     * if canvas is viewportTransformed you those points indicate the extension\n     * of canvas element in plain untrasformed coordinates\n     * The coordinates get updated with @method calcViewportBoundaries.\n     * @memberOf fabric.StaticCanvas.prototype\n     */\n    vptCoords: { },\n\n    /**\n     * Based on vptCoords and object.aCoords, skip rendering of objects that\n     * are not included in current viewport.\n     * May greatly help in applications with crowded canvas and use of zoom/pan\n     * If One of the corner of the bounding box of the object is on the canvas\n     * the objects get rendered.\n     * @memberOf fabric.StaticCanvas.prototype\n     * @type Boolean\n     * @default\n     */\n    skipOffscreen: true,\n\n    /**\n     * a fabricObject that, without stroke define a clipping area with their shape. filled in black\n     * the clipPath object gets used when the canvas has rendered, and the context is placed in the\n     * top left corner of the canvas.\n     * clipPath will clip away controls, if you do not want this to happen use controlsAboveOverlay = true\n     * @type fabric.Object\n     */\n    clipPath: undefined,\n\n    /**\n     * @private\n     * @param {HTMLElement | String} el &lt;canvas> element to initialize instance on\n     * @param {Object} [options] Options object\n     */\n    _initStatic: function(el, options) {\n      var cb = this.requestRenderAllBound;\n      this._objects = [];\n      this._createLowerCanvas(el);\n      this._initOptions(options);\n      this._setImageSmoothing();\n      // only initialize retina scaling once\n      if (!this.interactive) {\n        this._initRetinaScaling();\n      }\n\n      if (options.overlayImage) {\n        this.setOverlayImage(options.overlayImage, cb);\n      }\n      if (options.backgroundImage) {\n        this.setBackgroundImage(options.backgroundImage, cb);\n      }\n      if (options.backgroundColor) {\n        this.setBackgroundColor(options.backgroundColor, cb);\n      }\n      if (options.overlayColor) {\n        this.setOverlayColor(options.overlayColor, cb);\n      }\n      this.calcOffset();\n    },\n\n    /**\n     * @private\n     */\n    _isRetinaScaling: function() {\n      return (fabric.devicePixelRatio !== 1 && this.enableRetinaScaling);\n    },\n\n    /**\n     * @private\n     * @return {Number} retinaScaling if applied, otherwise 1;\n     */\n    getRetinaScaling: function() {\n      return this._isRetinaScaling() ? fabric.devicePixelRatio : 1;\n    },\n\n    /**\n     * @private\n     */\n    _initRetinaScaling: function() {\n      if (!this._isRetinaScaling()) {\n        return;\n      }\n      this.lowerCanvasEl.setAttribute('width', this.width * fabric.devicePixelRatio);\n      this.lowerCanvasEl.setAttribute('height', this.height * fabric.devicePixelRatio);\n\n      this.contextContainer.scale(fabric.devicePixelRatio, fabric.devicePixelRatio);\n    },\n\n    /**\n     * Calculates canvas element offset relative to the document\n     * This method is also attached as \"resize\" event handler of window\n     * @return {fabric.Canvas} instance\n     * @chainable\n     */\n    calcOffset: function () {\n      this._offset = getElementOffset(this.lowerCanvasEl);\n      return this;\n    },\n\n    /**\n     * Sets {@link fabric.StaticCanvas#overlayImage|overlay image} for this canvas\n     * @param {(fabric.Image|String)} image fabric.Image instance or URL of an image to set overlay to\n     * @param {Function} callback callback to invoke when image is loaded and set as an overlay\n     * @param {Object} [options] Optional options to set for the {@link fabric.Image|overlay image}.\n     * @return {fabric.Canvas} thisArg\n     * @chainable\n     * @see {@link http://jsfiddle.net/fabricjs/MnzHT/|jsFiddle demo}\n     * @example <caption>Normal overlayImage with left/top = 0</caption>\n     * canvas.setOverlayImage('http://fabricjs.com/assets/jail_cell_bars.png', canvas.renderAll.bind(canvas), {\n     *   // Needed to position overlayImage at 0/0\n     *   originX: 'left',\n     *   originY: 'top'\n     * });\n     * @example <caption>overlayImage with different properties</caption>\n     * canvas.setOverlayImage('http://fabricjs.com/assets/jail_cell_bars.png', canvas.renderAll.bind(canvas), {\n     *   opacity: 0.5,\n     *   angle: 45,\n     *   left: 400,\n     *   top: 400,\n     *   originX: 'left',\n     *   originY: 'top'\n     * });\n     * @example <caption>Stretched overlayImage #1 - width/height correspond to canvas width/height</caption>\n     * fabric.Image.fromURL('http://fabricjs.com/assets/jail_cell_bars.png', function(img) {\n     *    img.set({width: canvas.width, height: canvas.height, originX: 'left', originY: 'top'});\n     *    canvas.setOverlayImage(img, canvas.renderAll.bind(canvas));\n     * });\n     * @example <caption>Stretched overlayImage #2 - width/height correspond to canvas width/height</caption>\n     * canvas.setOverlayImage('http://fabricjs.com/assets/jail_cell_bars.png', canvas.renderAll.bind(canvas), {\n     *   width: canvas.width,\n     *   height: canvas.height,\n     *   // Needed to position overlayImage at 0/0\n     *   originX: 'left',\n     *   originY: 'top'\n     * });\n     * @example <caption>overlayImage loaded from cross-origin</caption>\n     * canvas.setOverlayImage('http://fabricjs.com/assets/jail_cell_bars.png', canvas.renderAll.bind(canvas), {\n     *   opacity: 0.5,\n     *   angle: 45,\n     *   left: 400,\n     *   top: 400,\n     *   originX: 'left',\n     *   originY: 'top',\n     *   crossOrigin: 'anonymous'\n     * });\n     */\n    setOverlayImage: function (image, callback, options) {\n      return this.__setBgOverlayImage('overlayImage', image, callback, options);\n    },\n\n    /**\n     * Sets {@link fabric.StaticCanvas#backgroundImage|background image} for this canvas\n     * @param {(fabric.Image|String)} image fabric.Image instance or URL of an image to set background to\n     * @param {Function} callback Callback to invoke when image is loaded and set as background\n     * @param {Object} [options] Optional options to set for the {@link fabric.Image|background image}.\n     * @return {fabric.Canvas} thisArg\n     * @chainable\n     * @see {@link http://jsfiddle.net/djnr8o7a/28/|jsFiddle demo}\n     * @example <caption>Normal backgroundImage with left/top = 0</caption>\n     * canvas.setBackgroundImage('http://fabricjs.com/assets/honey_im_subtle.png', canvas.renderAll.bind(canvas), {\n     *   // Needed to position backgroundImage at 0/0\n     *   originX: 'left',\n     *   originY: 'top'\n     * });\n     * @example <caption>backgroundImage with different properties</caption>\n     * canvas.setBackgroundImage('http://fabricjs.com/assets/honey_im_subtle.png', canvas.renderAll.bind(canvas), {\n     *   opacity: 0.5,\n     *   angle: 45,\n     *   left: 400,\n     *   top: 400,\n     *   originX: 'left',\n     *   originY: 'top'\n     * });\n     * @example <caption>Stretched backgroundImage #1 - width/height correspond to canvas width/height</caption>\n     * fabric.Image.fromURL('http://fabricjs.com/assets/honey_im_subtle.png', function(img) {\n     *    img.set({width: canvas.width, height: canvas.height, originX: 'left', originY: 'top'});\n     *    canvas.setBackgroundImage(img, canvas.renderAll.bind(canvas));\n     * });\n     * @example <caption>Stretched backgroundImage #2 - width/height correspond to canvas width/height</caption>\n     * canvas.setBackgroundImage('http://fabricjs.com/assets/honey_im_subtle.png', canvas.renderAll.bind(canvas), {\n     *   width: canvas.width,\n     *   height: canvas.height,\n     *   // Needed to position backgroundImage at 0/0\n     *   originX: 'left',\n     *   originY: 'top'\n     * });\n     * @example <caption>backgroundImage loaded from cross-origin</caption>\n     * canvas.setBackgroundImage('http://fabricjs.com/assets/honey_im_subtle.png', canvas.renderAll.bind(canvas), {\n     *   opacity: 0.5,\n     *   angle: 45,\n     *   left: 400,\n     *   top: 400,\n     *   originX: 'left',\n     *   originY: 'top',\n     *   crossOrigin: 'anonymous'\n     * });\n     */\n    setBackgroundImage: function (image, callback, options) {\n      return this.__setBgOverlayImage('backgroundImage', image, callback, options);\n    },\n\n    /**\n     * Sets {@link fabric.StaticCanvas#overlayColor|foreground color} for this canvas\n     * @param {(String|fabric.Pattern)} overlayColor Color or pattern to set foreground color to\n     * @param {Function} callback Callback to invoke when foreground color is set\n     * @return {fabric.Canvas} thisArg\n     * @chainable\n     * @see {@link http://jsfiddle.net/fabricjs/pB55h/|jsFiddle demo}\n     * @example <caption>Normal overlayColor - color value</caption>\n     * canvas.setOverlayColor('rgba(255, 73, 64, 0.6)', canvas.renderAll.bind(canvas));\n     * @example <caption>fabric.Pattern used as overlayColor</caption>\n     * canvas.setOverlayColor({\n     *   source: 'http://fabricjs.com/assets/escheresque_ste.png'\n     * }, canvas.renderAll.bind(canvas));\n     * @example <caption>fabric.Pattern used as overlayColor with repeat and offset</caption>\n     * canvas.setOverlayColor({\n     *   source: 'http://fabricjs.com/assets/escheresque_ste.png',\n     *   repeat: 'repeat',\n     *   offsetX: 200,\n     *   offsetY: 100\n     * }, canvas.renderAll.bind(canvas));\n     */\n    setOverlayColor: function(overlayColor, callback) {\n      return this.__setBgOverlayColor('overlayColor', overlayColor, callback);\n    },\n\n    /**\n     * Sets {@link fabric.StaticCanvas#backgroundColor|background color} for this canvas\n     * @param {(String|fabric.Pattern)} backgroundColor Color or pattern to set background color to\n     * @param {Function} callback Callback to invoke when background color is set\n     * @return {fabric.Canvas} thisArg\n     * @chainable\n     * @see {@link http://jsfiddle.net/fabricjs/hXzvk/|jsFiddle demo}\n     * @example <caption>Normal backgroundColor - color value</caption>\n     * canvas.setBackgroundColor('rgba(255, 73, 64, 0.6)', canvas.renderAll.bind(canvas));\n     * @example <caption>fabric.Pattern used as backgroundColor</caption>\n     * canvas.setBackgroundColor({\n     *   source: 'http://fabricjs.com/assets/escheresque_ste.png'\n     * }, canvas.renderAll.bind(canvas));\n     * @example <caption>fabric.Pattern used as backgroundColor with repeat and offset</caption>\n     * canvas.setBackgroundColor({\n     *   source: 'http://fabricjs.com/assets/escheresque_ste.png',\n     *   repeat: 'repeat',\n     *   offsetX: 200,\n     *   offsetY: 100\n     * }, canvas.renderAll.bind(canvas));\n     */\n    setBackgroundColor: function(backgroundColor, callback) {\n      return this.__setBgOverlayColor('backgroundColor', backgroundColor, callback);\n    },\n\n    /**\n     * @private\n     * @see {@link http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#dom-context-2d-imagesmoothingenabled|WhatWG Canvas Standard}\n     */\n    _setImageSmoothing: function() {\n      var ctx = this.getContext();\n\n      ctx.imageSmoothingEnabled = ctx.imageSmoothingEnabled || ctx.webkitImageSmoothingEnabled\n        || ctx.mozImageSmoothingEnabled || ctx.msImageSmoothingEnabled || ctx.oImageSmoothingEnabled;\n      ctx.imageSmoothingEnabled = this.imageSmoothingEnabled;\n    },\n\n    /**\n     * @private\n     * @param {String} property Property to set ({@link fabric.StaticCanvas#backgroundImage|backgroundImage}\n     * or {@link fabric.StaticCanvas#overlayImage|overlayImage})\n     * @param {(fabric.Image|String|null)} image fabric.Image instance, URL of an image or null to set background or overlay to\n     * @param {Function} callback Callback to invoke when image is loaded and set as background or overlay\n     * @param {Object} [options] Optional options to set for the {@link fabric.Image|image}.\n     */\n    __setBgOverlayImage: function(property, image, callback, options) {\n      if (typeof image === 'string') {\n        fabric.util.loadImage(image, function(img) {\n          if (img) {\n            var instance = new fabric.Image(img, options);\n            this[property] = instance;\n            instance.canvas = this;\n          }\n          callback && callback(img);\n        }, this, options && options.crossOrigin);\n      }\n      else {\n        options && image.setOptions(options);\n        this[property] = image;\n        image && (image.canvas = this);\n        callback && callback(image);\n      }\n\n      return this;\n    },\n\n    /**\n     * @private\n     * @param {String} property Property to set ({@link fabric.StaticCanvas#backgroundColor|backgroundColor}\n     * or {@link fabric.StaticCanvas#overlayColor|overlayColor})\n     * @param {(Object|String|null)} color Object with pattern information, color value or null\n     * @param {Function} [callback] Callback is invoked when color is set\n     */\n    __setBgOverlayColor: function(property, color, callback) {\n      this[property] = color;\n      this._initGradient(color, property);\n      this._initPattern(color, property, callback);\n      return this;\n    },\n\n    /**\n     * @private\n     */\n    _createCanvasElement: function() {\n      var element = createCanvasElement();\n      if (!element) {\n        throw CANVAS_INIT_ERROR;\n      }\n      if (!element.style) {\n        element.style = { };\n      }\n      if (typeof element.getContext === 'undefined') {\n        throw CANVAS_INIT_ERROR;\n      }\n      return element;\n    },\n\n    /**\n     * @private\n     * @param {Object} [options] Options object\n     */\n    _initOptions: function (options) {\n      var lowerCanvasEl = this.lowerCanvasEl;\n      this._setOptions(options);\n\n      this.width = this.width || parseInt(lowerCanvasEl.width, 10) || 0;\n      this.height = this.height || parseInt(lowerCanvasEl.height, 10) || 0;\n\n      if (!this.lowerCanvasEl.style) {\n        return;\n      }\n\n      lowerCanvasEl.width = this.width;\n      lowerCanvasEl.height = this.height;\n\n      lowerCanvasEl.style.width = this.width + 'px';\n      lowerCanvasEl.style.height = this.height + 'px';\n\n      this.viewportTransform = this.viewportTransform.slice();\n    },\n\n    /**\n     * Creates a bottom canvas\n     * @private\n     * @param {HTMLElement} [canvasEl]\n     */\n    _createLowerCanvas: function (canvasEl) {\n      // canvasEl === 'HTMLCanvasElement' does not work on jsdom/node\n      if (canvasEl && canvasEl.getContext) {\n        this.lowerCanvasEl = canvasEl;\n      }\n      else {\n        this.lowerCanvasEl = fabric.util.getById(canvasEl) || this._createCanvasElement();\n      }\n\n      fabric.util.addClass(this.lowerCanvasEl, 'lower-canvas');\n\n      if (this.interactive) {\n        this._applyCanvasStyle(this.lowerCanvasEl);\n      }\n\n      this.contextContainer = this.lowerCanvasEl.getContext('2d');\n    },\n\n    /**\n     * Returns canvas width (in px)\n     * @return {Number}\n     */\n    getWidth: function () {\n      return this.width;\n    },\n\n    /**\n     * Returns canvas height (in px)\n     * @return {Number}\n     */\n    getHeight: function () {\n      return this.height;\n    },\n\n    /**\n     * Sets width of this canvas instance\n     * @param {Number|String} value                         Value to set width to\n     * @param {Object}        [options]                     Options object\n     * @param {Boolean}       [options.backstoreOnly=false] Set the given dimensions only as canvas backstore dimensions\n     * @param {Boolean}       [options.cssOnly=false]       Set the given dimensions only as css dimensions\n     * @return {fabric.Canvas} instance\n     * @chainable true\n     */\n    setWidth: function (value, options) {\n      return this.setDimensions({ width: value }, options);\n    },\n\n    /**\n     * Sets height of this canvas instance\n     * @param {Number|String} value                         Value to set height to\n     * @param {Object}        [options]                     Options object\n     * @param {Boolean}       [options.backstoreOnly=false] Set the given dimensions only as canvas backstore dimensions\n     * @param {Boolean}       [options.cssOnly=false]       Set the given dimensions only as css dimensions\n     * @return {fabric.Canvas} instance\n     * @chainable true\n     */\n    setHeight: function (value, options) {\n      return this.setDimensions({ height: value }, options);\n    },\n\n    /**\n     * Sets dimensions (width, height) of this canvas instance. when options.cssOnly flag active you should also supply the unit of measure (px/%/em)\n     * @param {Object}        dimensions                    Object with width/height properties\n     * @param {Number|String} [dimensions.width]            Width of canvas element\n     * @param {Number|String} [dimensions.height]           Height of canvas element\n     * @param {Object}        [options]                     Options object\n     * @param {Boolean}       [options.backstoreOnly=false] Set the given dimensions only as canvas backstore dimensions\n     * @param {Boolean}       [options.cssOnly=false]       Set the given dimensions only as css dimensions\n     * @return {fabric.Canvas} thisArg\n     * @chainable\n     */\n    setDimensions: function (dimensions, options) {\n      var cssValue;\n\n      options = options || {};\n\n      for (var prop in dimensions) {\n        cssValue = dimensions[prop];\n\n        if (!options.cssOnly) {\n          this._setBackstoreDimension(prop, dimensions[prop]);\n          cssValue += 'px';\n          this.hasLostContext = true;\n        }\n\n        if (!options.backstoreOnly) {\n          this._setCssDimension(prop, cssValue);\n        }\n      }\n      if (this._isCurrentlyDrawing) {\n        this.freeDrawingBrush && this.freeDrawingBrush._setBrushStyles();\n      }\n      this._initRetinaScaling();\n      this._setImageSmoothing();\n      this.calcOffset();\n\n      if (!options.cssOnly) {\n        this.requestRenderAll();\n      }\n\n      return this;\n    },\n\n    /**\n     * Helper for setting width/height\n     * @private\n     * @param {String} prop property (width|height)\n     * @param {Number} value value to set property to\n     * @return {fabric.Canvas} instance\n     * @chainable true\n     */\n    _setBackstoreDimension: function (prop, value) {\n      this.lowerCanvasEl[prop] = value;\n\n      if (this.upperCanvasEl) {\n        this.upperCanvasEl[prop] = value;\n      }\n\n      if (this.cacheCanvasEl) {\n        this.cacheCanvasEl[prop] = value;\n      }\n\n      this[prop] = value;\n\n      return this;\n    },\n\n    /**\n     * Helper for setting css width/height\n     * @private\n     * @param {String} prop property (width|height)\n     * @param {String} value value to set property to\n     * @return {fabric.Canvas} instance\n     * @chainable true\n     */\n    _setCssDimension: function (prop, value) {\n      this.lowerCanvasEl.style[prop] = value;\n\n      if (this.upperCanvasEl) {\n        this.upperCanvasEl.style[prop] = value;\n      }\n\n      if (this.wrapperEl) {\n        this.wrapperEl.style[prop] = value;\n      }\n\n      return this;\n    },\n\n    /**\n     * Returns canvas zoom level\n     * @return {Number}\n     */\n    getZoom: function () {\n      return this.viewportTransform[0];\n    },\n\n    /**\n     * Sets viewport transform of this canvas instance\n     * @param {Array} vpt the transform in the form of context.transform\n     * @return {fabric.Canvas} instance\n     * @chainable true\n     */\n    setViewportTransform: function (vpt) {\n      var activeObject = this._activeObject, object, ignoreVpt = false, skipAbsolute = true, i, len;\n      this.viewportTransform = vpt;\n      for (i = 0, len = this._objects.length; i < len; i++) {\n        object = this._objects[i];\n        object.group || object.setCoords(ignoreVpt, skipAbsolute);\n      }\n      if (activeObject && activeObject.type === 'activeSelection') {\n        activeObject.setCoords(ignoreVpt, skipAbsolute);\n      }\n      this.calcViewportBoundaries();\n      this.renderOnAddRemove && this.requestRenderAll();\n      return this;\n    },\n\n    /**\n     * Sets zoom level of this canvas instance, zoom centered around point\n     * @param {fabric.Point} point to zoom with respect to\n     * @param {Number} value to set zoom to, less than 1 zooms out\n     * @return {fabric.Canvas} instance\n     * @chainable true\n     */\n    zoomToPoint: function (point, value) {\n      // TODO: just change the scale, preserve other transformations\n      var before = point, vpt = this.viewportTransform.slice(0);\n      point = transformPoint(point, invertTransform(this.viewportTransform));\n      vpt[0] = value;\n      vpt[3] = value;\n      var after = transformPoint(point, vpt);\n      vpt[4] += before.x - after.x;\n      vpt[5] += before.y - after.y;\n      return this.setViewportTransform(vpt);\n    },\n\n    /**\n     * Sets zoom level of this canvas instance\n     * @param {Number} value to set zoom to, less than 1 zooms out\n     * @return {fabric.Canvas} instance\n     * @chainable true\n     */\n    setZoom: function (value) {\n      this.zoomToPoint(new fabric.Point(0, 0), value);\n      return this;\n    },\n\n    /**\n     * Pan viewport so as to place point at top left corner of canvas\n     * @param {fabric.Point} point to move to\n     * @return {fabric.Canvas} instance\n     * @chainable true\n     */\n    absolutePan: function (point) {\n      var vpt = this.viewportTransform.slice(0);\n      vpt[4] = -point.x;\n      vpt[5] = -point.y;\n      return this.setViewportTransform(vpt);\n    },\n\n    /**\n     * Pans viewpoint relatively\n     * @param {fabric.Point} point (position vector) to move by\n     * @return {fabric.Canvas} instance\n     * @chainable true\n     */\n    relativePan: function (point) {\n      return this.absolutePan(new fabric.Point(\n        -point.x - this.viewportTransform[4],\n        -point.y - this.viewportTransform[5]\n      ));\n    },\n\n    /**\n     * Returns &lt;canvas> element corresponding to this instance\n     * @return {HTMLCanvasElement}\n     */\n    getElement: function () {\n      return this.lowerCanvasEl;\n    },\n\n    /**\n     * @private\n     * @param {fabric.Object} obj Object that was added\n     */\n    _onObjectAdded: function(obj) {\n      this.stateful && obj.setupState();\n      obj._set('canvas', this);\n      obj.setCoords();\n      this.fire('object:added', { target: obj });\n      obj.fire('added');\n    },\n\n    /**\n     * @private\n     * @param {fabric.Object} obj Object that was removed\n     */\n    _onObjectRemoved: function(obj) {\n      this.fire('object:removed', { target: obj });\n      obj.fire('removed');\n      delete obj.canvas;\n    },\n\n    /**\n     * Clears specified context of canvas element\n     * @param {CanvasRenderingContext2D} ctx Context to clear\n     * @return {fabric.Canvas} thisArg\n     * @chainable\n     */\n    clearContext: function(ctx) {\n      ctx.clearRect(0, 0, this.width, this.height);\n      return this;\n    },\n\n    /**\n     * Returns context of canvas where objects are drawn\n     * @return {CanvasRenderingContext2D}\n     */\n    getContext: function () {\n      return this.contextContainer;\n    },\n\n    /**\n     * Clears all contexts (background, main, top) of an instance\n     * @return {fabric.Canvas} thisArg\n     * @chainable\n     */\n    clear: function () {\n      this._objects.length = 0;\n      this.backgroundImage = null;\n      this.overlayImage = null;\n      this.backgroundColor = '';\n      this.overlayColor = '';\n      if (this._hasITextHandlers) {\n        this.off('mouse:up', this._mouseUpITextHandler);\n        this._iTextInstances = null;\n        this._hasITextHandlers = false;\n      }\n      this.clearContext(this.contextContainer);\n      this.fire('canvas:cleared');\n      this.renderOnAddRemove && this.requestRenderAll();\n      return this;\n    },\n\n    /**\n     * Renders the canvas\n     * @return {fabric.Canvas} instance\n     * @chainable\n     */\n    renderAll: function () {\n      var canvasToDrawOn = this.contextContainer;\n      this.renderCanvas(canvasToDrawOn, this._objects);\n      return this;\n    },\n\n    /**\n     * Function created to be instance bound at initialization\n     * used in requestAnimationFrame rendering\n     * Let the fabricJS call it. If you call it manually you could have more\n     * animationFrame stacking on to of each other\n     * for an imperative rendering, use canvas.renderAll\n     * @private\n     * @return {fabric.Canvas} instance\n     * @chainable\n     */\n    renderAndReset: function() {\n      this.isRendering = 0;\n      this.renderAll();\n    },\n\n    /**\n     * Append a renderAll request to next animation frame.\n     * unless one is already in progress, in that case nothing is done\n     * a boolean flag will avoid appending more.\n     * @return {fabric.Canvas} instance\n     * @chainable\n     */\n    requestRenderAll: function () {\n      if (!this.isRendering) {\n        this.isRendering = fabric.util.requestAnimFrame(this.renderAndResetBound);\n      }\n      return this;\n    },\n\n    /**\n     * Calculate the position of the 4 corner of canvas with current viewportTransform.\n     * helps to determinate when an object is in the current rendering viewport using\n     * object absolute coordinates ( aCoords )\n     * @return {Object} points.tl\n     * @chainable\n     */\n    calcViewportBoundaries: function() {\n      var points = { }, width = this.width, height = this.height,\n          iVpt = invertTransform(this.viewportTransform);\n      points.tl = transformPoint({ x: 0, y: 0 }, iVpt);\n      points.br = transformPoint({ x: width, y: height }, iVpt);\n      points.tr = new fabric.Point(points.br.x, points.tl.y);\n      points.bl = new fabric.Point(points.tl.x, points.br.y);\n      this.vptCoords = points;\n      return points;\n    },\n\n    cancelRequestedRender: function() {\n      if (this.isRendering) {\n        fabric.util.cancelAnimFrame(this.isRendering);\n        this.isRendering = 0;\n      }\n    },\n\n    /**\n     * Renders background, objects, overlay and controls.\n     * @param {CanvasRenderingContext2D} ctx\n     * @param {Array} objects to render\n     * @return {fabric.Canvas} instance\n     * @chainable\n     */\n    renderCanvas: function(ctx, objects) {\n      var v = this.viewportTransform, path = this.clipPath;\n      this.cancelRequestedRender();\n      this.calcViewportBoundaries();\n      this.clearContext(ctx);\n      this.fire('before:render', { ctx: ctx, });\n      if (this.clipTo) {\n        fabric.util.clipContext(this, ctx);\n      }\n      this._renderBackground(ctx);\n\n      ctx.save();\n      //apply viewport transform once for all rendering process\n      ctx.transform(v[0], v[1], v[2], v[3], v[4], v[5]);\n      this._renderObjects(ctx, objects);\n      ctx.restore();\n      if (!this.controlsAboveOverlay && this.interactive) {\n        this.drawControls(ctx);\n      }\n      if (this.clipTo) {\n        ctx.restore();\n      }\n      if (path) {\n        path.canvas = this;\n        // needed to setup a couple of variables\n        path.shouldCache();\n        path._transformDone = true;\n        path.renderCache({ forClipping: true });\n        this.drawClipPathOnCanvas(ctx);\n      }\n      this._renderOverlay(ctx);\n      if (this.controlsAboveOverlay && this.interactive) {\n        this.drawControls(ctx);\n      }\n      this.fire('after:render', { ctx: ctx, });\n    },\n\n    /**\n     * Paint the cached clipPath on the lowerCanvasEl\n     * @param {CanvasRenderingContext2D} ctx Context to render on\n     */\n    drawClipPathOnCanvas: function(ctx) {\n      var v = this.viewportTransform, path = this.clipPath;\n      ctx.save();\n      ctx.transform(v[0], v[1], v[2], v[3], v[4], v[5]);\n      // DEBUG: uncomment this line, comment the following\n      // ctx.globalAlpha = 0.4;\n      ctx.globalCompositeOperation = 'destination-in';\n      path.transform(ctx);\n      ctx.scale(1 / path.zoomX, 1 / path.zoomY);\n      ctx.drawImage(path._cacheCanvas, -path.cacheTranslationX, -path.cacheTranslationY);\n      ctx.restore();\n    },\n\n    /**\n     * @private\n     * @param {CanvasRenderingContext2D} ctx Context to render on\n     * @param {Array} objects to render\n     */\n    _renderObjects: function(ctx, objects) {\n      var i, len;\n      for (i = 0, len = objects.length; i < len; ++i) {\n        objects[i] && objects[i].render(ctx);\n      }\n    },\n\n    /**\n     * @private\n     * @param {CanvasRenderingContext2D} ctx Context to render on\n     * @param {string} property 'background' or 'overlay'\n     */\n    _renderBackgroundOrOverlay: function(ctx, property) {\n      var object = this[property + 'Color'], v;\n      if (object) {\n        ctx.fillStyle = object.toLive\n          ? object.toLive(ctx, this)\n          : object;\n\n        ctx.fillRect(\n          object.offsetX || 0,\n          object.offsetY || 0,\n          this.width,\n          this.height);\n      }\n      object = this[property + 'Image'];\n      if (object) {\n        if (this[property + 'Vpt']) {\n          v = this.viewportTransform;\n          ctx.save();\n          ctx.transform(v[0], v[1], v[2], v[3], v[4], v[5]);\n        }\n        object.render(ctx);\n        this[property + 'Vpt'] && ctx.restore();\n      }\n    },\n\n    /**\n     * @private\n     * @param {CanvasRenderingContext2D} ctx Context to render on\n     */\n    _renderBackground: function(ctx) {\n      this._renderBackgroundOrOverlay(ctx, 'background');\n    },\n\n    /**\n     * @private\n     * @param {CanvasRenderingContext2D} ctx Context to render on\n     */\n    _renderOverlay: function(ctx) {\n      this._renderBackgroundOrOverlay(ctx, 'overlay');\n    },\n\n    /**\n     * Returns coordinates of a center of canvas.\n     * Returned value is an object with top and left properties\n     * @return {Object} object with \"top\" and \"left\" number values\n     */\n    getCenter: function () {\n      return {\n        top: this.height / 2,\n        left: this.width / 2\n      };\n    },\n\n    /**\n     * Centers object horizontally in the canvas\n     * @param {fabric.Object} object Object to center horizontally\n     * @return {fabric.Canvas} thisArg\n     */\n    centerObjectH: function (object) {\n      return this._centerObject(object, new fabric.Point(this.getCenter().left, object.getCenterPoint().y));\n    },\n\n    /**\n     * Centers object vertically in the canvas\n     * @param {fabric.Object} object Object to center vertically\n     * @return {fabric.Canvas} thisArg\n     * @chainable\n     */\n    centerObjectV: function (object) {\n      return this._centerObject(object, new fabric.Point(object.getCenterPoint().x, this.getCenter().top));\n    },\n\n    /**\n     * Centers object vertically and horizontally in the canvas\n     * @param {fabric.Object} object Object to center vertically and horizontally\n     * @return {fabric.Canvas} thisArg\n     * @chainable\n     */\n    centerObject: function(object) {\n      var center = this.getCenter();\n\n      return this._centerObject(object, new fabric.Point(center.left, center.top));\n    },\n\n    /**\n     * Centers object vertically and horizontally in the viewport\n     * @param {fabric.Object} object Object to center vertically and horizontally\n     * @return {fabric.Canvas} thisArg\n     * @chainable\n     */\n    viewportCenterObject: function(object) {\n      var vpCenter = this.getVpCenter();\n\n      return this._centerObject(object, vpCenter);\n    },\n\n    /**\n     * Centers object horizontally in the viewport, object.top is unchanged\n     * @param {fabric.Object} object Object to center vertically and horizontally\n     * @return {fabric.Canvas} thisArg\n     * @chainable\n     */\n    viewportCenterObjectH: function(object) {\n      var vpCenter = this.getVpCenter();\n      this._centerObject(object, new fabric.Point(vpCenter.x, object.getCenterPoint().y));\n      return this;\n    },\n\n    /**\n     * Centers object Vertically in the viewport, object.top is unchanged\n     * @param {fabric.Object} object Object to center vertically and horizontally\n     * @return {fabric.Canvas} thisArg\n     * @chainable\n     */\n    viewportCenterObjectV: function(object) {\n      var vpCenter = this.getVpCenter();\n\n      return this._centerObject(object, new fabric.Point(object.getCenterPoint().x, vpCenter.y));\n    },\n\n    /**\n     * Calculate the point in canvas that correspond to the center of actual viewport.\n     * @return {fabric.Point} vpCenter, viewport center\n     * @chainable\n     */\n    getVpCenter: function() {\n      var center = this.getCenter(),\n          iVpt = invertTransform(this.viewportTransform);\n      return transformPoint({ x: center.left, y: center.top }, iVpt);\n    },\n\n    /**\n     * @private\n     * @param {fabric.Object} object Object to center\n     * @param {fabric.Point} center Center point\n     * @return {fabric.Canvas} thisArg\n     * @chainable\n     */\n    _centerObject: function(object, center) {\n      object.setPositionByOrigin(center, 'center', 'center');\n      object.setCoords();\n      this.renderOnAddRemove && this.requestRenderAll();\n      return this;\n    },\n\n    /**\n     * Returs dataless JSON representation of canvas\n     * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output\n     * @return {String} json string\n     */\n    toDatalessJSON: function (propertiesToInclude) {\n      return this.toDatalessObject(propertiesToInclude);\n    },\n\n    /**\n     * Returns object representation of canvas\n     * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output\n     * @return {Object} object representation of an instance\n     */\n    toObject: function (propertiesToInclude) {\n      return this._toObjectMethod('toObject', propertiesToInclude);\n    },\n\n    /**\n     * Returns dataless object representation of canvas\n     * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output\n     * @return {Object} object representation of an instance\n     */\n    toDatalessObject: function (propertiesToInclude) {\n      return this._toObjectMethod('toDatalessObject', propertiesToInclude);\n    },\n\n    /**\n     * @private\n     */\n    _toObjectMethod: function (methodName, propertiesToInclude) {\n\n      var clipPath = this.clipPath, data = {\n        version: fabric.version,\n        objects: this._toObjects(methodName, propertiesToInclude),\n      };\n      if (clipPath) {\n        clipPath = clipPath.toObject(propertiesToInclude);\n      }\n      extend(data, this.__serializeBgOverlay(methodName, propertiesToInclude));\n\n      fabric.util.populateWithProperties(this, data, propertiesToInclude);\n\n      return data;\n    },\n\n    /**\n     * @private\n     */\n    _toObjects: function(methodName, propertiesToInclude) {\n      return this._objects.filter(function(object) {\n        return !object.excludeFromExport;\n      }).map(function(instance) {\n        return this._toObject(instance, methodName, propertiesToInclude);\n      }, this);\n    },\n\n    /**\n     * @private\n     */\n    _toObject: function(instance, methodName, propertiesToInclude) {\n      var originalValue;\n\n      if (!this.includeDefaultValues) {\n        originalValue = instance.includeDefaultValues;\n        instance.includeDefaultValues = false;\n      }\n\n      var object = instance[methodName](propertiesToInclude);\n      if (!this.includeDefaultValues) {\n        instance.includeDefaultValues = originalValue;\n      }\n      return object;\n    },\n\n    /**\n     * @private\n     */\n    __serializeBgOverlay: function(methodName, propertiesToInclude) {\n      var data = { }, bgImage = this.backgroundImage, overlay = this.overlayImage;\n\n      if (this.backgroundColor) {\n        data.background = this.backgroundColor.toObject\n          ? this.backgroundColor.toObject(propertiesToInclude)\n          : this.backgroundColor;\n      }\n\n      if (this.overlayColor) {\n        data.overlay = this.overlayColor.toObject\n          ? this.overlayColor.toObject(propertiesToInclude)\n          : this.overlayColor;\n      }\n      if (bgImage && !bgImage.excludeFromExport) {\n        data.backgroundImage = this._toObject(bgImage, methodName, propertiesToInclude);\n      }\n      if (overlay && !overlay.excludeFromExport) {\n        data.overlayImage = this._toObject(overlay, methodName, propertiesToInclude);\n      }\n\n      return data;\n    },\n\n    /* _TO_SVG_START_ */\n    /**\n     * When true, getSvgTransform() will apply the StaticCanvas.viewportTransform to the SVG transformation. When true,\n     * a zoomed canvas will then produce zoomed SVG output.\n     * @type Boolean\n     * @default\n     */\n    svgViewportTransformation: true,\n\n    /**\n     * Returns SVG representation of canvas\n     * @function\n     * @param {Object} [options] Options object for SVG output\n     * @param {Boolean} [options.suppressPreamble=false] If true xml tag is not included\n     * @param {Object} [options.viewBox] SVG viewbox object\n     * @param {Number} [options.viewBox.x] x-cooridnate of viewbox\n     * @param {Number} [options.viewBox.y] y-coordinate of viewbox\n     * @param {Number} [options.viewBox.width] Width of viewbox\n     * @param {Number} [options.viewBox.height] Height of viewbox\n     * @param {String} [options.encoding=UTF-8] Encoding of SVG output\n     * @param {String} [options.width] desired width of svg with or without units\n     * @param {String} [options.height] desired height of svg with or without units\n     * @param {Function} [reviver] Method for further parsing of svg elements, called after each fabric object converted into svg representation.\n     * @return {String} SVG string\n     * @tutorial {@link http://fabricjs.com/fabric-intro-part-3#serialization}\n     * @see {@link http://jsfiddle.net/fabricjs/jQ3ZZ/|jsFiddle demo}\n     * @example <caption>Normal SVG output</caption>\n     * var svg = canvas.toSVG();\n     * @example <caption>SVG output without preamble (without &lt;?xml ../>)</caption>\n     * var svg = canvas.toSVG({suppressPreamble: true});\n     * @example <caption>SVG output with viewBox attribute</caption>\n     * var svg = canvas.toSVG({\n     *   viewBox: {\n     *     x: 100,\n     *     y: 100,\n     *     width: 200,\n     *     height: 300\n     *   }\n     * });\n     * @example <caption>SVG output with different encoding (default: UTF-8)</caption>\n     * var svg = canvas.toSVG({encoding: 'ISO-8859-1'});\n     * @example <caption>Modify SVG output with reviver function</caption>\n     * var svg = canvas.toSVG(null, function(svg) {\n     *   return svg.replace('stroke-dasharray: ; stroke-linecap: butt; stroke-linejoin: miter; stroke-miterlimit: 10; ', '');\n     * });\n     */\n    toSVG: function(options, reviver) {\n      options || (options = { });\n      options.reviver = reviver;\n      var markup = [];\n\n      this._setSVGPreamble(markup, options);\n      this._setSVGHeader(markup, options);\n\n      this._setSVGBgOverlayColor(markup, 'backgroundColor');\n      this._setSVGBgOverlayImage(markup, 'backgroundImage', reviver);\n      if (this.clipPath) {\n        markup.push('<g clip-path=\"url(#' + this.clipPath.clipPathId + ')\" >\\n');\n      }\n      this._setSVGObjects(markup, reviver);\n      if (this.clipPath) {\n        markup.push('</g>\\n');\n      }\n      this._setSVGBgOverlayColor(markup, 'overlayColor');\n      this._setSVGBgOverlayImage(markup, 'overlayImage', reviver);\n\n      markup.push('</svg>');\n\n      return markup.join('');\n    },\n\n    /**\n     * @private\n     */\n    _setSVGPreamble: function(markup, options) {\n      if (options.suppressPreamble) {\n        return;\n      }\n      markup.push(\n        '<?xml version=\"1.0\" encoding=\"', (options.encoding || 'UTF-8'), '\" standalone=\"no\" ?>\\n',\n        '<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.1//EN\" ',\n        '\"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\">\\n'\n      );\n    },\n\n    /**\n     * @private\n     */\n    _setSVGHeader: function(markup, options) {\n      var width = options.width || this.width,\n          height = options.height || this.height,\n          vpt, viewBox = 'viewBox=\"0 0 ' + this.width + ' ' + this.height + '\" ',\n          NUM_FRACTION_DIGITS = fabric.Object.NUM_FRACTION_DIGITS;\n\n      if (options.viewBox) {\n        viewBox = 'viewBox=\"' +\n                options.viewBox.x + ' ' +\n                options.viewBox.y + ' ' +\n                options.viewBox.width + ' ' +\n                options.viewBox.height + '\" ';\n      }\n      else {\n        if (this.svgViewportTransformation) {\n          vpt = this.viewportTransform;\n          viewBox = 'viewBox=\"' +\n                  toFixed(-vpt[4] / vpt[0], NUM_FRACTION_DIGITS) + ' ' +\n                  toFixed(-vpt[5] / vpt[3], NUM_FRACTION_DIGITS) + ' ' +\n                  toFixed(this.width / vpt[0], NUM_FRACTION_DIGITS) + ' ' +\n                  toFixed(this.height / vpt[3], NUM_FRACTION_DIGITS) + '\" ';\n        }\n      }\n\n      markup.push(\n        '<svg ',\n        'xmlns=\"http://www.w3.org/2000/svg\" ',\n        'xmlns:xlink=\"http://www.w3.org/1999/xlink\" ',\n        'version=\"1.1\" ',\n        'width=\"', width, '\" ',\n        'height=\"', height, '\" ',\n        viewBox,\n        'xml:space=\"preserve\">\\n',\n        '<desc>Created with Fabric.js ', fabric.version, '</desc>\\n',\n        '<defs>\\n',\n        this.createSVGFontFacesMarkup(),\n        this.createSVGRefElementsMarkup(),\n        this.createSVGClipPathMarkup(options),\n        '</defs>\\n'\n      );\n    },\n\n    createSVGClipPathMarkup: function(options) {\n      var clipPath = this.clipPath;\n      if (clipPath) {\n        clipPath.clipPathId = 'CLIPPATH_' + fabric.Object.__uid++;\n        return  '<clipPath id=\"' + clipPath.clipPathId + '\" >\\n' +\n          this.clipPath.toClipPathSVG(options.reviver) +\n          '</clipPath>\\n';\n      }\n      return '';\n    },\n\n    /**\n     * Creates markup containing SVG referenced elements like patterns, gradients etc.\n     * @return {String}\n     */\n    createSVGRefElementsMarkup: function() {\n      var _this = this,\n          markup = ['backgroundColor', 'overlayColor'].map(function(prop) {\n            var fill = _this[prop];\n            if (fill && fill.toLive) {\n              return fill.toSVG(_this, false);\n            }\n          });\n      return markup.join('');\n    },\n\n    /**\n     * Creates markup containing SVG font faces,\n     * font URLs for font faces must be collected by developers\n     * and are not extracted from the DOM by fabricjs\n     * @param {Array} objects Array of fabric objects\n     * @return {String}\n     */\n    createSVGFontFacesMarkup: function() {\n      var markup = '', fontList = { }, obj, fontFamily,\n          style, row, rowIndex, _char, charIndex, i, len,\n          fontPaths = fabric.fontPaths, objects = this._objects;\n\n      for (i = 0, len = objects.length; i < len; i++) {\n        obj = objects[i];\n        fontFamily = obj.fontFamily;\n        if (obj.type.indexOf('text') === -1 || fontList[fontFamily] || !fontPaths[fontFamily]) {\n          continue;\n        }\n        fontList[fontFamily] = true;\n        if (!obj.styles) {\n          continue;\n        }\n        style = obj.styles;\n        for (rowIndex in style) {\n          row = style[rowIndex];\n          for (charIndex in row) {\n            _char = row[charIndex];\n            fontFamily = _char.fontFamily;\n            if (!fontList[fontFamily] && fontPaths[fontFamily]) {\n              fontList[fontFamily] = true;\n            }\n          }\n        }\n      }\n\n      for (var j in fontList) {\n        markup += [\n          '\\t\\t@font-face {\\n',\n          '\\t\\t\\tfont-family: \\'', j, '\\';\\n',\n          '\\t\\t\\tsrc: url(\\'', fontPaths[j], '\\');\\n',\n          '\\t\\t}\\n'\n        ].join('');\n      }\n\n      if (markup) {\n        markup = [\n          '\\t<style type=\"text/css\">',\n          '<![CDATA[\\n',\n          markup,\n          ']]>',\n          '</style>\\n'\n        ].join('');\n      }\n\n      return markup;\n    },\n\n    /**\n     * @private\n     */\n    _setSVGObjects: function(markup, reviver) {\n      var instance, i, len, objects = this._objects;\n      for (i = 0, len = objects.length; i < len; i++) {\n        instance = objects[i];\n        if (instance.excludeFromExport) {\n          continue;\n        }\n        this._setSVGObject(markup, instance, reviver);\n      }\n    },\n\n    /**\n     * @private\n     */\n    _setSVGObject: function(markup, instance, reviver) {\n      markup.push(instance.toSVG(reviver));\n    },\n\n    /**\n     * @private\n     */\n    _setSVGBgOverlayImage: function(markup, property, reviver) {\n      if (this[property] && !this[property].excludeFromExport && this[property].toSVG) {\n        markup.push(this[property].toSVG(reviver));\n      }\n    },\n\n    /**\n     * @private\n     */\n    _setSVGBgOverlayColor: function(markup, property) {\n      var filler = this[property], vpt = this.viewportTransform, finalWidth = this.width / vpt[0],\n          finalHeight = this.height / vpt[3];\n      if (!filler) {\n        return;\n      }\n      if (filler.toLive) {\n        var repeat = filler.repeat;\n        markup.push(\n          '<rect transform=\"translate(', finalWidth / 2, ',', finalHeight / 2, ')\"',\n          ' x=\"', filler.offsetX - finalWidth / 2, '\" y=\"', filler.offsetY - finalHeight / 2, '\" ',\n          'width=\"',\n          (repeat === 'repeat-y' || repeat === 'no-repeat'\n            ? filler.source.width\n            : finalWidth ),\n          '\" height=\"',\n          (repeat === 'repeat-x' || repeat === 'no-repeat'\n            ? filler.source.height\n            : finalHeight),\n          '\" fill=\"url(#SVGID_' + filler.id + ')\"',\n          '></rect>\\n'\n        );\n      }\n      else {\n        markup.push(\n          '<rect x=\"0\" y=\"0\" width=\"100%\" height=\"100%\" ',\n          'fill=\"', this[property], '\"',\n          '></rect>\\n'\n        );\n      }\n    },\n    /* _TO_SVG_END_ */\n\n    /**\n     * Moves an object or the objects of a multiple selection\n     * to the bottom of the stack of drawn objects\n     * @param {fabric.Object} object Object to send to back\n     * @return {fabric.Canvas} thisArg\n     * @chainable\n     */\n    sendToBack: function (object) {\n      if (!object) {\n        return this;\n      }\n      var activeSelection = this._activeObject,\n          i, obj, objs;\n      if (object === activeSelection && object.type === 'activeSelection') {\n        objs = activeSelection._objects;\n        for (i = objs.length; i--;) {\n          obj = objs[i];\n          removeFromArray(this._objects, obj);\n          this._objects.unshift(obj);\n        }\n      }\n      else {\n        removeFromArray(this._objects, object);\n        this._objects.unshift(object);\n      }\n      this.renderOnAddRemove && this.requestRenderAll();\n      return this;\n    },\n\n    /**\n     * Moves an object or the objects of a multiple selection\n     * to the top of the stack of drawn objects\n     * @param {fabric.Object} object Object to send\n     * @return {fabric.Canvas} thisArg\n     * @chainable\n     */\n    bringToFront: function (object) {\n      if (!object) {\n        return this;\n      }\n      var activeSelection = this._activeObject,\n          i, obj, objs;\n      if (object === activeSelection && object.type === 'activeSelection') {\n        objs = activeSelection._objects;\n        for (i = 0; i < objs.length; i++) {\n          obj = objs[i];\n          removeFromArray(this._objects, obj);\n          this._objects.push(obj);\n        }\n      }\n      else {\n        removeFromArray(this._objects, object);\n        this._objects.push(object);\n      }\n      this.renderOnAddRemove && this.requestRenderAll();\n      return this;\n    },\n\n    /**\n     * Moves an object or a selection down in stack of drawn objects\n     * An optional paramter, intersecting allowes to move the object in behind\n     * the first intersecting object. Where intersection is calculated with\n     * bounding box. If no intersection is found, there will not be change in the\n     * stack.\n     * @param {fabric.Object} object Object to send\n     * @param {Boolean} [intersecting] If `true`, send object behind next lower intersecting object\n     * @return {fabric.Canvas} thisArg\n     * @chainable\n     */\n    sendBackwards: function (object, intersecting) {\n      if (!object) {\n        return this;\n      }\n      var activeSelection = this._activeObject,\n          i, obj, idx, newIdx, objs, objsMoved = 0;\n\n      if (object === activeSelection && object.type === 'activeSelection') {\n        objs = activeSelection._objects;\n        for (i = 0; i < objs.length; i++) {\n          obj = objs[i];\n          idx = this._objects.indexOf(obj);\n          if (idx > 0 + objsMoved) {\n            newIdx = idx - 1;\n            removeFromArray(this._objects, obj);\n            this._objects.splice(newIdx, 0, obj);\n          }\n          objsMoved++;\n        }\n      }\n      else {\n        idx = this._objects.indexOf(object);\n        if (idx !== 0) {\n          // if object is not on the bottom of stack\n          newIdx = this._findNewLowerIndex(object, idx, intersecting);\n          removeFromArray(this._objects, object);\n          this._objects.splice(newIdx, 0, object);\n        }\n      }\n      this.renderOnAddRemove && this.requestRenderAll();\n      return this;\n    },\n\n    /**\n     * @private\n     */\n    _findNewLowerIndex: function(object, idx, intersecting) {\n      var newIdx, i;\n\n      if (intersecting) {\n        newIdx = idx;\n\n        // traverse down the stack looking for the nearest intersecting object\n        for (i = idx - 1; i >= 0; --i) {\n\n          var isIntersecting = object.intersectsWithObject(this._objects[i]) ||\n                               object.isContainedWithinObject(this._objects[i]) ||\n                               this._objects[i].isContainedWithinObject(object);\n\n          if (isIntersecting) {\n            newIdx = i;\n            break;\n          }\n        }\n      }\n      else {\n        newIdx = idx - 1;\n      }\n\n      return newIdx;\n    },\n\n    /**\n     * Moves an object or a selection up in stack of drawn objects\n     * An optional paramter, intersecting allowes to move the object in front\n     * of the first intersecting object. Where intersection is calculated with\n     * bounding box. If no intersection is found, there will not be change in the\n     * stack.\n     * @param {fabric.Object} object Object to send\n     * @param {Boolean} [intersecting] If `true`, send object in front of next upper intersecting object\n     * @return {fabric.Canvas} thisArg\n     * @chainable\n     */\n    bringForward: function (object, intersecting) {\n      if (!object) {\n        return this;\n      }\n      var activeSelection = this._activeObject,\n          i, obj, idx, newIdx, objs, objsMoved = 0;\n\n      if (object === activeSelection && object.type === 'activeSelection') {\n        objs = activeSelection._objects;\n        for (i = objs.length; i--;) {\n          obj = objs[i];\n          idx = this._objects.indexOf(obj);\n          if (idx < this._objects.length - 1 - objsMoved) {\n            newIdx = idx + 1;\n            removeFromArray(this._objects, obj);\n            this._objects.splice(newIdx, 0, obj);\n          }\n          objsMoved++;\n        }\n      }\n      else {\n        idx = this._objects.indexOf(object);\n        if (idx !== this._objects.length - 1) {\n          // if object is not on top of stack (last item in an array)\n          newIdx = this._findNewUpperIndex(object, idx, intersecting);\n          removeFromArray(this._objects, object);\n          this._objects.splice(newIdx, 0, object);\n        }\n      }\n      this.renderOnAddRemove && this.requestRenderAll();\n      return this;\n    },\n\n    /**\n     * @private\n     */\n    _findNewUpperIndex: function(object, idx, intersecting) {\n      var newIdx, i, len;\n\n      if (intersecting) {\n        newIdx = idx;\n\n        // traverse up the stack looking for the nearest intersecting object\n        for (i = idx + 1, len = this._objects.length; i < len; ++i) {\n\n          var isIntersecting = object.intersectsWithObject(this._objects[i]) ||\n                               object.isContainedWithinObject(this._objects[i]) ||\n                               this._objects[i].isContainedWithinObject(object);\n\n          if (isIntersecting) {\n            newIdx = i;\n            break;\n          }\n        }\n      }\n      else {\n        newIdx = idx + 1;\n      }\n\n      return newIdx;\n    },\n\n    /**\n     * Moves an object to specified level in stack of drawn objects\n     * @param {fabric.Object} object Object to send\n     * @param {Number} index Position to move to\n     * @return {fabric.Canvas} thisArg\n     * @chainable\n     */\n    moveTo: function (object, index) {\n      removeFromArray(this._objects, object);\n      this._objects.splice(index, 0, object);\n      return this.renderOnAddRemove && this.requestRenderAll();\n    },\n\n    /**\n     * Clears a canvas element and dispose objects\n     * @return {fabric.Canvas} thisArg\n     * @chainable\n     */\n    dispose: function () {\n      // cancel eventually ongoing renders\n      if (this.isRendering) {\n        fabric.util.cancelAnimFrame(this.isRendering);\n        this.isRendering = 0;\n      }\n      this.forEachObject(function(object) {\n        object.dispose && object.dispose();\n      });\n      this._objects = [];\n      if (this.backgroundImage && this.backgroundImage.dispose) {\n        this.backgroundImage.dispose();\n      }\n      this.backgroundImage = null;\n      if (this.overlayImage && this.overlayImage.dispose) {\n        this.overlayImage.dispose();\n      }\n      this.overlayImage = null;\n      this._iTextInstances = null;\n      this.contextContainer = null;\n      fabric.util.cleanUpJsdomNode(this.lowerCanvasEl);\n      this.lowerCanvasEl = undefined;\n      return this;\n    },\n\n    /**\n     * Returns a string representation of an instance\n     * @return {String} string representation of an instance\n     */\n    toString: function () {\n      return '#<fabric.Canvas (' + this.complexity() + '): ' +\n               '{ objects: ' + this._objects.length + ' }>';\n    }\n  });\n\n  extend(fabric.StaticCanvas.prototype, fabric.Observable);\n  extend(fabric.StaticCanvas.prototype, fabric.Collection);\n  extend(fabric.StaticCanvas.prototype, fabric.DataURLExporter);\n\n  extend(fabric.StaticCanvas, /** @lends fabric.StaticCanvas */ {\n\n    /**\n     * @static\n     * @type String\n     * @default\n     */\n    EMPTY_JSON: '{\"objects\": [], \"background\": \"white\"}',\n\n    /**\n     * Provides a way to check support of some of the canvas methods\n     * (either those of HTMLCanvasElement itself, or rendering context)\n     *\n     * @param {String} methodName Method to check support for;\n     *                            Could be one of \"getImageData\", \"toDataURL\", \"toDataURLWithQuality\" or \"setLineDash\"\n     * @return {Boolean | null} `true` if method is supported (or at least exists),\n     *                          `null` if canvas element or context can not be initialized\n     */\n    supports: function (methodName) {\n      var el = createCanvasElement();\n\n      if (!el || !el.getContext) {\n        return null;\n      }\n\n      var ctx = el.getContext('2d');\n      if (!ctx) {\n        return null;\n      }\n\n      switch (methodName) {\n\n        case 'getImageData':\n          return typeof ctx.getImageData !== 'undefined';\n\n        case 'setLineDash':\n          return typeof ctx.setLineDash !== 'undefined';\n\n        case 'toDataURL':\n          return typeof el.toDataURL !== 'undefined';\n\n        case 'toDataURLWithQuality':\n          try {\n            el.toDataURL('image/jpeg', 0);\n            return true;\n          }\n          catch (e) { }\n          return false;\n\n        default:\n          return null;\n      }\n    }\n  });\n\n  /**\n   * Returns JSON representation of canvas\n   * @function\n   * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output\n   * @return {String} JSON string\n   * @tutorial {@link http://fabricjs.com/fabric-intro-part-3#serialization}\n   * @see {@link http://jsfiddle.net/fabricjs/pec86/|jsFiddle demo}\n   * @example <caption>JSON without additional properties</caption>\n   * var json = canvas.toJSON();\n   * @example <caption>JSON with additional properties included</caption>\n   * var json = canvas.toJSON(['lockMovementX', 'lockMovementY', 'lockRotation', 'lockScalingX', 'lockScalingY', 'lockUniScaling']);\n   * @example <caption>JSON without default values</caption>\n   * canvas.includeDefaultValues = false;\n   * var json = canvas.toJSON();\n   */\n  fabric.StaticCanvas.prototype.toJSON = fabric.StaticCanvas.prototype.toObject;\n\n  if (fabric.isLikelyNode) {\n    fabric.StaticCanvas.prototype.createPNGStream = function() {\n      var impl = getNodeCanvas(this.lowerCanvasEl);\n      return impl && impl.createPNGStream();\n    };\n    fabric.StaticCanvas.prototype.createJPEGStream = function(opts) {\n      var impl = getNodeCanvas(this.lowerCanvasEl);\n      return impl && impl.createJPEGStream(opts);\n    };\n  }\n})();\n\n\n/**\n * BaseBrush class\n * @class fabric.BaseBrush\n * @see {@link http://fabricjs.com/freedrawing|Freedrawing demo}\n */\nfabric.BaseBrush = fabric.util.createClass(/** @lends fabric.BaseBrush.prototype */ {\n\n  /**\n   * Color of a brush\n   * @type String\n   * @default\n   */\n  color: 'rgb(0, 0, 0)',\n\n  /**\n   * Width of a brush, has to be a Number, no string literals\n   * @type Number\n   * @default\n   */\n  width: 1,\n\n  /**\n   * Shadow object representing shadow of this shape.\n   * <b>Backwards incompatibility note:</b> This property replaces \"shadowColor\" (String), \"shadowOffsetX\" (Number),\n   * \"shadowOffsetY\" (Number) and \"shadowBlur\" (Number) since v1.2.12\n   * @type fabric.Shadow\n   * @default\n   */\n  shadow: null,\n\n  /**\n   * Line endings style of a brush (one of \"butt\", \"round\", \"square\")\n   * @type String\n   * @default\n   */\n  strokeLineCap: 'round',\n\n  /**\n   * Corner style of a brush (one of \"bevel\", \"round\", \"miter\")\n   * @type String\n   * @default\n   */\n  strokeLineJoin: 'round',\n\n  /**\n   * Maximum miter length (used for strokeLineJoin = \"miter\") of a brush's\n   * @type Number\n   * @default\n   */\n  strokeMiterLimit:         10,\n\n  /**\n   * Stroke Dash Array.\n   * @type Array\n   * @default\n   */\n  strokeDashArray: null,\n\n  /**\n   * Sets shadow of an object\n   * @param {Object|String} [options] Options object or string (e.g. \"2px 2px 10px rgba(0,0,0,0.2)\")\n   * @return {fabric.Object} thisArg\n   * @chainable\n   */\n  setShadow: function(options) {\n    this.shadow = new fabric.Shadow(options);\n    return this;\n  },\n\n  /**\n   * Sets brush styles\n   * @private\n   */\n  _setBrushStyles: function() {\n    var ctx = this.canvas.contextTop;\n    ctx.strokeStyle = this.color;\n    ctx.lineWidth = this.width;\n    ctx.lineCap = this.strokeLineCap;\n    ctx.miterLimit = this.strokeMiterLimit;\n    ctx.lineJoin = this.strokeLineJoin;\n    if (fabric.StaticCanvas.supports('setLineDash')) {\n      ctx.setLineDash(this.strokeDashArray || []);\n    }\n  },\n\n  /**\n   * Sets the transformation on given context\n   * @param {RenderingContext2d} ctx context to render on\n   * @private\n   */\n  _saveAndTransform: function(ctx) {\n    var v = this.canvas.viewportTransform;\n    ctx.save();\n    ctx.transform(v[0], v[1], v[2], v[3], v[4], v[5]);\n  },\n\n  /**\n   * Sets brush shadow styles\n   * @private\n   */\n  _setShadow: function() {\n    if (!this.shadow) {\n      return;\n    }\n\n    var ctx = this.canvas.contextTop,\n        zoom = this.canvas.getZoom();\n\n    ctx.shadowColor = this.shadow.color;\n    ctx.shadowBlur = this.shadow.blur * zoom;\n    ctx.shadowOffsetX = this.shadow.offsetX * zoom;\n    ctx.shadowOffsetY = this.shadow.offsetY * zoom;\n  },\n\n  /**\n   * Removes brush shadow styles\n   * @private\n   */\n  _resetShadow: function() {\n    var ctx = this.canvas.contextTop;\n\n    ctx.shadowColor = '';\n    ctx.shadowBlur = ctx.shadowOffsetX = ctx.shadowOffsetY = 0;\n  }\n});\n\n\n(function() {\n\n  /**\n   * PencilBrush class\n   * @class fabric.PencilBrush\n   * @extends fabric.BaseBrush\n   */\n  fabric.PencilBrush = fabric.util.createClass(fabric.BaseBrush, /** @lends fabric.PencilBrush.prototype */ {\n\n    /**\n     * Constructor\n     * @param {fabric.Canvas} canvas\n     * @return {fabric.PencilBrush} Instance of a pencil brush\n     */\n    initialize: function(canvas) {\n      this.canvas = canvas;\n      this._points = [];\n    },\n\n    /**\n     * Invoked inside on mouse down and mouse move\n     * @param {Object} pointer\n     */\n    _drawSegment: function (ctx, p1, p2) {\n      var midPoint = p1.midPointFrom(p2);\n      ctx.quadraticCurveTo(p1.x, p1.y, midPoint.x, midPoint.y);\n      return midPoint;\n    },\n\n    /**\n     * Inovoked on mouse down\n     * @param {Object} pointer\n     */\n    onMouseDown: function(pointer) {\n      this._prepareForDrawing(pointer);\n      // capture coordinates immediately\n      // this allows to draw dots (when movement never occurs)\n      this._captureDrawingPath(pointer);\n      this._render();\n    },\n\n    /**\n     * Inovoked on mouse move\n     * @param {Object} pointer\n     */\n    onMouseMove: function(pointer) {\n      if (this._captureDrawingPath(pointer) && this._points.length > 1) {\n        if (this.needsFullRender) {\n          // redraw curve\n          // clear top canvas\n          this.canvas.clearContext(this.canvas.contextTop);\n          this._render();\n        }\n        else {\n          var points = this._points, length = points.length, ctx = this.canvas.contextTop;\n          // draw the curve update\n          this._saveAndTransform(ctx);\n          if (this.oldEnd) {\n            ctx.beginPath();\n            ctx.moveTo(this.oldEnd.x, this.oldEnd.y);\n          }\n          this.oldEnd = this._drawSegment(ctx, points[length - 2], points[length - 1], true);\n          ctx.stroke();\n          ctx.restore();\n        }\n      }\n    },\n\n    /**\n     * Invoked on mouse up\n     */\n    onMouseUp: function() {\n      this.oldEnd = undefined;\n      this._finalizeAndAddPath();\n    },\n\n    /**\n     * @private\n     * @param {Object} pointer Actual mouse position related to the canvas.\n     */\n    _prepareForDrawing: function(pointer) {\n\n      var p = new fabric.Point(pointer.x, pointer.y);\n\n      this._reset();\n      this._addPoint(p);\n      this.canvas.contextTop.moveTo(p.x, p.y);\n    },\n\n    /**\n     * @private\n     * @param {fabric.Point} point Point to be added to points array\n     */\n    _addPoint: function(point) {\n      if (this._points.length > 1 && point.eq(this._points[this._points.length - 1])) {\n        return false;\n      }\n      this._points.push(point);\n      return true;\n    },\n\n    /**\n     * Clear points array and set contextTop canvas style.\n     * @private\n     */\n    _reset: function() {\n      this._points.length = 0;\n      this._setBrushStyles();\n      var color = new fabric.Color(this.color);\n      this.needsFullRender = (color.getAlpha() < 1);\n      this._setShadow();\n    },\n\n    /**\n     * @private\n     * @param {Object} pointer Actual mouse position related to the canvas.\n     */\n    _captureDrawingPath: function(pointer) {\n      var pointerPoint = new fabric.Point(pointer.x, pointer.y);\n      return this._addPoint(pointerPoint);\n    },\n\n    /**\n     * Draw a smooth path on the topCanvas using quadraticCurveTo\n     * @private\n     */\n    _render: function() {\n      var ctx  = this.canvas.contextTop, i, len,\n          p1 = this._points[0],\n          p2 = this._points[1];\n\n      this._saveAndTransform(ctx);\n      ctx.beginPath();\n      //if we only have 2 points in the path and they are the same\n      //it means that the user only clicked the canvas without moving the mouse\n      //then we should be drawing a dot. A path isn't drawn between two identical dots\n      //that's why we set them apart a bit\n      if (this._points.length === 2 && p1.x === p2.x && p1.y === p2.y) {\n        var width = this.width / 1000;\n        p1 = new fabric.Point(p1.x, p1.y);\n        p2 = new fabric.Point(p2.x, p2.y);\n        p1.x -= width;\n        p2.x += width;\n      }\n      ctx.moveTo(p1.x, p1.y);\n\n      for (i = 1, len = this._points.length; i < len; i++) {\n        // we pick the point between pi + 1 & pi + 2 as the\n        // end point and p1 as our control point.\n        this._drawSegment(ctx, p1, p2);\n        p1 = this._points[i];\n        p2 = this._points[i + 1];\n      }\n      // Draw last line as a straight line while\n      // we wait for the next point to be able to calculate\n      // the bezier control point\n      ctx.lineTo(p1.x, p1.y);\n      ctx.stroke();\n      ctx.restore();\n    },\n\n    /**\n     * Converts points to SVG path\n     * @param {Array} points Array of points\n     * @return {String} SVG path\n     */\n    convertPointsToSVGPath: function(points) {\n      var path = [], i, width = this.width / 1000,\n          p1 = new fabric.Point(points[0].x, points[0].y),\n          p2 = new fabric.Point(points[1].x, points[1].y),\n          len = points.length, multSignX = 1, multSignY = 1, manyPoints = len > 2;\n\n      if (manyPoints) {\n        multSignX = points[2].x < p2.x ? -1 : points[2].x === p2.x ? 0 : 1;\n        multSignY = points[2].y < p2.y ? -1 : points[2].y === p2.y ? 0 : 1;\n      }\n      path.push('M ', p1.x - multSignX * width, ' ', p1.y - multSignY * width, ' ');\n      for (i = 1; i < len; i++) {\n        if (!p1.eq(p2)) {\n          var midPoint = p1.midPointFrom(p2);\n          // p1 is our bezier control point\n          // midpoint is our endpoint\n          // start point is p(i-1) value.\n          path.push('Q ', p1.x, ' ', p1.y, ' ', midPoint.x, ' ', midPoint.y, ' ');\n        }\n        p1 = points[i];\n        if ((i + 1) < points.length) {\n          p2 = points[i + 1];\n        }\n      }\n      if (manyPoints) {\n        multSignX = p1.x > points[i - 2].x ? 1 : p1.x === points[i - 2].x ? 0 : -1;\n        multSignY = p1.y > points[i - 2].y ? 1 : p1.y === points[i - 2].y ? 0 : -1;\n      }\n      path.push('L ', p1.x + multSignX * width, ' ', p1.y + multSignY * width);\n      return path;\n    },\n\n    /**\n     * Creates fabric.Path object to add on canvas\n     * @param {String} pathData Path data\n     * @return {fabric.Path} Path to add on canvas\n     */\n    createPath: function(pathData) {\n      var path = new fabric.Path(pathData, {\n        fill: null,\n        stroke: this.color,\n        strokeWidth: this.width,\n        strokeLineCap: this.strokeLineCap,\n        strokeMiterLimit: this.strokeMiterLimit,\n        strokeLineJoin: this.strokeLineJoin,\n        strokeDashArray: this.strokeDashArray,\n      });\n      var position = new fabric.Point(path.left + path.width / 2, path.top + path.height / 2);\n      position = path.translateToGivenOrigin(position, 'center', 'center', path.originX, path.originY);\n      path.top = position.y;\n      path.left = position.x;\n      if (this.shadow) {\n        this.shadow.affectStroke = true;\n        path.setShadow(this.shadow);\n      }\n\n      return path;\n    },\n\n    /**\n     * On mouseup after drawing the path on contextTop canvas\n     * we use the points captured to create an new fabric path object\n     * and add it to the fabric canvas.\n     */\n    _finalizeAndAddPath: function() {\n      var ctx = this.canvas.contextTop;\n      ctx.closePath();\n\n      var pathData = this.convertPointsToSVGPath(this._points).join('');\n      if (pathData === 'M 0 0 Q 0 0 0 0 L 0 0') {\n        // do not create 0 width/height paths, as they are\n        // rendered inconsistently across browsers\n        // Firefox 4, for example, renders a dot,\n        // whereas Chrome 10 renders nothing\n        this.canvas.requestRenderAll();\n        return;\n      }\n\n      var path = this.createPath(pathData);\n      this.canvas.clearContext(this.canvas.contextTop);\n      this.canvas.add(path);\n      this.canvas.renderAll();\n      path.setCoords();\n      this._resetShadow();\n\n\n      // fire event 'path' created\n      this.canvas.fire('path:created', { path: path });\n    }\n  });\n})();\n\n\n/**\n * CircleBrush class\n * @class fabric.CircleBrush\n */\nfabric.CircleBrush = fabric.util.createClass(fabric.BaseBrush, /** @lends fabric.CircleBrush.prototype */ {\n\n  /**\n   * Width of a brush\n   * @type Number\n   * @default\n   */\n  width: 10,\n\n  /**\n   * Constructor\n   * @param {fabric.Canvas} canvas\n   * @return {fabric.CircleBrush} Instance of a circle brush\n   */\n  initialize: function(canvas) {\n    this.canvas = canvas;\n    this.points = [];\n  },\n\n  /**\n   * Invoked inside on mouse down and mouse move\n   * @param {Object} pointer\n   */\n  drawDot: function(pointer) {\n    var point = this.addPoint(pointer),\n        ctx = this.canvas.contextTop;\n    this._saveAndTransform(ctx);\n    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    ctx.restore();\n  },\n\n  /**\n   * Invoked on mouse down\n   */\n  onMouseDown: function(pointer) {\n    this.points.length = 0;\n    this.canvas.clearContext(this.canvas.contextTop);\n    this._setShadow();\n    this.drawDot(pointer);\n  },\n\n  /**\n   * Render the full state of the brush\n   * @private\n   */\n  _render: function() {\n    var ctx  = this.canvas.contextTop, i, len,\n        points = this.points, point;\n    this._saveAndTransform(ctx);\n    for (i = 0, len = points.length; i < len; i++) {\n      point = points[i];\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    ctx.restore();\n  },\n\n  /**\n   * Invoked on mouse move\n   * @param {Object} pointer\n   */\n  onMouseMove: function(pointer) {\n    this.drawDot(pointer);\n  },\n\n  /**\n   * Invoked on mouse up\n   */\n  onMouseUp: function() {\n    var originalRenderOnAddRemove = this.canvas.renderOnAddRemove, i, len;\n    this.canvas.renderOnAddRemove = false;\n\n    var circles = [];\n\n    for (i = 0, len = this.points.length; i < len; i++) {\n      var point = this.points[i],\n          circle = new fabric.Circle({\n            radius: point.radius,\n            left: point.x,\n            top: point.y,\n            originX: 'center',\n            originY: 'center',\n            fill: point.fill\n          });\n\n      this.shadow && circle.setShadow(this.shadow);\n\n      circles.push(circle);\n    }\n    var group = new fabric.Group(circles);\n    group.canvas = this.canvas;\n\n    this.canvas.add(group);\n    this.canvas.fire('path:created', { path: group });\n\n    this.canvas.clearContext(this.canvas.contextTop);\n    this._resetShadow();\n    this.canvas.renderOnAddRemove = originalRenderOnAddRemove;\n    this.canvas.requestRenderAll();\n  },\n\n  /**\n   * @param {Object} pointer\n   * @return {fabric.Point} Just added pointer point\n   */\n  addPoint: function(pointer) {\n    var pointerPoint = new fabric.Point(pointer.x, pointer.y),\n\n        circleRadius = fabric.util.getRandomInt(\n          Math.max(0, this.width - 20), this.width + 20) / 2,\n\n        circleColor = new fabric.Color(this.color)\n          .setAlpha(fabric.util.getRandomInt(0, 100) / 100)\n          .toRgba();\n\n    pointerPoint.radius = circleRadius;\n    pointerPoint.fill = circleColor;\n\n    this.points.push(pointerPoint);\n\n    return pointerPoint;\n  }\n});\n\n\n/**\n * SprayBrush class\n * @class fabric.SprayBrush\n */\nfabric.SprayBrush = fabric.util.createClass( fabric.BaseBrush, /** @lends fabric.SprayBrush.prototype */ {\n\n  /**\n   * Width of a spray\n   * @type Number\n   * @default\n   */\n  width:              10,\n\n  /**\n   * Density of a spray (number of dots per chunk)\n   * @type Number\n   * @default\n   */\n  density:            20,\n\n  /**\n   * Width of spray dots\n   * @type Number\n   * @default\n   */\n  dotWidth:           1,\n\n  /**\n   * Width variance of spray dots\n   * @type Number\n   * @default\n   */\n  dotWidthVariance:   1,\n\n  /**\n   * Whether opacity of a dot should be random\n   * @type Boolean\n   * @default\n   */\n  randomOpacity:        false,\n\n  /**\n   * Whether overlapping dots (rectangles) should be removed (for performance reasons)\n   * @type Boolean\n   * @default\n   */\n  optimizeOverlapping:  true,\n\n  /**\n   * Constructor\n   * @param {fabric.Canvas} canvas\n   * @return {fabric.SprayBrush} Instance of a spray brush\n   */\n  initialize: function(canvas) {\n    this.canvas = canvas;\n    this.sprayChunks = [];\n  },\n\n  /**\n   * Invoked on mouse down\n   * @param {Object} pointer\n   */\n  onMouseDown: function(pointer) {\n    this.sprayChunks.length = 0;\n    this.canvas.clearContext(this.canvas.contextTop);\n    this._setShadow();\n\n    this.addSprayChunk(pointer);\n    this.render(this.sprayChunkPoints);\n  },\n\n  /**\n   * Invoked on mouse move\n   * @param {Object} pointer\n   */\n  onMouseMove: function(pointer) {\n    this.addSprayChunk(pointer);\n    this.render(this.sprayChunkPoints);\n  },\n\n  /**\n   * Invoked on mouse up\n   */\n  onMouseUp: function() {\n    var originalRenderOnAddRemove = this.canvas.renderOnAddRemove;\n    this.canvas.renderOnAddRemove = false;\n\n    var rects = [];\n\n    for (var i = 0, ilen = this.sprayChunks.length; i < ilen; i++) {\n      var sprayChunk = this.sprayChunks[i];\n\n      for (var j = 0, jlen = sprayChunk.length; j < jlen; j++) {\n\n        var rect = new fabric.Rect({\n          width: sprayChunk[j].width,\n          height: sprayChunk[j].width,\n          left: sprayChunk[j].x + 1,\n          top: sprayChunk[j].y + 1,\n          originX: 'center',\n          originY: 'center',\n          fill: this.color\n        });\n        rects.push(rect);\n      }\n    }\n\n    if (this.optimizeOverlapping) {\n      rects = this._getOptimizedRects(rects);\n    }\n\n    var group = new fabric.Group(rects);\n    this.shadow && group.setShadow(this.shadow);\n    this.canvas.add(group);\n    this.canvas.fire('path:created', { path: group });\n\n    this.canvas.clearContext(this.canvas.contextTop);\n    this._resetShadow();\n    this.canvas.renderOnAddRemove = originalRenderOnAddRemove;\n    this.canvas.requestRenderAll();\n  },\n\n  /**\n   * @private\n   * @param {Array} rects\n   */\n  _getOptimizedRects: function(rects) {\n\n    // avoid creating duplicate rects at the same coordinates\n    var uniqueRects = { }, key, i, len;\n\n    for (i = 0, len = rects.length; i < len; i++) {\n      key = rects[i].left + '' + rects[i].top;\n      if (!uniqueRects[key]) {\n        uniqueRects[key] = rects[i];\n      }\n    }\n    var uniqueRectsArray = [];\n    for (key in uniqueRects) {\n      uniqueRectsArray.push(uniqueRects[key]);\n    }\n\n    return uniqueRectsArray;\n  },\n\n  /**\n   * Render new chunk of spray brush\n   */\n  render: function(sprayChunk) {\n    var ctx = this.canvas.contextTop, i, len;\n    ctx.fillStyle = this.color;\n\n    this._saveAndTransform(ctx);\n\n    for (i = 0, len = sprayChunk.length; i < len; i++) {\n      var point = sprayChunk[i];\n      if (typeof point.opacity !== 'undefined') {\n        ctx.globalAlpha = point.opacity;\n      }\n      ctx.fillRect(point.x, point.y, point.width, point.width);\n    }\n    ctx.restore();\n  },\n\n  /**\n   * Render all spray chunks\n   */\n  _render: function() {\n    var ctx = this.canvas.contextTop, i, ilen;\n    ctx.fillStyle = this.color;\n\n    this._saveAndTransform(ctx);\n\n    for (i = 0, ilen = this.sprayChunks.length; i < ilen; i++) {\n      this.render(this.sprayChunks[i]);\n    }\n    ctx.restore();\n  },\n\n  /**\n   * @param {Object} pointer\n   */\n  addSprayChunk: function(pointer) {\n    this.sprayChunkPoints = [];\n\n    var x, y, width, radius = this.width / 2, i;\n\n    for (i = 0; i < this.density; i++) {\n\n      x = fabric.util.getRandomInt(pointer.x - radius, pointer.x + radius);\n      y = fabric.util.getRandomInt(pointer.y - radius, pointer.y + radius);\n\n      if (this.dotWidthVariance) {\n        width = fabric.util.getRandomInt(\n          // bottom clamp width to 1\n          Math.max(1, this.dotWidth - this.dotWidthVariance),\n          this.dotWidth + this.dotWidthVariance);\n      }\n      else {\n        width = this.dotWidth;\n      }\n\n      var point = new fabric.Point(x, y);\n      point.width = width;\n\n      if (this.randomOpacity) {\n        point.opacity = fabric.util.getRandomInt(0, 100) / 100;\n      }\n\n      this.sprayChunkPoints.push(point);\n    }\n\n    this.sprayChunks.push(this.sprayChunkPoints);\n  }\n});\n\n\n/**\n * PatternBrush class\n * @class fabric.PatternBrush\n * @extends fabric.BaseBrush\n */\nfabric.PatternBrush = fabric.util.createClass(fabric.PencilBrush, /** @lends fabric.PatternBrush.prototype */ {\n\n  getPatternSrc: function() {\n\n    var dotWidth = 20,\n        dotDistance = 5,\n        patternCanvas = fabric.util.createCanvasElement(),\n        patternCtx = patternCanvas.getContext('2d');\n\n    patternCanvas.width = patternCanvas.height = dotWidth + dotDistance;\n\n    patternCtx.fillStyle = this.color;\n    patternCtx.beginPath();\n    patternCtx.arc(dotWidth / 2, dotWidth / 2, dotWidth / 2, 0, Math.PI * 2, false);\n    patternCtx.closePath();\n    patternCtx.fill();\n\n    return patternCanvas;\n  },\n\n  getPatternSrcFunction: function() {\n    return String(this.getPatternSrc).replace('this.color', '\"' + this.color + '\"');\n  },\n\n  /**\n   * Creates \"pattern\" instance property\n   */\n  getPattern: function() {\n    return this.canvas.contextTop.createPattern(this.source || this.getPatternSrc(), 'repeat');\n  },\n\n  /**\n   * Sets brush styles\n   */\n  _setBrushStyles: function() {\n    this.callSuper('_setBrushStyles');\n    this.canvas.contextTop.strokeStyle = this.getPattern();\n  },\n\n  /**\n   * Creates path\n   */\n  createPath: function(pathData) {\n    var path = this.callSuper('createPath', pathData),\n        topLeft = path._getLeftTopCoords().scalarAdd(path.strokeWidth / 2);\n\n    path.stroke = new fabric.Pattern({\n      source: this.source || this.getPatternSrcFunction(),\n      offsetX: -topLeft.x,\n      offsetY: -topLeft.y\n    });\n    return path;\n  }\n});\n\n\n(function() {\n\n  var getPointer = fabric.util.getPointer,\n      degreesToRadians = fabric.util.degreesToRadians,\n      radiansToDegrees = fabric.util.radiansToDegrees,\n      atan2 = Math.atan2,\n      abs = Math.abs,\n      supportLineDash = fabric.StaticCanvas.supports('setLineDash'),\n\n      STROKE_OFFSET = 0.5;\n\n  /**\n   * Canvas class\n   * @class fabric.Canvas\n   * @extends fabric.StaticCanvas\n   * @tutorial {@link http://fabricjs.com/fabric-intro-part-1#canvas}\n   * @see {@link fabric.Canvas#initialize} for constructor definition\n   *\n   * @fires object:modified\n   * @fires object:rotated\n   * @fires object:scaled\n   * @fires object:moved\n   * @fires object:skewed\n   * @fires object:rotating\n   * @fires object:scaling\n   * @fires object:moving\n   * @fires object:skewing\n   * @fires object:selected this event is deprecated. use selection:created\n   *\n   * @fires before:transform\n   * @fires before:selection:cleared\n   * @fires selection:cleared\n   * @fires selection:updated\n   * @fires selection:created\n   *\n   * @fires path:created\n   * @fires mouse:down\n   * @fires mouse:move\n   * @fires mouse:up\n   * @fires mouse:down:before\n   * @fires mouse:move:before\n   * @fires mouse:up:before\n   * @fires mouse:over\n   * @fires mouse:out\n   * @fires mouse:dblclick\n   *\n   * @fires dragover\n   * @fires dragenter\n   * @fires dragleave\n   * @fires drop\n   *\n   */\n  fabric.Canvas = fabric.util.createClass(fabric.StaticCanvas, /** @lends fabric.Canvas.prototype */ {\n\n    /**\n     * Constructor\n     * @param {HTMLElement | String} el &lt;canvas> element to initialize instance on\n     * @param {Object} [options] Options object\n     * @return {Object} thisArg\n     */\n    initialize: function(el, options) {\n      options || (options = { });\n      this.renderAndResetBound = this.renderAndReset.bind(this);\n      this.requestRenderAllBound = this.requestRenderAll.bind(this);\n      this._initStatic(el, options);\n      this._initInteractive();\n      this._createCacheCanvas();\n    },\n\n    /**\n     * When true, objects can be transformed by one side (unproportionally)\n     * @type Boolean\n     * @default\n     */\n    uniScaleTransform:      false,\n\n    /**\n     * Indicates which key enable unproportional scaling\n     * values: 'altKey', 'shiftKey', 'ctrlKey'.\n     * If `null` or 'none' or any other string that is not a modifier key\n     * feature is disabled feature disabled.\n     * @since 1.6.2\n     * @type String\n     * @default\n     */\n    uniScaleKey:           'shiftKey',\n\n    /**\n     * When true, objects use center point as the origin of scale transformation.\n     * <b>Backwards incompatibility note:</b> This property replaces \"centerTransform\" (Boolean).\n     * @since 1.3.4\n     * @type Boolean\n     * @default\n     */\n    centeredScaling:        false,\n\n    /**\n     * When true, objects use center point as the origin of rotate transformation.\n     * <b>Backwards incompatibility note:</b> This property replaces \"centerTransform\" (Boolean).\n     * @since 1.3.4\n     * @type Boolean\n     * @default\n     */\n    centeredRotation:       false,\n\n    /**\n     * Indicates which key enable centered Transform\n     * values: 'altKey', 'shiftKey', 'ctrlKey'.\n     * If `null` or 'none' or any other string that is not a modifier key\n     * feature is disabled feature disabled.\n     * @since 1.6.2\n     * @type String\n     * @default\n     */\n    centeredKey:           'altKey',\n\n    /**\n     * Indicates which key enable alternate action on corner\n     * values: 'altKey', 'shiftKey', 'ctrlKey'.\n     * If `null` or 'none' or any other string that is not a modifier key\n     * feature is disabled feature disabled.\n     * @since 1.6.2\n     * @type String\n     * @default\n     */\n    altActionKey:           'shiftKey',\n\n    /**\n     * Indicates that canvas is interactive. This property should not be changed.\n     * @type Boolean\n     * @default\n     */\n    interactive:            true,\n\n    /**\n     * Indicates whether group selection should be enabled\n     * @type Boolean\n     * @default\n     */\n    selection:              true,\n\n    /**\n     * Indicates which key or keys enable multiple click selection\n     * Pass value as a string or array of strings\n     * values: 'altKey', 'shiftKey', 'ctrlKey'.\n     * If `null` or empty or containing any other string that is not a modifier key\n     * feature is disabled.\n     * @since 1.6.2\n     * @type String|Array\n     * @default\n     */\n    selectionKey:           'shiftKey',\n\n    /**\n     * Indicates which key enable alternative selection\n     * in case of target overlapping with active object\n     * values: 'altKey', 'shiftKey', 'ctrlKey'.\n     * For a series of reason that come from the general expectations on how\n     * things should work, this feature works only for preserveObjectStacking true.\n     * If `null` or 'none' or any other string that is not a modifier key\n     * feature is disabled.\n     * @since 1.6.5\n     * @type null|String\n     * @default\n     */\n    altSelectionKey:           null,\n\n    /**\n     * Color of selection\n     * @type String\n     * @default\n     */\n    selectionColor:         'rgba(100, 100, 255, 0.3)', // blue\n\n    /**\n     * Default dash array pattern\n     * If not empty the selection border is dashed\n     * @type Array\n     */\n    selectionDashArray:     [],\n\n    /**\n     * Color of the border of selection (usually slightly darker than color of selection itself)\n     * @type String\n     * @default\n     */\n    selectionBorderColor:   'rgba(255, 255, 255, 0.3)',\n\n    /**\n     * Width of a line used in object/group selection\n     * @type Number\n     * @default\n     */\n    selectionLineWidth:     1,\n\n    /**\n     * Select only shapes that are fully contained in the dragged selection rectangle.\n     * @type Boolean\n     * @default\n     */\n    selectionFullyContained: false,\n\n    /**\n     * Default cursor value used when hovering over an object on canvas\n     * @type String\n     * @default\n     */\n    hoverCursor:            'move',\n\n    /**\n     * Default cursor value used when moving an object on canvas\n     * @type String\n     * @default\n     */\n    moveCursor:             'move',\n\n    /**\n     * Default cursor value used for the entire canvas\n     * @type String\n     * @default\n     */\n    defaultCursor:          'default',\n\n    /**\n     * Cursor value used during free drawing\n     * @type String\n     * @default\n     */\n    freeDrawingCursor:      'crosshair',\n\n    /**\n     * Cursor value used for rotation point\n     * @type String\n     * @default\n     */\n    rotationCursor:         'crosshair',\n\n    /**\n     * Cursor value used for disabled elements ( corners with disabled action )\n     * @type String\n     * @since 2.0.0\n     * @default\n     */\n    notAllowedCursor:         'not-allowed',\n\n    /**\n     * Default element class that's given to wrapper (div) element of canvas\n     * @type String\n     * @default\n     */\n    containerClass:         'canvas-container',\n\n    /**\n     * When true, object detection happens on per-pixel basis rather than on per-bounding-box\n     * @type Boolean\n     * @default\n     */\n    perPixelTargetFind:     false,\n\n    /**\n     * Number of pixels around target pixel to tolerate (consider active) during object detection\n     * @type Number\n     * @default\n     */\n    targetFindTolerance:    0,\n\n    /**\n     * When true, target detection is skipped when hovering over canvas. This can be used to improve performance.\n     * @type Boolean\n     * @default\n     */\n    skipTargetFind:         false,\n\n    /**\n     * When true, mouse events on canvas (mousedown/mousemove/mouseup) result in free drawing.\n     * After mousedown, mousemove creates a shape,\n     * and then mouseup finalizes it and adds an instance of `fabric.Path` onto canvas.\n     * @tutorial {@link http://fabricjs.com/fabric-intro-part-4#free_drawing}\n     * @type Boolean\n     * @default\n     */\n    isDrawingMode:          false,\n\n    /**\n     * Indicates whether objects should remain in current stack position when selected.\n     * When false objects are brought to top and rendered as part of the selection group\n     * @type Boolean\n     * @default\n     */\n    preserveObjectStacking: false,\n\n    /**\n     * Indicates the angle that an object will lock to while rotating.\n     * @type Number\n     * @since 1.6.7\n     * @default\n     */\n    snapAngle: 0,\n\n    /**\n     * Indicates the distance from the snapAngle the rotation will lock to the snapAngle.\n     * When `null`, the snapThreshold will default to the snapAngle.\n     * @type null|Number\n     * @since 1.6.7\n     * @default\n     */\n    snapThreshold: null,\n\n    /**\n     * Indicates if the right click on canvas can output the context menu or not\n     * @type Boolean\n     * @since 1.6.5\n     * @default\n     */\n    stopContextMenu: false,\n\n    /**\n     * Indicates if the canvas can fire right click events\n     * @type Boolean\n     * @since 1.6.5\n     * @default\n     */\n    fireRightClick: false,\n\n    /**\n     * Indicates if the canvas can fire middle click events\n     * @type Boolean\n     * @since 1.7.8\n     * @default\n     */\n    fireMiddleClick: false,\n\n    /**\n     * @private\n     */\n    _initInteractive: function() {\n      this._currentTransform = null;\n      this._groupSelector = null;\n      this._initWrapperElement();\n      this._createUpperCanvas();\n      this._initEventListeners();\n\n      this._initRetinaScaling();\n\n      this.freeDrawingBrush = fabric.PencilBrush && new fabric.PencilBrush(this);\n\n      this.calcOffset();\n    },\n\n    /**\n     * Divides objects in two groups, one to render immediately\n     * and one to render as activeGroup.\n     * @return {Array} objects to render immediately and pushes the other in the activeGroup.\n     */\n    _chooseObjectsToRender: function() {\n      var activeObjects = this.getActiveObjects(),\n          object, objsToRender, activeGroupObjects;\n\n      if (activeObjects.length > 0 && !this.preserveObjectStacking) {\n        objsToRender = [];\n        activeGroupObjects = [];\n        for (var i = 0, length = this._objects.length; i < length; i++) {\n          object = this._objects[i];\n          if (activeObjects.indexOf(object) === -1 ) {\n            objsToRender.push(object);\n          }\n          else {\n            activeGroupObjects.push(object);\n          }\n        }\n        if (activeObjects.length > 1) {\n          this._activeObject._objects = activeGroupObjects;\n        }\n        objsToRender.push.apply(objsToRender, activeGroupObjects);\n      }\n      else {\n        objsToRender = this._objects;\n      }\n      return objsToRender;\n    },\n\n    /**\n     * Renders both the top canvas and the secondary container canvas.\n     * @return {fabric.Canvas} instance\n     * @chainable\n     */\n    renderAll: function () {\n      if (this.contextTopDirty && !this._groupSelector && !this.isDrawingMode) {\n        this.clearContext(this.contextTop);\n        this.contextTopDirty = false;\n      }\n      if (this.hasLostContext) {\n        this.renderTopLayer(this.contextTop);\n      }\n      var canvasToDrawOn = this.contextContainer;\n      this.renderCanvas(canvasToDrawOn, this._chooseObjectsToRender());\n      return this;\n    },\n\n    renderTopLayer: function(ctx) {\n      if (this.isDrawingMode && this._isCurrentlyDrawing) {\n        this.freeDrawingBrush && this.freeDrawingBrush._render();\n        this.contextTopDirty = true;\n      }\n      // we render the top context - last object\n      if (this.selection && this._groupSelector) {\n        this._drawSelection(ctx);\n        this.contextTopDirty = true;\n      }\n    },\n\n    /**\n     * Method to render only the top canvas.\n     * Also used to render the group selection box.\n     * @return {fabric.Canvas} thisArg\n     * @chainable\n     */\n    renderTop: function () {\n      var ctx = this.contextTop;\n      this.clearContext(ctx);\n      this.renderTopLayer(ctx);\n      this.fire('after:render');\n      return this;\n    },\n\n    /**\n     * Resets the current transform to its original values and chooses the type of resizing based on the event\n     * @private\n     */\n    _resetCurrentTransform: function() {\n      var t = this._currentTransform;\n\n      t.target.set({\n        scaleX: t.original.scaleX,\n        scaleY: t.original.scaleY,\n        skewX: t.original.skewX,\n        skewY: t.original.skewY,\n        left: t.original.left,\n        top: t.original.top\n      });\n\n      if (this._shouldCenterTransform(t.target)) {\n        if (t.originX !== 'center') {\n          if (t.originX === 'right') {\n            t.mouseXSign = -1;\n          }\n          else {\n            t.mouseXSign = 1;\n          }\n        }\n        if (t.originY !== 'center') {\n          if (t.originY === 'bottom') {\n            t.mouseYSign = -1;\n          }\n          else {\n            t.mouseYSign = 1;\n          }\n        }\n\n        t.originX = 'center';\n        t.originY = 'center';\n      }\n      else {\n        t.originX = t.original.originX;\n        t.originY = t.original.originY;\n      }\n    },\n\n    /**\n     * Checks if point is contained within an area of given object\n     * @param {Event} e Event object\n     * @param {fabric.Object} target Object to test against\n     * @param {Object} [point] x,y object of point coordinates we want to check.\n     * @return {Boolean} true if point is contained within an area of given object\n     */\n    containsPoint: function (e, target, point) {\n      var ignoreZoom = true,\n          pointer = point || this.getPointer(e, ignoreZoom),\n          xy;\n\n      if (target.group && target.group === this._activeObject && target.group.type === 'activeSelection') {\n        xy = this._normalizePointer(target.group, pointer);\n      }\n      else {\n        xy = { x: pointer.x, y: pointer.y };\n      }\n      // http://www.geog.ubc.ca/courses/klink/gis.notes/ncgia/u32.html\n      // http://idav.ucdavis.edu/~okreylos/TAship/Spring2000/PointInPolygon.html\n      return (target.containsPoint(xy) || target._findTargetCorner(pointer));\n    },\n\n    /**\n     * @private\n     */\n    _normalizePointer: function (object, pointer) {\n      var m = object.calcTransformMatrix(),\n          invertedM = fabric.util.invertTransform(m),\n          vptPointer = this.restorePointerVpt(pointer);\n      return fabric.util.transformPoint(vptPointer, invertedM);\n    },\n\n    /**\n     * Returns true if object is transparent at a certain location\n     * @param {fabric.Object} target Object to check\n     * @param {Number} x Left coordinate\n     * @param {Number} y Top coordinate\n     * @return {Boolean}\n     */\n    isTargetTransparent: function (target, x, y) {\n      if (target.shouldCache() && target._cacheCanvas) {\n        var normalizedPointer = this._normalizePointer(target, {x: x, y: y}),\n            targetRelativeX = target.cacheTranslationX + (normalizedPointer.x * target.zoomX),\n            targetRelativeY = target.cacheTranslationY + (normalizedPointer.y * target.zoomY);\n\n        var isTransparent = fabric.util.isTransparent(\n          target._cacheContext, targetRelativeX, targetRelativeY, this.targetFindTolerance);\n\n        return isTransparent;\n      }\n\n      var ctx = this.contextCache,\n          originalColor = target.selectionBackgroundColor, v = this.viewportTransform;\n\n      target.selectionBackgroundColor = '';\n\n      this.clearContext(ctx);\n\n      ctx.save();\n      ctx.transform(v[0], v[1], v[2], v[3], v[4], v[5]);\n      target.render(ctx);\n      ctx.restore();\n\n      target === this._activeObject && target._renderControls(ctx, {\n        hasBorders: false,\n        transparentCorners: false\n      }, {\n        hasBorders: false,\n      });\n\n      target.selectionBackgroundColor = originalColor;\n\n      var isTransparent = fabric.util.isTransparent(\n        ctx, x, y, this.targetFindTolerance);\n\n      return isTransparent;\n    },\n\n    /**\n     * takes an event and determins if selection key has been pressed\n     * @private\n     * @param {Event} e Event object\n     */\n    _isSelectionKeyPressed: function(e) {\n      var selectionKeyPressed = false;\n\n      if (Object.prototype.toString.call(this.selectionKey) === '[object Array]') {\n        selectionKeyPressed = !!this.selectionKey.find(function(key) { return e[key] === true; });\n      }\n      else {\n        selectionKeyPressed = e[this.selectionKey];\n      }\n\n      return selectionKeyPressed;\n    },\n\n    /**\n     * @private\n     * @param {Event} e Event object\n     * @param {fabric.Object} target\n     */\n    _shouldClearSelection: function (e, target) {\n      var activeObjects = this.getActiveObjects(),\n          activeObject = this._activeObject;\n\n      return (\n        !target\n        ||\n        (target &&\n          activeObject &&\n          activeObjects.length > 1 &&\n          activeObjects.indexOf(target) === -1 &&\n          activeObject !== target &&\n          !this._isSelectionKeyPressed(e))\n        ||\n        (target && !target.evented)\n        ||\n        (target &&\n          !target.selectable &&\n          activeObject &&\n          activeObject !== target)\n      );\n    },\n\n    /**\n     * centeredScaling from object can't override centeredScaling from canvas.\n     * this should be fixed, since object setting should take precedence over canvas.\n     * @private\n     * @param {fabric.Object} target\n     */\n    _shouldCenterTransform: function (target) {\n      if (!target) {\n        return;\n      }\n\n      var t = this._currentTransform,\n          centerTransform;\n\n      if (t.action === 'scale' || t.action === 'scaleX' || t.action === 'scaleY') {\n        centerTransform = this.centeredScaling || target.centeredScaling;\n      }\n      else if (t.action === 'rotate') {\n        centerTransform = this.centeredRotation || target.centeredRotation;\n      }\n\n      return centerTransform ? !t.altKey : t.altKey;\n    },\n\n    /**\n     * @private\n     */\n    _getOriginFromCorner: function(target, corner) {\n      var origin = {\n        x: target.originX,\n        y: target.originY\n      };\n\n      if (corner === 'ml' || corner === 'tl' || corner === 'bl') {\n        origin.x = 'right';\n      }\n      else if (corner === 'mr' || corner === 'tr' || corner === 'br') {\n        origin.x = 'left';\n      }\n\n      if (corner === 'tl' || corner === 'mt' || corner === 'tr') {\n        origin.y = 'bottom';\n      }\n      else if (corner === 'bl' || corner === 'mb' || corner === 'br') {\n        origin.y = 'top';\n      }\n\n      return origin;\n    },\n\n    /**\n     * @private\n     */\n    _getActionFromCorner: function(target, corner, e) {\n      if (!corner) {\n        return 'drag';\n      }\n\n      switch (corner) {\n        case 'mtr':\n          return 'rotate';\n        case 'ml':\n        case 'mr':\n          return e[this.altActionKey] ? 'skewY' : 'scaleX';\n        case 'mt':\n        case 'mb':\n          return e[this.altActionKey] ? 'skewX' : 'scaleY';\n        default:\n          return 'scale';\n      }\n    },\n\n    /**\n     * @private\n     * @param {Event} e Event object\n     * @param {fabric.Object} target\n     */\n    _setupCurrentTransform: function (e, target) {\n      if (!target) {\n        return;\n      }\n\n      var pointer = this.getPointer(e),\n          corner = target._findTargetCorner(this.getPointer(e, true)),\n          action = this._getActionFromCorner(target, corner, e),\n          origin = this._getOriginFromCorner(target, corner);\n\n      this._currentTransform = {\n        target: target,\n        action: action,\n        corner: corner,\n        scaleX: target.scaleX,\n        scaleY: target.scaleY,\n        skewX: target.skewX,\n        skewY: target.skewY,\n        // used by transation\n        offsetX: pointer.x - target.left,\n        offsetY: pointer.y - target.top,\n        originX: origin.x,\n        originY: origin.y,\n        ex: pointer.x,\n        ey: pointer.y,\n        lastX: pointer.x,\n        lastY: pointer.y,\n        // unsure they are usefull anymore.\n        // left: target.left,\n        // top: target.top,\n        theta: degreesToRadians(target.angle),\n        // end of unsure\n        width: target.width * target.scaleX,\n        mouseXSign: 1,\n        mouseYSign: 1,\n        shiftKey: e.shiftKey,\n        altKey: e[this.centeredKey],\n        original: fabric.util.saveObjectTransform(target),\n      };\n\n      this._currentTransform.original.originX = origin.x;\n      this._currentTransform.original.originY = origin.y;\n\n      this._resetCurrentTransform();\n      this._beforeTransform(e);\n    },\n\n    /**\n     * Translates object by \"setting\" its left/top\n     * @private\n     * @param {Number} x pointer's x coordinate\n     * @param {Number} y pointer's y coordinate\n     * @return {Boolean} true if the translation occurred\n     */\n    _translateObject: function (x, y) {\n      var transform = this._currentTransform,\n          target = transform.target,\n          newLeft = x - transform.offsetX,\n          newTop = y - transform.offsetY,\n          moveX = !target.get('lockMovementX') && target.left !== newLeft,\n          moveY = !target.get('lockMovementY') && target.top !== newTop;\n\n      moveX && target.set('left', newLeft);\n      moveY && target.set('top', newTop);\n      return moveX || moveY;\n    },\n\n    /**\n     * Check if we are increasing a positive skew or lower it,\n     * checking mouse direction and pressed corner.\n     * @private\n     */\n    _changeSkewTransformOrigin: function(mouseMove, t, by) {\n      var property = 'originX', origins = { 0: 'center' },\n          skew = t.target.skewX, originA = 'left', originB = 'right',\n          corner = t.corner === 'mt' || t.corner === 'ml' ? 1 : -1,\n          flipSign = 1;\n\n      mouseMove = mouseMove > 0 ? 1 : -1;\n      if (by === 'y') {\n        skew = t.target.skewY;\n        originA = 'top';\n        originB = 'bottom';\n        property = 'originY';\n      }\n      origins[-1] = originA;\n      origins[1] = originB;\n\n      t.target.flipX && (flipSign *= -1);\n      t.target.flipY && (flipSign *= -1);\n\n      if (skew === 0) {\n        t.skewSign = -corner * mouseMove * flipSign;\n        t[property] = origins[-mouseMove];\n      }\n      else {\n        skew = skew > 0 ? 1 : -1;\n        t.skewSign = skew;\n        t[property] = origins[skew * corner * flipSign];\n      }\n    },\n\n    /**\n     * Skew object by mouse events\n     * @private\n     * @param {Number} x pointer's x coordinate\n     * @param {Number} y pointer's y coordinate\n     * @param {String} by Either 'x' or 'y'\n     * @return {Boolean} true if the skewing occurred\n     */\n    _skewObject: function (x, y, by) {\n      var t = this._currentTransform,\n          target = t.target, skewed = false,\n          lockSkewingX = target.get('lockSkewingX'),\n          lockSkewingY = target.get('lockSkewingY');\n\n      if ((lockSkewingX && by === 'x') || (lockSkewingY && by === 'y')) {\n        return false;\n      }\n\n      // Get the constraint point\n      var center = target.getCenterPoint(),\n          actualMouseByCenter = target.toLocalPoint(new fabric.Point(x, y), 'center', 'center')[by],\n          lastMouseByCenter = target.toLocalPoint(new fabric.Point(t.lastX, t.lastY), 'center', 'center')[by],\n          actualMouseByOrigin, constraintPosition, dim = target._getTransformedDimensions();\n\n      this._changeSkewTransformOrigin(actualMouseByCenter - lastMouseByCenter, t, by);\n      actualMouseByOrigin = target.toLocalPoint(new fabric.Point(x, y), t.originX, t.originY)[by];\n      constraintPosition = target.translateToOriginPoint(center, t.originX, t.originY);\n      // Actually skew the object\n      skewed = this._setObjectSkew(actualMouseByOrigin, t, by, dim);\n      t.lastX = x;\n      t.lastY = y;\n      // Make sure the constraints apply\n      target.setPositionByOrigin(constraintPosition, t.originX, t.originY);\n      return skewed;\n    },\n\n    /**\n     * Set object skew\n     * @private\n     * @return {Boolean} true if the skewing occurred\n     */\n    _setObjectSkew: function(localMouse, transform, by, _dim) {\n      var target = transform.target, newValue, skewed = false,\n          skewSign = transform.skewSign, newDim, dimNoSkew,\n          otherBy, _otherBy, _by, newDimMouse, skewX, skewY;\n\n      if (by === 'x') {\n        otherBy = 'y';\n        _otherBy = 'Y';\n        _by = 'X';\n        skewX = 0;\n        skewY = target.skewY;\n      }\n      else {\n        otherBy = 'x';\n        _otherBy = 'X';\n        _by = 'Y';\n        skewX = target.skewX;\n        skewY = 0;\n      }\n\n      dimNoSkew = target._getTransformedDimensions(skewX, skewY);\n      newDimMouse = 2 * Math.abs(localMouse) - dimNoSkew[by];\n      if (newDimMouse <= 2) {\n        newValue = 0;\n      }\n      else {\n        newValue = skewSign * Math.atan((newDimMouse / target['scale' + _by]) /\n                                        (dimNoSkew[otherBy] / target['scale' + _otherBy]));\n        newValue = fabric.util.radiansToDegrees(newValue);\n      }\n      skewed = target['skew' + _by] !== newValue;\n      target.set('skew' + _by, newValue);\n      if (target['skew' + _otherBy] !== 0) {\n        newDim = target._getTransformedDimensions();\n        newValue = (_dim[otherBy] / newDim[otherBy]) * target['scale' + _otherBy];\n        target.set('scale' + _otherBy, newValue);\n      }\n      return skewed;\n    },\n\n    /**\n     * Scales object by invoking its scaleX/scaleY methods\n     * @private\n     * @param {Number} x pointer's x coordinate\n     * @param {Number} y pointer's y coordinate\n     * @param {String} by Either 'x' or 'y' - specifies dimension constraint by which to scale an object.\n     *                    When not provided, an object is scaled by both dimensions equally\n     * @return {Boolean} true if the scaling occurred\n     */\n    _scaleObject: function (x, y, by) {\n      var t = this._currentTransform,\n          target = t.target,\n          lockScalingX = target.lockScalingX,\n          lockScalingY = target.lockScalingY,\n          lockScalingFlip = target.lockScalingFlip;\n\n      if (lockScalingX && lockScalingY) {\n        return false;\n      }\n\n      // Get the constraint point\n      var constraintPosition = target.translateToOriginPoint(target.getCenterPoint(), t.originX, t.originY),\n          localMouse = target.toLocalPoint(new fabric.Point(x, y), t.originX, t.originY),\n          dim = target._getTransformedDimensions(), scaled = false;\n\n      this._setLocalMouse(localMouse, t);\n\n      // Actually scale the object\n      scaled = this._setObjectScale(localMouse, t, lockScalingX, lockScalingY, by, lockScalingFlip, dim);\n\n      // Make sure the constraints apply\n      target.setPositionByOrigin(constraintPosition, t.originX, t.originY);\n      return scaled;\n    },\n\n    /**\n     * @private\n     * @return {Boolean} true if the scaling occurred\n     */\n    _setObjectScale: function(localMouse, transform, lockScalingX, lockScalingY, by, lockScalingFlip, _dim) {\n      var target = transform.target, forbidScalingX = false, forbidScalingY = false, scaled = false,\n          changeX, changeY, scaleX, scaleY;\n\n      scaleX = localMouse.x * target.scaleX / _dim.x;\n      scaleY = localMouse.y * target.scaleY / _dim.y;\n      changeX = target.scaleX !== scaleX;\n      changeY = target.scaleY !== scaleY;\n\n      if (lockScalingFlip && scaleX <= 0 && scaleX < target.scaleX) {\n        forbidScalingX = true;\n        localMouse.x = 0;\n      }\n\n      if (lockScalingFlip && scaleY <= 0 && scaleY < target.scaleY) {\n        forbidScalingY = true;\n        localMouse.y = 0;\n      }\n\n      if (by === 'equally' && !lockScalingX && !lockScalingY) {\n        scaled = this._scaleObjectEqually(localMouse, target, transform, _dim);\n      }\n      else if (!by) {\n        forbidScalingX || lockScalingX || (target.set('scaleX', scaleX) && (scaled = scaled || changeX));\n        forbidScalingY || lockScalingY || (target.set('scaleY', scaleY) && (scaled = scaled || changeY));\n      }\n      else if (by === 'x' && !target.get('lockUniScaling')) {\n        forbidScalingX || lockScalingX || (target.set('scaleX', scaleX) && (scaled = scaled || changeX));\n      }\n      else if (by === 'y' && !target.get('lockUniScaling')) {\n        forbidScalingY || lockScalingY || (target.set('scaleY', scaleY) && (scaled = scaled || changeY));\n      }\n      transform.newScaleX = scaleX;\n      transform.newScaleY = scaleY;\n      forbidScalingX || forbidScalingY || this._flipObject(transform, by);\n      return scaled;\n    },\n\n    /**\n     * @private\n     * @return {Boolean} true if the scaling occurred\n     */\n    _scaleObjectEqually: function(localMouse, target, transform, _dim) {\n\n      var dist = localMouse.y + localMouse.x,\n          lastDist = _dim.y * transform.original.scaleY / target.scaleY +\n                     _dim.x * transform.original.scaleX / target.scaleX,\n          scaled, signX = localMouse.x < 0 ? -1 : 1,\n          signY = localMouse.y < 0 ? -1 : 1;\n\n      // We use transform.scaleX/Y instead of target.scaleX/Y\n      // because the object may have a min scale and we'll loose the proportions\n      transform.newScaleX = signX * Math.abs(transform.original.scaleX * dist / lastDist);\n      transform.newScaleY = signY * Math.abs(transform.original.scaleY * dist / lastDist);\n      scaled = transform.newScaleX !== target.scaleX || transform.newScaleY !== target.scaleY;\n      target.set('scaleX', transform.newScaleX);\n      target.set('scaleY', transform.newScaleY);\n      return scaled;\n    },\n\n    /**\n     * @private\n     */\n    _flipObject: function(transform, by) {\n      if (transform.newScaleX < 0 && by !== 'y') {\n        if (transform.originX === 'left') {\n          transform.originX = 'right';\n        }\n        else if (transform.originX === 'right') {\n          transform.originX = 'left';\n        }\n      }\n\n      if (transform.newScaleY < 0 && by !== 'x') {\n        if (transform.originY === 'top') {\n          transform.originY = 'bottom';\n        }\n        else if (transform.originY === 'bottom') {\n          transform.originY = 'top';\n        }\n      }\n    },\n\n    /**\n     * @private\n     */\n    _setLocalMouse: function(localMouse, t) {\n      var target = t.target, zoom = this.getZoom(),\n          padding = target.padding / zoom;\n\n      if (t.originX === 'right') {\n        localMouse.x *= -1;\n      }\n      else if (t.originX === 'center') {\n        localMouse.x *= t.mouseXSign * 2;\n        if (localMouse.x < 0) {\n          t.mouseXSign = -t.mouseXSign;\n        }\n      }\n\n      if (t.originY === 'bottom') {\n        localMouse.y *= -1;\n      }\n      else if (t.originY === 'center') {\n        localMouse.y *= t.mouseYSign * 2;\n        if (localMouse.y < 0) {\n          t.mouseYSign = -t.mouseYSign;\n        }\n      }\n\n      // adjust the mouse coordinates when dealing with padding\n      if (abs(localMouse.x) > padding) {\n        if (localMouse.x < 0) {\n          localMouse.x += padding;\n        }\n        else {\n          localMouse.x -= padding;\n        }\n      }\n      else { // mouse is within the padding, set to 0\n        localMouse.x = 0;\n      }\n\n      if (abs(localMouse.y) > padding) {\n        if (localMouse.y < 0) {\n          localMouse.y += padding;\n        }\n        else {\n          localMouse.y -= padding;\n        }\n      }\n      else {\n        localMouse.y = 0;\n      }\n    },\n\n    /**\n     * Rotates object by invoking its rotate method\n     * @private\n     * @param {Number} x pointer's x coordinate\n     * @param {Number} y pointer's y coordinate\n     * @return {Boolean} true if the rotation occurred\n     */\n    _rotateObject: function (x, y) {\n\n      var t = this._currentTransform,\n          target = t.target, constraintPosition,\n          constraintPosition = target.translateToOriginPoint(target.getCenterPoint(), t.originX, t.originY);\n\n      if (target.lockRotation) {\n        return false;\n      }\n\n      var lastAngle = atan2(t.ey - constraintPosition.y, t.ex - constraintPosition.x),\n          curAngle = atan2(y - constraintPosition.y, x - constraintPosition.x),\n          angle = radiansToDegrees(curAngle - lastAngle + t.theta),\n          hasRotated = true;\n\n      if (target.snapAngle > 0) {\n        var snapAngle  = target.snapAngle,\n            snapThreshold  = target.snapThreshold || snapAngle,\n            rightAngleLocked = Math.ceil(angle / snapAngle) * snapAngle,\n            leftAngleLocked = Math.floor(angle / snapAngle) * snapAngle;\n\n        if (Math.abs(angle - leftAngleLocked) < snapThreshold) {\n          angle = leftAngleLocked;\n        }\n        else if (Math.abs(angle - rightAngleLocked) < snapThreshold) {\n          angle = rightAngleLocked;\n        }\n      }\n\n      // normalize angle to positive value\n      if (angle < 0) {\n        angle = 360 + angle;\n      }\n      angle %= 360;\n\n      if (target.angle === angle) {\n        hasRotated = false;\n      }\n      else {\n        // rotation only happen here\n        target.angle = angle;\n        // Make sure the constraints apply\n        target.setPositionByOrigin(constraintPosition, t.originX, t.originY);\n      }\n\n      return hasRotated;\n    },\n\n    /**\n     * Set the cursor type of the canvas element\n     * @param {String} value Cursor type of the canvas element.\n     * @see http://www.w3.org/TR/css3-ui/#cursor\n     */\n    setCursor: function (value) {\n      this.upperCanvasEl.style.cursor = value;\n    },\n\n    /**\n     * @private\n     * @param {CanvasRenderingContext2D} ctx to draw the selection on\n     */\n    _drawSelection: function (ctx) {\n      var groupSelector = this._groupSelector,\n          left = groupSelector.left,\n          top = groupSelector.top,\n          aleft = abs(left),\n          atop = abs(top);\n\n      if (this.selectionColor) {\n        ctx.fillStyle = this.selectionColor;\n\n        ctx.fillRect(\n          groupSelector.ex - ((left > 0) ? 0 : -left),\n          groupSelector.ey - ((top > 0) ? 0 : -top),\n          aleft,\n          atop\n        );\n      }\n\n      if (!this.selectionLineWidth || !this.selectionBorderColor) {\n        return;\n      }\n      ctx.lineWidth = this.selectionLineWidth;\n      ctx.strokeStyle = this.selectionBorderColor;\n\n      // selection border\n      if (this.selectionDashArray.length > 1 && !supportLineDash) {\n\n        var px = groupSelector.ex + STROKE_OFFSET - ((left > 0) ? 0 : aleft),\n            py = groupSelector.ey + STROKE_OFFSET - ((top > 0) ? 0 : atop);\n\n        ctx.beginPath();\n\n        fabric.util.drawDashedLine(ctx, px, py, px + aleft, py, this.selectionDashArray);\n        fabric.util.drawDashedLine(ctx, px, py + atop - 1, px + aleft, py + atop - 1, this.selectionDashArray);\n        fabric.util.drawDashedLine(ctx, px, py, px, py + atop, this.selectionDashArray);\n        fabric.util.drawDashedLine(ctx, px + aleft - 1, py, px + aleft - 1, py + atop, this.selectionDashArray);\n\n        ctx.closePath();\n        ctx.stroke();\n      }\n      else {\n        fabric.Object.prototype._setLineDash.call(this, ctx, this.selectionDashArray);\n        ctx.strokeRect(\n          groupSelector.ex + STROKE_OFFSET - ((left > 0) ? 0 : aleft),\n          groupSelector.ey + STROKE_OFFSET - ((top > 0) ? 0 : atop),\n          aleft,\n          atop\n        );\n      }\n    },\n\n    /**\n     * Method that determines what object we are clicking on\n     * the skipGroup parameter is for internal use, is needed for shift+click action\n     * @param {Event} e mouse event\n     * @param {Boolean} skipGroup when true, activeGroup is skipped and only objects are traversed through\n     */\n    findTarget: function (e, skipGroup) {\n      if (this.skipTargetFind) {\n        return;\n      }\n\n      var ignoreZoom = true,\n          pointer = this.getPointer(e, ignoreZoom),\n          activeObject = this._activeObject,\n          aObjects = this.getActiveObjects(),\n          activeTarget, activeTargetSubs;\n\n      // first check current group (if one exists)\n      // active group does not check sub targets like normal groups.\n      // if active group just exits.\n      this.targets = [];\n\n      if (aObjects.length > 1 && !skipGroup && activeObject === this._searchPossibleTargets([activeObject], pointer)) {\n        return activeObject;\n      }\n      // if we hit the corner of an activeObject, let's return that.\n      if (aObjects.length === 1 && activeObject._findTargetCorner(pointer)) {\n        return activeObject;\n      }\n      if (aObjects.length === 1 &&\n        activeObject === this._searchPossibleTargets([activeObject], pointer)) {\n        if (!this.preserveObjectStacking) {\n          return activeObject;\n        }\n        else {\n          activeTarget = activeObject;\n          activeTargetSubs = this.targets;\n          this.targets = [];\n        }\n      }\n      var target = this._searchPossibleTargets(this._objects, pointer);\n      if (e[this.altSelectionKey] && target && activeTarget && target !== activeTarget) {\n        target = activeTarget;\n        this.targets = activeTargetSubs;\n      }\n      return target;\n    },\n\n    /**\n     * Checks point is inside the object.\n     * @param {Object} [pointer] x,y object of point coordinates we want to check.\n     * @param {fabric.Object} obj Object to test against\n     * @param {Object} [globalPointer] x,y object of point coordinates relative to canvas used to search per pixel target.\n     * @return {Boolean} true if point is contained within an area of given object\n     * @private\n     */\n    _checkTarget: function(pointer, obj, globalPointer) {\n      if (obj &&\n          obj.visible &&\n          obj.evented &&\n          this.containsPoint(null, obj, pointer)){\n        if ((this.perPixelTargetFind || obj.perPixelTargetFind) && !obj.isEditing) {\n          var isTransparent = this.isTargetTransparent(obj, globalPointer.x, globalPointer.y);\n          if (!isTransparent) {\n            return true;\n          }\n        }\n        else {\n          return true;\n        }\n      }\n    },\n\n    /**\n     * Function used to search inside objects an object that contains pointer in bounding box or that contains pointerOnCanvas when painted\n     * @param {Array} [objects] objects array to look into\n     * @param {Object} [pointer] x,y object of point coordinates we want to check.\n     * @return {fabric.Object} object that contains pointer\n     * @private\n     */\n    _searchPossibleTargets: function(objects, pointer) {\n      // Cache all targets where their bounding box contains point.\n      var target, i = objects.length, subTarget;\n      // Do not check for currently grouped objects, since we check the parent group itself.\n      // until we call this function specifically to search inside the activeGroup\n      while (i--) {\n        var objToCheck = objects[i];\n        var pointerToUse = objToCheck.group && objToCheck.group.type !== 'activeSelection' ?\n          this._normalizePointer(objToCheck.group, pointer) : pointer;\n        if (this._checkTarget(pointerToUse, objToCheck, pointer)) {\n          target = objects[i];\n          if (target.subTargetCheck && target instanceof fabric.Group) {\n            subTarget = this._searchPossibleTargets(target._objects, pointer);\n            subTarget && this.targets.push(subTarget);\n          }\n          break;\n        }\n      }\n      return target;\n    },\n\n    /**\n     * Returns pointer coordinates without the effect of the viewport\n     * @param {Object} pointer with \"x\" and \"y\" number values\n     * @return {Object} object with \"x\" and \"y\" number values\n     */\n    restorePointerVpt: function(pointer) {\n      return fabric.util.transformPoint(\n        pointer,\n        fabric.util.invertTransform(this.viewportTransform)\n      );\n    },\n\n    /**\n     * Returns pointer coordinates relative to canvas.\n     * Can return coordinates with or without viewportTransform.\n     * ignoreZoom false gives back coordinates that represent\n     * the point clicked on canvas element.\n     * ignoreZoom true gives back coordinates after being processed\n     * by the viewportTransform ( sort of coordinates of what is displayed\n     * on the canvas where you are clicking.\n     * ignoreZoom true = HTMLElement coordinates relative to top,left\n     * ignoreZoom false, default = fabric space coordinates, the same used for shape position\n     * To interact with your shapes top and left you want to use ignoreZoom true\n     * most of the time, while ignoreZoom false will give you coordinates\n     * compatible with the object.oCoords system.\n     * of the time.\n     * @param {Event} e\n     * @param {Boolean} ignoreZoom\n     * @return {Object} object with \"x\" and \"y\" number values\n     */\n    getPointer: function (e, ignoreZoom) {\n      // return cached values if we are in the event processing chain\n      if (this._absolutePointer && !ignoreZoom) {\n        return this._absolutePointer;\n      }\n      if (this._pointer && ignoreZoom) {\n        return this._pointer;\n      }\n\n      var pointer = getPointer(e),\n          upperCanvasEl = this.upperCanvasEl,\n          bounds = upperCanvasEl.getBoundingClientRect(),\n          boundsWidth = bounds.width || 0,\n          boundsHeight = bounds.height || 0,\n          cssScale;\n\n      if (!boundsWidth || !boundsHeight ) {\n        if ('top' in bounds && 'bottom' in bounds) {\n          boundsHeight = Math.abs( bounds.top - bounds.bottom );\n        }\n        if ('right' in bounds && 'left' in bounds) {\n          boundsWidth = Math.abs( bounds.right - bounds.left );\n        }\n      }\n\n      this.calcOffset();\n      pointer.x = pointer.x - this._offset.left;\n      pointer.y = pointer.y - this._offset.top;\n      if (!ignoreZoom) {\n        pointer = this.restorePointerVpt(pointer);\n      }\n\n      if (boundsWidth === 0 || boundsHeight === 0) {\n        // If bounds are not available (i.e. not visible), do not apply scale.\n        cssScale = { width: 1, height: 1 };\n      }\n      else {\n        cssScale = {\n          width: upperCanvasEl.width / boundsWidth,\n          height: upperCanvasEl.height / boundsHeight\n        };\n      }\n\n      return {\n        x: pointer.x * cssScale.width,\n        y: pointer.y * cssScale.height\n      };\n    },\n\n    /**\n     * @private\n     * @throws {CANVAS_INIT_ERROR} If canvas can not be initialized\n     */\n    _createUpperCanvas: function () {\n      var lowerCanvasClass = this.lowerCanvasEl.className.replace(/\\s*lower-canvas\\s*/, '');\n\n      // there is no need to create a new upperCanvas element if we have already one.\n      if (this.upperCanvasEl) {\n        this.upperCanvasEl.className = '';\n      }\n      else {\n        this.upperCanvasEl = this._createCanvasElement();\n      }\n      fabric.util.addClass(this.upperCanvasEl, 'upper-canvas ' + lowerCanvasClass);\n\n      this.wrapperEl.appendChild(this.upperCanvasEl);\n\n      this._copyCanvasStyle(this.lowerCanvasEl, this.upperCanvasEl);\n      this._applyCanvasStyle(this.upperCanvasEl);\n      this.contextTop = this.upperCanvasEl.getContext('2d');\n    },\n\n    /**\n     * @private\n     */\n    _createCacheCanvas: function () {\n      this.cacheCanvasEl = this._createCanvasElement();\n      this.cacheCanvasEl.setAttribute('width', this.width);\n      this.cacheCanvasEl.setAttribute('height', this.height);\n      this.contextCache = this.cacheCanvasEl.getContext('2d');\n    },\n\n    /**\n     * @private\n     */\n    _initWrapperElement: function () {\n      this.wrapperEl = fabric.util.wrapElement(this.lowerCanvasEl, 'div', {\n        'class': this.containerClass\n      });\n      fabric.util.setStyle(this.wrapperEl, {\n        width: this.width + 'px',\n        height: this.height + 'px',\n        position: 'relative'\n      });\n      fabric.util.makeElementUnselectable(this.wrapperEl);\n    },\n\n    /**\n     * @private\n     * @param {HTMLElement} element canvas element to apply styles on\n     */\n    _applyCanvasStyle: function (element) {\n      var width = this.width || element.width,\n          height = this.height || element.height;\n\n      fabric.util.setStyle(element, {\n        position: 'absolute',\n        width: width + 'px',\n        height: height + 'px',\n        left: 0,\n        top: 0,\n        'touch-action': this.allowTouchScrolling ? 'manipulation' : 'none'\n      });\n      element.width = width;\n      element.height = height;\n      fabric.util.makeElementUnselectable(element);\n    },\n\n    /**\n     * Copy the entire inline style from one element (fromEl) to another (toEl)\n     * @private\n     * @param {Element} fromEl Element style is copied from\n     * @param {Element} toEl Element copied style is applied to\n     */\n    _copyCanvasStyle: function (fromEl, toEl) {\n      toEl.style.cssText = fromEl.style.cssText;\n    },\n\n    /**\n     * Returns context of canvas where object selection is drawn\n     * @return {CanvasRenderingContext2D}\n     */\n    getSelectionContext: function() {\n      return this.contextTop;\n    },\n\n    /**\n     * Returns &lt;canvas> element on which object selection is drawn\n     * @return {HTMLCanvasElement}\n     */\n    getSelectionElement: function () {\n      return this.upperCanvasEl;\n    },\n\n    /**\n     * Returns currently active object\n     * @return {fabric.Object} active object\n     */\n    getActiveObject: function () {\n      return this._activeObject;\n    },\n\n    /**\n     * Returns an array with the current selected objects\n     * @return {fabric.Object} active object\n     */\n    getActiveObjects: function () {\n      var active = this._activeObject;\n      if (active) {\n        if (active.type === 'activeSelection' && active._objects) {\n          return active._objects.slice(0);\n        }\n        else {\n          return [active];\n        }\n      }\n      return [];\n    },\n\n    /**\n     * @private\n     * @param {fabric.Object} obj Object that was removed\n     */\n    _onObjectRemoved: function(obj) {\n      // removing active object should fire \"selection:cleared\" events\n      if (obj === this._activeObject) {\n        this.fire('before:selection:cleared', { target: obj });\n        this._discardActiveObject();\n        this.fire('selection:cleared', { target: obj });\n        obj.fire('deselected');\n      }\n      if (this._hoveredTarget === obj) {\n        this._hoveredTarget = null;\n      }\n      this.callSuper('_onObjectRemoved', obj);\n    },\n\n    /**\n     * @private\n     * Compares the old activeObject with the current one and fires correct events\n     * @param {fabric.Object} obj old activeObject\n     */\n    _fireSelectionEvents: function(oldObjects, e) {\n      var somethingChanged = false, objects = this.getActiveObjects(),\n          added = [], removed = [], opt = { e: e };\n      oldObjects.forEach(function(oldObject) {\n        if (objects.indexOf(oldObject) === -1) {\n          somethingChanged = true;\n          oldObject.fire('deselected', opt);\n          removed.push(oldObject);\n        }\n      });\n      objects.forEach(function(object) {\n        if (oldObjects.indexOf(object) === -1) {\n          somethingChanged = true;\n          object.fire('selected', opt);\n          added.push(object);\n        }\n      });\n      if (oldObjects.length > 0 && objects.length > 0) {\n        opt.selected = added;\n        opt.deselected = removed;\n        // added for backward compatibility\n        opt.updated = added[0] || removed[0];\n        opt.target = this._activeObject;\n        somethingChanged && this.fire('selection:updated', opt);\n      }\n      else if (objects.length > 0) {\n        // deprecated event\n        if (objects.length === 1) {\n          opt.target = added[0];\n          this.fire('object:selected', opt);\n        }\n        opt.selected = added;\n        // added for backward compatibility\n        opt.target = this._activeObject;\n        this.fire('selection:created', opt);\n      }\n      else if (oldObjects.length > 0) {\n        opt.deselected = removed;\n        this.fire('selection:cleared', opt);\n      }\n    },\n\n    /**\n     * Sets given object as the only active object on canvas\n     * @param {fabric.Object} object Object to set as an active one\n     * @param {Event} [e] Event (passed along when firing \"object:selected\")\n     * @return {fabric.Canvas} thisArg\n     * @chainable\n     */\n    setActiveObject: function (object, e) {\n      var currentActives = this.getActiveObjects();\n      this._setActiveObject(object, e);\n      this._fireSelectionEvents(currentActives, e);\n      return this;\n    },\n\n    /**\n     * @private\n     * @param {Object} object to set as active\n     * @param {Event} [e] Event (passed along when firing \"object:selected\")\n     * @return {Boolean} true if the selection happened\n     */\n    _setActiveObject: function(object, e) {\n      if (this._activeObject === object) {\n        return false;\n      }\n      if (!this._discardActiveObject(e, object)) {\n        return false;\n      }\n      if (object.onSelect({ e: e })) {\n        return false;\n      }\n      this._activeObject = object;\n      return true;\n    },\n\n    /**\n     * @private\n     */\n    _discardActiveObject: function(e, object) {\n      var obj = this._activeObject;\n      if (obj) {\n        // onDeselect return TRUE to cancel selection;\n        if (obj.onDeselect({ e: e, object: object })) {\n          return false;\n        }\n        this._activeObject = null;\n      }\n      return true;\n    },\n\n    /**\n     * Discards currently active object and fire events. If the function is called by fabric\n     * as a consequence of a mouse event, the event is passed as a parameter and\n     * sent to the fire function for the custom events. When used as a method the\n     * e param does not have any application.\n     * @param {event} e\n     * @return {fabric.Canvas} thisArg\n     * @chainable\n     */\n    discardActiveObject: function (e) {\n      var currentActives = this.getActiveObjects();\n      if (currentActives.length) {\n        this.fire('before:selection:cleared', { target: currentActives[0], e: e });\n      }\n      this._discardActiveObject(e);\n      this._fireSelectionEvents(currentActives, e);\n      return this;\n    },\n\n    /**\n     * Clears a canvas element and removes all event listeners\n     * @return {fabric.Canvas} thisArg\n     * @chainable\n     */\n    dispose: function () {\n      var wrapper = this.wrapperEl;\n      this.removeListeners();\n      wrapper.removeChild(this.upperCanvasEl);\n      wrapper.removeChild(this.lowerCanvasEl);\n      this.contextCache = null;\n      this.contextTop = null;\n      ['upperCanvasEl', 'cacheCanvasEl'].forEach((function(element) {\n        fabric.util.cleanUpJsdomNode(this[element]);\n        this[element] = undefined;\n      }).bind(this));\n      if (wrapper.parentNode) {\n        wrapper.parentNode.replaceChild(this.lowerCanvasEl, this.wrapperEl);\n      }\n      delete this.wrapperEl;\n      fabric.StaticCanvas.prototype.dispose.call(this);\n      return this;\n    },\n\n    /**\n     * Clears all contexts (background, main, top) of an instance\n     * @return {fabric.Canvas} thisArg\n     * @chainable\n     */\n    clear: function () {\n      // this.discardActiveGroup();\n      this.discardActiveObject();\n      this.clearContext(this.contextTop);\n      return this.callSuper('clear');\n    },\n\n    /**\n     * Draws objects' controls (borders/controls)\n     * @param {CanvasRenderingContext2D} ctx Context to render controls on\n     */\n    drawControls: function(ctx) {\n      var activeObject = this._activeObject;\n\n      if (activeObject) {\n        activeObject._renderControls(ctx);\n      }\n    },\n\n    /**\n     * @private\n     */\n    _toObject: function(instance, methodName, propertiesToInclude) {\n      //If the object is part of the current selection group, it should\n      //be transformed appropriately\n      //i.e. it should be serialised as it would appear if the selection group\n      //were to be destroyed.\n      var originalProperties = this._realizeGroupTransformOnObject(instance),\n          object = this.callSuper('_toObject', instance, methodName, propertiesToInclude);\n      //Undo the damage we did by changing all of its properties\n      this._unwindGroupTransformOnObject(instance, originalProperties);\n      return object;\n    },\n\n    /**\n     * Realises an object's group transformation on it\n     * @private\n     * @param {fabric.Object} [instance] the object to transform (gets mutated)\n     * @returns the original values of instance which were changed\n     */\n    _realizeGroupTransformOnObject: function(instance) {\n      if (instance.group && instance.group.type === 'activeSelection' && this._activeObject === instance.group) {\n        var layoutProps = ['angle', 'flipX', 'flipY', 'left', 'scaleX', 'scaleY', 'skewX', 'skewY', 'top'];\n        //Copy all the positionally relevant properties across now\n        var originalValues = {};\n        layoutProps.forEach(function(prop) {\n          originalValues[prop] = instance[prop];\n        });\n        this._activeObject.realizeTransform(instance);\n        return originalValues;\n      }\n      else {\n        return null;\n      }\n    },\n\n    /**\n     * Restores the changed properties of instance\n     * @private\n     * @param {fabric.Object} [instance] the object to un-transform (gets mutated)\n     * @param {Object} [originalValues] the original values of instance, as returned by _realizeGroupTransformOnObject\n     */\n    _unwindGroupTransformOnObject: function(instance, originalValues) {\n      if (originalValues) {\n        instance.set(originalValues);\n      }\n    },\n\n    /**\n     * @private\n     */\n    _setSVGObject: function(markup, instance, reviver) {\n      //If the object is in a selection group, simulate what would happen to that\n      //object when the group is deselected\n      var originalProperties = this._realizeGroupTransformOnObject(instance);\n      this.callSuper('_setSVGObject', markup, instance, reviver);\n      this._unwindGroupTransformOnObject(instance, originalProperties);\n    },\n\n    setViewportTransform: function (vpt) {\n      if (this.renderOnAddRemove && this._activeObject && this._activeObject.isEditing) {\n        this._activeObject.clearContextTop();\n      }\n      fabric.StaticCanvas.prototype.setViewportTransform.call(this, vpt);\n    }\n  });\n\n  // copying static properties manually to work around Opera's bug,\n  // where \"prototype\" property is enumerable and overrides existing prototype\n  for (var prop in fabric.StaticCanvas) {\n    if (prop !== 'prototype') {\n      fabric.Canvas[prop] = fabric.StaticCanvas[prop];\n    }\n  }\n\n  if (fabric.isTouchSupported) {\n    /** @ignore */\n    fabric.Canvas.prototype._setCursorFromEvent = function() { };\n  }\n})();\n\n\n(function() {\n\n  var cursorOffset = {\n        mt: 0, // n\n        tr: 1, // ne\n        mr: 2, // e\n        br: 3, // se\n        mb: 4, // s\n        bl: 5, // sw\n        ml: 6, // w\n        tl: 7 // nw\n      },\n      addListener = fabric.util.addListener,\n      removeListener = fabric.util.removeListener,\n      RIGHT_CLICK = 3, MIDDLE_CLICK = 2, LEFT_CLICK = 1,\n      addEventOptions = { passive: false };\n\n  function checkClick(e, value) {\n    return 'which' in e ? e.which === value : e.button === value - 1;\n  }\n\n  fabric.util.object.extend(fabric.Canvas.prototype, /** @lends fabric.Canvas.prototype */ {\n\n    /**\n     * Map of cursor style values for each of the object controls\n     * @private\n     */\n    cursorMap: [\n      'n-resize',\n      'ne-resize',\n      'e-resize',\n      'se-resize',\n      's-resize',\n      'sw-resize',\n      'w-resize',\n      'nw-resize'\n    ],\n\n    /**\n     * Adds mouse listeners to canvas\n     * @private\n     */\n    _initEventListeners: function () {\n      // in case we initialized the class twice. This should not happen normally\n      // but in some kind of applications where the canvas element may be changed\n      // this is a workaround to having double listeners.\n      this.removeListeners();\n      this._bindEvents();\n      this.addOrRemove(addListener, 'add');\n    },\n\n    addOrRemove: function(functor, eventjsFunctor) {\n      functor(fabric.window, 'resize', this._onResize);\n      functor(this.upperCanvasEl, 'mousedown', this._onMouseDown);\n      functor(this.upperCanvasEl, 'mousemove', this._onMouseMove, addEventOptions);\n      functor(this.upperCanvasEl, 'mouseout', this._onMouseOut);\n      functor(this.upperCanvasEl, 'mouseenter', this._onMouseEnter);\n      functor(this.upperCanvasEl, 'wheel', this._onMouseWheel);\n      functor(this.upperCanvasEl, 'contextmenu', this._onContextMenu);\n      functor(this.upperCanvasEl, 'dblclick', this._onDoubleClick);\n      functor(this.upperCanvasEl, 'touchstart', this._onMouseDown, addEventOptions);\n      functor(this.upperCanvasEl, 'touchmove', this._onMouseMove, addEventOptions);\n      functor(this.upperCanvasEl, 'dragover', this._onDragOver);\n      functor(this.upperCanvasEl, 'dragenter', this._onDragEnter);\n      functor(this.upperCanvasEl, 'dragleave', this._onDragLeave);\n      functor(this.upperCanvasEl, 'drop', this._onDrop);\n      if (typeof eventjs !== 'undefined' && eventjsFunctor in eventjs) {\n        eventjs[eventjsFunctor](this.upperCanvasEl, 'gesture', this._onGesture);\n        eventjs[eventjsFunctor](this.upperCanvasEl, 'drag', this._onDrag);\n        eventjs[eventjsFunctor](this.upperCanvasEl, 'orientation', this._onOrientationChange);\n        eventjs[eventjsFunctor](this.upperCanvasEl, 'shake', this._onShake);\n        eventjs[eventjsFunctor](this.upperCanvasEl, 'longpress', this._onLongPress);\n      }\n    },\n\n    /**\n     * Removes all event listeners\n     */\n    removeListeners: function() {\n      this.addOrRemove(removeListener, 'remove');\n      // if you dispose on a mouseDown, before mouse up, you need to clean document to...\n      removeListener(fabric.document, 'mouseup', this._onMouseUp);\n      removeListener(fabric.document, 'touchend', this._onMouseUp, addEventOptions);\n      removeListener(fabric.document, 'mousemove', this._onMouseMove, addEventOptions);\n      removeListener(fabric.document, 'touchmove', this._onMouseMove, addEventOptions);\n    },\n\n    /**\n     * @private\n     */\n    _bindEvents: function() {\n      if (this.eventsBound) {\n        // for any reason we pass here twice we do not want to bind events twice.\n        return;\n      }\n      this._onMouseDown = this._onMouseDown.bind(this);\n      this._onMouseMove = this._onMouseMove.bind(this);\n      this._onMouseUp = this._onMouseUp.bind(this);\n      this._onResize = this._onResize.bind(this);\n      this._onGesture = this._onGesture.bind(this);\n      this._onDrag = this._onDrag.bind(this);\n      this._onShake = this._onShake.bind(this);\n      this._onLongPress = this._onLongPress.bind(this);\n      this._onOrientationChange = this._onOrientationChange.bind(this);\n      this._onMouseWheel = this._onMouseWheel.bind(this);\n      this._onMouseOut = this._onMouseOut.bind(this);\n      this._onMouseEnter = this._onMouseEnter.bind(this);\n      this._onContextMenu = this._onContextMenu.bind(this);\n      this._onDoubleClick = this._onDoubleClick.bind(this);\n      this._onDragOver = this._onDragOver.bind(this);\n      this._onDragEnter = this._simpleEventHandler.bind(this, 'dragenter');\n      this._onDragLeave = this._simpleEventHandler.bind(this, 'dragleave');\n      this._onDrop = this._simpleEventHandler.bind(this, 'drop');\n      this.eventsBound = true;\n    },\n\n    /**\n     * @private\n     * @param {Event} [e] Event object fired on Event.js gesture\n     * @param {Event} [self] Inner Event object\n     */\n    _onGesture: function(e, self) {\n      this.__onTransformGesture && this.__onTransformGesture(e, self);\n    },\n\n    /**\n     * @private\n     * @param {Event} [e] Event object fired on Event.js drag\n     * @param {Event} [self] Inner Event object\n     */\n    _onDrag: function(e, self) {\n      this.__onDrag && this.__onDrag(e, self);\n    },\n\n    /**\n     * @private\n     * @param {Event} [e] Event object fired on wheel event\n     */\n    _onMouseWheel: function(e) {\n      this.__onMouseWheel(e);\n    },\n\n    /**\n     * @private\n     * @param {Event} e Event object fired on mousedown\n     */\n    _onMouseOut: function(e) {\n      var target = this._hoveredTarget;\n      this.fire('mouse:out', { target: target, e: e });\n      this._hoveredTarget = null;\n      target && target.fire('mouseout', { e: e });\n      if (this._iTextInstances) {\n        this._iTextInstances.forEach(function(obj) {\n          if (obj.isEditing) {\n            obj.hiddenTextarea.focus();\n          }\n        });\n      }\n    },\n\n    /**\n     * @private\n     * @param {Event} e Event object fired on mouseenter\n     */\n    _onMouseEnter: function(e) {\n      if (!this.findTarget(e)) {\n        this.fire('mouse:over', { target: null, e: e });\n        this._hoveredTarget = null;\n      }\n    },\n\n    /**\n     * @private\n     * @param {Event} [e] Event object fired on Event.js orientation change\n     * @param {Event} [self] Inner Event object\n     */\n    _onOrientationChange: function(e, self) {\n      this.__onOrientationChange && this.__onOrientationChange(e, self);\n    },\n\n    /**\n     * @private\n     * @param {Event} [e] Event object fired on Event.js shake\n     * @param {Event} [self] Inner Event object\n     */\n    _onShake: function(e, self) {\n      this.__onShake && this.__onShake(e, self);\n    },\n\n    /**\n     * @private\n     * @param {Event} [e] Event object fired on Event.js shake\n     * @param {Event} [self] Inner Event object\n     */\n    _onLongPress: function(e, self) {\n      this.__onLongPress && this.__onLongPress(e, self);\n    },\n\n    /**\n     * prevent default to allow drop event to be fired\n     * @private\n     * @param {Event} [e] Event object fired on Event.js shake\n     */\n    _onDragOver: function(e) {\n      e.preventDefault();\n      var target = this._simpleEventHandler('dragover', e);\n      this._fireEnterLeaveEvents(target, e);\n    },\n\n    /**\n     * @private\n     * @param {Event} e Event object fired on mousedown\n     */\n    _onContextMenu: function (e) {\n      if (this.stopContextMenu) {\n        e.stopPropagation();\n        e.preventDefault();\n      }\n      return false;\n    },\n\n    /**\n     * @private\n     * @param {Event} e Event object fired on mousedown\n     */\n    _onDoubleClick: function (e) {\n      this._cacheTransformEventData(e);\n      this._handleEvent(e, 'dblclick');\n      this._resetTransformEventData(e);\n    },\n\n    /**\n     * @private\n     * @param {Event} e Event object fired on mousedown\n     */\n    _onMouseDown: function (e) {\n      this.__onMouseDown(e);\n      this._resetTransformEventData();\n      addListener(fabric.document, 'touchend', this._onMouseUp, addEventOptions);\n      addListener(fabric.document, 'touchmove', this._onMouseMove, addEventOptions);\n\n      removeListener(this.upperCanvasEl, 'mousemove', this._onMouseMove, addEventOptions);\n      removeListener(this.upperCanvasEl, 'touchmove', this._onMouseMove, addEventOptions);\n\n      if (e.type === 'touchstart') {\n        // Unbind mousedown to prevent double triggers from touch devices\n        removeListener(this.upperCanvasEl, 'mousedown', this._onMouseDown);\n      }\n      else {\n        addListener(fabric.document, 'mouseup', this._onMouseUp);\n        addListener(fabric.document, 'mousemove', this._onMouseMove, addEventOptions);\n      }\n    },\n\n    /**\n     * @private\n     * @param {Event} e Event object fired on mouseup\n     */\n    _onMouseUp: function (e) {\n      this.__onMouseUp(e);\n      this._resetTransformEventData();\n      removeListener(fabric.document, 'mouseup', this._onMouseUp);\n      removeListener(fabric.document, 'touchend', this._onMouseUp, addEventOptions);\n\n      removeListener(fabric.document, 'mousemove', this._onMouseMove, addEventOptions);\n      removeListener(fabric.document, 'touchmove', this._onMouseMove, addEventOptions);\n\n      addListener(this.upperCanvasEl, 'mousemove', this._onMouseMove, addEventOptions);\n      addListener(this.upperCanvasEl, 'touchmove', this._onMouseMove, addEventOptions);\n\n      if (e.type === 'touchend') {\n        // Wait 400ms before rebinding mousedown to prevent double triggers\n        // from touch devices\n        var _this = this;\n        setTimeout(function() {\n          addListener(_this.upperCanvasEl, 'mousedown', _this._onMouseDown);\n        }, 400);\n      }\n    },\n\n    /**\n     * @private\n     * @param {Event} e Event object fired on mousemove\n     */\n    _onMouseMove: function (e) {\n      !this.allowTouchScrolling && e.preventDefault && e.preventDefault();\n      this.__onMouseMove(e);\n    },\n\n    /**\n     * @private\n     */\n    _onResize: function () {\n      this.calcOffset();\n    },\n\n    /**\n     * Decides whether the canvas should be redrawn in mouseup and mousedown events.\n     * @private\n     * @param {Object} target\n     */\n    _shouldRender: function(target) {\n      var activeObject = this._activeObject;\n\n      if (\n        !!activeObject !== !!target ||\n        (activeObject && target && (activeObject !== target))\n      ) {\n        // this covers: switch of target, from target to no target, selection of target\n        // multiSelection with key and mouse\n        return true;\n      }\n      else if (activeObject && activeObject.isEditing) {\n        // if we mouse up/down over a editing textbox a cursor change,\n        // there is no need to re render\n        return false;\n      }\n      return false;\n    },\n\n    /**\n     * Method that defines the actions when mouse is released on canvas.\n     * The method resets the currentTransform parameters, store the image corner\n     * position in the image object and render the canvas on top.\n     * @private\n     * @param {Event} e Event object fired on mouseup\n     */\n    __onMouseUp: function (e) {\n      var target, transform = this._currentTransform,\n          groupSelector = this._groupSelector, shouldRender = false,\n          isClick = (!groupSelector || (groupSelector.left === 0 && groupSelector.top === 0));\n      this._cacheTransformEventData(e);\n      target = this._target;\n      this._handleEvent(e, 'up:before');\n      // if right/middle click just fire events and return\n      // target undefined will make the _handleEvent search the target\n      if (checkClick(e, RIGHT_CLICK)) {\n        if (this.fireRightClick) {\n          this._handleEvent(e, 'up', RIGHT_CLICK, isClick);\n        }\n        return;\n      }\n\n      if (checkClick(e, MIDDLE_CLICK)) {\n        if (this.fireMiddleClick) {\n          this._handleEvent(e, 'up', MIDDLE_CLICK, isClick);\n        }\n        this._resetTransformEventData();\n        return;\n      }\n\n      if (this.isDrawingMode && this._isCurrentlyDrawing) {\n        this._onMouseUpInDrawingMode(e);\n        return;\n      }\n\n      if (transform) {\n        this._finalizeCurrentTransform(e);\n        shouldRender = transform.actionPerformed;\n      }\n\n      if (!isClick) {\n        this._maybeGroupObjects(e);\n        shouldRender || (shouldRender = this._shouldRender(target));\n      }\n      if (target) {\n        target.isMoving = false;\n      }\n      this._setCursorFromEvent(e, target);\n      this._handleEvent(e, 'up', LEFT_CLICK, isClick);\n      this._groupSelector = null;\n      this._currentTransform = null;\n      // reset the target information about which corner is selected\n      target && (target.__corner = 0);\n      if (shouldRender) {\n        this.requestRenderAll();\n      }\n      else if (!isClick) {\n        this.renderTop();\n      }\n    },\n\n    /**\n     * @private\n     * Handle event firing for target and subtargets\n     * @param {Event} e event from mouse\n     * @param {String} eventType event to fire (up, down or move)\n     * @return {Fabric.Object} target return the the target found, for internal reasons.\n     */\n    _simpleEventHandler: function(eventType, e) {\n      var target = this.findTarget(e),\n          targets = this.targets,\n          options = {\n            e: e,\n            target: target,\n            subTargets: targets,\n          };\n      this.fire(eventType, options);\n      target && target.fire(eventType, options);\n      if (!targets) {\n        return target;\n      }\n      for (var i = 0; i < targets.length; i++) {\n        targets[i].fire(eventType, options);\n      }\n      return target;\n    },\n\n    /**\n     * @private\n     * Handle event firing for target and subtargets\n     * @param {Event} e event from mouse\n     * @param {String} eventType event to fire (up, down or move)\n     * @param {fabric.Object} targetObj receiving event\n     * @param {Number} [button] button used in the event 1 = left, 2 = middle, 3 = right\n     * @param {Boolean} isClick for left button only, indicates that the mouse up happened without move.\n     */\n    _handleEvent: function(e, eventType, button, isClick) {\n      var target = this._target,\n          targets = this.targets || [],\n          options = {\n            e: e,\n            target: target,\n            subTargets: targets,\n            button: button || LEFT_CLICK,\n            isClick: isClick || false,\n            pointer: this._pointer,\n            absolutePointer: this._absolutePointer,\n            transform: this._currentTransform\n          };\n      this.fire('mouse:' + eventType, options);\n      target && target.fire('mouse' + eventType, options);\n      for (var i = 0; i < targets.length; i++) {\n        targets[i].fire('mouse' + eventType, options);\n      }\n    },\n\n    /**\n     * @private\n     * @param {Event} e send the mouse event that generate the finalize down, so it can be used in the event\n     */\n    _finalizeCurrentTransform: function(e) {\n\n      var transform = this._currentTransform,\n          target = transform.target,\n          eventName,\n          options = {\n            e: e,\n            target: target,\n            transform: transform,\n          };\n\n      if (target._scaling) {\n        target._scaling = false;\n      }\n\n      target.setCoords();\n\n      if (transform.actionPerformed || (this.stateful && target.hasStateChanged())) {\n        if (transform.actionPerformed) {\n          eventName = this._addEventOptions(options, transform);\n          this._fire(eventName, options);\n        }\n        this._fire('modified', options);\n      }\n    },\n\n    /**\n     * Mutate option object in order to add by property and give back the event name.\n     * @private\n     * @param {Object} options to mutate\n     * @param {Object} transform to inspect action from\n     */\n    _addEventOptions: function(options, transform) {\n      // we can probably add more details at low cost\n      // scale change, rotation changes, translation changes\n      var eventName, by;\n      switch (transform.action) {\n        case 'scaleX':\n          eventName = 'scaled';\n          by = 'x';\n          break;\n        case 'scaleY':\n          eventName = 'scaled';\n          by = 'y';\n          break;\n        case 'skewX':\n          eventName = 'skewed';\n          by = 'x';\n          break;\n        case 'skewY':\n          eventName = 'skewed';\n          by = 'y';\n          break;\n        case 'scale':\n          eventName = 'scaled';\n          by = 'equally';\n          break;\n        case 'rotate':\n          eventName = 'rotated';\n          break;\n        case 'drag':\n          eventName = 'moved';\n          break;\n      }\n      options.by = by;\n      return eventName;\n    },\n\n    /**\n     * @private\n     * @param {Event} e Event object fired on mousedown\n     */\n    _onMouseDownInDrawingMode: function(e) {\n      this._isCurrentlyDrawing = true;\n      if (this.getActiveObject()) {\n        this.discardActiveObject(e).requestRenderAll();\n      }\n      if (this.clipTo) {\n        fabric.util.clipContext(this, this.contextTop);\n      }\n      var pointer = this.getPointer(e);\n      this.freeDrawingBrush.onMouseDown(pointer);\n      this._handleEvent(e, 'down');\n    },\n\n    /**\n     * @private\n     * @param {Event} e Event object fired on mousemove\n     */\n    _onMouseMoveInDrawingMode: function(e) {\n      if (this._isCurrentlyDrawing) {\n        var pointer = this.getPointer(e);\n        this.freeDrawingBrush.onMouseMove(pointer);\n      }\n      this.setCursor(this.freeDrawingCursor);\n      this._handleEvent(e, 'move');\n    },\n\n    /**\n     * @private\n     * @param {Event} e Event object fired on mouseup\n     */\n    _onMouseUpInDrawingMode: function(e) {\n      this._isCurrentlyDrawing = false;\n      if (this.clipTo) {\n        this.contextTop.restore();\n      }\n      this.freeDrawingBrush.onMouseUp();\n      this._handleEvent(e, 'up');\n    },\n\n    /**\n     * Method that defines the actions when mouse is clicked on canvas.\n     * The method inits the currentTransform parameters and renders all the\n     * canvas so the current image can be placed on the top canvas and the rest\n     * in on the container one.\n     * @private\n     * @param {Event} e Event object fired on mousedown\n     */\n    __onMouseDown: function (e) {\n      this._cacheTransformEventData(e);\n      this._handleEvent(e, 'down:before');\n      var target = this._target;\n      // if right click just fire events\n      if (checkClick(e, RIGHT_CLICK)) {\n        if (this.fireRightClick) {\n          this._handleEvent(e, 'down', RIGHT_CLICK);\n        }\n        return;\n      }\n\n      if (checkClick(e, MIDDLE_CLICK)) {\n        if (this.fireMiddleClick) {\n          this._handleEvent(e, 'down', MIDDLE_CLICK);\n        }\n        return;\n      }\n\n      if (this.isDrawingMode) {\n        this._onMouseDownInDrawingMode(e);\n        return;\n      }\n\n      // ignore if some object is being transformed at this moment\n      if (this._currentTransform) {\n        return;\n      }\n\n      var pointer = this._pointer;\n      // save pointer for check in __onMouseUp event\n      this._previousPointer = pointer;\n      var shouldRender = this._shouldRender(target),\n          shouldGroup = this._shouldGroup(e, target);\n      if (this._shouldClearSelection(e, target)) {\n        this.discardActiveObject(e);\n      }\n      else if (shouldGroup) {\n        this._handleGrouping(e, target);\n        target = this._activeObject;\n      }\n\n      if (this.selection && (!target ||\n        (!target.selectable && !target.isEditing && target !== this._activeObject))) {\n        this._groupSelector = {\n          ex: pointer.x,\n          ey: pointer.y,\n          top: 0,\n          left: 0\n        };\n      }\n\n      if (target) {\n        if (target.selectable) {\n          this.setActiveObject(target, e);\n        }\n        if (target === this._activeObject && (target.__corner || !shouldGroup)) {\n          this._setupCurrentTransform(e, target);\n        }\n      }\n      this._handleEvent(e, 'down');\n      // we must renderAll so that we update the visuals\n      (shouldRender || shouldGroup) && this.requestRenderAll();\n    },\n\n    /**\n     * reset cache form common information needed during event processing\n     * @private\n     */\n    _resetTransformEventData: function() {\n      this._target = null;\n      this._pointer = null;\n      this._absolutePointer = null;\n    },\n\n    /**\n     * Cache common information needed during event processing\n     * @private\n     * @param {Event} e Event object fired on event\n     */\n    _cacheTransformEventData: function(e) {\n      // reset in order to avoid stale caching\n      this._resetTransformEventData();\n      this._pointer = this.getPointer(e, true);\n      this._absolutePointer = this.restorePointerVpt(this._pointer);\n      this._target = this._currentTransform ? this._currentTransform.target : this.findTarget(e) || null;\n    },\n\n    /**\n     * @private\n     */\n    _beforeTransform: function(e) {\n      var t = this._currentTransform;\n      this.stateful && t.target.saveState();\n      this.fire('before:transform', {\n        e: e,\n        transform: t,\n      });\n      // determine if it's a drag or rotate case\n      if (t.corner) {\n        this.onBeforeScaleRotate(t.target);\n      }\n    },\n\n    /**\n     * Method that defines the actions when mouse is hovering the canvas.\n     * The currentTransform parameter will definde whether the user is rotating/scaling/translating\n     * an image or neither of them (only hovering). A group selection is also possible and would cancel\n     * all any other type of action.\n     * In case of an image transformation only the top canvas will be rendered.\n     * @private\n     * @param {Event} e Event object fired on mousemove\n     */\n    __onMouseMove: function (e) {\n      this._handleEvent(e, 'move:before');\n      this._cacheTransformEventData(e);\n      var target, pointer;\n\n      if (this.isDrawingMode) {\n        this._onMouseMoveInDrawingMode(e);\n        return;\n      }\n      if (typeof e.touches !== 'undefined' && e.touches.length > 1) {\n        return;\n      }\n\n      var groupSelector = this._groupSelector;\n\n      // We initially clicked in an empty area, so we draw a box for multiple selection\n      if (groupSelector) {\n        pointer = this._pointer;\n\n        groupSelector.left = pointer.x - groupSelector.ex;\n        groupSelector.top = pointer.y - groupSelector.ey;\n\n        this.renderTop();\n      }\n      else if (!this._currentTransform) {\n        target = this.findTarget(e) || null;\n        this._setCursorFromEvent(e, target);\n        this._fireOverOutEvents(target, e);\n      }\n      else {\n        this._transformObject(e);\n      }\n      this._handleEvent(e, 'move');\n      this._resetTransformEventData();\n    },\n\n    /**\n     * Manage the mouseout, mouseover events for the fabric object on the canvas\n     * @param {Fabric.Object} target the target where the target from the mousemove event\n     * @param {Event} e Event object fired on mousemove\n     * @private\n     */\n    _fireOverOutEvents: function(target, e) {\n      this.fireSynteticInOutEvents(target, e, {\n        targetName: '_hoveredTarget',\n        canvasEvtOut: 'mouse:out',\n        evtOut: 'mouseout',\n        canvasEvtIn: 'mouse:over',\n        evtIn: 'mouseover',\n      });\n    },\n\n    /**\n     * Manage the dragEnter, dragLeave events for the fabric objects on the canvas\n     * @param {Fabric.Object} target the target where the target from the onDrag event\n     * @param {Event} e Event object fired on ondrag\n     * @private\n     */\n    _fireEnterLeaveEvents: function(target, e) {\n      this.fireSynteticInOutEvents(target, e, {\n        targetName: '_draggedoverTarget',\n        evtOut: 'dragleave',\n        evtIn: 'dragenter',\n      });\n    },\n\n    /**\n     * Manage the syntetic 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    fireSynteticInOutEvents: function(target, e, config) {\n      var inOpt, outOpt, oldTarget = this[config.targetName], outFires, inFires,\n          targetChanged = oldTarget !== target, canvasEvtIn = config.canvasEvtIn, canvasEvtOut = config.canvasEvtOut;\n      if (targetChanged) {\n        inOpt = { e: e, target: target, previousTarget: oldTarget };\n        outOpt = { e: e, target: oldTarget, nextTarget: target };\n        this[config.targetName] = target;\n      }\n      inFires = target && targetChanged;\n      outFires = oldTarget && targetChanged;\n      if (outFires) {\n        canvasEvtOut && this.fire(canvasEvtOut, outOpt);\n        oldTarget.fire(config.evtOut, outOpt);\n      }\n      if (inFires) {\n        canvasEvtIn && this.fire(canvasEvtIn, inOpt);\n        target.fire(config.evtIn, inOpt);\n      }\n    },\n\n    /**\n     * Method that defines actions when an Event Mouse Wheel\n     * @param {Event} e Event object fired on mouseup\n     */\n    __onMouseWheel: function(e) {\n      this._cacheTransformEventData(e);\n      this._handleEvent(e, 'wheel');\n      this._resetTransformEventData();\n    },\n\n    /**\n     * @private\n     * @param {Event} e Event fired on mousemove\n     */\n    _transformObject: function(e) {\n      var pointer = this.getPointer(e),\n          transform = this._currentTransform;\n\n      transform.reset = false;\n      transform.target.isMoving = true;\n      transform.shiftKey = e.shiftKey;\n      transform.altKey = e[this.centeredKey];\n\n      this._beforeScaleTransform(e, transform);\n      this._performTransformAction(e, transform, pointer);\n\n      transform.actionPerformed && this.requestRenderAll();\n    },\n\n    /**\n     * @private\n     */\n    _performTransformAction: function(e, transform, pointer) {\n      var x = pointer.x,\n          y = pointer.y,\n          action = transform.action,\n          actionPerformed = false,\n          options = {\n            target: transform.target,\n            e: e,\n            transform: transform,\n            pointer: pointer\n          };\n\n      if (action === 'rotate') {\n        (actionPerformed = this._rotateObject(x, y)) && this._fire('rotating', options);\n      }\n      else if (action === 'scale') {\n        (actionPerformed = this._onScale(e, transform, x, y)) && this._fire('scaling', options);\n      }\n      else if (action === 'scaleX') {\n        (actionPerformed = this._scaleObject(x, y, 'x')) && this._fire('scaling', options);\n      }\n      else if (action === 'scaleY') {\n        (actionPerformed = this._scaleObject(x, y, 'y')) && this._fire('scaling', options);\n      }\n      else if (action === 'skewX') {\n        (actionPerformed = this._skewObject(x, y, 'x')) && this._fire('skewing', options);\n      }\n      else if (action === 'skewY') {\n        (actionPerformed = this._skewObject(x, y, 'y')) && this._fire('skewing', options);\n      }\n      else {\n        actionPerformed = this._translateObject(x, y);\n        if (actionPerformed) {\n          this._fire('moving', options);\n          this.setCursor(options.target.moveCursor || this.moveCursor);\n        }\n      }\n      transform.actionPerformed = transform.actionPerformed || actionPerformed;\n    },\n\n    /**\n     * @private\n     */\n    _fire: function(eventName, options) {\n      this.fire('object:' + eventName, options);\n      options.target.fire(eventName, options);\n    },\n\n    /**\n     * @private\n     */\n    _beforeScaleTransform: function(e, transform) {\n      if (transform.action === 'scale' || transform.action === 'scaleX' || transform.action === 'scaleY') {\n        var centerTransform = this._shouldCenterTransform(transform.target);\n\n        // Switch from a normal resize to center-based\n        if ((centerTransform && (transform.originX !== 'center' || transform.originY !== 'center')) ||\n           // Switch from center-based resize to normal one\n           (!centerTransform && transform.originX === 'center' && transform.originY === 'center')\n        ) {\n          this._resetCurrentTransform();\n          transform.reset = true;\n        }\n      }\n    },\n\n    /**\n     * @private\n     * @param {Event} e Event object\n     * @param {Object} transform current tranform\n     * @param {Number} x mouse position x from origin\n     * @param {Number} y mouse poistion y from origin\n     * @return {Boolean} true if the scaling occurred\n     */\n    _onScale: function(e, transform, x, y) {\n      if (this._isUniscalePossible(e, transform.target)) {\n        transform.currentAction = 'scale';\n        return this._scaleObject(x, y);\n      }\n      else {\n        // Switch from a normal resize to proportional\n        if (!transform.reset && transform.currentAction === 'scale') {\n          this._resetCurrentTransform();\n        }\n\n        transform.currentAction = 'scaleEqually';\n        return this._scaleObject(x, y, 'equally');\n      }\n    },\n\n    /**\n     * @private\n     * @param {Event} e Event object\n     * @param {fabric.Object} target current target\n     * @return {Boolean} true if unproportional scaling is possible\n     */\n    _isUniscalePossible: function(e, target) {\n      return (e[this.uniScaleKey] || this.uniScaleTransform) && !target.get('lockUniScaling');\n    },\n\n    /**\n     * Sets the cursor depending on where the canvas is being hovered.\n     * Note: very buggy in Opera\n     * @param {Event} e Event object\n     * @param {Object} target Object that the mouse is hovering, if so.\n     */\n    _setCursorFromEvent: function (e, target) {\n      if (!target) {\n        this.setCursor(this.defaultCursor);\n        return false;\n      }\n\n      var hoverCursor = target.hoverCursor || this.hoverCursor,\n          activeSelection = this._activeObject && this._activeObject.type === 'activeSelection' ?\n            this._activeObject : null,\n          // only show proper corner when group selection is not active\n          corner = (!activeSelection || !activeSelection.contains(target))\n                    && target._findTargetCorner(this.getPointer(e, true));\n\n      if (!corner) {\n        this.setCursor(hoverCursor);\n      }\n      else {\n        this.setCursor(this.getCornerCursor(corner, target, e));\n      }\n    },\n\n    /**\n     * @private\n     */\n    getCornerCursor: function(corner, target, e) {\n      if (this.actionIsDisabled(corner, target, e)) {\n        return this.notAllowedCursor;\n      }\n      else if (corner in cursorOffset) {\n        return this._getRotatedCornerCursor(corner, target, e);\n      }\n      else if (corner === 'mtr' && target.hasRotatingPoint) {\n        return this.rotationCursor;\n      }\n      else {\n        return this.defaultCursor;\n      }\n    },\n\n    actionIsDisabled: function(corner, target, e) {\n      if (corner === 'mt' || corner === 'mb') {\n        return e[this.altActionKey] ? target.lockSkewingX : target.lockScalingY;\n      }\n      else if (corner === 'ml' || corner === 'mr') {\n        return e[this.altActionKey] ? target.lockSkewingY : target.lockScalingX;\n      }\n      else if (corner === 'mtr') {\n        return target.lockRotation;\n      }\n      else {\n        return this._isUniscalePossible(e, target) ?\n          target.lockScalingX && target.lockScalingY : target.lockScalingX || target.lockScalingY;\n      }\n    },\n\n    /**\n     * @private\n     */\n    _getRotatedCornerCursor: function(corner, target, e) {\n      var n = Math.round((target.angle % 360) / 45);\n\n      if (n < 0) {\n        n += 8; // full circle ahead\n      }\n      n += cursorOffset[corner];\n      if (e[this.altActionKey] && cursorOffset[corner] % 2 === 0) {\n        //if we are holding shift and we are on a mx corner...\n        n += 2;\n      }\n      // normalize n to be from 0 to 7\n      n %= 8;\n\n      return this.cursorMap[n];\n    }\n  });\n})();\n\n\n(function() {\n\n  var min = Math.min,\n      max = Math.max;\n\n  fabric.util.object.extend(fabric.Canvas.prototype, /** @lends fabric.Canvas.prototype */ {\n\n    /**\n     * @private\n     * @param {Event} e Event object\n     * @param {fabric.Object} target\n     * @return {Boolean}\n     */\n    _shouldGroup: function(e, target) {\n      var activeObject = this._activeObject;\n      return activeObject && this._isSelectionKeyPressed(e) && target && target.selectable && this.selection &&\n            (activeObject !== target || activeObject.type === 'activeSelection') && !target.onSelect({ e: e });\n    },\n\n    /**\n     * @private\n     * @param {Event} e Event object\n     * @param {fabric.Object} target\n     */\n    _handleGrouping: function (e, target) {\n      var activeObject = this._activeObject;\n      // avoid multi select when shift click on a corner\n      if (activeObject.__corner) {\n        return;\n      }\n      if (target === activeObject) {\n        // if it's a group, find target again, using activeGroup objects\n        target = this.findTarget(e, true);\n        // if even object is not found or we are on activeObjectCorner, bail out\n        if (!target || !target.selectable) {\n          return;\n        }\n      }\n      if (activeObject && activeObject.type === 'activeSelection') {\n        this._updateActiveSelection(target, e);\n      }\n      else {\n        this._createActiveSelection(target, e);\n      }\n    },\n\n    /**\n     * @private\n     */\n    _updateActiveSelection: function(target, e) {\n      var activeSelection = this._activeObject,\n          currentActiveObjects = activeSelection._objects.slice(0);\n      if (activeSelection.contains(target)) {\n        activeSelection.removeWithUpdate(target);\n        this._hoveredTarget = target;\n        if (activeSelection.size() === 1) {\n          // activate last remaining object\n          this._setActiveObject(activeSelection.item(0), e);\n        }\n      }\n      else {\n        activeSelection.addWithUpdate(target);\n        this._hoveredTarget = activeSelection;\n      }\n      this._fireSelectionEvents(currentActiveObjects, e);\n    },\n\n    /**\n     * @private\n     */\n    _createActiveSelection: function(target, e) {\n      var currentActives = this.getActiveObjects(), group = this._createGroup(target);\n      this._hoveredTarget = group;\n      this._setActiveObject(group, e);\n      this._fireSelectionEvents(currentActives, e);\n    },\n\n    /**\n     * @private\n     * @param {Object} target\n     */\n    _createGroup: function(target) {\n      var objects = this._objects,\n          isActiveLower = objects.indexOf(this._activeObject) < objects.indexOf(target),\n          groupObjects = isActiveLower\n            ? [this._activeObject, target]\n            : [target, this._activeObject];\n      this._activeObject.isEditing && this._activeObject.exitEditing();\n      return new fabric.ActiveSelection(groupObjects, {\n        canvas: this\n      });\n    },\n\n    /**\n     * @private\n     * @param {Event} e mouse event\n     */\n    _groupSelectedObjects: function (e) {\n\n      var group = this._collectObjects(e),\n          aGroup;\n\n      // do not create group for 1 element only\n      if (group.length === 1) {\n        this.setActiveObject(group[0], e);\n      }\n      else if (group.length > 1) {\n        aGroup = new fabric.ActiveSelection(group.reverse(), {\n          canvas: this\n        });\n        this.setActiveObject(aGroup, e);\n      }\n    },\n\n    /**\n     * @private\n     */\n    _collectObjects: function(e) {\n      var group = [],\n          currentObject,\n          x1 = this._groupSelector.ex,\n          y1 = this._groupSelector.ey,\n          x2 = x1 + this._groupSelector.left,\n          y2 = y1 + this._groupSelector.top,\n          selectionX1Y1 = new fabric.Point(min(x1, x2), min(y1, y2)),\n          selectionX2Y2 = new fabric.Point(max(x1, x2), max(y1, y2)),\n          allowIntersect = !this.selectionFullyContained,\n          isClick = x1 === x2 && y1 === y2;\n      // we iterate reverse order to collect top first in case of click.\n      for (var i = this._objects.length; i--; ) {\n        currentObject = this._objects[i];\n\n        if (!currentObject || !currentObject.selectable || !currentObject.visible || currentObject.onSelect({ e: e })) {\n          continue;\n        }\n\n        if ((allowIntersect && currentObject.intersectsWithRect(selectionX1Y1, selectionX2Y2)) ||\n            currentObject.isContainedWithinRect(selectionX1Y1, selectionX2Y2) ||\n            (allowIntersect && currentObject.containsPoint(selectionX1Y1)) ||\n            (allowIntersect && currentObject.containsPoint(selectionX2Y2))\n        ) {\n          group.push(currentObject);\n\n          // only add one object if it's a click\n          if (isClick) {\n            break;\n          }\n        }\n      }\n\n      return group;\n    },\n\n    /**\n     * @private\n     */\n    _maybeGroupObjects: function(e) {\n      if (this.selection && this._groupSelector) {\n        this._groupSelectedObjects(e);\n      }\n      this.setCursor(this.defaultCursor);\n      // clear selection and current transformation\n      this._groupSelector = null;\n    }\n  });\n\n})();\n\n\n(function () {\n\n  var supportQuality = fabric.StaticCanvas.supports('toDataURLWithQuality');\n\n  fabric.util.object.extend(fabric.StaticCanvas.prototype, /** @lends fabric.StaticCanvas.prototype */ {\n\n    /**\n     * Exports canvas element to a dataurl image. Note that when multiplier is used, cropping is scaled appropriately\n     * @param {Object} [options] Options object\n     * @param {String} [options.format=png] The format of the output image. Either \"jpeg\" or \"png\"\n     * @param {Number} [options.quality=1] Quality level (0..1). Only used for jpeg.\n     * @param {Number} [options.multiplier=1] Multiplier to scale by, to have consistent\n     * @param {Number} [options.left] Cropping left offset. Introduced in v1.2.14\n     * @param {Number} [options.top] Cropping top offset. Introduced in v1.2.14\n     * @param {Number} [options.width] Cropping width. Introduced in v1.2.14\n     * @param {Number} [options.height] Cropping height. Introduced in v1.2.14\n     * @param {Boolean} [options.enableRetinaScaling] Enable retina scaling for clone image. Introduce in 2.0.0\n     * @return {String} Returns a data: URL containing a representation of the object in the format specified by options.format\n     * @see {@link http://jsfiddle.net/fabricjs/NfZVb/|jsFiddle demo}\n     * @example <caption>Generate jpeg dataURL with lower quality</caption>\n     * var dataURL = canvas.toDataURL({\n     *   format: 'jpeg',\n     *   quality: 0.8\n     * });\n     * @example <caption>Generate cropped png dataURL (clipping of canvas)</caption>\n     * var dataURL = canvas.toDataURL({\n     *   format: 'png',\n     *   left: 100,\n     *   top: 100,\n     *   width: 200,\n     *   height: 200\n     * });\n     * @example <caption>Generate double scaled png dataURL</caption>\n     * var dataURL = canvas.toDataURL({\n     *   format: 'png',\n     *   multiplier: 2\n     * });\n     */\n    toDataURL: function (options) {\n      options || (options = { });\n\n      var format = options.format || 'png',\n          quality = options.quality || 1,\n          multiplier = (options.multiplier || 1) * (options.enableRetinaScaling ? 1 : 1 / this.getRetinaScaling()),\n          cropping = {\n            left: options.left || 0,\n            top: options.top || 0,\n            width: options.width || 0,\n            height: options.height || 0,\n          };\n      return this.__toDataURLWithMultiplier(format, quality, cropping, multiplier);\n    },\n\n    /**\n     * @private\n     */\n    __toDataURLWithMultiplier: function(format, quality, cropping, multiplier) {\n\n      var origWidth = this.width,\n          origHeight = this.height,\n          scaledWidth = (cropping.width || this.width) * multiplier,\n          scaledHeight = (cropping.height || this.height) * multiplier,\n          zoom = this.getZoom(),\n          newZoom = zoom * multiplier,\n          vp = this.viewportTransform,\n          translateX = (vp[4] - cropping.left) * multiplier,\n          translateY = (vp[5] - cropping.top) * multiplier,\n          newVp = [newZoom, 0, 0, newZoom, translateX, translateY],\n          originalInteractive = this.interactive,\n          originalSkipOffScreen = this.skipOffscreen,\n          needsResize = origWidth !== scaledWidth || origHeight !== scaledHeight;\n\n      this.viewportTransform = newVp;\n      this.skipOffscreen = false;\n      // setting interactive to false avoid exporting controls\n      this.interactive = false;\n      if (needsResize) {\n        this.setDimensions({ width: scaledWidth, height: scaledHeight }, { backstoreOnly: true });\n      }\n      // call a renderAll to force sync update. This will cancel the scheduled requestRenderAll\n      // from setDimensions\n      this.renderAll();\n      var data = this.__toDataURL(format, quality, cropping);\n      this.interactive = originalInteractive;\n      this.skipOffscreen = originalSkipOffScreen;\n      this.viewportTransform = vp;\n      //setDimensions with no option object is taking care of:\n      //this.width, this.height, this.requestRenderAll()\n      if (needsResize) {\n        this.setDimensions({ width: origWidth, height: origHeight }, { backstoreOnly: true });\n      }\n      this.renderAll();\n      return data;\n    },\n\n    /**\n     * @private\n     */\n    __toDataURL: function(format, quality) {\n\n      var canvasEl = this.contextContainer.canvas;\n      var data = supportQuality\n        ? canvasEl.toDataURL('image/' + format, quality)\n        : canvasEl.toDataURL('image/' + format);\n\n      return data;\n    },\n  });\n\n})();\n\n\nfabric.util.object.extend(fabric.StaticCanvas.prototype, /** @lends fabric.StaticCanvas.prototype */ {\n\n  /**\n   * Populates canvas with data from the specified dataless JSON.\n   * JSON format must conform to the one of {@link fabric.Canvas#toDatalessJSON}\n   * @deprecated since 1.2.2\n   * @param {String|Object} json JSON string or object\n   * @param {Function} callback Callback, invoked when json is parsed\n   *                            and corresponding objects (e.g: {@link fabric.Image})\n   *                            are initialized\n   * @param {Function} [reviver] Method for further parsing of JSON elements, called after each fabric object created.\n   * @return {fabric.Canvas} instance\n   * @chainable\n   * @tutorial {@link http://fabricjs.com/fabric-intro-part-3#deserialization}\n   */\n  loadFromDatalessJSON: function (json, callback, reviver) {\n    return this.loadFromJSON(json, callback, reviver);\n  },\n\n  /**\n   * Populates canvas with data from the specified JSON.\n   * JSON format must conform to the one of {@link fabric.Canvas#toJSON}\n   * @param {String|Object} json JSON string or object\n   * @param {Function} callback Callback, invoked when json is parsed\n   *                            and corresponding objects (e.g: {@link fabric.Image})\n   *                            are initialized\n   * @param {Function} [reviver] Method for further parsing of JSON elements, called after each fabric object created.\n   * @return {fabric.Canvas} instance\n   * @chainable\n   * @tutorial {@link http://fabricjs.com/fabric-intro-part-3#deserialization}\n   * @see {@link http://jsfiddle.net/fabricjs/fmgXt/|jsFiddle demo}\n   * @example <caption>loadFromJSON</caption>\n   * canvas.loadFromJSON(json, canvas.renderAll.bind(canvas));\n   * @example <caption>loadFromJSON with reviver</caption>\n   * canvas.loadFromJSON(json, canvas.renderAll.bind(canvas), function(o, object) {\n   *   // `o` = json object\n   *   // `object` = fabric.Object instance\n   *   // ... do some stuff ...\n   * });\n   */\n  loadFromJSON: function (json, callback, reviver) {\n    if (!json) {\n      return;\n    }\n\n    // serialize if it wasn't already\n    var serialized = (typeof json === 'string')\n      ? JSON.parse(json)\n      : fabric.util.object.clone(json);\n\n    var _this = this,\n        renderOnAddRemove = this.renderOnAddRemove;\n    this.renderOnAddRemove = false;\n\n    this._enlivenObjects(serialized.objects, function (enlivenedObjects) {\n      _this.clear();\n      _this._setBgOverlay(serialized, function () {\n        enlivenedObjects.forEach(function(obj, index) {\n          // we splice the array just in case some custom classes restored from JSON\n          // will add more object to canvas at canvas init.\n          _this.insertAt(obj, index);\n        });\n        _this.renderOnAddRemove = renderOnAddRemove;\n        // remove parts i cannot set as options\n        delete serialized.objects;\n        delete serialized.backgroundImage;\n        delete serialized.overlayImage;\n        delete serialized.background;\n        delete serialized.overlay;\n        // this._initOptions does too many things to just\n        // call it. Normally loading an Object from JSON\n        // create the Object instance. Here the Canvas is\n        // already an instance and we are just loading things over it\n        _this._setOptions(serialized);\n        _this.renderAll();\n        callback && callback();\n      });\n    }, reviver);\n    return this;\n  },\n\n  /**\n   * @private\n   * @param {Object} serialized Object with background and overlay information\n   * @param {Function} callback Invoked after all background and overlay images/patterns loaded\n   */\n  _setBgOverlay: function(serialized, callback) {\n    var loaded = {\n      backgroundColor: false,\n      overlayColor: false,\n      backgroundImage: false,\n      overlayImage: false\n    };\n\n    if (!serialized.backgroundImage && !serialized.overlayImage && !serialized.background && !serialized.overlay) {\n      callback && callback();\n      return;\n    }\n\n    var cbIfLoaded = function () {\n      if (loaded.backgroundImage && loaded.overlayImage && loaded.backgroundColor && loaded.overlayColor) {\n        callback && callback();\n      }\n    };\n\n    this.__setBgOverlay('backgroundImage', serialized.backgroundImage, loaded, cbIfLoaded);\n    this.__setBgOverlay('overlayImage', serialized.overlayImage, loaded, cbIfLoaded);\n    this.__setBgOverlay('backgroundColor', serialized.background, loaded, cbIfLoaded);\n    this.__setBgOverlay('overlayColor', serialized.overlay, loaded, cbIfLoaded);\n  },\n\n  /**\n   * @private\n   * @param {String} property Property to set (backgroundImage, overlayImage, backgroundColor, overlayColor)\n   * @param {(Object|String)} value Value to set\n   * @param {Object} loaded Set loaded property to true if property is set\n   * @param {Object} callback Callback function to invoke after property is set\n   */\n  __setBgOverlay: function(property, value, loaded, callback) {\n    var _this = this;\n\n    if (!value) {\n      loaded[property] = true;\n      callback && callback();\n      return;\n    }\n\n    if (property === 'backgroundImage' || property === 'overlayImage') {\n      fabric.util.enlivenObjects([value], function(enlivedObject){\n        _this[property] = enlivedObject[0];\n        loaded[property] = true;\n        callback && callback();\n      });\n    }\n    else {\n      this['set' + fabric.util.string.capitalize(property, true)](value, function() {\n        loaded[property] = true;\n        callback && callback();\n      });\n    }\n  },\n\n  /**\n   * @private\n   * @param {Array} objects\n   * @param {Function} callback\n   * @param {Function} [reviver]\n   */\n  _enlivenObjects: function (objects, callback, reviver) {\n    if (!objects || objects.length === 0) {\n      callback && callback([]);\n      return;\n    }\n\n    fabric.util.enlivenObjects(objects, function(enlivenedObjects) {\n      callback && callback(enlivenedObjects);\n    }, null, reviver);\n  },\n\n  /**\n   * @private\n   * @param {String} format\n   * @param {Function} callback\n   */\n  _toDataURL: function (format, callback) {\n    this.clone(function (clone) {\n      callback(clone.toDataURL(format));\n    });\n  },\n\n  /**\n   * @private\n   * @param {String} format\n   * @param {Number} multiplier\n   * @param {Function} callback\n   */\n  _toDataURLWithMultiplier: function (format, multiplier, callback) {\n    this.clone(function (clone) {\n      callback(clone.toDataURLWithMultiplier(format, multiplier));\n    });\n  },\n\n  /**\n   * Clones canvas instance\n   * @param {Object} [callback] Receives cloned instance as a first argument\n   * @param {Array} [properties] Array of properties to include in the cloned canvas and children\n   */\n  clone: function (callback, properties) {\n    var data = JSON.stringify(this.toJSON(properties));\n    this.cloneWithoutData(function(clone) {\n      clone.loadFromJSON(data, function() {\n        callback && callback(clone);\n      });\n    });\n  },\n\n  /**\n   * Clones canvas instance without cloning existing data.\n   * This essentially copies canvas dimensions, clipping properties, etc.\n   * but leaves data empty (so that you can populate it with your own)\n   * @param {Object} [callback] Receives cloned instance as a first argument\n   */\n  cloneWithoutData: function(callback) {\n    var el = fabric.util.createCanvasElement();\n\n    el.width = this.width;\n    el.height = this.height;\n\n    var clone = new fabric.Canvas(el);\n    clone.clipTo = this.clipTo;\n    if (this.backgroundImage) {\n      clone.setBackgroundImage(this.backgroundImage.src, function() {\n        clone.renderAll();\n        callback && callback(clone);\n      });\n      clone.backgroundImageOpacity = this.backgroundImageOpacity;\n      clone.backgroundImageStretch = this.backgroundImageStretch;\n    }\n    else {\n      callback && callback(clone);\n    }\n  }\n});\n\n\n(function(global) {\n\n  'use strict';\n\n  var fabric = global.fabric || (global.fabric = { }),\n      extend = fabric.util.object.extend,\n      clone = fabric.util.object.clone,\n      toFixed = fabric.util.toFixed,\n      capitalize = fabric.util.string.capitalize,\n      degreesToRadians = fabric.util.degreesToRadians,\n      supportsLineDash = fabric.StaticCanvas.supports('setLineDash'),\n      objectCaching = !fabric.isLikelyNode,\n      ALIASING_LIMIT = 2;\n\n  if (fabric.Object) {\n    return;\n  }\n\n  /**\n   * Root object class from which all 2d shape classes inherit from\n   * @class fabric.Object\n   * @tutorial {@link http://fabricjs.com/fabric-intro-part-1#objects}\n   * @see {@link fabric.Object#initialize} for constructor definition\n   *\n   * @fires added\n   * @fires removed\n   *\n   * @fires selected\n   * @fires deselected\n   * @fires modified\n   * @fires modified\n   * @fires moved\n   * @fires scaled\n   * @fires rotated\n   * @fires skewed\n   *\n   * @fires rotating\n   * @fires scaling\n   * @fires moving\n   * @fires skewing\n   *\n   * @fires mousedown\n   * @fires mouseup\n   * @fires mouseover\n   * @fires mouseout\n   * @fires mousewheel\n   * @fires mousedblclick\n   *\n   * @fires dragover\n   * @fires dragenter\n   * @fires dragleave\n   * @fires drop\n   */\n  fabric.Object = fabric.util.createClass(fabric.CommonMethods, /** @lends fabric.Object.prototype */ {\n\n    /**\n     * Type of an object (rect, circle, path, etc.).\n     * Note that this property is meant to be read-only and not meant to be modified.\n     * If you modify, certain parts of Fabric (such as JSON loading) won't work correctly.\n     * @type String\n     * @default\n     */\n    type:                     'object',\n\n    /**\n     * Horizontal origin of transformation of an object (one of \"left\", \"right\", \"center\")\n     * See http://jsfiddle.net/1ow02gea/244/ on how originX/originY affect objects in groups\n     * @type String\n     * @default\n     */\n    originX:                  'left',\n\n    /**\n     * Vertical origin of transformation of an object (one of \"top\", \"bottom\", \"center\")\n     * See http://jsfiddle.net/1ow02gea/244/ on how originX/originY affect objects in groups\n     * @type String\n     * @default\n     */\n    originY:                  'top',\n\n    /**\n     * Top position of an object. Note that by default it's relative to object top. You can change this by setting originY={top/center/bottom}\n     * @type Number\n     * @default\n     */\n    top:                      0,\n\n    /**\n     * Left position of an object. Note that by default it's relative to object left. You can change this by setting originX={left/center/right}\n     * @type Number\n     * @default\n     */\n    left:                     0,\n\n    /**\n     * Object width\n     * @type Number\n     * @default\n     */\n    width:                    0,\n\n    /**\n     * Object height\n     * @type Number\n     * @default\n     */\n    height:                   0,\n\n    /**\n     * Object scale factor (horizontal)\n     * @type Number\n     * @default\n     */\n    scaleX:                   1,\n\n    /**\n     * Object scale factor (vertical)\n     * @type Number\n     * @default\n     */\n    scaleY:                   1,\n\n    /**\n     * When true, an object is rendered as flipped horizontally\n     * @type Boolean\n     * @default\n     */\n    flipX:                    false,\n\n    /**\n     * When true, an object is rendered as flipped vertically\n     * @type Boolean\n     * @default\n     */\n    flipY:                    false,\n\n    /**\n     * Opacity of an object\n     * @type Number\n     * @default\n     */\n    opacity:                  1,\n\n    /**\n     * Angle of rotation of an object (in degrees)\n     * @type Number\n     * @default\n     */\n    angle:                    0,\n\n    /**\n     * Angle of skew on x axes of an object (in degrees)\n     * @type Number\n     * @default\n     */\n    skewX:                    0,\n\n    /**\n     * Angle of skew on y axes of an object (in degrees)\n     * @type Number\n     * @default\n     */\n    skewY:                    0,\n\n    /**\n     * Size of object's controlling corners (in pixels)\n     * @type Number\n     * @default\n     */\n    cornerSize:               13,\n\n    /**\n     * When true, object's controlling corners are rendered as transparent inside (i.e. stroke instead of fill)\n     * @type Boolean\n     * @default\n     */\n    transparentCorners:       true,\n\n    /**\n     * Default cursor value used when hovering over this object on canvas\n     * @type String\n     * @default\n     */\n    hoverCursor:              null,\n\n    /**\n     * Default cursor value used when moving this object on canvas\n     * @type String\n     * @default\n     */\n    moveCursor:               null,\n\n    /**\n     * Padding between object and its controlling borders (in pixels)\n     * @type Number\n     * @default\n     */\n    padding:                  0,\n\n    /**\n     * Color of controlling borders of an object (when it's active)\n     * @type String\n     * @default\n     */\n    borderColor:              'rgba(102,153,255,0.75)',\n\n    /**\n     * Array specifying dash pattern of an object's borders (hasBorder must be true)\n     * @since 1.6.2\n     * @type Array\n     */\n    borderDashArray:          null,\n\n    /**\n     * Color of controlling corners of an object (when it's active)\n     * @type String\n     * @default\n     */\n    cornerColor:              'rgba(102,153,255,0.5)',\n\n    /**\n     * Color of controlling corners of an object (when it's active and transparentCorners false)\n     * @since 1.6.2\n     * @type String\n     * @default\n     */\n    cornerStrokeColor:        null,\n\n    /**\n     * Specify style of control, 'rect' or 'circle'\n     * @since 1.6.2\n     * @type String\n     */\n    cornerStyle:          'rect',\n\n    /**\n     * Array specifying dash pattern of an object's control (hasBorder must be true)\n     * @since 1.6.2\n     * @type Array\n     */\n    cornerDashArray:          null,\n\n    /**\n     * When true, this object will use center point as the origin of transformation\n     * when being scaled via the controls.\n     * <b>Backwards incompatibility note:</b> This property replaces \"centerTransform\" (Boolean).\n     * @since 1.3.4\n     * @type Boolean\n     * @default\n     */\n    centeredScaling:          false,\n\n    /**\n     * When true, this object will use center point as the origin of transformation\n     * when being rotated via the controls.\n     * <b>Backwards incompatibility note:</b> This property replaces \"centerTransform\" (Boolean).\n     * @since 1.3.4\n     * @type Boolean\n     * @default\n     */\n    centeredRotation:         true,\n\n    /**\n     * Color of object's fill\n     * takes css colors https://www.w3.org/TR/css-color-3/\n     * @type String\n     * @default\n     */\n    fill:                     'rgb(0,0,0)',\n\n    /**\n     * Fill rule used to fill an object\n     * accepted values are nonzero, evenodd\n     * <b>Backwards incompatibility note:</b> This property was used for setting globalCompositeOperation until v1.4.12 (use `fabric.Object#globalCompositeOperation` instead)\n     * @type String\n     * @default\n     */\n    fillRule:                 'nonzero',\n\n    /**\n     * Composite rule used for canvas globalCompositeOperation\n     * @type String\n     * @default\n     */\n    globalCompositeOperation: 'source-over',\n\n    /**\n     * Background color of an object.\n     * takes css colors https://www.w3.org/TR/css-color-3/\n     * @type String\n     * @default\n     */\n    backgroundColor:          '',\n\n    /**\n     * Selection Background color of an object. colored layer behind the object when it is active.\n     * does not mix good with globalCompositeOperation methods.\n     * @type String\n     * @default\n     */\n    selectionBackgroundColor:          '',\n\n    /**\n     * When defined, an object is rendered via stroke and this property specifies its color\n     * takes css colors https://www.w3.org/TR/css-color-3/\n     * @type String\n     * @default\n     */\n    stroke:                   null,\n\n    /**\n     * Width of a stroke used to render this object\n     * @type Number\n     * @default\n     */\n    strokeWidth:              1,\n\n    /**\n     * Array specifying dash pattern of an object's stroke (stroke must be defined)\n     * @type Array\n     */\n    strokeDashArray:          null,\n\n    /**\n     * Line endings style of an object's stroke (one of \"butt\", \"round\", \"square\")\n     * @type String\n     * @default\n     */\n    strokeLineCap:            'butt',\n\n    /**\n     * Corner style of an object's stroke (one of \"bevil\", \"round\", \"miter\")\n     * @type String\n     * @default\n     */\n    strokeLineJoin:           'miter',\n\n    /**\n     * Maximum miter length (used for strokeLineJoin = \"miter\") of an object's stroke\n     * @type Number\n     * @default\n     */\n    strokeMiterLimit:         4,\n\n    /**\n     * Shadow object representing shadow of this shape\n     * @type fabric.Shadow\n     * @default\n     */\n    shadow:                   null,\n\n    /**\n     * Opacity of object's controlling borders when object is active and moving\n     * @type Number\n     * @default\n     */\n    borderOpacityWhenMoving:  0.4,\n\n    /**\n     * Scale factor of object's controlling borders\n     * @type Number\n     * @default\n     */\n    borderScaleFactor:        1,\n\n    /**\n     * Transform matrix (similar to SVG's transform matrix)\n     * @type Array\n     */\n    transformMatrix:          null,\n\n    /**\n     * Minimum allowed scale value of an object\n     * @type Number\n     * @default\n     */\n    minScaleLimit:            0,\n\n    /**\n     * When set to `false`, an object can not be selected for modification (using either point-click-based or group-based selection).\n     * But events still fire on it.\n     * @type Boolean\n     * @default\n     */\n    selectable:               true,\n\n    /**\n     * When set to `false`, an object can not be a target of events. All events propagate through it. Introduced in v1.3.4\n     * @type Boolean\n     * @default\n     */\n    evented:                  true,\n\n    /**\n     * When set to `false`, an object is not rendered on canvas\n     * @type Boolean\n     * @default\n     */\n    visible:                  true,\n\n    /**\n     * When set to `false`, object's controls are not displayed and can not be used to manipulate object\n     * @type Boolean\n     * @default\n     */\n    hasControls:              true,\n\n    /**\n     * When set to `false`, object's controlling borders are not rendered\n     * @type Boolean\n     * @default\n     */\n    hasBorders:               true,\n\n    /**\n     * When set to `false`, object's controlling rotating point will not be visible or selectable\n     * @type Boolean\n     * @default\n     */\n    hasRotatingPoint:         true,\n\n    /**\n     * Offset for object's controlling rotating point (when enabled via `hasRotatingPoint`)\n     * @type Number\n     * @default\n     */\n    rotatingPointOffset:      40,\n\n    /**\n     * When set to `true`, objects are \"found\" on canvas on per-pixel basis rather than according to bounding box\n     * @type Boolean\n     * @default\n     */\n    perPixelTargetFind:       false,\n\n    /**\n     * When `false`, default object's values are not included in its serialization\n     * @type Boolean\n     * @default\n     */\n    includeDefaultValues:     true,\n\n    /**\n     * Function that determines clipping of an object (context is passed as a first argument).\n     * If you are using code minification, ctx argument can be minified/manglied you should use\n     * as a workaround `var ctx = arguments[0];` in the function;\n     * Note that context origin is at the object's center point (not left/top corner)\n     * @deprecated since 2.0.0\n     * @type Function\n     */\n    clipTo:                   null,\n\n    /**\n     * When `true`, object horizontal movement is locked\n     * @type Boolean\n     * @default\n     */\n    lockMovementX:            false,\n\n    /**\n     * When `true`, object vertical movement is locked\n     * @type Boolean\n     * @default\n     */\n    lockMovementY:            false,\n\n    /**\n     * When `true`, object rotation is locked\n     * @type Boolean\n     * @default\n     */\n    lockRotation:             false,\n\n    /**\n     * When `true`, object horizontal scaling is locked\n     * @type Boolean\n     * @default\n     */\n    lockScalingX:             false,\n\n    /**\n     * When `true`, object vertical scaling is locked\n     * @type Boolean\n     * @default\n     */\n    lockScalingY:             false,\n\n    /**\n     * When `true`, object non-uniform scaling is locked\n     * @type Boolean\n     * @default\n     */\n    lockUniScaling:           false,\n\n    /**\n     * When `true`, object horizontal skewing is locked\n     * @type Boolean\n     * @default\n     */\n    lockSkewingX:             false,\n\n    /**\n     * When `true`, object vertical skewing is locked\n     * @type Boolean\n     * @default\n     */\n    lockSkewingY:             false,\n\n    /**\n     * When `true`, object cannot be flipped by scaling into negative values\n     * @type Boolean\n     * @default\n     */\n    lockScalingFlip:          false,\n\n    /**\n     * When `true`, object is not exported in OBJECT/JSON\n     * since 1.6.3\n     * @type Boolean\n     * @default\n     */\n    excludeFromExport:        false,\n\n    /**\n     * When `true`, object is cached on an additional canvas.\n     * 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 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 coner 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     * Determins if the fill or the stroke is drawn first (one of \"fill\" or \"stroke\")\n     * @type String\n     * @default\n     */\n    paintFirst:           'fill',\n\n    /**\n     * List of properties to consider when checking if state\n     * of an object is changed (fabric.Object#hasStateChanged)\n     * as well as for history (undo/redo) purposes\n     * @type Array\n     */\n    stateProperties: (\n      'top left width height scaleX scaleY flipX flipY originX originY transformMatrix ' +\n      'stroke strokeWidth strokeDashArray strokeLineCap strokeLineJoin strokeMiterLimit ' +\n      'angle opacity fill globalCompositeOperation shadow clipTo visible backgroundColor ' +\n      'skewX skewY fillRule paintFirst'\n    ).split(' '),\n\n    /**\n     * List of properties to consider when checking if cache needs refresh\n     * Those properties are checked by statefullCache ON ( or lazy mode if we want ) or from single\n     * calls to Object.set(key, value). If the key is in this list, the object is marked as dirty\n     * and refreshed at the next render\n     * @type Array\n     */\n    cacheProperties: (\n      'fill stroke strokeWidth strokeDashArray width height paintFirst' +\n      ' strokeLineCap strokeLineJoin strokeMiterLimit backgroundColor'\n    ).split(' '),\n\n    /**\n     * a fabricObject that, without stroke define a clipping area with their shape. filled in black\n     * the clipPath object gets used when the object has rendered, and the context is placed in the center\n     * of the object cacheCanvas.\n     * If you want 0,0 of a clipPath to align with an object center, use clipPath.originX/Y to 'center'\n     * @type fabric.Object\n     */\n    clipPath: undefined,\n\n    /**\n     * Meaningfull 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     * Meaningfull ONLY when the object is used as clipPath.\n     * if true, the clipPath will have its top and left relative to canvas, and will\n     * not be influenced by the object transform. This will make the clipPath relative\n     * to the canvas, but clipping just a particular object.\n     * WARNING this is beta, this feature may change or be renamed.\n     * since 2.4.0\n     * @type boolean\n     * @default false\n     */\n    absolutePositioned: false,\n\n    /**\n     * Constructor\n     * @param {Object} [options] Options object\n     */\n    initialize: function(options) {\n      if (options) {\n        this.setOptions(options);\n      }\n    },\n\n    /**\n     * Create a the canvas used to keep the cached copy of the object\n     * @private\n     */\n    _createCacheCanvas: function() {\n      this._cacheProperties = {};\n      this._cacheCanvas = fabric.util.createCanvasElement();\n      this._cacheContext = this._cacheCanvas.getContext('2d');\n      this._updateCacheCanvas();\n      // if canvas gets created, is empty, so dirty.\n      this.dirty = true;\n    },\n\n    /**\n     * Limit the cache dimensions so that X * Y do not cross fabric.perfLimitSizeTotal\n     * and each side do not cross fabric.cacheSideLimit\n     * those numbers are configurable so that you can get as much detail as you want\n     * making bargain with performances.\n     * @param {Object} dims\n     * @param {Object} dims.width width of canvas\n     * @param {Object} dims.height height of canvas\n     * @param {Object} dims.zoomX zoomX zoom value to unscale the canvas before drawing cache\n     * @param {Object} dims.zoomY zoomY zoom value to unscale the canvas before drawing cache\n     * @return {Object}.width width of canvas\n     * @return {Object}.height height of canvas\n     * @return {Object}.zoomX zoomX zoom value to unscale the canvas before drawing cache\n     * @return {Object}.zoomY zoomY zoom value to unscale the canvas before drawing cache\n     */\n    _limitCacheSize: function(dims) {\n      var perfLimitSizeTotal = fabric.perfLimitSizeTotal,\n          width = dims.width, height = dims.height,\n          max = fabric.maxCacheSideLimit, min = fabric.minCacheSideLimit;\n      if (width <= max && height <= max && width * height <= perfLimitSizeTotal) {\n        if (width < min) {\n          dims.width = min;\n        }\n        if (height < min) {\n          dims.height = min;\n        }\n        return dims;\n      }\n      var ar = width / height, limitedDims = fabric.util.limitDimsByArea(ar, perfLimitSizeTotal),\n          capValue = fabric.util.capValue,\n          x = capValue(min, limitedDims.x, max),\n          y = capValue(min, limitedDims.y, max);\n      if (width > x) {\n        dims.zoomX /= width / x;\n        dims.width = x;\n        dims.capped = true;\n      }\n      if (height > y) {\n        dims.zoomY /= height / y;\n        dims.height = y;\n        dims.capped = true;\n      }\n      return dims;\n    },\n\n    /**\n     * Return the dimension and the zoom level needed to create a cache canvas\n     * big enough to host the object to be cached.\n     * @private\n     * @return {Object}.x width of object to be cached\n     * @return {Object}.y height of object to be cached\n     * @return {Object}.width width of canvas\n     * @return {Object}.height height of canvas\n     * @return {Object}.zoomX zoomX zoom value to unscale the canvas before drawing cache\n     * @return {Object}.zoomY zoomY zoom value to unscale the canvas before drawing cache\n     */\n    _getCacheCanvasDimensions: function() {\n      var objectScale = this.getTotalObjectScaling(),\n          dim = this._getNonTransformedDimensions(),\n          zoomX = objectScale.scaleX,\n          zoomY = objectScale.scaleY,\n          width = dim.x * zoomX,\n          height = dim.y * zoomY;\n      return {\n        // for sure this ALIASING_LIMIT is slightly crating problem\n        // in situation in wich the cache canvas gets an upper limit\n        width: width + ALIASING_LIMIT,\n        height: height + ALIASING_LIMIT,\n        zoomX: zoomX,\n        zoomY: zoomY,\n        x: dim.x,\n        y: dim.y\n      };\n    },\n\n    /**\n     * Update width and height of the canvas for cache\n     * returns true or false if canvas needed resize.\n     * @private\n     * @return {Boolean} true if the canvas has been resized\n     */\n    _updateCacheCanvas: function() {\n      var targetCanvas = this.canvas;\n      if (this.noScaleCache && targetCanvas && targetCanvas._currentTransform) {\n        var target = targetCanvas._currentTransform.target,\n            action = targetCanvas._currentTransform.action;\n        if (this === target && action.slice && action.slice(0, 5) === 'scale') {\n          return false;\n        }\n      }\n      var canvas = this._cacheCanvas,\n          dims = this._limitCacheSize(this._getCacheCanvasDimensions()),\n          minCacheSize = fabric.minCacheSideLimit,\n          width = dims.width, height = dims.height, drawingWidth, drawingHeight,\n          zoomX = dims.zoomX, zoomY = dims.zoomY,\n          dimensionsChanged = width !== this.cacheWidth || height !== this.cacheHeight,\n          zoomChanged = this.zoomX !== zoomX || this.zoomY !== zoomY,\n          shouldRedraw = dimensionsChanged || zoomChanged,\n          additionalWidth = 0, additionalHeight = 0, shouldResizeCanvas = false;\n      if (dimensionsChanged) {\n        var canvasWidth = this._cacheCanvas.width,\n            canvasHeight = this._cacheCanvas.height,\n            sizeGrowing = width > canvasWidth || height > canvasHeight,\n            sizeShrinking = (width < canvasWidth * 0.9 || height < canvasHeight * 0.9) &&\n              canvasWidth > minCacheSize && canvasHeight > minCacheSize;\n        shouldResizeCanvas = sizeGrowing || sizeShrinking;\n        if (sizeGrowing && !dims.capped && (width > minCacheSize || height > minCacheSize)) {\n          additionalWidth = width * 0.1;\n          additionalHeight = height * 0.1;\n        }\n      }\n      if (shouldRedraw) {\n        if (shouldResizeCanvas) {\n          canvas.width = Math.ceil(width + additionalWidth);\n          canvas.height = Math.ceil(height + additionalHeight);\n        }\n        else {\n          this._cacheContext.setTransform(1, 0, 0, 1, 0, 0);\n          this._cacheContext.clearRect(0, 0, canvas.width, canvas.height);\n        }\n        drawingWidth = dims.x * zoomX / 2;\n        drawingHeight = dims.y * zoomY / 2;\n        this.cacheTranslationX = Math.round(canvas.width / 2 - drawingWidth) + drawingWidth;\n        this.cacheTranslationY = Math.round(canvas.height / 2 - drawingHeight) + drawingHeight;\n        this.cacheWidth = width;\n        this.cacheHeight = height;\n        this._cacheContext.translate(this.cacheTranslationX, this.cacheTranslationY);\n        this._cacheContext.scale(zoomX, zoomY);\n        this.zoomX = zoomX;\n        this.zoomY = zoomY;\n        return true;\n      }\n      return false;\n    },\n\n    /**\n     * Sets object's properties from options\n     * @param {Object} [options] Options object\n     */\n    setOptions: function(options) {\n      this._setOptions(options);\n      this._initGradient(options.fill, 'fill');\n      this._initGradient(options.stroke, 'stroke');\n      this._initClipping(options);\n      this._initPattern(options.fill, 'fill');\n      this._initPattern(options.stroke, 'stroke');\n    },\n\n    /**\n     * Transforms context when rendering an object\n     * @param {CanvasRenderingContext2D} ctx Context\n     */\n    transform: function(ctx) {\n      var m;\n      if (this.group && !this.group._transformDone) {\n        m = this.calcTransformMatrix();\n      }\n      else {\n        m = this.calcOwnMatrix();\n      }\n      ctx.transform(m[0], m[1], m[2], m[3], m[4], m[5]);\n    },\n\n    /**\n     * Returns an object representation of an instance\n     * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output\n     * @return {Object} Object representation of an instance\n     */\n    toObject: function(propertiesToInclude) {\n      var NUM_FRACTION_DIGITS = fabric.Object.NUM_FRACTION_DIGITS,\n\n          object = {\n            type:                     this.type,\n            version:                  fabric.version,\n            originX:                  this.originX,\n            originY:                  this.originY,\n            left:                     toFixed(this.left, NUM_FRACTION_DIGITS),\n            top:                      toFixed(this.top, NUM_FRACTION_DIGITS),\n            width:                    toFixed(this.width, NUM_FRACTION_DIGITS),\n            height:                   toFixed(this.height, NUM_FRACTION_DIGITS),\n            fill:                     (this.fill && this.fill.toObject) ? this.fill.toObject() : this.fill,\n            stroke:                   (this.stroke && this.stroke.toObject) ? this.stroke.toObject() : this.stroke,\n            strokeWidth:              toFixed(this.strokeWidth, NUM_FRACTION_DIGITS),\n            strokeDashArray:          this.strokeDashArray ? this.strokeDashArray.concat() : this.strokeDashArray,\n            strokeLineCap:            this.strokeLineCap,\n            strokeLineJoin:           this.strokeLineJoin,\n            strokeMiterLimit:         toFixed(this.strokeMiterLimit, NUM_FRACTION_DIGITS),\n            scaleX:                   toFixed(this.scaleX, NUM_FRACTION_DIGITS),\n            scaleY:                   toFixed(this.scaleY, NUM_FRACTION_DIGITS),\n            angle:                    toFixed(this.angle, NUM_FRACTION_DIGITS),\n            flipX:                    this.flipX,\n            flipY:                    this.flipY,\n            opacity:                  toFixed(this.opacity, NUM_FRACTION_DIGITS),\n            shadow:                   (this.shadow && this.shadow.toObject) ? this.shadow.toObject() : this.shadow,\n            visible:                  this.visible,\n            clipTo:                   this.clipTo && String(this.clipTo),\n            backgroundColor:          this.backgroundColor,\n            fillRule:                 this.fillRule,\n            paintFirst:               this.paintFirst,\n            globalCompositeOperation: this.globalCompositeOperation,\n            transformMatrix:          this.transformMatrix ? this.transformMatrix.concat() : null,\n            skewX:                    toFixed(this.skewX, NUM_FRACTION_DIGITS),\n            skewY:                    toFixed(this.skewY, NUM_FRACTION_DIGITS),\n          };\n\n      if (this.clipPath) {\n        object.clipPath = this.clipPath.toObject(propertiesToInclude);\n        object.clipPath.inverted = this.clipPath.inverted;\n        object.clipPath.absolutePositioned = this.clipPath.absolutePositioned;\n      }\n\n      fabric.util.populateWithProperties(this, object, propertiesToInclude);\n      if (!this.includeDefaultValues) {\n        object = this._removeDefaultValues(object);\n      }\n\n      return object;\n    },\n\n    /**\n     * Returns (dataless) object representation of an instance\n     * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output\n     * @return {Object} Object representation of an instance\n     */\n    toDatalessObject: function(propertiesToInclude) {\n      // will be overwritten by subclasses\n      return this.toObject(propertiesToInclude);\n    },\n\n    /**\n     * @private\n     * @param {Object} object\n     */\n    _removeDefaultValues: function(object) {\n      var prototype = fabric.util.getKlass(object.type).prototype,\n          stateProperties = prototype.stateProperties;\n      stateProperties.forEach(function(prop) {\n        if (object[prop] === prototype[prop]) {\n          delete object[prop];\n        }\n        var isArray = Object.prototype.toString.call(object[prop]) === '[object Array]' &&\n                      Object.prototype.toString.call(prototype[prop]) === '[object Array]';\n\n        // basically a check for [] === []\n        if (isArray && object[prop].length === 0 && prototype[prop].length === 0) {\n          delete object[prop];\n        }\n      });\n\n      return object;\n    },\n\n    /**\n     * Returns a string representation of an instance\n     * @return {String}\n     */\n    toString: function() {\n      return '#<fabric.' + capitalize(this.type) + '>';\n    },\n\n    /**\n     * Return the object scale factor counting also the group scaling\n     * @return {Object} object with scaleX and scaleY properties\n     */\n    getObjectScaling: function() {\n      var scaleX = this.scaleX, scaleY = this.scaleY;\n      if (this.group) {\n        var scaling = this.group.getObjectScaling();\n        scaleX *= scaling.scaleX;\n        scaleY *= scaling.scaleY;\n      }\n      return { scaleX: scaleX, scaleY: scaleY };\n    },\n\n    /**\n     * Return the object scale factor counting also the group scaling, zoom and retina\n     * @return {Object} object with scaleX and scaleY properties\n     */\n    getTotalObjectScaling: function() {\n      var scale = this.getObjectScaling(), scaleX = scale.scaleX, scaleY = scale.scaleY;\n      if (this.canvas) {\n        var zoom = this.canvas.getZoom();\n        var retina = this.canvas.getRetinaScaling();\n        scaleX *= zoom * retina;\n        scaleY *= zoom * retina;\n      }\n      return { scaleX: scaleX, scaleY: scaleY };\n    },\n\n    /**\n     * Return the object opacity counting also the group property\n     * @return {Number}\n     */\n    getObjectOpacity: function() {\n      var opacity = this.opacity;\n      if (this.group) {\n        opacity *= this.group.getObjectOpacity();\n      }\n      return opacity;\n    },\n\n    /**\n     * @private\n     * @param {String} key\n     * @param {*} value\n     * @return {fabric.Object} thisArg\n     */\n    _set: function(key, value) {\n      var shouldConstrainValue = (key === 'scaleX' || key === 'scaleY'),\n          isChanged = this[key] !== value, groupNeedsUpdate = false;\n\n      if (shouldConstrainValue) {\n        value = this._constrainScale(value);\n      }\n      if (key === 'scaleX' && value < 0) {\n        this.flipX = !this.flipX;\n        value *= -1;\n      }\n      else if (key === 'scaleY' && value < 0) {\n        this.flipY = !this.flipY;\n        value *= -1;\n      }\n      else if (key === 'shadow' && value && !(value instanceof fabric.Shadow)) {\n        value = new fabric.Shadow(value);\n      }\n      else if (key === 'dirty' && this.group) {\n        this.group.set('dirty', value);\n      }\n\n      this[key] = value;\n\n      if (isChanged) {\n        groupNeedsUpdate = this.group && this.group.isOnACache();\n        if (this.cacheProperties.indexOf(key) > -1) {\n          this.dirty = true;\n          groupNeedsUpdate && this.group.set('dirty', true);\n        }\n        else if (groupNeedsUpdate && this.stateProperties.indexOf(key) > -1) {\n          this.group.set('dirty', true);\n        }\n      }\n\n      return this;\n    },\n\n    /**\n     * This callback function is called by the parent group of an object every\n     * time a non-delegated property changes on the group. It is passed the key\n     * and value as parameters. Not adding in this function's signature to avoid\n     * Travis build error about unused variables.\n     */\n    setOnGroup: function() {\n      // implemented by sub-classes, as needed.\n    },\n\n    /**\n     * Retrieves viewportTransform from Object's canvas if possible\n     * @method getViewportTransform\n     * @memberOf fabric.Object.prototype\n     * @return {Boolean}\n     */\n    getViewportTransform: function() {\n      if (this.canvas && this.canvas.viewportTransform) {\n        return this.canvas.viewportTransform;\n      }\n      return fabric.iMatrix.concat();\n    },\n\n    /*\n     * @private\n     * return if the object would be visible in rendering\n     * @memberOf fabric.Object.prototype\n     * @return {Boolean}\n     */\n    isNotVisible: function() {\n      return this.opacity === 0 || (this.width === 0 && this.height === 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(ctx) {\n      // do not render if width/height are zeros or object is not visible\n      if (this.isNotVisible()) {\n        return;\n      }\n      if (this.canvas && this.canvas.skipOffscreen && !this.group && !this.isOnScreen()) {\n        return;\n      }\n      ctx.save();\n      this._setupCompositeOperation(ctx);\n      this.drawSelectionBackground(ctx);\n      this.transform(ctx);\n      this._setOpacity(ctx);\n      this._setShadow(ctx, this);\n      if (this.transformMatrix) {\n        ctx.transform.apply(ctx, this.transformMatrix);\n      }\n      this.clipTo && fabric.util.clipContext(this, ctx);\n      if (this.shouldCache()) {\n        this.renderCache();\n        this.drawCacheOnCanvas(ctx);\n      }\n      else {\n        this._removeCacheCanvas();\n        this.dirty = false;\n        this.drawObject(ctx);\n        if (this.objectCaching && this.statefullCache) {\n          this.saveState({ propertySet: 'cacheProperties' });\n        }\n      }\n      this.clipTo && ctx.restore();\n      ctx.restore();\n    },\n\n    renderCache: function(options) {\n      options = options || {};\n      if (!this._cacheCanvas) {\n        this._createCacheCanvas();\n      }\n      if (this.isCacheDirty()) {\n        this.statefullCache && this.saveState({ propertySet: 'cacheProperties' });\n        this.drawObject(this._cacheContext, options.forClipping);\n        this.dirty = false;\n      }\n    },\n\n    /**\n     * Remove cacheCanvas and its dimensions from the objects\n     */\n    _removeCacheCanvas: function() {\n      this._cacheCanvas = null;\n      this.cacheWidth = 0;\n      this.cacheHeight = 0;\n    },\n\n    /**\n     * 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 false\n     */\n    needsItsOwnCache: function() {\n      if (this.paintFirst === 'stroke' && typeof this.shadow === 'object') {\n        return true;\n      }\n      if (this.clipPath) {\n        return true;\n      }\n      return false;\n    },\n\n    /**\n     * Decide if the object should cache or not. Create its own cache level\n     * objectCaching is a global flag, wins over everything\n     * needsItsOwnCache should be used when the object drawing method requires\n     * a cache step. None of the fabric classes requires it.\n     * Generally you do not cache objects in groups because the group outside is cached.\n     * @return {Boolean}\n     */\n    shouldCache: function() {\n      this.ownCaching = this.objectCaching &&\n      (!this.group || this.needsItsOwnCache() || !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() {\n      return !!this.shadow && (this.shadow.offsetX !== 0 || this.shadow.offsetY !== 0);\n    },\n\n    /**\n     * Execute the drawing operation for an object clipPath\n     * @param {CanvasRenderingContext2D} ctx Context to render on\n     */\n    drawClipPathOnCache: function(ctx) {\n      var path = this.clipPath;\n      ctx.save();\n      // DEBUG: uncomment this line, comment the following\n      // ctx.globalAlpha = 0.4\n      if (path.inverted) {\n        ctx.globalCompositeOperation = 'destination-out';\n      }\n      else {\n        ctx.globalCompositeOperation = 'destination-in';\n      }\n      //ctx.scale(1 / 2, 1 / 2);\n      if (path.absolutePositioned) {\n        var m = fabric.util.invertTransform(this.calcTransformMatrix());\n        ctx.transform(m[0], m[1], m[2], m[3], m[4], m[5]);\n      }\n      path.transform(ctx);\n      ctx.scale(1 / path.zoomX, 1 / path.zoomY);\n      ctx.drawImage(path._cacheCanvas, -path.cacheTranslationX, -path.cacheTranslationY);\n      ctx.restore();\n    },\n\n    /**\n     * Execute the drawing operation for an object on a specified context\n     * @param {CanvasRenderingContext2D} ctx Context to render on\n     */\n    drawObject: function(ctx, forClipping) {\n\n      if (forClipping) {\n        this._setClippingProperties(ctx);\n      }\n      else {\n        this._renderBackground(ctx);\n        this._setStrokeStyles(ctx, this);\n        this._setFillStyles(ctx, this);\n      }\n      this._render(ctx);\n      this._drawClipPath(ctx);\n    },\n\n    _drawClipPath: function(ctx) {\n      var path = this.clipPath;\n      if (!path) { return; }\n      // needed to setup a couple of variables\n      // path canvas gets overridden with this one.\n      // TODO find a better solution?\n      path.canvas = this.canvas;\n      path.shouldCache();\n      path._transformDone = true;\n      path.renderCache({ forClipping: true });\n      this.drawClipPathOnCache(ctx);\n    },\n\n    /**\n     * Paint the cached copy of the object on the target context.\n     * @param {CanvasRenderingContext2D} ctx Context to render on\n     */\n    drawCacheOnCanvas: function(ctx) {\n      ctx.scale(1 / this.zoomX, 1 / this.zoomY);\n      ctx.drawImage(this._cacheCanvas, -this.cacheTranslationX, -this.cacheTranslationY);\n    },\n\n    /**\n     * Check if cache is dirty\n     * @param {Boolean} skipCanvas skip canvas checks because this object is painted\n     * on parent canvas.\n     */\n    isCacheDirty: function(skipCanvas) {\n      if (this.isNotVisible()) {\n        return false;\n      }\n      if (this._cacheCanvas && !skipCanvas && this._updateCacheCanvas()) {\n        // in this case the context is already cleared.\n        return true;\n      }\n      else {\n        if (this.dirty ||\n          (this.clipPath && this.clipPath.absolutePositioned) ||\n          (this.statefullCache && this.hasStateChanged('cacheProperties'))\n        ) {\n          if (this._cacheCanvas && !skipCanvas) {\n            var width = this.cacheWidth / this.zoomX;\n            var height = this.cacheHeight / this.zoomY;\n            this._cacheContext.clearRect(-width / 2, -height / 2, width, height);\n          }\n          return true;\n        }\n      }\n      return false;\n    },\n\n    /**\n     * Draws a background for the object big as its untrasformed dimensions\n     * @private\n     * @param {CanvasRenderingContext2D} ctx Context to render on\n     */\n    _renderBackground: function(ctx) {\n      if (!this.backgroundColor) {\n        return;\n      }\n      var dim = this._getNonTransformedDimensions();\n      ctx.fillStyle = this.backgroundColor;\n\n      ctx.fillRect(\n        -dim.x / 2,\n        -dim.y / 2,\n        dim.x,\n        dim.y\n      );\n      // if there is background color no other shadows\n      // should be casted\n      this._removeShadow(ctx);\n    },\n\n    /**\n     * @private\n     * @param {CanvasRenderingContext2D} ctx Context to render on\n     */\n    _setOpacity: function(ctx) {\n      if (this.group && !this.group._transformDone) {\n        ctx.globalAlpha = this.getObjectOpacity();\n      }\n      else {\n        ctx.globalAlpha *= this.opacity;\n      }\n    },\n\n    _setStrokeStyles: function(ctx, decl) {\n      if (decl.stroke) {\n        ctx.lineWidth = decl.strokeWidth;\n        ctx.lineCap = decl.strokeLineCap;\n        ctx.lineJoin = decl.strokeLineJoin;\n        ctx.miterLimit = decl.strokeMiterLimit;\n        ctx.strokeStyle = decl.stroke.toLive\n          ? decl.stroke.toLive(ctx, this)\n          : decl.stroke;\n      }\n    },\n\n    _setFillStyles: function(ctx, decl) {\n      if (decl.fill) {\n        ctx.fillStyle = decl.fill.toLive\n          ? decl.fill.toLive(ctx, this)\n          : decl.fill;\n      }\n    },\n\n    _setClippingProperties: function(ctx) {\n      ctx.globalAlpha = 1;\n      ctx.strokeStyle = 'transparent';\n      ctx.fillStyle = '#000000';\n    },\n\n    /**\n     * @private\n     * Sets line dash\n     * @param {CanvasRenderingContext2D} ctx Context to set the dash line on\n     * @param {Array} dashArray array representing dashes\n     * @param {Function} alternative function to call if browaser does not support lineDash\n     */\n    _setLineDash: function(ctx, dashArray, alternative) {\n      if (!dashArray) {\n        return;\n      }\n      // Spec requires the concatenation of two copies the dash list when the number of elements is odd\n      if (1 & dashArray.length) {\n        dashArray.push.apply(dashArray, dashArray);\n      }\n      if (supportsLineDash) {\n        ctx.setLineDash(dashArray);\n      }\n      else {\n        alternative && alternative(ctx);\n      }\n    },\n\n    /**\n     * Renders controls and borders for the object\n     * @param {CanvasRenderingContext2D} ctx Context to render on\n     * @param {Object} [styleOverride] properties to override the object style\n     */\n    _renderControls: function(ctx, styleOverride) {\n      var vpt = this.getViewportTransform(),\n          matrix = this.calcTransformMatrix(),\n          options, drawBorders, drawControls;\n      styleOverride = styleOverride || { };\n      drawBorders = typeof styleOverride.hasBorders !== 'undefined' ? styleOverride.hasBorders : this.hasBorders;\n      drawControls = typeof styleOverride.hasControls !== 'undefined' ? styleOverride.hasControls : this.hasControls;\n      matrix = fabric.util.multiplyTransformMatrices(vpt, matrix);\n      options = fabric.util.qrDecompose(matrix);\n      ctx.save();\n      ctx.translate(options.translateX, options.translateY);\n      ctx.lineWidth = 1 * this.borderScaleFactor;\n      if (!this.group) {\n        ctx.globalAlpha = this.isMoving ? this.borderOpacityWhenMoving : 1;\n      }\n      if (styleOverride.forActiveSelection) {\n        ctx.rotate(degreesToRadians(options.angle));\n        drawBorders && this.drawBordersInGroup(ctx, options, styleOverride);\n      }\n      else {\n        ctx.rotate(degreesToRadians(this.angle));\n        drawBorders && this.drawBorders(ctx, styleOverride);\n      }\n      drawControls && this.drawControls(ctx, styleOverride);\n      ctx.restore();\n    },\n\n    /**\n     * @private\n     * @param {CanvasRenderingContext2D} ctx Context to render on\n     */\n    _setShadow: function(ctx) {\n      if (!this.shadow) {\n        return;\n      }\n\n      var multX = (this.canvas && this.canvas.viewportTransform[0]) || 1,\n          multY = (this.canvas && this.canvas.viewportTransform[3]) || 1,\n          scaling = this.getObjectScaling();\n      if (this.canvas && this.canvas._isRetinaScaling()) {\n        multX *= fabric.devicePixelRatio;\n        multY *= fabric.devicePixelRatio;\n      }\n      ctx.shadowColor = this.shadow.color;\n      ctx.shadowBlur = this.shadow.blur * fabric.browserShadowBlurConstant *\n        (multX + multY) * (scaling.scaleX + scaling.scaleY) / 4;\n      ctx.shadowOffsetX = this.shadow.offsetX * multX * scaling.scaleX;\n      ctx.shadowOffsetY = this.shadow.offsetY * multY * scaling.scaleY;\n    },\n\n    /**\n     * @private\n     * @param {CanvasRenderingContext2D} ctx Context to render on\n     */\n    _removeShadow: function(ctx) {\n      if (!this.shadow) {\n        return;\n      }\n\n      ctx.shadowColor = '';\n      ctx.shadowBlur = ctx.shadowOffsetX = ctx.shadowOffsetY = 0;\n    },\n\n    /**\n     * @private\n     * @param {CanvasRenderingContext2D} ctx Context to render on\n     * @param {Object} filler fabric.Pattern or fabric.Gradient\n     */\n    _applyPatternGradientTransform: function(ctx, filler) {\n      if (!filler || !filler.toLive) {\n        return { offsetX: 0, offsetY: 0 };\n      }\n      var t = filler.gradientTransform || filler.patternTransform;\n      var offsetX = -this.width / 2 + filler.offsetX || 0,\n          offsetY = -this.height / 2 + filler.offsetY || 0;\n      ctx.translate(offsetX, offsetY);\n      if (t) {\n        ctx.transform(t[0], t[1], t[2], t[3], t[4], t[5]);\n      }\n      return { offsetX: offsetX, offsetY: offsetY };\n    },\n\n    /**\n     * @private\n     * @param {CanvasRenderingContext2D} ctx Context to render on\n     */\n    _renderPaintInOrder: function(ctx) {\n      if (this.paintFirst === 'stroke') {\n        this._renderStroke(ctx);\n        this._renderFill(ctx);\n      }\n      else {\n        this._renderFill(ctx);\n        this._renderStroke(ctx);\n      }\n    },\n\n    /**\n     * @private\n     * @param {CanvasRenderingContext2D} ctx Context to render on\n     */\n    _renderFill: function(ctx) {\n      if (!this.fill) {\n        return;\n      }\n\n      ctx.save();\n      this._applyPatternGradientTransform(ctx, this.fill);\n      if (this.fillRule === 'evenodd') {\n        ctx.fill('evenodd');\n      }\n      else {\n        ctx.fill();\n      }\n      ctx.restore();\n    },\n\n    _renderStroke: function(ctx) {\n      if (!this.stroke || this.strokeWidth === 0) {\n        return;\n      }\n\n      if (this.shadow && !this.shadow.affectStroke) {\n        this._removeShadow(ctx);\n      }\n\n      ctx.save();\n      this._setLineDash(ctx, this.strokeDashArray, this._renderDashedStroke);\n      this._applyPatternGradientTransform(ctx, this.stroke);\n      ctx.stroke();\n      ctx.restore();\n    },\n\n    /**\n     * This function is an helper for svg import. it returns the center of the object in the svg\n     * untransformed coordinates\n     * @private\n     * @return {Object} center point from element coordinates\n     */\n    _findCenterFromElement: function() {\n      return { x: this.left + this.width / 2, y: this.top + this.height / 2 };\n    },\n\n    /**\n     * This function is an helper for svg import. it decoompose the transformMatrix\n     * and assign properties to object.\n     * untransformed coordinates\n     * @private\n     * @chainable\n     */\n    _assignTransformMatrixProps: function() {\n      if (this.transformMatrix) {\n        var options = fabric.util.qrDecompose(this.transformMatrix);\n        this.flipX = false;\n        this.flipY = false;\n        this.set('scaleX', options.scaleX);\n        this.set('scaleY', options.scaleY);\n        this.angle = options.angle;\n        this.skewX = options.skewX;\n        this.skewY = 0;\n      }\n    },\n\n    /**\n     * This function is an helper for svg import. it removes the transform matrix\n     * and set to object properties that fabricjs can handle\n     * @private\n     * @param {Object} preserveAspectRatioOptions\n     * @return {thisArg}\n     */\n    _removeTransformMatrix: function(preserveAspectRatioOptions) {\n      var center = this._findCenterFromElement();\n      if (this.transformMatrix) {\n        this._assignTransformMatrixProps();\n        center = fabric.util.transformPoint(center, this.transformMatrix);\n      }\n      this.transformMatrix = null;\n      if (preserveAspectRatioOptions) {\n        this.scaleX *= preserveAspectRatioOptions.scaleX;\n        this.scaleY *= preserveAspectRatioOptions.scaleY;\n        this.cropX = preserveAspectRatioOptions.cropX;\n        this.cropY = preserveAspectRatioOptions.cropY;\n        center.x += preserveAspectRatioOptions.offsetLeft;\n        center.y += preserveAspectRatioOptions.offsetTop;\n        this.width = preserveAspectRatioOptions.width;\n        this.height = preserveAspectRatioOptions.height;\n      }\n      this.setPositionByOrigin(center, 'center', 'center');\n    },\n\n    /**\n     * Clones an instance, using a callback method will work for every object.\n     * @param {Function} callback Callback is invoked with a clone as a first argument\n     * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output\n     */\n    clone: function(callback, propertiesToInclude) {\n      var objectForm = this.toObject(propertiesToInclude);\n      if (this.constructor.fromObject) {\n        this.constructor.fromObject(objectForm, callback);\n      }\n      else {\n        fabric.Object._fromObject('Object', objectForm, callback);\n      }\n    },\n\n    /**\n     * Creates an instance of fabric.Image out of an object\n     * @param {Function} callback callback, invoked with an instance as a first argument\n     * @param {Object} [options] for clone as image, passed to toDataURL\n     * @param {String} [options.format=png] The format of the output image. Either \"jpeg\" or \"png\"\n     * @param {Number} [options.quality=1] Quality level (0..1). Only used for jpeg.\n     * @param {Number} [options.multiplier=1] Multiplier to scale by\n     * @param {Number} [options.left] Cropping left offset. Introduced in v1.2.14\n     * @param {Number} [options.top] Cropping top offset. Introduced in v1.2.14\n     * @param {Number} [options.width] Cropping width. Introduced in v1.2.14\n     * @param {Number} [options.height] Cropping height. Introduced in v1.2.14\n     * @param {Boolean} [options.enableRetinaScaling] Enable retina scaling for clone image. Introduce in 1.6.4\n     * @param {Boolean} [options.withoutTransform] Remove current object transform ( no scale , no angle, no flip, no skew ). Introduced in 2.3.4\n     * @param {Boolean} [options.withoutShadow] Remove current object shadow. Introduced in 2.4.2\n     * @return {fabric.Object} thisArg\n     */\n    cloneAsImage: function(callback, options) {\n      var dataUrl = this.toDataURL(options);\n      fabric.util.loadImage(dataUrl, function(img) {\n        if (callback) {\n          callback(new fabric.Image(img));\n        }\n      });\n      return this;\n    },\n\n    /**\n     * Converts an object into a data-url-like string\n     * @param {Object} options Options object\n     * @param {String} [options.format=png] The format of the output image. Either \"jpeg\" or \"png\"\n     * @param {Number} [options.quality=1] Quality level (0..1). Only used for jpeg.\n     * @param {Number} [options.multiplier=1] Multiplier to scale by\n     * @param {Number} [options.left] Cropping left offset. Introduced in v1.2.14\n     * @param {Number} [options.top] Cropping top offset. Introduced in v1.2.14\n     * @param {Number} [options.width] Cropping width. Introduced in v1.2.14\n     * @param {Number} [options.height] Cropping height. Introduced in v1.2.14\n     * @param {Boolean} [options.enableRetinaScaling] Enable retina scaling for clone image. Introduce in 1.6.4\n     * @param {Boolean} [options.withoutTransform] Remove current object transform ( no scale , no angle, no flip, no skew ). Introduced in 2.3.4\n     * @param {Boolean} [options.withoutShadow] Remove current object shadow. Introduced in 2.4.2\n     * @return {String} Returns a data: URL containing a representation of the object in the format specified by options.format\n     */\n    toDataURL: function(options) {\n      options || (options = { });\n\n      var utils = fabric.util, origParams = utils.saveObjectTransform(this),\n          originalShadow = this.shadow, abs = Math.abs;\n\n      if (options.withoutTransform) {\n        utils.resetObjectTransform(this);\n      }\n      if (options.withoutShadow) {\n        this.shadow = null;\n      }\n\n      var el = fabric.util.createCanvasElement(),\n          // skip canvas zoom and calculate with setCoords now.\n          boundingRect = this.getBoundingRect(true, true),\n          shadow = this.shadow, scaling,\n          shadowOffset = { x: 0, y: 0 }, shadowBlur;\n\n      if (shadow) {\n        shadowBlur = shadow.blur;\n        scaling = this.getObjectScaling();\n        shadowOffset.x = 2 * Math.round((abs(shadow.offsetX) + shadowBlur) * abs(scaling.scaleX));\n        shadowOffset.y = 2 * Math.round((abs(shadow.offsetY) + shadowBlur) * abs(scaling.scaleY));\n      }\n      el.width = boundingRect.width + shadowOffset.x;\n      el.height = boundingRect.height + shadowOffset.y;\n      el.width += el.width % 2 ? 2 - el.width % 2 : 0;\n      el.height += el.height % 2 ? 2 - el.height % 2 : 0;\n      var canvas = new fabric.StaticCanvas(el, {\n        enableRetinaScaling: options.enableRetinaScaling,\n        renderOnAddRemove: false,\n        skipOffscreen: false,\n      });\n      if (options.format === 'jpeg') {\n        canvas.backgroundColor = '#fff';\n      }\n      this.setPositionByOrigin(new fabric.Point(canvas.width / 2, canvas.height / 2), 'center', 'center');\n\n      var originalCanvas = this.canvas;\n      canvas.add(this);\n      var data = canvas.toDataURL(options);\n      this.shadow = originalShadow;\n      this.set(origParams).setCoords();\n      this.canvas = originalCanvas;\n      // canvas.dispose will call image.dispose that will nullify the elements\n      // since this canvas is a simple element for the process, we remove references\n      // to objects in this way in order to avoid object trashing.\n      canvas._objects = [];\n      canvas.dispose();\n      canvas = null;\n\n      return data;\n    },\n\n    /**\n     * Returns true if specified type is identical to the type of an instance\n     * @param {String} type Type to check against\n     * @return {Boolean}\n     */\n    isType: function(type) {\n      return this.type === type;\n    },\n\n    /**\n     * Returns complexity of an instance\n     * @return {Number} complexity of this instance (is 1 unless subclassed)\n     */\n    complexity: function() {\n      return 1;\n    },\n\n    /**\n     * Returns a JSON representation of an instance\n     * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output\n     * @return {Object} JSON\n     */\n    toJSON: function(propertiesToInclude) {\n      // delegate, not alias\n      return this.toObject(propertiesToInclude);\n    },\n\n    /**\n     * Sets gradient (fill or stroke) of an object\n     * <b>Backwards incompatibility note:</b> This method was named \"setGradientFill\" until v1.1.0\n     * @param {String} property Property name 'stroke' or 'fill'\n     * @param {Object} [options] Options object\n     * @param {String} [options.type] Type of gradient 'radial' or 'linear'\n     * @param {Number} [options.x1=0] x-coordinate of start point\n     * @param {Number} [options.y1=0] y-coordinate of start point\n     * @param {Number} [options.x2=0] x-coordinate of end point\n     * @param {Number} [options.y2=0] y-coordinate of end point\n     * @param {Number} [options.r1=0] Radius of start point (only for radial gradients)\n     * @param {Number} [options.r2=0] Radius of end point (only for radial gradients)\n     * @param {Object} [options.colorStops] Color stops object eg. {0: 'ff0000', 1: '000000'}\n     * @param {Object} [options.gradientTransform] transforMatrix for gradient\n     * @return {fabric.Object} thisArg\n     * @chainable\n     * @see {@link http://jsfiddle.net/fabricjs/58y8b/|jsFiddle demo}\n     * @example <caption>Set linear gradient</caption>\n     * object.setGradient('fill', {\n     *   type: 'linear',\n     *   x1: -object.width / 2,\n     *   y1: 0,\n     *   x2: object.width / 2,\n     *   y2: 0,\n     *   colorStops: {\n     *     0: 'red',\n     *     0.5: '#005555',\n     *     1: 'rgba(0,0,255,0.5)'\n     *   }\n     * });\n     * canvas.renderAll();\n     * @example <caption>Set radial gradient</caption>\n     * object.setGradient('fill', {\n     *   type: 'radial',\n     *   x1: 0,\n     *   y1: 0,\n     *   x2: 0,\n     *   y2: 0,\n     *   r1: object.width / 2,\n     *   r2: 10,\n     *   colorStops: {\n     *     0: 'red',\n     *     0.5: '#005555',\n     *     1: 'rgba(0,0,255,0.5)'\n     *   }\n     * });\n     * canvas.renderAll();\n     */\n    setGradient: function(property, options) {\n      options || (options = { });\n\n      var gradient = { colorStops: [] };\n\n      gradient.type = options.type || (options.r1 || options.r2 ? 'radial' : 'linear');\n      gradient.coords = {\n        x1: options.x1,\n        y1: options.y1,\n        x2: options.x2,\n        y2: options.y2\n      };\n\n      if (options.r1 || options.r2) {\n        gradient.coords.r1 = options.r1;\n        gradient.coords.r2 = options.r2;\n      }\n\n      gradient.gradientTransform = options.gradientTransform;\n      fabric.Gradient.prototype.addColorStop.call(gradient, options.colorStops);\n\n      return this.set(property, fabric.Gradient.forObject(this, gradient));\n    },\n\n    /**\n     * Sets pattern fill of an object\n     * @param {Object} options Options object\n     * @param {(String|HTMLImageElement)} options.source Pattern source\n     * @param {String} [options.repeat=repeat] Repeat property of a pattern (one of repeat, repeat-x, repeat-y or no-repeat)\n     * @param {Number} [options.offsetX=0] Pattern horizontal offset from object's left/top corner\n     * @param {Number} [options.offsetY=0] Pattern vertical offset from object's left/top corner\n     * @param {Function} [callback] Callback to invoke when image set as a pattern\n     * @return {fabric.Object} thisArg\n     * @chainable\n     * @see {@link http://jsfiddle.net/fabricjs/QT3pa/|jsFiddle demo}\n     * @example <caption>Set pattern</caption>\n     * object.setPatternFill({\n     *   source: 'http://fabricjs.com/assets/escheresque_ste.png',\n     *   repeat: 'repeat'\n     * },canvas.renderAll.bind(canvas));\n     */\n    setPatternFill: function(options, callback) {\n      return this.set('fill', new fabric.Pattern(options, callback));\n    },\n\n    /**\n     * Sets {@link fabric.Object#shadow|shadow} of an object\n     * @param {Object|String} [options] Options object or string (e.g. \"2px 2px 10px rgba(0,0,0,0.2)\")\n     * @param {String} [options.color=rgb(0,0,0)] Shadow color\n     * @param {Number} [options.blur=0] Shadow blur\n     * @param {Number} [options.offsetX=0] Shadow horizontal offset\n     * @param {Number} [options.offsetY=0] Shadow vertical offset\n     * @return {fabric.Object} thisArg\n     * @chainable\n     * @see {@link http://jsfiddle.net/fabricjs/7gvJG/|jsFiddle demo}\n     * @example <caption>Set shadow with string notation</caption>\n     * object.setShadow('2px 2px 10px rgba(0,0,0,0.2)');\n     * canvas.renderAll();\n     * @example <caption>Set shadow with object notation</caption>\n     * object.setShadow({\n     *   color: 'red',\n     *   blur: 10,\n     *   offsetX: 20,\n     *   offsetY: 20\n     * });\n     * canvas.renderAll();\n     */\n    setShadow: function(options) {\n      return this.set('shadow', options ? new fabric.Shadow(options) : null);\n    },\n\n    /**\n     * Sets \"color\" of an instance (alias of `set('fill', &hellip;)`)\n     * @param {String} color Color value\n     * @return {fabric.Object} thisArg\n     * @chainable\n     */\n    setColor: function(color) {\n      this.set('fill', color);\n      return this;\n    },\n\n    /**\n     * Sets \"angle\" of an instance with centered rotation\n     * @param {Number} angle Angle value (in degrees)\n     * @return {fabric.Object} thisArg\n     * @chainable\n     */\n    rotate: function(angle) {\n      var shouldCenterOrigin = (this.originX !== 'center' || this.originY !== 'center') && this.centeredRotation;\n\n      if (shouldCenterOrigin) {\n        this._setOriginToCenter();\n      }\n\n      this.set('angle', angle);\n\n      if (shouldCenterOrigin) {\n        this._resetOrigin();\n      }\n\n      return this;\n    },\n\n    /**\n     * Centers object horizontally on canvas to which it was added last.\n     * You might need to call `setCoords` on an object after centering, to update controls area.\n     * @return {fabric.Object} thisArg\n     * @chainable\n     */\n    centerH: function () {\n      this.canvas && this.canvas.centerObjectH(this);\n      return this;\n    },\n\n    /**\n     * Centers object horizontally on current viewport of canvas to which it was added last.\n     * You might need to call `setCoords` on an object after centering, to update controls area.\n     * @return {fabric.Object} thisArg\n     * @chainable\n     */\n    viewportCenterH: function () {\n      this.canvas && this.canvas.viewportCenterObjectH(this);\n      return this;\n    },\n\n    /**\n     * Centers object vertically on canvas to which it was added last.\n     * You might need to call `setCoords` on an object after centering, to update controls area.\n     * @return {fabric.Object} thisArg\n     * @chainable\n     */\n    centerV: function () {\n      this.canvas && this.canvas.centerObjectV(this);\n      return this;\n    },\n\n    /**\n     * Centers object vertically on current viewport of canvas to which it was added last.\n     * You might need to call `setCoords` on an object after centering, to update controls area.\n     * @return {fabric.Object} thisArg\n     * @chainable\n     */\n    viewportCenterV: function () {\n      this.canvas && this.canvas.viewportCenterObjectV(this);\n      return this;\n    },\n\n    /**\n     * Centers object vertically and horizontally on canvas to which is was added last\n     * You might need to call `setCoords` on an object after centering, to update controls area.\n     * @return {fabric.Object} thisArg\n     * @chainable\n     */\n    center: function () {\n      this.canvas && this.canvas.centerObject(this);\n      return this;\n    },\n\n    /**\n     * Centers object on current viewport of canvas to which it was added last.\n     * You might need to call `setCoords` on an object after centering, to update controls area.\n     * @return {fabric.Object} thisArg\n     * @chainable\n     */\n    viewportCenter: function () {\n      this.canvas && this.canvas.viewportCenterObject(this);\n      return this;\n    },\n\n    /**\n     * Returns coordinates of a pointer relative to an object\n     * @param {Event} e Event to operate upon\n     * @param {Object} [pointer] Pointer to operate upon (instead of event)\n     * @return {Object} Coordinates of a pointer (x, y)\n     */\n    getLocalPointer: function(e, pointer) {\n      pointer = pointer || this.canvas.getPointer(e);\n      var pClicked = new fabric.Point(pointer.x, pointer.y),\n          objectLeftTop = this._getLeftTopCoords();\n      if (this.angle) {\n        pClicked = fabric.util.rotatePoint(\n          pClicked, objectLeftTop, degreesToRadians(-this.angle));\n      }\n      return {\n        x: pClicked.x - objectLeftTop.x,\n        y: pClicked.y - objectLeftTop.y\n      };\n    },\n\n    /**\n     * Sets canvas globalCompositeOperation for specific object\n     * custom composition operation for the particular object can be specifed using globalCompositeOperation property\n     * @param {CanvasRenderingContext2D} ctx Rendering canvas context\n     */\n    _setupCompositeOperation: function (ctx) {\n      if (this.globalCompositeOperation) {\n        ctx.globalCompositeOperation = this.globalCompositeOperation;\n      }\n    }\n  });\n\n  fabric.util.createAccessors && fabric.util.createAccessors(fabric.Object);\n\n  extend(fabric.Object.prototype, fabric.Observable);\n\n  /**\n   * Defines the number of fraction digits to use when serializing object values.\n   * You can use it to increase/decrease precision of such values like left, top, scaleX, scaleY, etc.\n   * @static\n   * @memberOf fabric.Object\n   * @constant\n   * @type Number\n   */\n  fabric.Object.NUM_FRACTION_DIGITS = 2;\n\n  fabric.Object._fromObject = function(className, object, callback, extraParam) {\n    var klass = fabric[className];\n    object = clone(object, true);\n    fabric.util.enlivenPatterns([object.fill, object.stroke], function(patterns) {\n      if (typeof patterns[0] !== 'undefined') {\n        object.fill = patterns[0];\n      }\n      if (typeof patterns[1] !== 'undefined') {\n        object.stroke = patterns[1];\n      }\n      fabric.util.enlivenObjects([object.clipPath], function(enlivedProps) {\n        object.clipPath = enlivedProps[0];\n        var instance = extraParam ? new klass(object[extraParam], object) : new klass(object);\n        callback && callback(instance);\n      });\n    });\n  };\n\n  /**\n   * Unique id used internally when creating SVG elements\n   * @static\n   * @memberOf fabric.Object\n   * @type Number\n   */\n  fabric.Object.__uid = 0;\n\n})(typeof exports !== 'undefined' ? exports : this);\n\n\n(function() {\n\n  var degreesToRadians = fabric.util.degreesToRadians,\n      originXOffset = {\n        left: -0.5,\n        center: 0,\n        right: 0.5\n      },\n      originYOffset = {\n        top: -0.5,\n        center: 0,\n        bottom: 0.5\n      };\n\n  fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prototype */ {\n\n    /**\n     * Translates the coordinates from a set of origin to another (based on the object's dimensions)\n     * @param {fabric.Point} point The point which corresponds to the originX and originY params\n     * @param {String} fromOriginX Horizontal origin: 'left', 'center' or 'right'\n     * @param {String} fromOriginY Vertical origin: 'top', 'center' or 'bottom'\n     * @param {String} toOriginX Horizontal origin: 'left', 'center' or 'right'\n     * @param {String} toOriginY Vertical origin: 'top', 'center' or 'bottom'\n     * @return {fabric.Point}\n     */\n    translateToGivenOrigin: function(point, fromOriginX, fromOriginY, toOriginX, toOriginY) {\n      var x = point.x,\n          y = point.y,\n          offsetX, offsetY, dim;\n\n      if (typeof fromOriginX === 'string') {\n        fromOriginX = originXOffset[fromOriginX];\n      }\n      else {\n        fromOriginX -= 0.5;\n      }\n\n      if (typeof toOriginX === 'string') {\n        toOriginX = originXOffset[toOriginX];\n      }\n      else {\n        toOriginX -= 0.5;\n      }\n\n      offsetX = toOriginX - fromOriginX;\n\n      if (typeof fromOriginY === 'string') {\n        fromOriginY = originYOffset[fromOriginY];\n      }\n      else {\n        fromOriginY -= 0.5;\n      }\n\n      if (typeof toOriginY === 'string') {\n        toOriginY = originYOffset[toOriginY];\n      }\n      else {\n        toOriginY -= 0.5;\n      }\n\n      offsetY = toOriginY - fromOriginY;\n\n      if (offsetX || offsetY) {\n        dim = this._getTransformedDimensions();\n        x = point.x + offsetX * dim.x;\n        y = point.y + offsetY * dim.y;\n      }\n\n      return new fabric.Point(x, y);\n    },\n\n    /**\n     * Translates the coordinates from origin to center coordinates (based on the object's dimensions)\n     * @param {fabric.Point} point The point which corresponds to the originX and originY params\n     * @param {String} originX Horizontal origin: 'left', 'center' or 'right'\n     * @param {String} originY Vertical origin: 'top', 'center' or 'bottom'\n     * @return {fabric.Point}\n     */\n    translateToCenterPoint: function(point, originX, originY) {\n      var p = this.translateToGivenOrigin(point, originX, originY, 'center', 'center');\n      if (this.angle) {\n        return fabric.util.rotatePoint(p, point, degreesToRadians(this.angle));\n      }\n      return p;\n    },\n\n    /**\n     * Translates the coordinates from center to origin coordinates (based on the object's dimensions)\n     * @param {fabric.Point} center The point which corresponds to center of the object\n     * @param {String} originX Horizontal origin: 'left', 'center' or 'right'\n     * @param {String} originY Vertical origin: 'top', 'center' or 'bottom'\n     * @return {fabric.Point}\n     */\n    translateToOriginPoint: function(center, originX, originY) {\n      var p = this.translateToGivenOrigin(center, 'center', 'center', originX, originY);\n      if (this.angle) {\n        return fabric.util.rotatePoint(p, center, degreesToRadians(this.angle));\n      }\n      return p;\n    },\n\n    /**\n     * Returns the real center coordinates of the object\n     * @return {fabric.Point}\n     */\n    getCenterPoint: function() {\n      var leftTop = new fabric.Point(this.left, this.top);\n      return this.translateToCenterPoint(leftTop, this.originX, this.originY);\n    },\n\n    /**\n     * Returns the coordinates of the object based on center coordinates\n     * @param {fabric.Point} point The point which corresponds to the originX and originY params\n     * @return {fabric.Point}\n     */\n    // getOriginPoint: function(center) {\n    //   return this.translateToOriginPoint(center, this.originX, this.originY);\n    // },\n\n    /**\n     * Returns the coordinates of the object as if it has a different origin\n     * @param {String} originX Horizontal origin: 'left', 'center' or 'right'\n     * @param {String} originY Vertical origin: 'top', 'center' or 'bottom'\n     * @return {fabric.Point}\n     */\n    getPointByOrigin: function(originX, originY) {\n      var center = this.getCenterPoint();\n      return this.translateToOriginPoint(center, originX, originY);\n    },\n\n    /**\n     * Returns the point in local coordinates\n     * @param {fabric.Point} point The point relative to the global coordinate system\n     * @param {String} originX Horizontal origin: 'left', 'center' or 'right'\n     * @param {String} originY Vertical origin: 'top', 'center' or 'bottom'\n     * @return {fabric.Point}\n     */\n    toLocalPoint: function(point, originX, originY) {\n      var center = this.getCenterPoint(),\n          p, p2;\n\n      if (typeof originX !== 'undefined' && typeof originY !== 'undefined' ) {\n        p = this.translateToGivenOrigin(center, 'center', 'center', originX, originY);\n      }\n      else {\n        p = new fabric.Point(this.left, this.top);\n      }\n\n      p2 = new fabric.Point(point.x, point.y);\n      if (this.angle) {\n        p2 = fabric.util.rotatePoint(p2, center, -degreesToRadians(this.angle));\n      }\n      return p2.subtractEquals(p);\n    },\n\n    /**\n     * Returns the point in global coordinates\n     * @param {fabric.Point} The point relative to the local coordinate system\n     * @return {fabric.Point}\n     */\n    // toGlobalPoint: function(point) {\n    //   return fabric.util.rotatePoint(point, this.getCenterPoint(), degreesToRadians(this.angle)).addEquals(new fabric.Point(this.left, this.top));\n    // },\n\n    /**\n     * Sets the position of the object taking into consideration the object's origin\n     * @param {fabric.Point} pos The new position of the object\n     * @param {String} originX Horizontal origin: 'left', 'center' or 'right'\n     * @param {String} originY Vertical origin: 'top', 'center' or 'bottom'\n     * @return {void}\n     */\n    setPositionByOrigin: function(pos, originX, originY) {\n      var center = this.translateToCenterPoint(pos, originX, originY),\n          position = this.translateToOriginPoint(center, this.originX, this.originY);\n      this.set('left', position.x);\n      this.set('top', position.y);\n    },\n\n    /**\n     * @param {String} to One of 'left', 'center', 'right'\n     */\n    adjustPosition: function(to) {\n      var angle = degreesToRadians(this.angle),\n          hypotFull = this.getScaledWidth(),\n          xFull = fabric.util.cos(angle) * hypotFull,\n          yFull = fabric.util.sin(angle) * hypotFull,\n          offsetFrom, offsetTo;\n\n      //TODO: this function does not consider mixed situation like top, center.\n      if (typeof this.originX === 'string') {\n        offsetFrom = originXOffset[this.originX];\n      }\n      else {\n        offsetFrom = this.originX - 0.5;\n      }\n      if (typeof to === 'string') {\n        offsetTo = originXOffset[to];\n      }\n      else {\n        offsetTo = to - 0.5;\n      }\n      this.left += xFull * (offsetTo - offsetFrom);\n      this.top += yFull * (offsetTo - offsetFrom);\n      this.setCoords();\n      this.originX = to;\n    },\n\n    /**\n     * Sets the origin/position of the object to it's center point\n     * @private\n     * @return {void}\n     */\n    _setOriginToCenter: function() {\n      this._originalOriginX = this.originX;\n      this._originalOriginY = this.originY;\n\n      var center = this.getCenterPoint();\n\n      this.originX = 'center';\n      this.originY = 'center';\n\n      this.left = center.x;\n      this.top = center.y;\n    },\n\n    /**\n     * Resets the origin/position of the object to it's original origin\n     * @private\n     * @return {void}\n     */\n    _resetOrigin: function() {\n      var originPoint = this.translateToOriginPoint(\n        this.getCenterPoint(),\n        this._originalOriginX,\n        this._originalOriginY);\n\n      this.originX = this._originalOriginX;\n      this.originY = this._originalOriginY;\n\n      this.left = originPoint.x;\n      this.top = originPoint.y;\n\n      this._originalOriginX = null;\n      this._originalOriginY = null;\n    },\n\n    /**\n     * @private\n     */\n    _getLeftTopCoords: function() {\n      return this.translateToOriginPoint(this.getCenterPoint(), 'left', 'top');\n    },\n  });\n\n})();\n\n\n(function() {\n\n  function getCoords(coords) {\n    return [\n      new fabric.Point(coords.tl.x, coords.tl.y),\n      new fabric.Point(coords.tr.x, coords.tr.y),\n      new fabric.Point(coords.br.x, coords.br.y),\n      new fabric.Point(coords.bl.x, coords.bl.y)\n    ];\n  }\n\n  var degreesToRadians = fabric.util.degreesToRadians,\n      multiplyMatrices = fabric.util.multiplyTransformMatrices,\n      transformPoint = fabric.util.transformPoint;\n\n  fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prototype */ {\n\n    /**\n     * Describe object's corner position in canvas element coordinates.\n     * properties are tl,mt,tr,ml,mr,bl,mb,br,mtr for the main controls.\n     * each property is an object with x, y and corner.\n     * The `corner` property contains in a similar manner the 4 points of the\n     * interactive area of the corner.\n     * The coordinates depends from this properties: width, height, scaleX, scaleY\n     * skewX, skewY, angle, strokeWidth, viewportTransform, top, left, padding.\n     * The coordinates get updated with @method setCoords.\n     * You can calculate them without updating with @method calcCoords;\n     * @memberOf fabric.Object.prototype\n     */\n    oCoords: null,\n\n    /**\n     * Describe object's corner position in canvas object absolute coordinates\n     * properties are tl,tr,bl,br and describe the four main corner.\n     * each property is an object with x, y, instance of Fabric.Point.\n     * The coordinates depends from this properties: width, height, scaleX, scaleY\n     * skewX, skewY, angle, strokeWidth, top, left.\n     * Those coordinates are usefull to understand where an object is. They get updated\n     * with oCoords but they do not need to be updated when zoom or panning change.\n     * The coordinates get updated with @method setCoords.\n     * You can calculate them without updating with @method calcCoords(true);\n     * @memberOf fabric.Object.prototype\n     */\n    aCoords: null,\n\n    /**\n     * storage for object transform matrix\n     */\n    ownMatrixCache: null,\n\n    /**\n     * storage for object full transform matrix\n     */\n    matrixCache: null,\n\n    /**\n     * return correct set of coordinates for intersection\n     */\n    getCoords: function(absolute, calculate) {\n      if (!this.oCoords) {\n        this.setCoords();\n      }\n      var coords = absolute ? this.aCoords : this.oCoords;\n      return getCoords(calculate ? this.calcCoords(absolute) : coords);\n    },\n\n    /**\n     * Checks if object intersects with an area formed by 2 points\n     * @param {Object} pointTL top-left point of area\n     * @param {Object} pointBR bottom-right point of area\n     * @param {Boolean} [absolute] use coordinates without viewportTransform\n     * @param {Boolean} [calculate] use coordinates of current position instead of .oCoords\n     * @return {Boolean} true if object intersects with an area formed by 2 points\n     */\n    intersectsWithRect: function(pointTL, pointBR, absolute, calculate) {\n      var coords = this.getCoords(absolute, calculate),\n          intersection = fabric.Intersection.intersectPolygonRectangle(\n            coords,\n            pointTL,\n            pointBR\n          );\n      return intersection.status === 'Intersection';\n    },\n\n    /**\n     * Checks if object intersects with another object\n     * @param {Object} other Object to test\n     * @param {Boolean} [absolute] use coordinates without viewportTransform\n     * @param {Boolean} [calculate] use coordinates of current position instead of .oCoords\n     * @return {Boolean} true if object intersects with another object\n     */\n    intersectsWithObject: function(other, absolute, calculate) {\n      var intersection = fabric.Intersection.intersectPolygonPolygon(\n        this.getCoords(absolute, calculate),\n        other.getCoords(absolute, calculate)\n      );\n\n      return intersection.status === 'Intersection'\n        || other.isContainedWithinObject(this, absolute, calculate)\n        || this.isContainedWithinObject(other, absolute, calculate);\n    },\n\n    /**\n     * Checks if object is fully contained within area of another object\n     * @param {Object} other Object to test\n     * @param {Boolean} [absolute] use coordinates without viewportTransform\n     * @param {Boolean} [calculate] use coordinates of current position instead of .oCoords\n     * @return {Boolean} true if object is fully contained within area of another object\n     */\n    isContainedWithinObject: function(other, absolute, calculate) {\n      var points = this.getCoords(absolute, calculate),\n          i = 0, lines = other._getImageLines(\n            calculate ? other.calcCoords(absolute) : absolute ? other.aCoords : other.oCoords\n          );\n      for (; i < 4; i++) {\n        if (!other.containsPoint(points[i], lines)) {\n          return false;\n        }\n      }\n      return true;\n    },\n\n    /**\n     * Checks if object is fully contained within area formed by 2 points\n     * @param {Object} pointTL top-left point of area\n     * @param {Object} pointBR bottom-right point of area\n     * @param {Boolean} [absolute] use coordinates without viewportTransform\n     * @param {Boolean} [calculate] use coordinates of current position instead of .oCoords\n     * @return {Boolean} true if object is fully contained within area formed by 2 points\n     */\n    isContainedWithinRect: function(pointTL, pointBR, absolute, calculate) {\n      var boundingRect = this.getBoundingRect(absolute, calculate);\n\n      return (\n        boundingRect.left >= pointTL.x &&\n        boundingRect.left + boundingRect.width <= pointBR.x &&\n        boundingRect.top >= pointTL.y &&\n        boundingRect.top + boundingRect.height <= pointBR.y\n      );\n    },\n\n    /**\n     * Checks if point is inside the object\n     * @param {fabric.Point} point Point to check against\n     * @param {Object} [lines] object returned from @method _getImageLines\n     * @param {Boolean} [absolute] use coordinates without viewportTransform\n     * @param {Boolean} [calculate] use coordinates of current position instead of .oCoords\n     * @return {Boolean} true if point is inside the object\n     */\n    containsPoint: function(point, lines, absolute, calculate) {\n      var lines = lines || this._getImageLines(\n            calculate ? this.calcCoords(absolute) : absolute ? this.aCoords : this.oCoords\n          ),\n          xPoints = this._findCrossPoints(point, lines);\n\n      // if xPoints is odd then point is inside the object\n      return (xPoints !== 0 && xPoints % 2 === 1);\n    },\n\n    /**\n     * Checks if object is contained within the canvas with current viewportTransform\n     * the check is done stopping at first point that appears on screen\n     * @param {Boolean} [calculate] use coordinates of current position instead of .oCoords\n     * @return {Boolean} true if object is fully or partially contained within canvas\n     */\n    isOnScreen: function(calculate) {\n      if (!this.canvas) {\n        return false;\n      }\n      var pointTL = this.canvas.vptCoords.tl, pointBR = this.canvas.vptCoords.br;\n      var points = this.getCoords(true, calculate), point;\n      for (var i = 0; i < 4; i++) {\n        point = points[i];\n        if (point.x <= pointBR.x && point.x >= pointTL.x && point.y <= pointBR.y && point.y >= pointTL.y) {\n          return true;\n        }\n      }\n      // no points on screen, check intersection with absolute coordinates\n      if (this.intersectsWithRect(pointTL, pointBR, true, calculate)) {\n        return true;\n      }\n      return this._containsCenterOfCanvas(pointTL, pointBR, calculate);\n    },\n\n    /**\n     * Checks if the object contains the midpoint between canvas extremities\n     * Does not make sense outside the context of isOnScreen and isPartiallyOnScreen\n     * @private\n     * @param {Fabric.Point} pointTL Top Left point\n     * @param {Fabric.Point} pointBR Top Right point\n     * @param {Boolean} calculate use coordinates of current position instead of .oCoords\n     * @return {Boolean} true if the objects containe the point\n     */\n    _containsCenterOfCanvas: function(pointTL, pointBR, calculate) {\n      // worst case scenario the object is so big that contains the screen\n      var centerPoint = { x: (pointTL.x + pointBR.x) / 2, y: (pointTL.y + pointBR.y) / 2 };\n      if (this.containsPoint(centerPoint, null, true, calculate)) {\n        return true;\n      }\n      return false;\n    },\n\n    /**\n     * Checks if object is partially contained within the canvas with current viewportTransform\n     * @param {Boolean} [calculate] use coordinates of current position instead of .oCoords\n     * @return {Boolean} true if object is partially contained within canvas\n     */\n    isPartiallyOnScreen: function(calculate) {\n      if (!this.canvas) {\n        return false;\n      }\n      var pointTL = this.canvas.vptCoords.tl, pointBR = this.canvas.vptCoords.br;\n      if (this.intersectsWithRect(pointTL, pointBR, true, calculate)) {\n        return true;\n      }\n      return this._containsCenterOfCanvas(pointTL, pointBR, calculate);\n    },\n\n    /**\n     * Method that returns an object with the object edges in it, given the coordinates of the corners\n     * @private\n     * @param {Object} oCoords Coordinates of the object corners\n     */\n    _getImageLines: function(oCoords) {\n      return {\n        topline: {\n          o: oCoords.tl,\n          d: oCoords.tr\n        },\n        rightline: {\n          o: oCoords.tr,\n          d: oCoords.br\n        },\n        bottomline: {\n          o: oCoords.br,\n          d: oCoords.bl\n        },\n        leftline: {\n          o: oCoords.bl,\n          d: oCoords.tl\n        }\n      };\n    },\n\n    /**\n     * Helper method to determine how many cross points are between the 4 object edges\n     * and the horizontal line determined by a point on canvas\n     * @private\n     * @param {fabric.Point} point Point to check\n     * @param {Object} lines Coordinates of the object being evaluated\n     */\n    // remove yi, not used but left code here just in case.\n    _findCrossPoints: function(point, lines) {\n      var b1, b2, a1, a2, xi, // yi,\n          xcount = 0,\n          iLine;\n\n      for (var lineKey in lines) {\n        iLine = lines[lineKey];\n        // optimisation 1: line below point. no cross\n        if ((iLine.o.y < point.y) && (iLine.d.y < point.y)) {\n          continue;\n        }\n        // optimisation 2: line above point. no cross\n        if ((iLine.o.y >= point.y) && (iLine.d.y >= point.y)) {\n          continue;\n        }\n        // optimisation 3: vertical line case\n        if ((iLine.o.x === iLine.d.x) && (iLine.o.x >= point.x)) {\n          xi = iLine.o.x;\n          // yi = point.y;\n        }\n        // calculate the intersection point\n        else {\n          b1 = 0;\n          b2 = (iLine.d.y - iLine.o.y) / (iLine.d.x - iLine.o.x);\n          a1 = point.y - b1 * point.x;\n          a2 = iLine.o.y - b2 * iLine.o.x;\n\n          xi = -(a1 - a2) / (b1 - b2);\n          // yi = a1 + b1 * xi;\n        }\n        // dont count xi < point.x cases\n        if (xi >= point.x) {\n          xcount += 1;\n        }\n        // optimisation 4: specific for square images\n        if (xcount === 2) {\n          break;\n        }\n      }\n      return xcount;\n    },\n\n    /**\n     * Returns coordinates of object's bounding rectangle (left, top, width, height)\n     * the box is intented as aligned to axis of canvas.\n     * @param {Boolean} [absolute] use coordinates without viewportTransform\n     * @param {Boolean} [calculate] use coordinates of current position instead of .oCoords / .aCoords\n     * @return {Object} Object with left, top, width, height properties\n     */\n    getBoundingRect: function(absolute, calculate) {\n      var coords = this.getCoords(absolute, calculate);\n      return fabric.util.makeBoundingBoxFromPoints(coords);\n    },\n\n    /**\n     * Returns width of an object bounding box counting transformations\n     * before 2.0 it was named getWidth();\n     * @return {Number} width value\n     */\n    getScaledWidth: function() {\n      return this._getTransformedDimensions().x;\n    },\n\n    /**\n     * Returns height of an object bounding box counting transformations\n     * before 2.0 it was named getHeight();\n     * @return {Number} height value\n     */\n    getScaledHeight: function() {\n      return this._getTransformedDimensions().y;\n    },\n\n    /**\n     * Makes sure the scale is valid and modifies it if necessary\n     * @private\n     * @param {Number} value\n     * @return {Number}\n     */\n    _constrainScale: function(value) {\n      if (Math.abs(value) < this.minScaleLimit) {\n        if (value < 0) {\n          return -this.minScaleLimit;\n        }\n        else {\n          return this.minScaleLimit;\n        }\n      }\n      else if (value === 0) {\n        return 0.0001;\n      }\n      return value;\n    },\n\n    /**\n     * Scales an object (equally by x and y)\n     * @param {Number} value Scale factor\n     * @return {fabric.Object} thisArg\n     * @chainable\n     */\n    scale: function(value) {\n      this._set('scaleX', value);\n      this._set('scaleY', value);\n      return this.setCoords();\n    },\n\n    /**\n     * Scales an object to a given width, with respect to bounding box (scaling by x/y equally)\n     * @param {Number} value New width value\n     * @param {Boolean} absolute ignore viewport\n     * @return {fabric.Object} thisArg\n     * @chainable\n     */\n    scaleToWidth: function(value, absolute) {\n      // adjust to bounding rect factor so that rotated shapes would fit as well\n      var boundingRectFactor = this.getBoundingRect(absolute).width / this.getScaledWidth();\n      return this.scale(value / this.width / boundingRectFactor);\n    },\n\n    /**\n     * Scales an object to a given height, with respect to bounding box (scaling by x/y equally)\n     * @param {Number} value New height value\n     * @param {Boolean} absolute ignore viewport\n     * @return {fabric.Object} thisArg\n     * @chainable\n     */\n    scaleToHeight: function(value, absolute) {\n      // adjust to bounding rect factor so that rotated shapes would fit as well\n      var boundingRectFactor = this.getBoundingRect(absolute).height / this.getScaledHeight();\n      return this.scale(value / this.height / boundingRectFactor);\n    },\n\n    /**\n     * Calculate and returns the .coords of an object.\n     * @return {Object} Object with tl, tr, br, bl ....\n     * @chainable\n     */\n    calcCoords: function(absolute) {\n      var rotateMatrix = this._calcRotateMatrix(),\n          translateMatrix = this._calcTranslateMatrix(),\n          startMatrix = multiplyMatrices(translateMatrix, rotateMatrix),\n          vpt = this.getViewportTransform(),\n          finalMatrix = absolute ? startMatrix : multiplyMatrices(vpt, startMatrix),\n          dim = this._getTransformedDimensions(),\n          w = dim.x / 2, h = dim.y / 2,\n          tl = transformPoint({ x: -w, y: -h }, finalMatrix),\n          tr = transformPoint({ x: w, y: -h }, finalMatrix),\n          bl = transformPoint({ x: -w, y: h }, finalMatrix),\n          br = transformPoint({ x: w, y: h }, finalMatrix);\n      if (!absolute) {\n        var padding = this.padding, angle = degreesToRadians(this.angle),\n            cos = fabric.util.cos(angle), sin = fabric.util.sin(angle),\n            cosP = cos * padding, sinP = sin * padding, cosPSinP = cosP + sinP,\n            cosPMinusSinP = cosP - sinP;\n        if (padding) {\n          tl.x -= cosPMinusSinP;\n          tl.y -= cosPSinP;\n          tr.x += cosPSinP;\n          tr.y -= cosPMinusSinP;\n          bl.x -= cosPSinP;\n          bl.y += cosPMinusSinP;\n          br.x += cosPMinusSinP;\n          br.y += cosPSinP;\n        }\n        var ml  = new fabric.Point((tl.x + bl.x) / 2, (tl.y + bl.y) / 2),\n            mt  = new fabric.Point((tr.x + tl.x) / 2, (tr.y + tl.y) / 2),\n            mr  = new fabric.Point((br.x + tr.x) / 2, (br.y + tr.y) / 2),\n            mb  = new fabric.Point((br.x + bl.x) / 2, (br.y + bl.y) / 2),\n            mtr = new fabric.Point(mt.x + sin * this.rotatingPointOffset, mt.y - cos * this.rotatingPointOffset);\n      }\n\n      // if (!absolute) {\n      //   var canvas = this.canvas;\n      //   setTimeout(function() {\n      //     canvas.contextTop.clearRect(0, 0, 700, 700);\n      //     canvas.contextTop.fillStyle = 'green';\n      //     canvas.contextTop.fillRect(mb.x, mb.y, 3, 3);\n      //     canvas.contextTop.fillRect(bl.x, bl.y, 3, 3);\n      //     canvas.contextTop.fillRect(br.x, br.y, 3, 3);\n      //     canvas.contextTop.fillRect(tl.x, tl.y, 3, 3);\n      //     canvas.contextTop.fillRect(tr.x, tr.y, 3, 3);\n      //     canvas.contextTop.fillRect(ml.x, ml.y, 3, 3);\n      //     canvas.contextTop.fillRect(mr.x, mr.y, 3, 3);\n      //     canvas.contextTop.fillRect(mt.x, mt.y, 3, 3);\n      //     canvas.contextTop.fillRect(mtr.x, mtr.y, 3, 3);\n      //   }, 50);\n      // }\n\n      var coords = {\n        // corners\n        tl: tl, tr: tr, br: br, bl: bl,\n      };\n      if (!absolute) {\n        // middle\n        coords.ml = ml;\n        coords.mt = mt;\n        coords.mr = mr;\n        coords.mb = mb;\n        // rotating point\n        coords.mtr = mtr;\n      }\n      return coords;\n    },\n\n    /**\n     * Sets corner position coordinates based on current angle, width and height.\n     * See {@link https://github.com/kangax/fabric.js/wiki/When-to-call-setCoords|When-to-call-setCoords}\n     * @param {Boolean} [ignoreZoom] set oCoords with or without the viewport transform.\n     * @param {Boolean} [skipAbsolute] skip calculation of aCoords, usefull in setViewportTransform\n     * @return {fabric.Object} thisArg\n     * @chainable\n     */\n    setCoords: function(ignoreZoom, skipAbsolute) {\n      this.oCoords = this.calcCoords(ignoreZoom);\n      if (!skipAbsolute) {\n        this.aCoords = this.calcCoords(true);\n      }\n\n      // set coordinates of the draggable boxes in the corners used to scale/rotate the image\n      ignoreZoom || (this._setCornerCoords && this._setCornerCoords());\n\n      return this;\n    },\n\n    /**\n     * calculate rotation matrix of an object\n     * @return {Array} rotation matrix for the object\n     */\n    _calcRotateMatrix: function() {\n      if (this.angle) {\n        var theta = degreesToRadians(this.angle), cos = fabric.util.cos(theta), sin = fabric.util.sin(theta);\n        return [cos, sin, -sin, cos, 0, 0];\n      }\n      return fabric.iMatrix.concat();\n    },\n\n    /**\n     * calculate the translation matrix for an object transform\n     * @return {Array} rotation matrix for the object\n     */\n    _calcTranslateMatrix: function() {\n      var center = this.getCenterPoint();\n      return [1, 0, 0, 1, center.x, center.y];\n    },\n\n    transformMatrixKey: function(skipGroup) {\n      var sep = '_', prefix = '';\n      if (!skipGroup && this.group) {\n        prefix = this.group.transformMatrixKey(skipGroup) + sep;\n      };\n      return prefix + this.top + sep + this.left + sep + this.scaleX + sep + this.scaleY +\n        sep + this.skewX + sep + this.skewY + sep + this.angle + sep + this.originX + sep + this.originY +\n        sep + this.width + sep + this.height + sep + this.strokeWidth + this.flipX + this.flipY;\n    },\n\n    /**\n     * calculate trasform Matrix that represent current transformation from\n     * object properties.\n     * @param {Boolean} [skipGroup] return transformMatrix for object and not go upward with parents\n     * @return {Array} matrix Transform Matrix for the object\n     */\n    calcTransformMatrix: function(skipGroup) {\n      if (skipGroup) {\n        return this.calcOwnMatrix();\n      }\n      var key = this.transformMatrixKey(), cache = this.matrixCache || (this.matrixCache = {});\n      if (cache.key === key) {\n        return cache.value;\n      }\n      var matrix = this.calcOwnMatrix();\n      if (this.group) {\n        matrix = multiplyMatrices(this.group.calcTransformMatrix(), matrix);\n      }\n      cache.key = key;\n      cache.value = matrix;\n      return matrix;\n    },\n\n    calcOwnMatrix: function() {\n      var key = this.transformMatrixKey(true), cache = this.ownMatrixCache || (this.ownMatrixCache = {});\n      if (cache.key === key) {\n        return cache.value;\n      }\n      var matrix = this._calcTranslateMatrix(),\n          rotateMatrix,\n          dimensionMatrix = this._calcDimensionsTransformMatrix(this.skewX, this.skewY, true);\n      if (this.angle) {\n        rotateMatrix = this._calcRotateMatrix();\n        matrix = multiplyMatrices(matrix, rotateMatrix);\n      }\n      matrix = multiplyMatrices(matrix, dimensionMatrix);\n      cache.key = key;\n      cache.value = matrix;\n      return matrix;\n    },\n\n    _calcDimensionsTransformMatrix: function(skewX, skewY, flipping) {\n      var skewMatrix,\n          scaleX = this.scaleX * (flipping && this.flipX ? -1 : 1),\n          scaleY = this.scaleY * (flipping && this.flipY ? -1 : 1),\n          scaleMatrix = [scaleX, 0, 0, scaleY, 0, 0];\n      if (skewX) {\n        skewMatrix = [1, 0, Math.tan(degreesToRadians(skewX)), 1];\n        scaleMatrix = multiplyMatrices(scaleMatrix, skewMatrix, true);\n      }\n      if (skewY) {\n        skewMatrix = [1, Math.tan(degreesToRadians(skewY)), 0, 1];\n        scaleMatrix = multiplyMatrices(scaleMatrix, skewMatrix, true);\n      }\n      return scaleMatrix;\n    },\n\n\n    /*\n     * Calculate object dimensions from its properties\n     * @private\n     * @return {Object} .x width dimension\n     * @return {Object} .y height dimension\n     */\n    _getNonTransformedDimensions: function() {\n      var strokeWidth = this.strokeWidth,\n          w = this.width + strokeWidth,\n          h = this.height + strokeWidth;\n      return { x: w, y: h };\n    },\n\n    /*\n     * Calculate object bounding boxdimensions from its properties scale, skew.\n     * @private\n     * @return {Object} .x width dimension\n     * @return {Object} .y height dimension\n     */\n    _getTransformedDimensions: function(skewX, skewY) {\n      if (typeof skewX === 'undefined') {\n        skewX = this.skewX;\n      }\n      if (typeof skewY === 'undefined') {\n        skewY = this.skewY;\n      }\n      var dimensions = this._getNonTransformedDimensions();\n      if (skewX === 0 && skewY === 0) {\n        return { x: dimensions.x * this.scaleX, y: dimensions.y * this.scaleY };\n      }\n      var dimX = dimensions.x / 2, dimY = dimensions.y / 2,\n          points = [\n            {\n              x: -dimX,\n              y: -dimY\n            },\n            {\n              x: dimX,\n              y: -dimY\n            },\n            {\n              x: -dimX,\n              y: dimY\n            },\n            {\n              x: dimX,\n              y: dimY\n            }],\n          i, transformMatrix = this._calcDimensionsTransformMatrix(skewX, skewY, false),\n          bbox;\n      for (i = 0; i < points.length; i++) {\n        points[i] = fabric.util.transformPoint(points[i], transformMatrix);\n      }\n      bbox = fabric.util.makeBoundingBoxFromPoints(points);\n      return { x: bbox.width, y: bbox.height };\n    },\n\n    /*\n     * Calculate object dimensions for controls. include padding and canvas zoom\n     * private\n     */\n    _calculateCurrentDimensions: function()  {\n      var vpt = this.getViewportTransform(),\n          dim = this._getTransformedDimensions(),\n          p = fabric.util.transformPoint(dim, vpt, true);\n\n      return p.scalarAdd(2 * this.padding);\n    },\n  });\n})();\n\n\nfabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prototype */ {\n\n  /**\n   * Moves an object to the bottom of the stack of drawn objects\n   * @return {fabric.Object} thisArg\n   * @chainable\n   */\n  sendToBack: function() {\n    if (this.group) {\n      fabric.StaticCanvas.prototype.sendToBack.call(this.group, this);\n    }\n    else {\n      this.canvas.sendToBack(this);\n    }\n    return this;\n  },\n\n  /**\n   * Moves an object to the top of the stack of drawn objects\n   * @return {fabric.Object} thisArg\n   * @chainable\n   */\n  bringToFront: function() {\n    if (this.group) {\n      fabric.StaticCanvas.prototype.bringToFront.call(this.group, this);\n    }\n    else {\n      this.canvas.bringToFront(this);\n    }\n    return this;\n  },\n\n  /**\n   * Moves an object down in stack of drawn objects\n   * @param {Boolean} [intersecting] If `true`, send object behind next lower intersecting object\n   * @return {fabric.Object} thisArg\n   * @chainable\n   */\n  sendBackwards: function(intersecting) {\n    if (this.group) {\n      fabric.StaticCanvas.prototype.sendBackwards.call(this.group, this, intersecting);\n    }\n    else {\n      this.canvas.sendBackwards(this, intersecting);\n    }\n    return this;\n  },\n\n  /**\n   * Moves an object up in stack of drawn objects\n   * @param {Boolean} [intersecting] If `true`, send object in front of next upper intersecting object\n   * @return {fabric.Object} thisArg\n   * @chainable\n   */\n  bringForward: function(intersecting) {\n    if (this.group) {\n      fabric.StaticCanvas.prototype.bringForward.call(this.group, this, intersecting);\n    }\n    else {\n      this.canvas.bringForward(this, intersecting);\n    }\n    return this;\n  },\n\n  /**\n   * Moves an object to specified level in stack of drawn objects\n   * @param {Number} index New position of object\n   * @return {fabric.Object} thisArg\n   * @chainable\n   */\n  moveTo: function(index) {\n    if (this.group && this.group.type !== 'activeSelection') {\n      fabric.StaticCanvas.prototype.moveTo.call(this.group, this, index);\n    }\n    else {\n      this.canvas.moveTo(this, index);\n    }\n    return this;\n  }\n});\n\n\n/* _TO_SVG_START_ */\n(function() {\n  function getSvgColorString(prop, value) {\n    if (!value) {\n      return prop + ': none; ';\n    }\n    else if (value.toLive) {\n      return prop + ': url(#SVGID_' + value.id + '); ';\n    }\n    else {\n      var color = new fabric.Color(value),\n          str = prop + ': ' + color.toRgb() + '; ',\n          opacity = color.getAlpha();\n      if (opacity !== 1) {\n        //change the color in rgb + opacity\n        str += prop + '-opacity: ' + opacity.toString() + '; ';\n      }\n      return str;\n    }\n  }\n\n  var toFixed = fabric.util.toFixed;\n\n  fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prototype */ {\n    /**\n     * Returns styles-string for svg-export\n     * @param {Boolean} skipShadow a boolean to skip shadow filter output\n     * @return {String}\n     */\n    getSvgStyles: function(skipShadow) {\n\n      var fillRule = this.fillRule ? this.fillRule : 'nonzero',\n          strokeWidth = this.strokeWidth ? this.strokeWidth : '0',\n          strokeDashArray = this.strokeDashArray ? this.strokeDashArray.join(' ') : 'none',\n          strokeLineCap = this.strokeLineCap ? this.strokeLineCap : 'butt',\n          strokeLineJoin = this.strokeLineJoin ? this.strokeLineJoin : 'miter',\n          strokeMiterLimit = this.strokeMiterLimit ? this.strokeMiterLimit : '4',\n          opacity = typeof this.opacity !== 'undefined' ? this.opacity : '1',\n          visibility = this.visible ? '' : ' visibility: hidden;',\n          filter = skipShadow ? '' : this.getSvgFilter(),\n          fill = getSvgColorString('fill', this.fill),\n          stroke = getSvgColorString('stroke', this.stroke);\n\n      return [\n        stroke,\n        'stroke-width: ', strokeWidth, '; ',\n        'stroke-dasharray: ', strokeDashArray, '; ',\n        'stroke-linecap: ', strokeLineCap, '; ',\n        'stroke-linejoin: ', strokeLineJoin, '; ',\n        'stroke-miterlimit: ', strokeMiterLimit, '; ',\n        fill,\n        'fill-rule: ', fillRule, '; ',\n        'opacity: ', opacity, ';',\n        filter,\n        visibility\n      ].join('');\n    },\n\n    /**\n     * Returns styles-string for svg-export\n     * @param {Object} style the object from which to retrieve style properties\n     * @param {Boolean} useWhiteSpace a boolean to include an additional attribute in the style.\n     * @return {String}\n     */\n    getSvgSpanStyles: function(style, useWhiteSpace) {\n      var term = '; ';\n      var fontFamily = style.fontFamily ?\n        'font-family: ' + (((style.fontFamily.indexOf('\\'') === -1 && style.fontFamily.indexOf('\"') === -1) ?\n          '\\'' + style.fontFamily  + '\\'' : style.fontFamily)) + term : '';\n      var strokeWidth = style.strokeWidth ? 'stroke-width: ' + style.strokeWidth + term : '',\n          fontFamily = fontFamily,\n          fontSize = style.fontSize ? 'font-size: ' + style.fontSize + 'px' + term : '',\n          fontStyle = style.fontStyle ? 'font-style: ' + style.fontStyle + term : '',\n          fontWeight = style.fontWeight ? 'font-weight: ' + style.fontWeight + term : '',\n          fill = style.fill ? getSvgColorString('fill', style.fill) : '',\n          stroke = style.stroke ? getSvgColorString('stroke', style.stroke) : '',\n          textDecoration = this.getSvgTextDecoration(style),\n          deltaY = style.deltaY ? 'baseline-shift: ' + (-style.deltaY) + '; ' : '';\n      if (textDecoration) {\n        textDecoration = 'text-decoration: ' + textDecoration + term;\n      }\n\n      return [\n        stroke,\n        strokeWidth,\n        fontFamily,\n        fontSize,\n        fontStyle,\n        fontWeight,\n        textDecoration,\n        fill,\n        deltaY,\n        useWhiteSpace ? 'white-space: pre; ' : ''\n      ].join('');\n    },\n\n    /**\n     * Returns text-decoration property for svg-export\n     * @param {Object} style the object from which to retrieve style properties\n     * @return {String}\n     */\n    getSvgTextDecoration: function(style) {\n      if ('overline' in style || 'underline' in style || 'linethrough' in style) {\n        return (style.overline ? 'overline ' : '') +\n          (style.underline ? 'underline ' : '') + (style.linethrough ? 'line-through ' : '');\n      }\n      return '';\n    },\n\n    /**\n     * Returns filter for svg shadow\n     * @return {String}\n     */\n    getSvgFilter: function() {\n      return this.shadow ? 'filter: url(#SVGID_' + this.shadow.id + ');' : '';\n    },\n\n    /**\n     * Returns id attribute for svg output\n     * @return {String}\n     */\n    getSvgCommons: function() {\n      return [\n        this.id ? 'id=\"' + this.id + '\" ' : '',\n        this.clipPath ? 'clip-path=\"url(#' + this.clipPath.clipPathId + ')\" ' : '',\n      ].join('');\n    },\n\n    /**\n     * Returns transform-string for svg-export\n     * @param {Boolean} use the full transform or the single object one.\n     * @return {String}\n     */\n    getSvgTransform: function(full, additionalTransform) {\n      var transform = full ? this.calcTransformMatrix() : this.calcOwnMatrix(),\n          svgTransform = transform.map(function(value) {\n            return toFixed(value, fabric.Object.NUM_FRACTION_DIGITS);\n          }).join(' ');\n      return 'transform=\"matrix(' + svgTransform + ')' +\n        (additionalTransform || '') + this.getSvgTransformMatrix() + '\" ';\n    },\n\n    /**\n     * Returns transform-string for svg-export from the transform matrix of single elements\n     * @return {String}\n     */\n    getSvgTransformMatrix: function() {\n      return this.transformMatrix ? ' matrix(' + this.transformMatrix.join(' ') + ')' : '';\n    },\n\n    _setSVGBg: function(textBgRects) {\n      if (this.backgroundColor) {\n        var NUM_FRACTION_DIGITS = fabric.Object.NUM_FRACTION_DIGITS;\n        textBgRects.push(\n          '\\t\\t<rect ',\n          this._getFillAttributes(this.backgroundColor),\n          ' x=\"',\n          toFixed(-this.width / 2, NUM_FRACTION_DIGITS),\n          '\" y=\"',\n          toFixed(-this.height / 2, NUM_FRACTION_DIGITS),\n          '\" width=\"',\n          toFixed(this.width, NUM_FRACTION_DIGITS),\n          '\" height=\"',\n          toFixed(this.height, NUM_FRACTION_DIGITS),\n          '\"></rect>\\n');\n      }\n    },\n\n    /**\n     * Returns svg representation of an instance\n     * @param {Function} [reviver] Method for further parsing of svg representation.\n     * @return {String} svg representation of an instance\n     */\n    toSVG: function(reviver) {\n      return this._createBaseSVGMarkup(this._toSVG(), { reviver: reviver });\n    },\n\n    /**\n     * Returns svg clipPath representation of an instance\n     * @param {Function} [reviver] Method for further parsing of svg representation.\n     * @return {String} svg representation of an instance\n     */\n    toClipPathSVG: function(reviver) {\n      return '\\t' + this._createBaseClipPathSVGMarkup(this._toSVG(), { reviver: reviver });\n    },\n\n    /**\n     * @private\n     */\n    _createBaseClipPathSVGMarkup: function(objectMarkup, options) {\n      options = options || {};\n      var reviver = options.reviver,\n          additionalTransform = options.additionalTransform || '',\n          commonPieces = [\n            this.getSvgTransform(true, additionalTransform),\n            this.getSvgCommons(),\n          ].join(''),\n          // insert commons in the markup, style and svgCommons\n          index = objectMarkup.indexOf('COMMON_PARTS');\n      objectMarkup[index] = commonPieces;\n      return reviver ? reviver(objectMarkup.join('')) : objectMarkup.join('');\n    },\n\n    /**\n     * @private\n     */\n    _createBaseSVGMarkup: function(objectMarkup, options) {\n      options = options || {};\n      var noStyle = options.noStyle, withShadow = options.withShadow,\n          reviver = options.reviver,\n          styleInfo = noStyle ? '' : 'style=\"' + this.getSvgStyles() + '\" ',\n          shadowInfo = withShadow ? 'style=\"' + this.getSvgFilter() + '\" ' : '',\n          clipPath = this.clipPath,\n          absoluteClipPath = this.clipPath && this.clipPath.absolutePositioned,\n          commonPieces, markup = [], clipPathMarkup,\n          // insert commons in the markup, style and svgCommons\n          index = objectMarkup.indexOf('COMMON_PARTS');\n      if (clipPath) {\n        clipPath.clipPathId = 'CLIPPATH_' + fabric.Object.__uid++;\n        clipPathMarkup = '<clipPath id=\"' + clipPath.clipPathId + '\" >\\n' +\n          this.clipPath.toClipPathSVG(reviver) +\n          '</clipPath>\\n';\n      }\n      if (absoluteClipPath) {\n        markup.push(\n          '<g ', shadowInfo, this.getSvgCommons(), ' >\\n'\n        );\n      }\n      markup.push(\n        '<g ',\n        this.getSvgTransform(false),\n        !absoluteClipPath ? shadowInfo + this.getSvgCommons() : '',\n        ' >\\n'\n      );\n      commonPieces = [\n        styleInfo,\n        noStyle ? '' : this.addPaintOrder(), ' '\n      ].join('');\n      objectMarkup[index] = commonPieces;\n      if (this.fill && this.fill.toLive) {\n        markup.push(this.fill.toSVG(this, false));\n      }\n      if (this.stroke && this.stroke.toLive) {\n        markup.push(this.stroke.toSVG(this, false));\n      }\n      if (this.shadow) {\n        markup.push(this.shadow.toSVG(this));\n      }\n      if (clipPath) {\n        markup.push(clipPathMarkup);\n      }\n      markup.push(objectMarkup.join(''));\n      markup.push('</g>\\n');\n      absoluteClipPath && markup.push('</g>\\n');\n      return reviver ? reviver(markup.join('')) : markup.join('');\n    },\n\n    addPaintOrder: function() {\n      return this.paintFirst !== 'fill' ? ' paint-order=\"' + this.paintFirst + '\" ' : '';\n    }\n  });\n})();\n/* _TO_SVG_END_ */\n\n\n(function() {\n\n  var extend = fabric.util.object.extend,\n      originalSet = 'stateProperties';\n\n  /*\n    Depends on `stateProperties`\n  */\n  function saveProps(origin, destination, props) {\n    var tmpObj = { }, deep = true;\n    props.forEach(function(prop) {\n      tmpObj[prop] = origin[prop];\n    });\n    extend(origin[destination], tmpObj, deep);\n  }\n\n  function _isEqual(origValue, currentValue, firstPass) {\n    if (origValue === currentValue) {\n      // if the objects are identical, return\n      return true;\n    }\n    else if (Array.isArray(origValue)) {\n      if (!Array.isArray(currentValue) || origValue.length !== currentValue.length) {\n        return false;\n      }\n      for (var i = 0, len = origValue.length; i < len; i++) {\n        if (!_isEqual(origValue[i], currentValue[i])) {\n          return false;\n        }\n      }\n      return true;\n    }\n    else if (origValue && typeof origValue === 'object') {\n      var keys = Object.keys(origValue), key;\n      if (!currentValue ||\n          typeof currentValue !== 'object' ||\n          (!firstPass && keys.length !== Object.keys(currentValue).length)\n      ) {\n        return false;\n      }\n      for (var i = 0, len = keys.length; i < len; i++) {\n        key = keys[i];\n        if (!_isEqual(origValue[key], currentValue[key])) {\n          return false;\n        }\n      }\n      return true;\n    }\n  }\n\n\n  fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prototype */ {\n\n    /**\n     * Returns true if object state (one of its state properties) was changed\n     * @param {String} [propertySet] optional name for the set of property we want to save\n     * @return {Boolean} true if instance' state has changed since `{@link fabric.Object#saveState}` was called\n     */\n    hasStateChanged: function(propertySet) {\n      propertySet = propertySet || originalSet;\n      var dashedPropertySet = '_' + propertySet;\n      if (Object.keys(this[dashedPropertySet]).length < this[propertySet].length) {\n        return true;\n      }\n      return !_isEqual(this[dashedPropertySet], this, true);\n    },\n\n    /**\n     * Saves state of an object\n     * @param {Object} [options] Object with additional `stateProperties` array to include when saving state\n     * @return {fabric.Object} thisArg\n     */\n    saveState: function(options) {\n      var propertySet = options && options.propertySet || originalSet,\n          destination = '_' + propertySet;\n      if (!this[destination]) {\n        return this.setupState(options);\n      }\n      saveProps(this, destination, this[propertySet]);\n      if (options && options.stateProperties) {\n        saveProps(this, destination, options.stateProperties);\n      }\n      return this;\n    },\n\n    /**\n     * Setups state of an object\n     * @param {Object} [options] Object with additional `stateProperties` array to include when saving state\n     * @return {fabric.Object} thisArg\n     */\n    setupState: function(options) {\n      options = options || { };\n      var propertySet = options.propertySet || originalSet;\n      options.propertySet = propertySet;\n      this['_' + propertySet] = { };\n      this.saveState(options);\n      return this;\n    }\n  });\n})();\n\n\n(function() {\n\n  var degreesToRadians = fabric.util.degreesToRadians;\n\n  fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prototype */ {\n\n    /**\n     * The object interactivity controls.\n     * @private\n     */\n    _controlsVisibility: null,\n\n    /**\n     * Determines which corner has been clicked\n     * @private\n     * @param {Object} pointer The pointer indicating the mouse position\n     * @return {String|Boolean} corner code (tl, tr, bl, br, etc.), or false if nothing is found\n     */\n    _findTargetCorner: function(pointer) {\n      // objects in group, anykind, are not self modificable,\n      // must not return an hovered corner.\n      if (!this.hasControls || this.group || (!this.canvas || this.canvas._activeObject !== this)) {\n        return false;\n      }\n\n      var ex = pointer.x,\n          ey = pointer.y,\n          xPoints,\n          lines;\n      this.__corner = 0;\n      for (var i in this.oCoords) {\n\n        if (!this.isControlVisible(i)) {\n          continue;\n        }\n\n        if (i === 'mtr' && !this.hasRotatingPoint) {\n          continue;\n        }\n\n        if (this.get('lockUniScaling') &&\n           (i === 'mt' || i === 'mr' || i === 'mb' || i === 'ml')) {\n          continue;\n        }\n\n        lines = this._getImageLines(this.oCoords[i].corner);\n\n        // debugging\n\n        // canvas.contextTop.fillRect(lines.bottomline.d.x, lines.bottomline.d.y, 2, 2);\n        // canvas.contextTop.fillRect(lines.bottomline.o.x, lines.bottomline.o.y, 2, 2);\n\n        // canvas.contextTop.fillRect(lines.leftline.d.x, lines.leftline.d.y, 2, 2);\n        // canvas.contextTop.fillRect(lines.leftline.o.x, lines.leftline.o.y, 2, 2);\n\n        // canvas.contextTop.fillRect(lines.topline.d.x, lines.topline.d.y, 2, 2);\n        // canvas.contextTop.fillRect(lines.topline.o.x, lines.topline.o.y, 2, 2);\n\n        // canvas.contextTop.fillRect(lines.rightline.d.x, lines.rightline.d.y, 2, 2);\n        // canvas.contextTop.fillRect(lines.rightline.o.x, lines.rightline.o.y, 2, 2);\n\n        xPoints = this._findCrossPoints({ x: ex, y: ey }, lines);\n        if (xPoints !== 0 && xPoints % 2 === 1) {\n          this.__corner = i;\n          return i;\n        }\n      }\n      return false;\n    },\n\n    /**\n     * Sets the coordinates of the draggable boxes in the corners of\n     * the image used to scale/rotate it.\n     * @private\n     */\n    _setCornerCoords: function() {\n      var coords = this.oCoords,\n          newTheta = degreesToRadians(45 - this.angle),\n          /* Math.sqrt(2 * Math.pow(this.cornerSize, 2)) / 2, */\n          /* 0.707106 stands for sqrt(2)/2 */\n          cornerHypotenuse = this.cornerSize * 0.707106,\n          cosHalfOffset = cornerHypotenuse * fabric.util.cos(newTheta),\n          sinHalfOffset = cornerHypotenuse * fabric.util.sin(newTheta),\n          x, y;\n\n      for (var point in coords) {\n        x = coords[point].x;\n        y = coords[point].y;\n        coords[point].corner = {\n          tl: {\n            x: x - sinHalfOffset,\n            y: y - cosHalfOffset\n          },\n          tr: {\n            x: x + cosHalfOffset,\n            y: y - sinHalfOffset\n          },\n          bl: {\n            x: x - cosHalfOffset,\n            y: y + sinHalfOffset\n          },\n          br: {\n            x: x + sinHalfOffset,\n            y: y + cosHalfOffset\n          }\n        };\n      }\n    },\n\n    /**\n     * Draws a colored layer behind the object, inside its selection borders.\n     * Requires public options: padding, selectionBackgroundColor\n     * this function is called when the context is transformed\n     * has checks to be skipped when the object is on a staticCanvas\n     * @param {CanvasRenderingContext2D} ctx Context to draw on\n     * @return {fabric.Object} thisArg\n     * @chainable\n     */\n    drawSelectionBackground: function(ctx) {\n      if (!this.selectionBackgroundColor ||\n        (this.canvas && !this.canvas.interactive) ||\n        (this.canvas && this.canvas._activeObject !== this)\n      ) {\n        return this;\n      }\n      ctx.save();\n      var center = this.getCenterPoint(), wh = this._calculateCurrentDimensions(),\n          vpt = this.canvas.viewportTransform;\n      ctx.translate(center.x, center.y);\n      ctx.scale(1 / vpt[0], 1 / vpt[3]);\n      ctx.rotate(degreesToRadians(this.angle));\n      ctx.fillStyle = this.selectionBackgroundColor;\n      ctx.fillRect(-wh.x / 2, -wh.y / 2, wh.x, wh.y);\n      ctx.restore();\n      return this;\n    },\n\n    /**\n     * Draws borders of an object's bounding box.\n     * Requires public properties: width, height\n     * Requires public options: padding, borderColor\n     * @param {CanvasRenderingContext2D} ctx Context to draw on\n     * @param {Object} styleOverride object to override the object style\n     * @return {fabric.Object} thisArg\n     * @chainable\n     */\n    drawBorders: function(ctx, styleOverride) {\n      styleOverride = styleOverride || {};\n      var wh = this._calculateCurrentDimensions(),\n          strokeWidth = 1 / this.borderScaleFactor,\n          width = wh.x + strokeWidth,\n          height = wh.y + strokeWidth,\n          drawRotatingPoint = typeof styleOverride.hasRotatingPoint !== 'undefined' ?\n            styleOverride.hasRotatingPoint : this.hasRotatingPoint,\n          hasControls = typeof styleOverride.hasControls !== 'undefined' ?\n            styleOverride.hasControls : this.hasControls,\n          rotatingPointOffset = typeof styleOverride.rotatingPointOffset !== 'undefined' ?\n            styleOverride.rotatingPointOffset : this.rotatingPointOffset;\n\n      ctx.save();\n      ctx.strokeStyle = styleOverride.borderColor || this.borderColor;\n      this._setLineDash(ctx, styleOverride.borderDashArray || this.borderDashArray, null);\n\n      ctx.strokeRect(\n        -width / 2,\n        -height / 2,\n        width,\n        height\n      );\n\n      if (drawRotatingPoint && this.isControlVisible('mtr') && hasControls) {\n\n        var rotateHeight = -height / 2;\n\n        ctx.beginPath();\n        ctx.moveTo(0, rotateHeight);\n        ctx.lineTo(0, rotateHeight - rotatingPointOffset);\n        ctx.stroke();\n      }\n\n      ctx.restore();\n      return this;\n    },\n\n    /**\n     * Draws borders of an object's bounding box when it is inside a group.\n     * Requires public properties: width, height\n     * Requires public options: padding, borderColor\n     * @param {CanvasRenderingContext2D} ctx Context to draw on\n     * @param {object} options object representing current object parameters\n     * @param {Object} styleOverride object to override the object style\n     * @return {fabric.Object} thisArg\n     * @chainable\n     */\n    drawBordersInGroup: function(ctx, options, styleOverride) {\n      styleOverride = styleOverride || {};\n      var p = this._getNonTransformedDimensions(),\n          matrix = fabric.util.customTransformMatrix(options.scaleX, options.scaleY, options.skewX),\n          wh = fabric.util.transformPoint(p, matrix),\n          strokeWidth = 1 / this.borderScaleFactor,\n          width = wh.x + strokeWidth,\n          height = wh.y + strokeWidth;\n\n      ctx.save();\n      this._setLineDash(ctx, styleOverride.borderDashArray || this.borderDashArray, null);\n      ctx.strokeStyle = styleOverride.borderColor || this.borderColor;\n\n      ctx.strokeRect(\n        -width / 2,\n        -height / 2,\n        width,\n        height\n      );\n\n      ctx.restore();\n      return this;\n    },\n\n    /**\n     * Draws corners of an object's bounding box.\n     * Requires public properties: width, height\n     * Requires public options: cornerSize, padding\n     * @param {CanvasRenderingContext2D} ctx Context to draw on\n     * @param {Object} styleOverride object to override the object style\n     * @return {fabric.Object} thisArg\n     * @chainable\n     */\n    drawControls: function(ctx, styleOverride) {\n      styleOverride = styleOverride || {};\n      var wh = this._calculateCurrentDimensions(),\n          width = wh.x,\n          height = wh.y,\n          scaleOffset = styleOverride.cornerSize || this.cornerSize,\n          left = -(width + scaleOffset) / 2,\n          top = -(height + scaleOffset) / 2,\n          transparentCorners = typeof styleOverride.transparentCorners !== 'undefined' ?\n            styleOverride.transparentCorners : this.transparentCorners,\n          hasRotatingPoint = typeof styleOverride.hasRotatingPoint !== 'undefined' ?\n            styleOverride.hasRotatingPoint : this.hasRotatingPoint,\n          methodName = transparentCorners ? 'stroke' : 'fill';\n\n      ctx.save();\n      ctx.strokeStyle = ctx.fillStyle = styleOverride.cornerColor || this.cornerColor;\n      if (!this.transparentCorners) {\n        ctx.strokeStyle = styleOverride.cornerStrokeColor || this.cornerStrokeColor;\n      }\n      this._setLineDash(ctx, styleOverride.cornerDashArray || this.cornerDashArray, null);\n\n      // top-left\n      this._drawControl('tl', ctx, methodName,\n        left,\n        top, styleOverride);\n\n      // top-right\n      this._drawControl('tr', ctx, methodName,\n        left + width,\n        top, styleOverride);\n\n      // bottom-left\n      this._drawControl('bl', ctx, methodName,\n        left,\n        top + height, styleOverride);\n\n      // bottom-right\n      this._drawControl('br', ctx, methodName,\n        left + width,\n        top + height, styleOverride);\n\n      if (!this.get('lockUniScaling')) {\n\n        // middle-top\n        this._drawControl('mt', ctx, methodName,\n          left + width / 2,\n          top, styleOverride);\n\n        // middle-bottom\n        this._drawControl('mb', ctx, methodName,\n          left + width / 2,\n          top + height, styleOverride);\n\n        // middle-right\n        this._drawControl('mr', ctx, methodName,\n          left + width,\n          top + height / 2, styleOverride);\n\n        // middle-left\n        this._drawControl('ml', ctx, methodName,\n          left,\n          top + height / 2, styleOverride);\n      }\n\n      // middle-top-rotate\n      if (hasRotatingPoint) {\n        this._drawControl('mtr', ctx, methodName,\n          left + width / 2,\n          top - this.rotatingPointOffset, styleOverride);\n      }\n\n      ctx.restore();\n\n      return this;\n    },\n\n    /**\n     * @private\n     */\n    _drawControl: function(control, ctx, methodName, left, top, styleOverride) {\n      styleOverride = styleOverride || {};\n      if (!this.isControlVisible(control)) {\n        return;\n      }\n      var size = this.cornerSize, stroke = !this.transparentCorners && this.cornerStrokeColor;\n      switch (styleOverride.cornerStyle || this.cornerStyle) {\n        case 'circle':\n          ctx.beginPath();\n          ctx.arc(left + size / 2, top + size / 2, size / 2, 0, 2 * Math.PI, false);\n          ctx[methodName]();\n          if (stroke) {\n            ctx.stroke();\n          }\n          break;\n        default:\n          this.transparentCorners || ctx.clearRect(left, top, size, size);\n          ctx[methodName + 'Rect'](left, top, size, size);\n          if (stroke) {\n            ctx.strokeRect(left, top, size, size);\n          }\n      }\n    },\n\n    /**\n     * Returns true if the specified control is visible, false otherwise.\n     * @param {String} controlName The name of the control. Possible values are 'tl', 'tr', 'br', 'bl', 'ml', 'mt', 'mr', 'mb', 'mtr'.\n     * @returns {Boolean} true if the specified control is visible, false otherwise\n     */\n    isControlVisible: function(controlName) {\n      return this._getControlsVisibility()[controlName];\n    },\n\n    /**\n     * Sets the visibility of the specified control.\n     * @param {String} controlName The name of the control. Possible values are 'tl', 'tr', 'br', 'bl', 'ml', 'mt', 'mr', 'mb', 'mtr'.\n     * @param {Boolean} visible true to set the specified control visible, false otherwise\n     * @return {fabric.Object} thisArg\n     * @chainable\n     */\n    setControlVisible: function(controlName, visible) {\n      this._getControlsVisibility()[controlName] = visible;\n      return this;\n    },\n\n    /**\n     * Sets the visibility state of object controls.\n     * @param {Object} [options] Options object\n     * @param {Boolean} [options.bl] true to enable the bottom-left control, false to disable it\n     * @param {Boolean} [options.br] true to enable the bottom-right control, false to disable it\n     * @param {Boolean} [options.mb] true to enable the middle-bottom control, false to disable it\n     * @param {Boolean} [options.ml] true to enable the middle-left control, false to disable it\n     * @param {Boolean} [options.mr] true to enable the middle-right control, false to disable it\n     * @param {Boolean} [options.mt] true to enable the middle-top control, false to disable it\n     * @param {Boolean} [options.tl] true to enable the top-left control, false to disable it\n     * @param {Boolean} [options.tr] true to enable the top-right control, false to disable it\n     * @param {Boolean} [options.mtr] true to enable the middle-top-rotate control, false to disable it\n     * @return {fabric.Object} thisArg\n     * @chainable\n     */\n    setControlsVisibility: function(options) {\n      options || (options = { });\n\n      for (var p in options) {\n        this.setControlVisible(p, options[p]);\n      }\n      return this;\n    },\n\n    /**\n     * Returns the instance of the control visibility set for this object.\n     * @private\n     * @returns {Object}\n     */\n    _getControlsVisibility: function() {\n      if (!this._controlsVisibility) {\n        this._controlsVisibility = {\n          tl: true,\n          tr: true,\n          br: true,\n          bl: true,\n          ml: true,\n          mt: true,\n          mr: true,\n          mb: true,\n          mtr: true\n        };\n      }\n      return this._controlsVisibility;\n    },\n\n    /**\n     * This callback function is called every time _discardActiveObject or _setActiveObject\n     * try to to deselect this object. If the function returns true, the process is cancelled\n     * @param {Object} [options] options sent from the upper functions\n     * @param {Event} [options.e] event if the process is generated by an event\n     */\n    onDeselect: function() {\n      // implemented by sub-classes, as needed.\n    },\n\n\n    /**\n     * This callback function is called every time _discardActiveObject or _setActiveObject\n     * try to to select this object. If the function returns true, the process is cancelled\n     * @param {Object} [options] options sent from the upper functions\n     * @param {Event} [options.e] event if the process is generated by an event\n     */\n    onSelect: function() {\n      // implemented by sub-classes, as needed.\n    }\n  });\n})();\n\n\nfabric.util.object.extend(fabric.StaticCanvas.prototype, /** @lends fabric.StaticCanvas.prototype */ {\n\n  /**\n   * Animation duration (in ms) for fx* methods\n   * @type Number\n   * @default\n   */\n  FX_DURATION: 500,\n\n  /**\n   * Centers object horizontally with animation.\n   * @param {fabric.Object} object Object to center\n   * @param {Object} [callbacks] Callbacks object with optional \"onComplete\" and/or \"onChange\" properties\n   * @param {Function} [callbacks.onComplete] Invoked on completion\n   * @param {Function} [callbacks.onChange] Invoked on every step of animation\n   * @return {fabric.Canvas} thisArg\n   * @chainable\n   */\n  fxCenterObjectH: function (object, callbacks) {\n    callbacks = callbacks || { };\n\n    var empty = function() { },\n        onComplete = callbacks.onComplete || empty,\n        onChange = callbacks.onChange || empty,\n        _this = this;\n\n    fabric.util.animate({\n      startValue: object.left,\n      endValue: this.getCenter().left,\n      duration: this.FX_DURATION,\n      onChange: function(value) {\n        object.set('left', value);\n        _this.requestRenderAll();\n        onChange();\n      },\n      onComplete: function() {\n        object.setCoords();\n        onComplete();\n      }\n    });\n\n    return this;\n  },\n\n  /**\n   * Centers object vertically with animation.\n   * @param {fabric.Object} object Object to center\n   * @param {Object} [callbacks] Callbacks object with optional \"onComplete\" and/or \"onChange\" properties\n   * @param {Function} [callbacks.onComplete] Invoked on completion\n   * @param {Function} [callbacks.onChange] Invoked on every step of animation\n   * @return {fabric.Canvas} thisArg\n   * @chainable\n   */\n  fxCenterObjectV: function (object, callbacks) {\n    callbacks = callbacks || { };\n\n    var empty = function() { },\n        onComplete = callbacks.onComplete || empty,\n        onChange = callbacks.onChange || empty,\n        _this = this;\n\n    fabric.util.animate({\n      startValue: object.top,\n      endValue: this.getCenter().top,\n      duration: this.FX_DURATION,\n      onChange: function(value) {\n        object.set('top', value);\n        _this.requestRenderAll();\n        onChange();\n      },\n      onComplete: function() {\n        object.setCoords();\n        onComplete();\n      }\n    });\n\n    return this;\n  },\n\n  /**\n   * Same as `fabric.Canvas#remove` but animated\n   * @param {fabric.Object} object Object to remove\n   * @param {Object} [callbacks] Callbacks object with optional \"onComplete\" and/or \"onChange\" properties\n   * @param {Function} [callbacks.onComplete] Invoked on completion\n   * @param {Function} [callbacks.onChange] Invoked on every step of animation\n   * @return {fabric.Canvas} thisArg\n   * @chainable\n   */\n  fxRemove: function (object, callbacks) {\n    callbacks = callbacks || { };\n\n    var empty = function() { },\n        onComplete = callbacks.onComplete || empty,\n        onChange = callbacks.onChange || empty,\n        _this = this;\n\n    fabric.util.animate({\n      startValue: object.opacity,\n      endValue: 0,\n      duration: this.FX_DURATION,\n      onChange: function(value) {\n        object.set('opacity', value);\n        _this.requestRenderAll();\n        onChange();\n      },\n      onComplete: function () {\n        _this.remove(object);\n        onComplete();\n      }\n    });\n\n    return this;\n  }\n});\n\nfabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prototype */ {\n  /**\n   * Animates object's properties\n   * @param {String|Object} property Property to animate (if string) or properties to animate (if object)\n   * @param {Number|Object} value Value to animate property to (if string was given first) or options object\n   * @return {fabric.Object} thisArg\n   * @tutorial {@link http://fabricjs.com/fabric-intro-part-2#animation}\n   * @chainable\n   *\n   * As object — multiple properties\n   *\n   * object.animate({ left: ..., top: ... });\n   * object.animate({ left: ..., top: ... }, { duration: ... });\n   *\n   * As string — one property\n   *\n   * object.animate('left', ...);\n   * object.animate('left', { duration: ... });\n   *\n   */\n  animate: function() {\n    if (arguments[0] && typeof arguments[0] === 'object') {\n      var propsToAnimate = [], prop, skipCallbacks;\n      for (prop in arguments[0]) {\n        propsToAnimate.push(prop);\n      }\n      for (var i = 0, len = propsToAnimate.length; i < len; i++) {\n        prop = propsToAnimate[i];\n        skipCallbacks = i !== len - 1;\n        this._animate(prop, arguments[0][prop], arguments[1], skipCallbacks);\n      }\n    }\n    else {\n      this._animate.apply(this, arguments);\n    }\n    return this;\n  },\n\n  /**\n   * @private\n   * @param {String} property Property to animate\n   * @param {String} to Value to animate to\n   * @param {Object} [options] Options object\n   * @param {Boolean} [skipCallbacks] When true, callbacks like onchange and oncomplete are not invoked\n   */\n  _animate: function(property, to, options, skipCallbacks) {\n    var _this = this, propPair;\n\n    to = to.toString();\n\n    if (!options) {\n      options = { };\n    }\n    else {\n      options = fabric.util.object.clone(options);\n    }\n\n    if (~property.indexOf('.')) {\n      propPair = property.split('.');\n    }\n\n    var currentValue = propPair\n      ? this.get(propPair[0])[propPair[1]]\n      : this.get(property);\n\n    if (!('from' in options)) {\n      options.from = currentValue;\n    }\n\n    if (~to.indexOf('=')) {\n      to = currentValue + parseFloat(to.replace('=', ''));\n    }\n    else {\n      to = parseFloat(to);\n    }\n\n    fabric.util.animate({\n      startValue: options.from,\n      endValue: to,\n      byValue: options.by,\n      easing: options.easing,\n      duration: options.duration,\n      abort: options.abort && function() {\n        return options.abort.call(_this);\n      },\n      onChange: function(value, valueProgress, timeProgress) {\n        if (propPair) {\n          _this[propPair[0]][propPair[1]] = value;\n        }\n        else {\n          _this.set(property, value);\n        }\n        if (skipCallbacks) {\n          return;\n        }\n        options.onChange && options.onChange(value, valueProgress, timeProgress);\n      },\n      onComplete: function(value, valueProgress, timeProgress) {\n        if (skipCallbacks) {\n          return;\n        }\n\n        _this.setCoords();\n        options.onComplete && options.onComplete(value, valueProgress, timeProgress);\n      }\n    });\n  }\n});\n\n\n(function(global) {\n\n  'use strict';\n\n  var fabric = global.fabric || (global.fabric = { }),\n      extend = fabric.util.object.extend,\n      clone = fabric.util.object.clone,\n      coordProps = { x1: 1, x2: 1, y1: 1, y2: 1 },\n      supportsLineDash = fabric.StaticCanvas.supports('setLineDash');\n\n  if (fabric.Line) {\n    fabric.warn('fabric.Line is already defined');\n    return;\n  }\n\n  /**\n   * Line class\n   * @class fabric.Line\n   * @extends fabric.Object\n   * @see {@link fabric.Line#initialize} for constructor definition\n   */\n  fabric.Line = fabric.util.createClass(fabric.Object, /** @lends fabric.Line.prototype */ {\n\n    /**\n     * Type of an object\n     * @type String\n     * @default\n     */\n    type: 'line',\n\n    /**\n     * x value or first line edge\n     * @type Number\n     * @default\n     */\n    x1: 0,\n\n    /**\n     * y value or first line edge\n     * @type Number\n     * @default\n     */\n    y1: 0,\n\n    /**\n     * x value or second line edge\n     * @type Number\n     * @default\n     */\n    x2: 0,\n\n    /**\n     * y value or second line edge\n     * @type Number\n     * @default\n     */\n    y2: 0,\n\n    cacheProperties: fabric.Object.prototype.cacheProperties.concat('x1', 'x2', 'y1', 'y2'),\n\n    /**\n     * Constructor\n     * @param {Array} [points] Array of points\n     * @param {Object} [options] Options object\n     * @return {fabric.Line} thisArg\n     */\n    initialize: function(points, options) {\n      if (!points) {\n        points = [0, 0, 0, 0];\n      }\n\n      this.callSuper('initialize', options);\n\n      this.set('x1', points[0]);\n      this.set('y1', points[1]);\n      this.set('x2', points[2]);\n      this.set('y2', points[3]);\n\n      this._setWidthHeight(options);\n    },\n\n    /**\n     * @private\n     * @param {Object} [options] Options\n     */\n    _setWidthHeight: function(options) {\n      options || (options = { });\n\n      this.width = Math.abs(this.x2 - this.x1);\n      this.height = Math.abs(this.y2 - this.y1);\n\n      this.left = 'left' in options\n        ? options.left\n        : this._getLeftToOriginX();\n\n      this.top = 'top' in options\n        ? options.top\n        : this._getTopToOriginY();\n    },\n\n    /**\n     * @private\n     * @param {String} key\n     * @param {*} value\n     */\n    _set: function(key, value) {\n      this.callSuper('_set', key, value);\n      if (typeof coordProps[key] !== 'undefined') {\n        this._setWidthHeight();\n      }\n      return this;\n    },\n\n    /**\n     * @private\n     * @return {Number} leftToOriginX Distance from left edge of canvas to originX of Line.\n     */\n    _getLeftToOriginX: makeEdgeToOriginGetter(\n      { // property names\n        origin: 'originX',\n        axis1: 'x1',\n        axis2: 'x2',\n        dimension: 'width'\n      },\n      { // possible values of origin\n        nearest: 'left',\n        center: 'center',\n        farthest: 'right'\n      }\n    ),\n\n    /**\n     * @private\n     * @return {Number} topToOriginY Distance from top edge of canvas to originY of Line.\n     */\n    _getTopToOriginY: makeEdgeToOriginGetter(\n      { // property names\n        origin: 'originY',\n        axis1: 'y1',\n        axis2: 'y2',\n        dimension: 'height'\n      },\n      { // possible values of origin\n        nearest: 'top',\n        center: 'center',\n        farthest: 'bottom'\n      }\n    ),\n\n    /**\n     * @private\n     * @param {CanvasRenderingContext2D} ctx Context to render on\n     */\n    _render: function(ctx) {\n      ctx.beginPath();\n\n      if (!this.strokeDashArray || this.strokeDashArray && supportsLineDash) {\n        // move from center (of virtual box) to its left/top corner\n        // we can't assume x1, y1 is top left and x2, y2 is bottom right\n        var p = this.calcLinePoints();\n        ctx.moveTo(p.x1, p.y1);\n        ctx.lineTo(p.x2, p.y2);\n      }\n\n      ctx.lineWidth = this.strokeWidth;\n\n      // TODO: test this\n      // make sure setting \"fill\" changes color of a line\n      // (by copying fillStyle to strokeStyle, since line is stroked, not filled)\n      var origStrokeStyle = ctx.strokeStyle;\n      ctx.strokeStyle = this.stroke || ctx.fillStyle;\n      this.stroke && this._renderStroke(ctx);\n      ctx.strokeStyle = origStrokeStyle;\n    },\n\n    /**\n     * @private\n     * @param {CanvasRenderingContext2D} ctx Context to render on\n     */\n    _renderDashedStroke: function(ctx) {\n      var p = this.calcLinePoints();\n\n      ctx.beginPath();\n      fabric.util.drawDashedLine(ctx, p.x1, p.y1, p.x2, p.y2, this.strokeDashArray);\n      ctx.closePath();\n    },\n\n    /**\n     * This function is an helper for svg import. it returns the center of the object in the svg\n     * untransformed coordinates\n     * @private\n     * @return {Object} center point from element coordinates\n     */\n    _findCenterFromElement: function() {\n      return {\n        x: (this.x1 + this.x2) / 2,\n        y: (this.y1 + this.y2) / 2,\n      };\n    },\n\n    /**\n     * Returns object representation of an instance\n     * @methd toObject\n     * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output\n     * @return {Object} object representation of an instance\n     */\n    toObject: function(propertiesToInclude) {\n      return extend(this.callSuper('toObject', propertiesToInclude), this.calcLinePoints());\n    },\n\n    /*\n     * Calculate object dimensions from its properties\n     * @private\n     */\n    _getNonTransformedDimensions: function() {\n      var dim = this.callSuper('_getNonTransformedDimensions');\n      if (this.strokeLineCap === 'butt') {\n        if (this.width === 0) {\n          dim.y -= this.strokeWidth;\n        }\n        if (this.height === 0) {\n          dim.x -= this.strokeWidth;\n        }\n      }\n      return dim;\n    },\n\n    /**\n     * Recalculates line points given width and height\n     * @private\n     */\n    calcLinePoints: function() {\n      var xMult = this.x1 <= this.x2 ? -1 : 1,\n          yMult = this.y1 <= this.y2 ? -1 : 1,\n          x1 = (xMult * this.width * 0.5),\n          y1 = (yMult * this.height * 0.5),\n          x2 = (xMult * this.width * -0.5),\n          y2 = (yMult * this.height * -0.5);\n\n      return {\n        x1: x1,\n        x2: x2,\n        y1: y1,\n        y2: y2\n      };\n    },\n\n    /* _TO_SVG_START_ */\n    /**\n     * Returns svg representation of an instance\n     * @return {Array} an array of strings with the specific svg representation\n     * of the instance\n     */\n    _toSVG: function() {\n      var p = this.calcLinePoints();\n      return [\n        '<line ', 'COMMON_PARTS',\n        'x1=\"', p.x1,\n        '\" y1=\"', p.y1,\n        '\" x2=\"', p.x2,\n        '\" y2=\"', p.y2,\n        '\" />\\n'\n      ];\n    },\n    /* _TO_SVG_END_ */\n  });\n\n  /* _FROM_SVG_START_ */\n  /**\n   * List of attribute names to account for when parsing SVG element (used by {@link fabric.Line.fromElement})\n   * @static\n   * @memberOf fabric.Line\n   * @see http://www.w3.org/TR/SVG/shapes.html#LineElement\n   */\n  fabric.Line.ATTRIBUTE_NAMES = fabric.SHARED_ATTRIBUTES.concat('x1 y1 x2 y2'.split(' '));\n\n  /**\n   * Returns fabric.Line instance from an SVG element\n   * @static\n   * @memberOf fabric.Line\n   * @param {SVGElement} element Element to parse\n   * @param {Object} [options] Options object\n   * @param {Function} [callback] callback function invoked after parsing\n   */\n  fabric.Line.fromElement = function(element, callback, options) {\n    options = options || { };\n    var parsedAttributes = fabric.parseAttributes(element, fabric.Line.ATTRIBUTE_NAMES),\n        points = [\n          parsedAttributes.x1 || 0,\n          parsedAttributes.y1 || 0,\n          parsedAttributes.x2 || 0,\n          parsedAttributes.y2 || 0\n        ];\n    callback(new fabric.Line(points, extend(parsedAttributes, options)));\n  };\n  /* _FROM_SVG_END_ */\n\n  /**\n   * Returns fabric.Line instance from an object representation\n   * @static\n   * @memberOf fabric.Line\n   * @param {Object} object Object to create an instance from\n   * @param {function} [callback] invoked with new instance as first argument\n   */\n  fabric.Line.fromObject = function(object, callback) {\n    function _callback(instance) {\n      delete instance.points;\n      callback && callback(instance);\n    };\n    var options = clone(object, true);\n    options.points = [object.x1, object.y1, object.x2, object.y2];\n    fabric.Object._fromObject('Line', options, _callback, 'points');\n  };\n\n  /**\n   * Produces a function that calculates distance from canvas edge to Line origin.\n   */\n  function makeEdgeToOriginGetter(propertyNames, originValues) {\n    var origin = propertyNames.origin,\n        axis1 = propertyNames.axis1,\n        axis2 = propertyNames.axis2,\n        dimension = propertyNames.dimension,\n        nearest = originValues.nearest,\n        center = originValues.center,\n        farthest = originValues.farthest;\n\n    return function() {\n      switch (this.get(origin)) {\n        case nearest:\n          return Math.min(this.get(axis1), this.get(axis2));\n        case center:\n          return Math.min(this.get(axis1), this.get(axis2)) + (0.5 * this.get(dimension));\n        case farthest:\n          return Math.max(this.get(axis1), this.get(axis2));\n      }\n    };\n\n  }\n\n})(typeof exports !== 'undefined' ? exports : this);\n\n\n(function(global) {\n\n  'use strict';\n\n  var fabric = global.fabric || (global.fabric = { }),\n      pi = Math.PI;\n\n  if (fabric.Circle) {\n    fabric.warn('fabric.Circle is already defined.');\n    return;\n  }\n\n  /**\n   * Circle class\n   * @class fabric.Circle\n   * @extends fabric.Object\n   * @see {@link fabric.Circle#initialize} for constructor definition\n   */\n  fabric.Circle = fabric.util.createClass(fabric.Object, /** @lends fabric.Circle.prototype */ {\n\n    /**\n     * Type of an object\n     * @type String\n     * @default\n     */\n    type: 'circle',\n\n    /**\n     * Radius of this circle\n     * @type Number\n     * @default\n     */\n    radius: 0,\n\n    /**\n     * Start angle of the circle, moving clockwise\n     * deprectated type, this should be in degree, this was an oversight.\n     * probably will change to degrees in next major version\n     * @type Number\n     * @default 0\n     */\n    startAngle: 0,\n\n    /**\n     * End angle of the circle\n     * deprectated type, this should be in degree, this was an oversight.\n     * probably will change to degrees in next major version\n     * @type Number\n     * @default 2Pi\n     */\n    endAngle: pi * 2,\n\n    cacheProperties: fabric.Object.prototype.cacheProperties.concat('radius', 'startAngle', 'endAngle'),\n\n    /**\n     * @private\n     * @param {String} key\n     * @param {*} value\n     * @return {fabric.Circle} thisArg\n     */\n    _set: function(key, value) {\n      this.callSuper('_set', key, value);\n\n      if (key === 'radius') {\n        this.setRadius(value);\n      }\n\n      return this;\n    },\n\n    /**\n     * Returns object representation of an instance\n     * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output\n     * @return {Object} object representation of an instance\n     */\n    toObject: function(propertiesToInclude) {\n      return this.callSuper('toObject', ['radius', 'startAngle', 'endAngle'].concat(propertiesToInclude));\n    },\n\n    /* _TO_SVG_START_ */\n\n    /**\n     * Returns svg representation of an instance\n     * @return {Array} an array of strings with the specific svg representation\n     * of the instance\n     */\n    _toSVG: function() {\n      var svgString, x = 0, y = 0,\n          angle = (this.endAngle - this.startAngle) % ( 2 * pi);\n\n      if (angle === 0) {\n        svgString = [\n          '<circle ', 'COMMON_PARTS',\n          'cx=\"' + x + '\" cy=\"' + y + '\" ',\n          'r=\"', this.radius,\n          '\" />\\n'\n        ];\n      }\n      else {\n        var startX = fabric.util.cos(this.startAngle) * this.radius,\n            startY = fabric.util.sin(this.startAngle) * this.radius,\n            endX = fabric.util.cos(this.endAngle) * this.radius,\n            endY = fabric.util.sin(this.endAngle) * this.radius,\n            largeFlag = angle > pi ? '1' : '0';\n        svgString = [\n          '<path d=\"M ' + startX + ' ' + startY,\n          ' A ' + this.radius + ' ' + this.radius,\n          ' 0 ', +largeFlag + ' 1', ' ' + endX + ' ' + endY,\n          '\"', 'COMMON_PARTS', ' />\\n'\n        ];\n      }\n      return svgString;\n    },\n    /* _TO_SVG_END_ */\n\n    /**\n     * @private\n     * @param {CanvasRenderingContext2D} ctx context to render on\n     */\n    _render: function(ctx) {\n      ctx.beginPath();\n      ctx.arc(\n        0,\n        0,\n        this.radius,\n        this.startAngle,\n        this.endAngle, false);\n      this._renderPaintInOrder(ctx);\n    },\n\n    /**\n     * Returns horizontal radius of an object (according to how an object is scaled)\n     * @return {Number}\n     */\n    getRadiusX: function() {\n      return this.get('radius') * this.get('scaleX');\n    },\n\n    /**\n     * Returns vertical radius of an object (according to how an object is scaled)\n     * @return {Number}\n     */\n    getRadiusY: function() {\n      return this.get('radius') * this.get('scaleY');\n    },\n\n    /**\n     * Sets radius of an object (and updates width accordingly)\n     * @return {fabric.Circle} thisArg\n     */\n    setRadius: function(value) {\n      this.radius = value;\n      return this.set('width', value * 2).set('height', value * 2);\n    },\n  });\n\n  /* _FROM_SVG_START_ */\n  /**\n   * List of attribute names to account for when parsing SVG element (used by {@link fabric.Circle.fromElement})\n   * @static\n   * @memberOf fabric.Circle\n   * @see: http://www.w3.org/TR/SVG/shapes.html#CircleElement\n   */\n  fabric.Circle.ATTRIBUTE_NAMES = fabric.SHARED_ATTRIBUTES.concat('cx cy r'.split(' '));\n\n  /**\n   * Returns {@link fabric.Circle} instance from an SVG element\n   * @static\n   * @memberOf fabric.Circle\n   * @param {SVGElement} element Element to parse\n   * @param {Function} [callback] Options callback invoked after parsing is finished\n   * @param {Object} [options] Options object\n   * @throws {Error} If value of `r` attribute is missing or invalid\n   */\n  fabric.Circle.fromElement = function(element, callback) {\n    var parsedAttributes = fabric.parseAttributes(element, fabric.Circle.ATTRIBUTE_NAMES);\n\n    if (!isValidRadius(parsedAttributes)) {\n      throw new Error('value of `r` attribute is required and can not be negative');\n    }\n\n    parsedAttributes.left = (parsedAttributes.left || 0) - parsedAttributes.radius;\n    parsedAttributes.top = (parsedAttributes.top || 0) - parsedAttributes.radius;\n    callback(new fabric.Circle(parsedAttributes));\n  };\n\n  /**\n   * @private\n   */\n  function isValidRadius(attributes) {\n    return (('radius' in attributes) && (attributes.radius >= 0));\n  }\n  /* _FROM_SVG_END_ */\n\n  /**\n   * Returns {@link fabric.Circle} instance from an object representation\n   * @static\n   * @memberOf fabric.Circle\n   * @param {Object} object Object to create an instance from\n   * @param {function} [callback] invoked with new instance as first argument\n   * @return {Object} Instance of fabric.Circle\n   */\n  fabric.Circle.fromObject = function(object, callback) {\n    return fabric.Object._fromObject('Circle', object, callback);\n  };\n\n})(typeof exports !== 'undefined' ? exports : this);\n\n\n(function(global) {\n\n  'use strict';\n\n  var fabric = global.fabric || (global.fabric = { });\n\n  if (fabric.Triangle) {\n    fabric.warn('fabric.Triangle is already defined');\n    return;\n  }\n\n  /**\n   * Triangle class\n   * @class fabric.Triangle\n   * @extends fabric.Object\n   * @return {fabric.Triangle} thisArg\n   * @see {@link fabric.Triangle#initialize} for constructor definition\n   */\n  fabric.Triangle = fabric.util.createClass(fabric.Object, /** @lends fabric.Triangle.prototype */ {\n\n    /**\n     * Type of an object\n     * @type String\n     * @default\n     */\n    type: 'triangle',\n\n    /**\n     * Width is set to 100 to compensate the old initialize code that was setting it to 100\n     * @type Number\n     * @default\n     */\n    width: 100,\n\n    /**\n     * Height is set to 100 to compensate the old initialize code that was setting it to 100\n     * @type Number\n     * @default\n     */\n    height: 100,\n\n    /**\n     * @private\n     * @param {CanvasRenderingContext2D} ctx Context to render on\n     */\n    _render: function(ctx) {\n      var widthBy2 = this.width / 2,\n          heightBy2 = this.height / 2;\n\n      ctx.beginPath();\n      ctx.moveTo(-widthBy2, heightBy2);\n      ctx.lineTo(0, -heightBy2);\n      ctx.lineTo(widthBy2, heightBy2);\n      ctx.closePath();\n\n      this._renderPaintInOrder(ctx);\n    },\n\n    /**\n     * @private\n     * @param {CanvasRenderingContext2D} ctx Context to render on\n     */\n    _renderDashedStroke: function(ctx) {\n      var widthBy2 = this.width / 2,\n          heightBy2 = this.height / 2;\n\n      ctx.beginPath();\n      fabric.util.drawDashedLine(ctx, -widthBy2, heightBy2, 0, -heightBy2, this.strokeDashArray);\n      fabric.util.drawDashedLine(ctx, 0, -heightBy2, widthBy2, heightBy2, this.strokeDashArray);\n      fabric.util.drawDashedLine(ctx, widthBy2, heightBy2, -widthBy2, heightBy2, this.strokeDashArray);\n      ctx.closePath();\n    },\n\n    /* _TO_SVG_START_ */\n    /**\n     * Returns svg representation of an instance\n     * @return {Array} an array of strings with the specific svg representation\n     * of the instance\n     */\n    _toSVG: function() {\n      var widthBy2 = this.width / 2,\n          heightBy2 = this.height / 2,\n          points = [\n            -widthBy2 + ' ' + heightBy2,\n            '0 ' + -heightBy2,\n            widthBy2 + ' ' + heightBy2\n          ].join(',');\n      return [\n        '<polygon ', 'COMMON_PARTS',\n        'points=\"', points,\n        '\" />'\n      ];\n    },\n    /* _TO_SVG_END_ */\n  });\n\n  /**\n   * Returns {@link fabric.Triangle} instance from an object representation\n   * @static\n   * @memberOf fabric.Triangle\n   * @param {Object} object Object to create an instance from\n   * @param {function} [callback] invoked with new instance as first argument\n   */\n  fabric.Triangle.fromObject = function(object, callback) {\n    return fabric.Object._fromObject('Triangle', object, callback);\n  };\n\n})(typeof exports !== 'undefined' ? exports : this);\n\n\n(function(global) {\n\n  'use strict';\n\n  var fabric = global.fabric || (global.fabric = { }),\n      piBy2   = Math.PI * 2;\n\n  if (fabric.Ellipse) {\n    fabric.warn('fabric.Ellipse is already defined.');\n    return;\n  }\n\n  /**\n   * Ellipse class\n   * @class fabric.Ellipse\n   * @extends fabric.Object\n   * @return {fabric.Ellipse} thisArg\n   * @see {@link fabric.Ellipse#initialize} for constructor definition\n   */\n  fabric.Ellipse = fabric.util.createClass(fabric.Object, /** @lends fabric.Ellipse.prototype */ {\n\n    /**\n     * Type of an object\n     * @type String\n     * @default\n     */\n    type: 'ellipse',\n\n    /**\n     * Horizontal radius\n     * @type Number\n     * @default\n     */\n    rx:   0,\n\n    /**\n     * Vertical radius\n     * @type Number\n     * @default\n     */\n    ry:   0,\n\n    cacheProperties: fabric.Object.prototype.cacheProperties.concat('rx', 'ry'),\n\n    /**\n     * Constructor\n     * @param {Object} [options] Options object\n     * @return {fabric.Ellipse} thisArg\n     */\n    initialize: function(options) {\n      this.callSuper('initialize', options);\n      this.set('rx', options && options.rx || 0);\n      this.set('ry', options && options.ry || 0);\n    },\n\n    /**\n     * @private\n     * @param {String} key\n     * @param {*} value\n     * @return {fabric.Ellipse} thisArg\n     */\n    _set: function(key, value) {\n      this.callSuper('_set', key, value);\n      switch (key) {\n\n        case 'rx':\n          this.rx = value;\n          this.set('width', value * 2);\n          break;\n\n        case 'ry':\n          this.ry = value;\n          this.set('height', value * 2);\n          break;\n\n      }\n      return this;\n    },\n\n    /**\n     * Returns horizontal radius of an object (according to how an object is scaled)\n     * @return {Number}\n     */\n    getRx: function() {\n      return this.get('rx') * this.get('scaleX');\n    },\n\n    /**\n     * Returns Vertical radius of an object (according to how an object is scaled)\n     * @return {Number}\n     */\n    getRy: function() {\n      return this.get('ry') * this.get('scaleY');\n    },\n\n    /**\n     * Returns object representation of an instance\n     * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output\n     * @return {Object} object representation of an instance\n     */\n    toObject: function(propertiesToInclude) {\n      return this.callSuper('toObject', ['rx', 'ry'].concat(propertiesToInclude));\n    },\n\n    /* _TO_SVG_START_ */\n    /**\n     * Returns svg representation of an instance\n     * @return {Array} an array of strings with the specific svg representation\n     * of the instance\n     */\n    _toSVG: function() {\n      return [\n        '<ellipse ', 'COMMON_PARTS',\n        'cx=\"0\" cy=\"0\" ',\n        'rx=\"', this.rx,\n        '\" ry=\"', this.ry,\n        '\" />\\n'\n      ];\n    },\n    /* _TO_SVG_END_ */\n\n    /**\n     * @private\n     * @param {CanvasRenderingContext2D} ctx context to render on\n     */\n    _render: function(ctx) {\n      ctx.beginPath();\n      ctx.save();\n      ctx.transform(1, 0, 0, this.ry / this.rx, 0, 0);\n      ctx.arc(\n        0,\n        0,\n        this.rx,\n        0,\n        piBy2,\n        false);\n      ctx.restore();\n      this._renderPaintInOrder(ctx);\n    },\n  });\n\n  /* _FROM_SVG_START_ */\n  /**\n   * List of attribute names to account for when parsing SVG element (used by {@link fabric.Ellipse.fromElement})\n   * @static\n   * @memberOf fabric.Ellipse\n   * @see http://www.w3.org/TR/SVG/shapes.html#EllipseElement\n   */\n  fabric.Ellipse.ATTRIBUTE_NAMES = fabric.SHARED_ATTRIBUTES.concat('cx cy rx ry'.split(' '));\n\n  /**\n   * Returns {@link fabric.Ellipse} instance from an SVG element\n   * @static\n   * @memberOf fabric.Ellipse\n   * @param {SVGElement} element Element to parse\n   * @param {Function} [callback] Options callback invoked after parsing is finished\n   * @return {fabric.Ellipse}\n   */\n  fabric.Ellipse.fromElement = function(element, callback) {\n\n    var parsedAttributes = fabric.parseAttributes(element, fabric.Ellipse.ATTRIBUTE_NAMES);\n\n    parsedAttributes.left = (parsedAttributes.left || 0) - parsedAttributes.rx;\n    parsedAttributes.top = (parsedAttributes.top || 0) - parsedAttributes.ry;\n    callback(new fabric.Ellipse(parsedAttributes));\n  };\n  /* _FROM_SVG_END_ */\n\n  /**\n   * Returns {@link fabric.Ellipse} instance from an object representation\n   * @static\n   * @memberOf fabric.Ellipse\n   * @param {Object} object Object to create an instance from\n   * @param {function} [callback] invoked with new instance as first argument\n   * @return {fabric.Ellipse}\n   */\n  fabric.Ellipse.fromObject = function(object, callback) {\n    return fabric.Object._fromObject('Ellipse', object, callback);\n  };\n\n})(typeof exports !== 'undefined' ? exports : this);\n\n\n(function(global) {\n\n  'use strict';\n\n  var fabric = global.fabric || (global.fabric = { }),\n      extend = fabric.util.object.extend;\n\n  if (fabric.Rect) {\n    fabric.warn('fabric.Rect is already defined');\n    return;\n  }\n\n  /**\n   * Rectangle class\n   * @class fabric.Rect\n   * @extends fabric.Object\n   * @return {fabric.Rect} thisArg\n   * @see {@link fabric.Rect#initialize} for constructor definition\n   */\n  fabric.Rect = fabric.util.createClass(fabric.Object, /** @lends fabric.Rect.prototype */ {\n\n    /**\n     * List of properties to consider when checking if state of an object is changed ({@link fabric.Object#hasStateChanged})\n     * as well as for history (undo/redo) purposes\n     * @type Array\n     */\n    stateProperties: fabric.Object.prototype.stateProperties.concat('rx', 'ry'),\n\n    /**\n     * Type of an object\n     * @type String\n     * @default\n     */\n    type: 'rect',\n\n    /**\n     * Horizontal border radius\n     * @type Number\n     * @default\n     */\n    rx:   0,\n\n    /**\n     * Vertical border radius\n     * @type Number\n     * @default\n     */\n    ry:   0,\n\n    cacheProperties: fabric.Object.prototype.cacheProperties.concat('rx', 'ry'),\n\n    /**\n     * Constructor\n     * @param {Object} [options] Options object\n     * @return {Object} thisArg\n     */\n    initialize: function(options) {\n      this.callSuper('initialize', options);\n      this._initRxRy();\n    },\n\n    /**\n     * Initializes rx/ry attributes\n     * @private\n     */\n    _initRxRy: function() {\n      if (this.rx && !this.ry) {\n        this.ry = this.rx;\n      }\n      else if (this.ry && !this.rx) {\n        this.rx = this.ry;\n      }\n    },\n\n    /**\n     * @private\n     * @param {CanvasRenderingContext2D} ctx Context to render on\n     */\n    _render: function(ctx) {\n\n      // 1x1 case (used in spray brush) optimization was removed because\n      // with caching and higher zoom level this makes more damage than help\n\n      var rx = this.rx ? Math.min(this.rx, this.width / 2) : 0,\n          ry = this.ry ? Math.min(this.ry, this.height / 2) : 0,\n          w = this.width,\n          h = this.height,\n          x = -this.width / 2,\n          y = -this.height / 2,\n          isRounded = rx !== 0 || ry !== 0,\n          /* \"magic number\" for bezier approximations of arcs (http://itc.ktu.lt/itc354/Riskus354.pdf) */\n          k = 1 - 0.5522847498;\n      ctx.beginPath();\n\n      ctx.moveTo(x + rx, y);\n\n      ctx.lineTo(x + w - rx, y);\n      isRounded && ctx.bezierCurveTo(x + w - k * rx, y, x + w, y + k * ry, x + w, y + ry);\n\n      ctx.lineTo(x + w, y + h - ry);\n      isRounded && ctx.bezierCurveTo(x + w, y + h - k * ry, x + w - k * rx, y + h, x + w - rx, y + h);\n\n      ctx.lineTo(x + rx, y + h);\n      isRounded && ctx.bezierCurveTo(x + k * rx, y + h, x, y + h - k * ry, x, y + h - ry);\n\n      ctx.lineTo(x, y + ry);\n      isRounded && ctx.bezierCurveTo(x, y + k * ry, x + k * rx, y, x + rx, y);\n\n      ctx.closePath();\n\n      this._renderPaintInOrder(ctx);\n    },\n\n    /**\n     * @private\n     * @param {CanvasRenderingContext2D} ctx Context to render on\n     */\n    _renderDashedStroke: function(ctx) {\n      var x = -this.width / 2,\n          y = -this.height / 2,\n          w = this.width,\n          h = this.height;\n\n      ctx.beginPath();\n      fabric.util.drawDashedLine(ctx, x, y, x + w, y, this.strokeDashArray);\n      fabric.util.drawDashedLine(ctx, x + w, y, x + w, y + h, this.strokeDashArray);\n      fabric.util.drawDashedLine(ctx, x + w, y + h, x, y + h, this.strokeDashArray);\n      fabric.util.drawDashedLine(ctx, x, y + h, x, y, this.strokeDashArray);\n      ctx.closePath();\n    },\n\n    /**\n     * Returns object representation of an instance\n     * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output\n     * @return {Object} object representation of an instance\n     */\n    toObject: function(propertiesToInclude) {\n      return this.callSuper('toObject', ['rx', 'ry'].concat(propertiesToInclude));\n    },\n\n    /* _TO_SVG_START_ */\n    /**\n     * Returns svg representation of an instance\n     * @return {Array} an array of strings with the specific svg representation\n     * of the instance\n     */\n    _toSVG: function() {\n      var x = -this.width / 2, y = -this.height / 2;\n      return [\n        '<rect ', 'COMMON_PARTS',\n        'x=\"', x, '\" y=\"', y,\n        '\" rx=\"', this.rx, '\" ry=\"', this.ry,\n        '\" width=\"', this.width, '\" height=\"', this.height,\n        '\" />\\n'\n      ];\n    },\n    /* _TO_SVG_END_ */\n  });\n\n  /* _FROM_SVG_START_ */\n  /**\n   * List of attribute names to account for when parsing SVG element (used by `fabric.Rect.fromElement`)\n   * @static\n   * @memberOf fabric.Rect\n   * @see: http://www.w3.org/TR/SVG/shapes.html#RectElement\n   */\n  fabric.Rect.ATTRIBUTE_NAMES = fabric.SHARED_ATTRIBUTES.concat('x y rx ry width height'.split(' '));\n\n  /**\n   * Returns {@link fabric.Rect} instance from an SVG element\n   * @static\n   * @memberOf fabric.Rect\n   * @param {SVGElement} element Element to parse\n   * @param {Function} callback callback function invoked after parsing\n   * @param {Object} [options] Options object\n   */\n  fabric.Rect.fromElement = function(element, callback, options) {\n    if (!element) {\n      return callback(null);\n    }\n    options = options || { };\n\n    var parsedAttributes = fabric.parseAttributes(element, fabric.Rect.ATTRIBUTE_NAMES);\n\n    parsedAttributes.left = parsedAttributes.left || 0;\n    parsedAttributes.top  = parsedAttributes.top  || 0;\n    var rect = new fabric.Rect(extend((options ? fabric.util.object.clone(options) : { }), parsedAttributes));\n    rect.visible = rect.visible && rect.width > 0 && rect.height > 0;\n    callback(rect);\n  };\n  /* _FROM_SVG_END_ */\n\n  /**\n   * Returns {@link fabric.Rect} instance from an object representation\n   * @static\n   * @memberOf fabric.Rect\n   * @param {Object} object Object to create an instance from\n   * @param {Function} [callback] Callback to invoke when an fabric.Rect instance is created\n   */\n  fabric.Rect.fromObject = function(object, callback) {\n    return fabric.Object._fromObject('Rect', object, callback);\n  };\n\n})(typeof exports !== 'undefined' ? exports : this);\n\n\n(function(global) {\n\n  'use strict';\n\n  var fabric = global.fabric || (global.fabric = { }),\n      extend = fabric.util.object.extend,\n      min = fabric.util.array.min,\n      max = fabric.util.array.max,\n      toFixed = fabric.util.toFixed;\n\n  if (fabric.Polyline) {\n    fabric.warn('fabric.Polyline is already defined');\n    return;\n  }\n\n  /**\n   * Polyline class\n   * @class fabric.Polyline\n   * @extends fabric.Object\n   * @see {@link fabric.Polyline#initialize} for constructor definition\n   */\n  fabric.Polyline = fabric.util.createClass(fabric.Object, /** @lends fabric.Polyline.prototype */ {\n\n    /**\n     * Type of an object\n     * @type String\n     * @default\n     */\n    type: 'polyline',\n\n    /**\n     * Points array\n     * @type Array\n     * @default\n     */\n    points: null,\n\n    cacheProperties: fabric.Object.prototype.cacheProperties.concat('points'),\n\n    /**\n     * Constructor\n     * @param {Array} points Array of points (where each point is an object with x and y)\n     * @param {Object} [options] Options object\n     * @return {fabric.Polyline} thisArg\n     * @example\n     * var poly = new fabric.Polyline([\n     *     { x: 10, y: 10 },\n     *     { x: 50, y: 30 },\n     *     { x: 40, y: 70 },\n     *     { x: 60, y: 50 },\n     *     { x: 100, y: 150 },\n     *     { x: 40, y: 100 }\n     *   ], {\n     *   stroke: 'red',\n     *   left: 100,\n     *   top: 100\n     * });\n     */\n    initialize: function(points, options) {\n      options = options || {};\n      this.points = points || [];\n      this.callSuper('initialize', options);\n      var calcDim = this._calcDimensions();\n      if (typeof options.left === 'undefined') {\n        this.left = calcDim.left;\n      }\n      if (typeof options.top === 'undefined') {\n        this.top = calcDim.top;\n      }\n      this.width = calcDim.width;\n      this.height = calcDim.height;\n      this.pathOffset = {\n        x: calcDim.left + this.width / 2,\n        y: calcDim.top + this.height / 2\n      };\n    },\n\n    /**\n     * Calculate the polygon min and max point from points array,\n     * returning an object with left, top, widht, height to measure the\n     * polygon size\n     * @return {Object} object.left X coordinate of the polygon leftmost point\n     * @return {Object} object.top Y coordinate of the polygon topmost point\n     * @return {Object} object.width distance between X coordinates of the polygon leftmost and rightmost point\n     * @return {Object} object.height distance between Y coordinates of the polygon topmost and bottommost point\n     * @private\n     */\n    _calcDimensions: function() {\n\n      var points = this.points,\n          minX = min(points, 'x') || 0,\n          minY = min(points, 'y') || 0,\n          maxX = max(points, 'x') || 0,\n          maxY = max(points, 'y') || 0,\n          width = (maxX - minX),\n          height = (maxY - minY);\n\n      return {\n        left: minX,\n        top: minY,\n        width: width,\n        height: height\n      };\n    },\n\n    /**\n     * Returns object representation of an instance\n     * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output\n     * @return {Object} Object representation of an instance\n     */\n    toObject: function(propertiesToInclude) {\n      return extend(this.callSuper('toObject', propertiesToInclude), {\n        points: this.points.concat()\n      });\n    },\n\n    /* _TO_SVG_START_ */\n    /**\n     * Returns svg representation of an instance\n     * @return {Array} an array of strings with the specific svg representation\n     * of the instance\n     */\n    _toSVG: function() {\n      var points = [], diffX = this.pathOffset.x, diffY = this.pathOffset.y,\n          NUM_FRACTION_DIGITS = fabric.Object.NUM_FRACTION_DIGITS;\n\n      for (var i = 0, len = this.points.length; i < len; i++) {\n        points.push(\n          toFixed(this.points[i].x - diffX, NUM_FRACTION_DIGITS), ',',\n          toFixed(this.points[i].y - diffY, NUM_FRACTION_DIGITS), ' '\n        );\n      }\n      return [\n        '<' + this.type + ' ', 'COMMON_PARTS',\n        'points=\"', points.join(''),\n        '\" />\\n'\n      ];\n    },\n    /* _TO_SVG_END_ */\n\n\n    /**\n     * @private\n     * @param {CanvasRenderingContext2D} ctx Context to render on\n     */\n    commonRender: function(ctx) {\n      var point, len = this.points.length,\n          x = this.pathOffset.x,\n          y = this.pathOffset.y;\n\n      if (!len || isNaN(this.points[len - 1].y)) {\n        // do not draw if no points or odd points\n        // NaN comes from parseFloat of a empty string in parser\n        return false;\n      }\n      ctx.beginPath();\n      ctx.moveTo(this.points[0].x - x, this.points[0].y - y);\n      for (var i = 0; i < len; i++) {\n        point = this.points[i];\n        ctx.lineTo(point.x - x, point.y - y);\n      }\n      return true;\n    },\n\n    /**\n     * @private\n     * @param {CanvasRenderingContext2D} ctx Context to render on\n     */\n    _render: function(ctx) {\n      if (!this.commonRender(ctx)) {\n        return;\n      }\n      this._renderPaintInOrder(ctx);\n    },\n\n    /**\n     * @private\n     * @param {CanvasRenderingContext2D} ctx Context to render on\n     */\n    _renderDashedStroke: function(ctx) {\n      var p1, p2;\n\n      ctx.beginPath();\n      for (var i = 0, len = this.points.length; i < len; i++) {\n        p1 = this.points[i];\n        p2 = this.points[i + 1] || p1;\n        fabric.util.drawDashedLine(ctx, p1.x, p1.y, p2.x, p2.y, this.strokeDashArray);\n      }\n    },\n\n    /**\n     * Returns complexity of an instance\n     * @return {Number} complexity of this instance\n     */\n    complexity: function() {\n      return this.get('points').length;\n    }\n  });\n\n  /* _FROM_SVG_START_ */\n  /**\n   * List of attribute names to account for when parsing SVG element (used by {@link fabric.Polyline.fromElement})\n   * @static\n   * @memberOf fabric.Polyline\n   * @see: http://www.w3.org/TR/SVG/shapes.html#PolylineElement\n   */\n  fabric.Polyline.ATTRIBUTE_NAMES = fabric.SHARED_ATTRIBUTES.concat();\n\n  /**\n   * Returns fabric.Polyline instance from an SVG element\n   * @static\n   * @memberOf fabric.Polyline\n   * @param {SVGElement} element Element to parser\n   * @param {Function} callback callback function invoked after parsing\n   * @param {Object} [options] Options object\n   */\n  fabric.Polyline.fromElement = function(element, callback, options) {\n    if (!element) {\n      return callback(null);\n    }\n    options || (options = { });\n\n    var points = fabric.parsePointsAttribute(element.getAttribute('points')),\n        parsedAttributes = fabric.parseAttributes(element, fabric.Polyline.ATTRIBUTE_NAMES);\n\n    callback(new fabric.Polyline(points, fabric.util.object.extend(parsedAttributes, options)));\n  };\n  /* _FROM_SVG_END_ */\n\n  /**\n   * Returns fabric.Polyline instance from an object representation\n   * @static\n   * @memberOf fabric.Polyline\n   * @param {Object} object Object to create an instance from\n   * @param {Function} [callback] Callback to invoke when an fabric.Path instance is created\n   */\n  fabric.Polyline.fromObject = function(object, callback) {\n    return fabric.Object._fromObject('Polyline', object, callback, 'points');\n  };\n\n})(typeof exports !== 'undefined' ? exports : this);\n\n\n(function(global) {\n\n  'use strict';\n\n  var fabric = global.fabric || (global.fabric = { }),\n      extend = fabric.util.object.extend;\n\n  if (fabric.Polygon) {\n    fabric.warn('fabric.Polygon is already defined');\n    return;\n  }\n\n  /**\n   * Polygon class\n   * @class fabric.Polygon\n   * @extends fabric.Polyline\n   * @see {@link fabric.Polygon#initialize} for constructor definition\n   */\n  fabric.Polygon = fabric.util.createClass(fabric.Polyline, /** @lends fabric.Polygon.prototype */ {\n\n    /**\n     * Type of an object\n     * @type String\n     * @default\n     */\n    type: 'polygon',\n\n    /**\n     * @private\n     * @param {CanvasRenderingContext2D} ctx Context to render on\n     */\n    _render: function(ctx) {\n      if (!this.commonRender(ctx)) {\n        return;\n      }\n      ctx.closePath();\n      this._renderPaintInOrder(ctx);\n    },\n\n    /**\n     * @private\n     * @param {CanvasRenderingContext2D} ctx Context to render on\n     */\n    _renderDashedStroke: function(ctx) {\n      this.callSuper('_renderDashedStroke', ctx);\n      ctx.closePath();\n    },\n  });\n\n  /* _FROM_SVG_START_ */\n  /**\n   * List of attribute names to account for when parsing SVG element (used by `fabric.Polygon.fromElement`)\n   * @static\n   * @memberOf fabric.Polygon\n   * @see: http://www.w3.org/TR/SVG/shapes.html#PolygonElement\n   */\n  fabric.Polygon.ATTRIBUTE_NAMES = fabric.SHARED_ATTRIBUTES.concat();\n\n  /**\n   * Returns {@link fabric.Polygon} instance from an SVG element\n   * @static\n   * @memberOf fabric.Polygon\n   * @param {SVGElement} element Element to parse\n   * @param {Function} callback callback function invoked after parsing\n   * @param {Object} [options] Options object\n   */\n  fabric.Polygon.fromElement = function(element, callback, options) {\n    if (!element) {\n      return callback(null);\n    }\n\n    options || (options = { });\n\n    var points = fabric.parsePointsAttribute(element.getAttribute('points')),\n        parsedAttributes = fabric.parseAttributes(element, fabric.Polygon.ATTRIBUTE_NAMES);\n\n    callback(new fabric.Polygon(points, extend(parsedAttributes, options)));\n  };\n  /* _FROM_SVG_END_ */\n\n  /**\n   * Returns fabric.Polygon instance from an object representation\n   * @static\n   * @memberOf fabric.Polygon\n   * @param {Object} object Object to create an instance from\n   * @param {Function} [callback] Callback to invoke when an fabric.Path instance is created\n   */\n  fabric.Polygon.fromObject = function(object, callback) {\n    return fabric.Object._fromObject('Polygon', object, callback, 'points');\n  };\n\n})(typeof exports !== 'undefined' ? exports : this);\n\n\n(function(global) {\n\n  'use strict';\n\n  var fabric = global.fabric || (global.fabric = { }),\n      min = fabric.util.array.min,\n      max = fabric.util.array.max,\n      extend = fabric.util.object.extend,\n      _toString = Object.prototype.toString,\n      drawArc = fabric.util.drawArc,\n      toFixed = fabric.util.toFixed,\n      commandLengths = {\n        m: 2,\n        l: 2,\n        h: 1,\n        v: 1,\n        c: 6,\n        s: 4,\n        q: 4,\n        t: 2,\n        a: 7\n      },\n      repeatedCommands = {\n        m: 'l',\n        M: 'L'\n      };\n\n  if (fabric.Path) {\n    fabric.warn('fabric.Path is already defined');\n    return;\n  }\n\n  /**\n   * Path class\n   * @class fabric.Path\n   * @extends fabric.Object\n   * @tutorial {@link http://fabricjs.com/fabric-intro-part-1#path_and_pathgroup}\n   * @see {@link fabric.Path#initialize} for constructor definition\n   */\n  fabric.Path = fabric.util.createClass(fabric.Object, /** @lends fabric.Path.prototype */ {\n\n    /**\n     * Type of an object\n     * @type String\n     * @default\n     */\n    type: 'path',\n\n    /**\n     * Array of path points\n     * @type Array\n     * @default\n     */\n    path: null,\n\n    cacheProperties: fabric.Object.prototype.cacheProperties.concat('path', 'fillRule'),\n\n    stateProperties: fabric.Object.prototype.stateProperties.concat('path'),\n\n    /**\n     * Constructor\n     * @param {Array|String} path Path data (sequence of coordinates and corresponding \"command\" tokens)\n     * @param {Object} [options] Options object\n     * @return {fabric.Path} thisArg\n     */\n    initialize: function(path, options) {\n      options = options || { };\n      this.callSuper('initialize', options);\n\n      if (!path) {\n        path = [];\n      }\n\n      var fromArray = _toString.call(path) === '[object Array]';\n\n      this.path = fromArray\n        ? path\n        // one of commands (m,M,l,L,q,Q,c,C,etc.) followed by non-command characters (i.e. command values)\n        : path.match && path.match(/[mzlhvcsqta][^mzlhvcsqta]*/gi);\n\n      if (!this.path) {\n        return;\n      }\n\n      if (!fromArray) {\n        this.path = this._parsePath();\n      }\n\n      this._setPositionDimensions(options);\n    },\n\n    /**\n     * @private\n     * @param {Object} options Options object\n     */\n    _setPositionDimensions: function(options) {\n      var calcDim = this._parseDimensions();\n\n      this.width = calcDim.width;\n      this.height = calcDim.height;\n\n      if (typeof options.left === 'undefined') {\n        this.left = calcDim.left;\n      }\n\n      if (typeof options.top === 'undefined') {\n        this.top = calcDim.top;\n      }\n\n      this.pathOffset = this.pathOffset || {\n        x: calcDim.left + this.width / 2,\n        y: calcDim.top + this.height / 2\n      };\n    },\n\n    /**\n     * @private\n     * @param {CanvasRenderingContext2D} ctx context to render path on\n     */\n    _renderPathCommands: function(ctx) {\n      var current, // current instruction\n          previous = null,\n          subpathStartX = 0,\n          subpathStartY = 0,\n          x = 0, // current x\n          y = 0, // current y\n          controlX = 0, // current control point x\n          controlY = 0, // current control point y\n          tempX,\n          tempY,\n          l = -this.pathOffset.x,\n          t = -this.pathOffset.y;\n\n      ctx.beginPath();\n\n      for (var i = 0, len = this.path.length; i < len; ++i) {\n\n        current = this.path[i];\n\n        switch (current[0]) { // first letter\n\n          case 'l': // lineto, relative\n            x += current[1];\n            y += current[2];\n            ctx.lineTo(x + l, y + t);\n            break;\n\n          case 'L': // lineto, absolute\n            x = current[1];\n            y = current[2];\n            ctx.lineTo(x + l, y + t);\n            break;\n\n          case 'h': // horizontal lineto, relative\n            x += current[1];\n            ctx.lineTo(x + l, y + t);\n            break;\n\n          case 'H': // horizontal lineto, absolute\n            x = current[1];\n            ctx.lineTo(x + l, y + t);\n            break;\n\n          case 'v': // vertical lineto, relative\n            y += current[1];\n            ctx.lineTo(x + l, y + t);\n            break;\n\n          case 'V': // verical lineto, absolute\n            y = current[1];\n            ctx.lineTo(x + l, y + t);\n            break;\n\n          case 'm': // moveTo, relative\n            x += current[1];\n            y += current[2];\n            subpathStartX = x;\n            subpathStartY = y;\n            ctx.moveTo(x + l, y + t);\n            break;\n\n          case 'M': // moveTo, absolute\n            x = current[1];\n            y = current[2];\n            subpathStartX = x;\n            subpathStartY = y;\n            ctx.moveTo(x + l, y + t);\n            break;\n\n          case 'c': // bezierCurveTo, relative\n            tempX = x + current[5];\n            tempY = y + current[6];\n            controlX = x + current[3];\n            controlY = y + current[4];\n            ctx.bezierCurveTo(\n              x + current[1] + l, // x1\n              y + current[2] + t, // y1\n              controlX + l, // x2\n              controlY + t, // y2\n              tempX + l,\n              tempY + t\n            );\n            x = tempX;\n            y = tempY;\n            break;\n\n          case 'C': // bezierCurveTo, absolute\n            x = current[5];\n            y = current[6];\n            controlX = current[3];\n            controlY = current[4];\n            ctx.bezierCurveTo(\n              current[1] + l,\n              current[2] + t,\n              controlX + l,\n              controlY + t,\n              x + l,\n              y + t\n            );\n            break;\n\n          case 's': // shorthand cubic bezierCurveTo, relative\n\n            // transform to absolute x,y\n            tempX = x + current[3];\n            tempY = y + current[4];\n\n            if (previous[0].match(/[CcSs]/) === null) {\n              // If there is no previous command or if the previous command was not a C, c, S, or s,\n              // the control point is coincident with the current point\n              controlX = x;\n              controlY = y;\n            }\n            else {\n              // calculate reflection of previous control points\n              controlX = 2 * x - controlX;\n              controlY = 2 * y - controlY;\n            }\n\n            ctx.bezierCurveTo(\n              controlX + l,\n              controlY + t,\n              x + current[1] + l,\n              y + current[2] + t,\n              tempX + l,\n              tempY + t\n            );\n            // set control point to 2nd one of this command\n            // \"... the first control point is assumed to be\n            // the reflection of the second control point on\n            // the previous command relative to the current point.\"\n            controlX = x + current[1];\n            controlY = y + current[2];\n\n            x = tempX;\n            y = tempY;\n            break;\n\n          case 'S': // shorthand cubic bezierCurveTo, absolute\n            tempX = current[3];\n            tempY = current[4];\n            if (previous[0].match(/[CcSs]/) === null) {\n              // If there is no previous command or if the previous command was not a C, c, S, or s,\n              // the control point is coincident with the current point\n              controlX = x;\n              controlY = y;\n            }\n            else {\n              // calculate reflection of previous control points\n              controlX = 2 * x - controlX;\n              controlY = 2 * y - controlY;\n            }\n            ctx.bezierCurveTo(\n              controlX + l,\n              controlY + t,\n              current[1] + l,\n              current[2] + t,\n              tempX + l,\n              tempY + t\n            );\n            x = tempX;\n            y = tempY;\n\n            // set control point to 2nd one of this command\n            // \"... the first control point is assumed to be\n            // the reflection of the second control point on\n            // the previous command relative to the current point.\"\n            controlX = current[1];\n            controlY = current[2];\n\n            break;\n\n          case 'q': // quadraticCurveTo, relative\n            // transform to absolute x,y\n            tempX = x + current[3];\n            tempY = y + current[4];\n\n            controlX = x + current[1];\n            controlY = y + current[2];\n\n            ctx.quadraticCurveTo(\n              controlX + l,\n              controlY + t,\n              tempX + l,\n              tempY + t\n            );\n            x = tempX;\n            y = tempY;\n            break;\n\n          case 'Q': // quadraticCurveTo, absolute\n            tempX = current[3];\n            tempY = current[4];\n\n            ctx.quadraticCurveTo(\n              current[1] + l,\n              current[2] + t,\n              tempX + l,\n              tempY + t\n            );\n            x = tempX;\n            y = tempY;\n            controlX = current[1];\n            controlY = current[2];\n            break;\n\n          case 't': // shorthand quadraticCurveTo, relative\n\n            // transform to absolute x,y\n            tempX = x + current[1];\n            tempY = y + current[2];\n\n            if (previous[0].match(/[QqTt]/) === null) {\n              // If there is no previous command or if the previous command was not a Q, q, T or t,\n              // assume the control point is coincident with the current point\n              controlX = x;\n              controlY = y;\n            }\n            else {\n              // calculate reflection of previous control point\n              controlX = 2 * x - controlX;\n              controlY = 2 * y - controlY;\n            }\n\n            ctx.quadraticCurveTo(\n              controlX + l,\n              controlY + t,\n              tempX + l,\n              tempY + t\n            );\n            x = tempX;\n            y = tempY;\n\n            break;\n\n          case 'T':\n            tempX = current[1];\n            tempY = current[2];\n\n            if (previous[0].match(/[QqTt]/) === null) {\n              // If there is no previous command or if the previous command was not a Q, q, T or t,\n              // assume the control point is coincident with the current point\n              controlX = x;\n              controlY = y;\n            }\n            else {\n              // calculate reflection of previous control point\n              controlX = 2 * x - controlX;\n              controlY = 2 * y - controlY;\n            }\n            ctx.quadraticCurveTo(\n              controlX + l,\n              controlY + t,\n              tempX + l,\n              tempY + t\n            );\n            x = tempX;\n            y = tempY;\n            break;\n\n          case 'a':\n            // TODO: optimize this\n            drawArc(ctx, x + l, y + t, [\n              current[1],\n              current[2],\n              current[3],\n              current[4],\n              current[5],\n              current[6] + x + l,\n              current[7] + y + t\n            ]);\n            x += current[6];\n            y += current[7];\n            break;\n\n          case 'A':\n            // TODO: optimize this\n            drawArc(ctx, x + l, y + t, [\n              current[1],\n              current[2],\n              current[3],\n              current[4],\n              current[5],\n              current[6] + l,\n              current[7] + t\n            ]);\n            x = current[6];\n            y = current[7];\n            break;\n\n          case 'z':\n          case 'Z':\n            x = subpathStartX;\n            y = subpathStartY;\n            ctx.closePath();\n            break;\n        }\n        previous = current;\n      }\n    },\n\n    /**\n     * @private\n     * @param {CanvasRenderingContext2D} ctx context to render path on\n     */\n    _render: function(ctx) {\n      this._renderPathCommands(ctx);\n      this._renderPaintInOrder(ctx);\n    },\n\n    /**\n     * Returns string representation of an instance\n     * @return {String} string representation of an instance\n     */\n    toString: function() {\n      return '#<fabric.Path (' + this.complexity() +\n        '): { \"top\": ' + this.top + ', \"left\": ' + this.left + ' }>';\n    },\n\n    /**\n     * Returns object representation of an instance\n     * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output\n     * @return {Object} object representation of an instance\n     */\n    toObject: function(propertiesToInclude) {\n      var o = extend(this.callSuper('toObject', propertiesToInclude), {\n        path: this.path.map(function(item) { return item.slice(); }),\n        top: this.top,\n        left: this.left,\n      });\n      return o;\n    },\n\n    /**\n     * Returns dataless object representation of an instance\n     * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output\n     * @return {Object} object representation of an instance\n     */\n    toDatalessObject: function(propertiesToInclude) {\n      var o = this.toObject(['sourcePath'].concat(propertiesToInclude));\n      if (o.sourcePath) {\n        delete o.path;\n      }\n      return o;\n    },\n\n    /* _TO_SVG_START_ */\n    /**\n     * Returns svg representation of an instance\n     * @return {Array} an array of strings with the specific svg representation\n     * of the instance\n     */\n    _toSVG: function() {\n      var specificTransform = this._getOffsetTransform(),\n          path = this.path.map(function(path) {\n            return path.join(' ');\n          }).join(' ');\n      return [\n        '<path ', 'COMMON_PARTS',\n        'd=\"', path,\n        '\" stroke-linecap=\"round\" ',\n        'transform=\"' + specificTransform + '\" ',\n        '/>\\n'\n      ];\n    },\n\n    _getOffsetTransform: function() {\n      var digits = fabric.Object.NUM_FRACTION_DIGITS;\n      return ' translate(' + toFixed(-this.pathOffset.x, digits) + ', ' +\n          toFixed(-this.pathOffset.y, digits) + ')';\n    },\n\n    /**\n     * Returns svg clipPath representation of an instance\n     * @param {Function} [reviver] Method for further parsing of svg representation.\n     * @return {String} svg representation of an instance\n     */\n    toClipPathSVG: function(reviver) {\n      var additionalTransform = this._getOffsetTransform();\n      return '\\t' + this._createBaseClipPathSVGMarkup(\n        this._toSVG(), { reviver: reviver, additionalTransform: additionalTransform }\n      );\n    },\n    /* _TO_SVG_END_ */\n\n    /**\n     * Returns number representation of an instance complexity\n     * @return {Number} complexity of this instance\n     */\n    complexity: function() {\n      return this.path.length;\n    },\n\n    /**\n     * @private\n     */\n    _parsePath: function() {\n      var result = [],\n          coords = [],\n          currentPath,\n          parsed,\n          re = /([-+]?((\\d+\\.\\d+)|((\\d+)|(\\.\\d+)))(?:e[-+]?\\d+)?)/ig,\n          match,\n          coordsStr;\n\n      for (var i = 0, coordsParsed, len = this.path.length; i < len; i++) {\n        currentPath = this.path[i];\n\n        coordsStr = currentPath.slice(1).trim();\n        coords.length = 0;\n\n        while ((match = re.exec(coordsStr))) {\n          coords.push(match[0]);\n        }\n\n        coordsParsed = [currentPath.charAt(0)];\n\n        for (var j = 0, jlen = coords.length; j < jlen; j++) {\n          parsed = parseFloat(coords[j]);\n          if (!isNaN(parsed)) {\n            coordsParsed.push(parsed);\n          }\n        }\n\n        var command = coordsParsed[0],\n            commandLength = commandLengths[command.toLowerCase()],\n            repeatedCommand = repeatedCommands[command] || command;\n\n        if (coordsParsed.length - 1 > commandLength) {\n          for (var k = 1, klen = coordsParsed.length; k < klen; k += commandLength) {\n            result.push([command].concat(coordsParsed.slice(k, k + commandLength)));\n            command = repeatedCommand;\n          }\n        }\n        else {\n          result.push(coordsParsed);\n        }\n      }\n\n      return result;\n    },\n\n    /**\n     * @private\n     */\n    _parseDimensions: function() {\n\n      var aX = [],\n          aY = [],\n          current, // current instruction\n          previous = null,\n          subpathStartX = 0,\n          subpathStartY = 0,\n          x = 0, // current x\n          y = 0, // current y\n          controlX = 0, // current control point x\n          controlY = 0, // current control point y\n          tempX,\n          tempY,\n          bounds;\n\n      for (var i = 0, len = this.path.length; i < len; ++i) {\n\n        current = this.path[i];\n\n        switch (current[0]) { // first letter\n\n          case 'l': // lineto, relative\n            x += current[1];\n            y += current[2];\n            bounds = [];\n            break;\n\n          case 'L': // lineto, absolute\n            x = current[1];\n            y = current[2];\n            bounds = [];\n            break;\n\n          case 'h': // horizontal lineto, relative\n            x += current[1];\n            bounds = [];\n            break;\n\n          case 'H': // horizontal lineto, absolute\n            x = current[1];\n            bounds = [];\n            break;\n\n          case 'v': // vertical lineto, relative\n            y += current[1];\n            bounds = [];\n            break;\n\n          case 'V': // verical lineto, absolute\n            y = current[1];\n            bounds = [];\n            break;\n\n          case 'm': // moveTo, relative\n            x += current[1];\n            y += current[2];\n            subpathStartX = x;\n            subpathStartY = y;\n            bounds = [];\n            break;\n\n          case 'M': // moveTo, absolute\n            x = current[1];\n            y = current[2];\n            subpathStartX = x;\n            subpathStartY = y;\n            bounds = [];\n            break;\n\n          case 'c': // bezierCurveTo, relative\n            tempX = x + current[5];\n            tempY = y + current[6];\n            controlX = x + current[3];\n            controlY = y + current[4];\n            bounds = fabric.util.getBoundsOfCurve(x, y,\n              x + current[1], // x1\n              y + current[2], // y1\n              controlX, // x2\n              controlY, // y2\n              tempX,\n              tempY\n            );\n            x = tempX;\n            y = tempY;\n            break;\n\n          case 'C': // bezierCurveTo, absolute\n            controlX = current[3];\n            controlY = current[4];\n            bounds = fabric.util.getBoundsOfCurve(x, y,\n              current[1],\n              current[2],\n              controlX,\n              controlY,\n              current[5],\n              current[6]\n            );\n            x = current[5];\n            y = current[6];\n            break;\n\n          case 's': // shorthand cubic bezierCurveTo, relative\n\n            // transform to absolute x,y\n            tempX = x + current[3];\n            tempY = y + current[4];\n\n            if (previous[0].match(/[CcSs]/) === null) {\n              // If there is no previous command or if the previous command was not a C, c, S, or s,\n              // the control point is coincident with the current point\n              controlX = x;\n              controlY = y;\n            }\n            else {\n              // calculate reflection of previous control points\n              controlX = 2 * x - controlX;\n              controlY = 2 * y - controlY;\n            }\n\n            bounds = fabric.util.getBoundsOfCurve(x, y,\n              controlX,\n              controlY,\n              x + current[1],\n              y + current[2],\n              tempX,\n              tempY\n            );\n            // set control point to 2nd one of this command\n            // \"... the first control point is assumed to be\n            // the reflection of the second control point on\n            // the previous command relative to the current point.\"\n            controlX = x + current[1];\n            controlY = y + current[2];\n            x = tempX;\n            y = tempY;\n            break;\n\n          case 'S': // shorthand cubic bezierCurveTo, absolute\n            tempX = current[3];\n            tempY = current[4];\n            if (previous[0].match(/[CcSs]/) === null) {\n              // If there is no previous command or if the previous command was not a C, c, S, or s,\n              // the control point is coincident with the current point\n              controlX = x;\n              controlY = y;\n            }\n            else {\n              // calculate reflection of previous control points\n              controlX = 2 * x - controlX;\n              controlY = 2 * y - controlY;\n            }\n            bounds = fabric.util.getBoundsOfCurve(x, y,\n              controlX,\n              controlY,\n              current[1],\n              current[2],\n              tempX,\n              tempY\n            );\n            x = tempX;\n            y = tempY;\n            // set control point to 2nd one of this command\n            // \"... the first control point is assumed to be\n            // the reflection of the second control point on\n            // the previous command relative to the current point.\"\n            controlX = current[1];\n            controlY = current[2];\n            break;\n\n          case 'q': // quadraticCurveTo, relative\n            // transform to absolute x,y\n            tempX = x + current[3];\n            tempY = y + current[4];\n            controlX = x + current[1];\n            controlY = y + current[2];\n            bounds = fabric.util.getBoundsOfCurve(x, y,\n              controlX,\n              controlY,\n              controlX,\n              controlY,\n              tempX,\n              tempY\n            );\n            x = tempX;\n            y = tempY;\n            break;\n\n          case 'Q': // quadraticCurveTo, absolute\n            controlX = current[1];\n            controlY = current[2];\n            bounds = fabric.util.getBoundsOfCurve(x, y,\n              controlX,\n              controlY,\n              controlX,\n              controlY,\n              current[3],\n              current[4]\n            );\n            x = current[3];\n            y = current[4];\n            break;\n\n          case 't': // shorthand quadraticCurveTo, relative\n            // transform to absolute x,y\n            tempX = x + current[1];\n            tempY = y + current[2];\n            if (previous[0].match(/[QqTt]/) === null) {\n              // If there is no previous command or if the previous command was not a Q, q, T or t,\n              // assume the control point is coincident with the current point\n              controlX = x;\n              controlY = y;\n            }\n            else {\n              // calculate reflection of previous control point\n              controlX = 2 * x - controlX;\n              controlY = 2 * y - controlY;\n            }\n\n            bounds = fabric.util.getBoundsOfCurve(x, y,\n              controlX,\n              controlY,\n              controlX,\n              controlY,\n              tempX,\n              tempY\n            );\n            x = tempX;\n            y = tempY;\n\n            break;\n\n          case 'T':\n            tempX = current[1];\n            tempY = current[2];\n\n            if (previous[0].match(/[QqTt]/) === null) {\n              // If there is no previous command or if the previous command was not a Q, q, T or t,\n              // assume the control point is coincident with the current point\n              controlX = x;\n              controlY = y;\n            }\n            else {\n              // calculate reflection of previous control point\n              controlX = 2 * x - controlX;\n              controlY = 2 * y - controlY;\n            }\n            bounds = fabric.util.getBoundsOfCurve(x, y,\n              controlX,\n              controlY,\n              controlX,\n              controlY,\n              tempX,\n              tempY\n            );\n            x = tempX;\n            y = tempY;\n            break;\n\n          case 'a':\n            // TODO: optimize this\n            bounds = fabric.util.getBoundsOfArc(x, y,\n              current[1],\n              current[2],\n              current[3],\n              current[4],\n              current[5],\n              current[6] + x,\n              current[7] + y\n            );\n            x += current[6];\n            y += current[7];\n            break;\n\n          case 'A':\n            // TODO: optimize this\n            bounds = fabric.util.getBoundsOfArc(x, y,\n              current[1],\n              current[2],\n              current[3],\n              current[4],\n              current[5],\n              current[6],\n              current[7]\n            );\n            x = current[6];\n            y = current[7];\n            break;\n\n          case 'z':\n          case 'Z':\n            x = subpathStartX;\n            y = subpathStartY;\n            break;\n        }\n        previous = current;\n        bounds.forEach(function (point) {\n          aX.push(point.x);\n          aY.push(point.y);\n        });\n        aX.push(x);\n        aY.push(y);\n      }\n\n      var minX = min(aX) || 0,\n          minY = min(aY) || 0,\n          maxX = max(aX) || 0,\n          maxY = max(aY) || 0,\n          deltaX = maxX - minX,\n          deltaY = maxY - minY,\n\n          o = {\n            left: minX,\n            top: minY,\n            width: deltaX,\n            height: deltaY\n          };\n\n      return o;\n    }\n  });\n\n  /**\n   * Creates an instance of fabric.Path from an object\n   * @static\n   * @memberOf fabric.Path\n   * @param {Object} object\n   * @param {Function} [callback] Callback to invoke when an fabric.Path instance is created\n   */\n  fabric.Path.fromObject = function(object, callback) {\n    if (typeof object.sourcePath === 'string') {\n      var pathUrl = object.sourcePath;\n      fabric.loadSVGFromURL(pathUrl, function (elements) {\n        var path = elements[0];\n        path.setOptions(object);\n        callback && callback(path);\n      });\n    }\n    else {\n      fabric.Object._fromObject('Path', object, callback, 'path');\n    }\n  };\n\n  /* _FROM_SVG_START_ */\n  /**\n   * List of attribute names to account for when parsing SVG element (used by `fabric.Path.fromElement`)\n   * @static\n   * @memberOf fabric.Path\n   * @see http://www.w3.org/TR/SVG/paths.html#PathElement\n   */\n  fabric.Path.ATTRIBUTE_NAMES = fabric.SHARED_ATTRIBUTES.concat(['d']);\n\n  /**\n   * Creates an instance of fabric.Path from an SVG <path> element\n   * @static\n   * @memberOf fabric.Path\n   * @param {SVGElement} element to parse\n   * @param {Function} callback Callback to invoke when an fabric.Path instance is created\n   * @param {Object} [options] Options object\n   * @param {Function} [callback] Options callback invoked after parsing is finished\n   */\n  fabric.Path.fromElement = function(element, callback, options) {\n    var parsedAttributes = fabric.parseAttributes(element, fabric.Path.ATTRIBUTE_NAMES);\n    callback(new fabric.Path(parsedAttributes.d, extend(parsedAttributes, options)));\n  };\n  /* _FROM_SVG_END_ */\n\n})(typeof exports !== 'undefined' ? exports : this);\n\n\n(function(global) {\n\n  'use strict';\n\n  var fabric = global.fabric || (global.fabric = { }),\n      min = fabric.util.array.min,\n      max = fabric.util.array.max;\n\n  if (fabric.Group) {\n    return;\n  }\n\n  /**\n   * Group class\n   * @class fabric.Group\n   * @extends fabric.Object\n   * @mixes fabric.Collection\n   * @tutorial {@link http://fabricjs.com/fabric-intro-part-3#groups}\n   * @see {@link fabric.Group#initialize} for constructor definition\n   */\n  fabric.Group = fabric.util.createClass(fabric.Object, fabric.Collection, /** @lends fabric.Group.prototype */ {\n\n    /**\n     * Type of an object\n     * @type String\n     * @default\n     */\n    type: 'group',\n\n    /**\n     * Width of stroke\n     * @type Number\n     * @default\n     */\n    strokeWidth: 0,\n\n    /**\n     * Indicates if click events should also check for subtargets\n     * @type Boolean\n     * @default\n     */\n    subTargetCheck: false,\n\n    /**\n     * Groups are container, do not render anything on theyr own, ence no cache properties\n     * @type Array\n     * @default\n     */\n    cacheProperties: [],\n\n    /**\n     * setOnGroup is a method used for TextBox that is no more used since 2.0.0 The behavior is still\n     * available setting this boolean to true.\n     * @type Boolean\n     * @since 2.0.0\n     * @default\n     */\n    useSetOnGroup: false,\n\n    /**\n     * Constructor\n     * @param {Object} objects Group objects\n     * @param {Object} [options] Options object\n     * @param {Boolean} [isAlreadyGrouped] if true, objects have been grouped already.\n     * @return {Object} thisArg\n     */\n    initialize: function(objects, options, isAlreadyGrouped) {\n      options = options || {};\n      this._objects = [];\n      // if objects enclosed in a group have been grouped already,\n      // we cannot change properties of objects.\n      // Thus we need to set options to group without objects,\n      isAlreadyGrouped && this.callSuper('initialize', options);\n      this._objects = objects || [];\n      for (var i = this._objects.length; i--; ) {\n        this._objects[i].group = this;\n      }\n\n      if (!isAlreadyGrouped) {\n        var center = options && options.centerPoint;\n        // we want to set origins before calculating the bounding box.\n        // so that the topleft can be set with that in mind.\n        // if specific top and left are passed, are overwritten later\n        // with the callSuper('initialize', options)\n        if (options.originX !== undefined) {\n          this.originX = options.originX;\n        }\n        if (options.originY !== undefined) {\n          this.originY = options.originY;\n        }\n        // if coming from svg i do not want to calc bounds.\n        // i assume width and height are passed along options\n        center || this._calcBounds();\n        this._updateObjectsCoords(center);\n        delete options.centerPoint;\n        this.callSuper('initialize', options);\n      }\n      else {\n        this._updateObjectsACoords();\n      }\n\n      this.setCoords();\n    },\n\n    /**\n     * @private\n     * @param {Boolean} [skipCoordsChange] if true, coordinates of objects enclosed in a group do not change\n     */\n    _updateObjectsACoords: function() {\n      var ignoreZoom = true, skipAbsolute = true;\n      for (var i = this._objects.length; i--; ){\n        this._objects[i].setCoords(ignoreZoom, skipAbsolute);\n      }\n    },\n\n    /**\n     * @private\n     * @param {Boolean} [skipCoordsChange] if true, coordinates of objects enclosed in a group do not change\n     */\n    _updateObjectsCoords: function(center) {\n      var center = center || this.getCenterPoint();\n      for (var i = this._objects.length; i--; ){\n        this._updateObjectCoords(this._objects[i], center);\n      }\n    },\n\n    /**\n     * @private\n     * @param {Object} object\n     * @param {fabric.Point} center, current center of group.\n     */\n    _updateObjectCoords: function(object, center) {\n      var objectLeft = object.left,\n          objectTop = object.top,\n          ignoreZoom = true, skipAbsolute = true;\n\n      object.set({\n        left: objectLeft - center.x,\n        top: objectTop - center.y\n      });\n      object.group = this;\n      object.setCoords(ignoreZoom, skipAbsolute);\n    },\n\n    /**\n     * Returns string represenation of a group\n     * @return {String}\n     */\n    toString: function() {\n      return '#<fabric.Group: (' + this.complexity() + ')>';\n    },\n\n    /**\n     * Adds an object to a group; Then recalculates group's dimension, position.\n     * @param {Object} object\n     * @return {fabric.Group} thisArg\n     * @chainable\n     */\n    addWithUpdate: function(object) {\n      this._restoreObjectsState();\n      fabric.util.resetObjectTransform(this);\n      if (object) {\n        this._objects.push(object);\n        object.group = this;\n        object._set('canvas', this.canvas);\n      }\n      this._calcBounds();\n      this._updateObjectsCoords();\n      this.setCoords();\n      this.dirty = true;\n      return this;\n    },\n\n    /**\n     * Removes an object from a group; Then recalculates group's dimension, position.\n     * @param {Object} object\n     * @return {fabric.Group} thisArg\n     * @chainable\n     */\n    removeWithUpdate: function(object) {\n      this._restoreObjectsState();\n      fabric.util.resetObjectTransform(this);\n\n      this.remove(object);\n      this._calcBounds();\n      this._updateObjectsCoords();\n      this.setCoords();\n      this.dirty = true;\n      return this;\n    },\n\n    /**\n     * @private\n     */\n    _onObjectAdded: function(object) {\n      this.dirty = true;\n      object.group = this;\n      object._set('canvas', this.canvas);\n    },\n\n    /**\n     * @private\n     */\n    _onObjectRemoved: function(object) {\n      this.dirty = true;\n      delete object.group;\n    },\n\n    /**\n     * @private\n     */\n    _set: function(key, value) {\n      var i = this._objects.length;\n      if (this.useSetOnGroup) {\n        while (i--) {\n          this._objects[i].setOnGroup(key, value);\n        }\n      }\n      if (key === 'canvas') {\n        while (i--) {\n          this._objects[i]._set(key, value);\n        }\n      }\n      fabric.Object.prototype._set.call(this, key, value);\n    },\n\n    /**\n     * Returns object representation of an instance\n     * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output\n     * @return {Object} object representation of an instance\n     */\n    toObject: function(propertiesToInclude) {\n      var _includeDefaultValues = this.includeDefaultValues;\n      var objsToObject = this._objects.map(function(obj) {\n        var originalDefaults = obj.includeDefaultValues;\n        obj.includeDefaultValues = _includeDefaultValues;\n        var _obj = obj.toObject(propertiesToInclude);\n        obj.includeDefaultValues = originalDefaults;\n        return _obj;\n      });\n      var obj = fabric.Object.prototype.toObject.call(this, propertiesToInclude);\n      obj.objects = objsToObject;\n      return obj;\n    },\n\n    /**\n     * Returns object representation of an instance, in dataless mode.\n     * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output\n     * @return {Object} object representation of an instance\n     */\n    toDatalessObject: function(propertiesToInclude) {\n      var objsToObject, sourcePath = this.sourcePath;\n      if (sourcePath) {\n        objsToObject = sourcePath;\n      }\n      else {\n        var _includeDefaultValues = this.includeDefaultValues;\n        objsToObject = this._objects.map(function(obj) {\n          var originalDefaults = obj.includeDefaultValues;\n          obj.includeDefaultValues = _includeDefaultValues;\n          var _obj = obj.toDatalessObject(propertiesToInclude);\n          obj.includeDefaultValues = originalDefaults;\n          return _obj;\n        });\n      }\n      var obj = fabric.Object.prototype.toDatalessObject.call(this, propertiesToInclude);\n      obj.objects = objsToObject;\n      return obj;\n    },\n\n    /**\n     * Renders instance on a given context\n     * @param {CanvasRenderingContext2D} ctx context to render instance on\n     */\n    render: function(ctx) {\n      this._transformDone = true;\n      this.callSuper('render', ctx);\n      this._transformDone = false;\n    },\n\n    /**\n     * Decide if the object should cache or not. Create its own cache level\n     * objectCaching is a global flag, wins over everything\n     * needsItsOwnCache should be used when the object drawing method requires\n     * a cache step. None of the fabric classes requires it.\n     * Generally you do not cache objects in groups because the group outside is cached.\n     * @return {Boolean}\n     */\n    shouldCache: function() {\n      var ownCache = this.objectCaching && (!this.group || this.needsItsOwnCache() || !this.group.isOnACache());\n      this.ownCaching = ownCache;\n      if (ownCache) {\n        for (var i = 0, len = this._objects.length; i < len; i++) {\n          if (this._objects[i].willDrawShadow()) {\n            this.ownCaching = false;\n            return false;\n          }\n        }\n      }\n      return ownCache;\n    },\n\n    /**\n     * Check if this object or a child object will cast a shadow\n     * @return {Boolean}\n     */\n    willDrawShadow: function() {\n      if (this.shadow) {\n        return fabric.Object.prototype.willDrawShadow.call(this);\n      }\n      for (var i = 0, len = this._objects.length; i < len; i++) {\n        if (this._objects[i].willDrawShadow()) {\n          return true;\n        }\n      }\n      return false;\n    },\n\n    /**\n     * Check if this group or its parent group are caching, recursively up\n     * @return {Boolean}\n     */\n    isOnACache: function() {\n      return this.ownCaching || (this.group && this.group.isOnACache());\n    },\n\n    /**\n     * Execute the drawing operation for an object on a specified context\n     * @param {CanvasRenderingContext2D} ctx Context to render on\n     */\n    drawObject: function(ctx) {\n      for (var i = 0, len = this._objects.length; i < len; i++) {\n        this._objects[i].render(ctx);\n      }\n      this._drawClipPath(ctx);\n    },\n\n    /**\n     * Check if cache is dirty\n     */\n    isCacheDirty: function(skipCanvas) {\n      if (this.callSuper('isCacheDirty', skipCanvas)) {\n        return true;\n      }\n      if (!this.statefullCache) {\n        return false;\n      }\n      for (var i = 0, len = this._objects.length; i < len; i++) {\n        if (this._objects[i].isCacheDirty(true)) {\n          if (this._cacheCanvas) {\n            // if this group has not a cache canvas there is nothing to clean\n            var x = this.cacheWidth / this.zoomX, y = this.cacheHeight / this.zoomY;\n            this._cacheContext.clearRect(-x / 2, -y / 2, x, y);\n          }\n          return true;\n        }\n      }\n      return false;\n    },\n\n    /**\n     * Retores original state of each of group objects (original state is that which was before group was created).\n     * @private\n     * @return {fabric.Group} thisArg\n     * @chainable\n     */\n    _restoreObjectsState: function() {\n      this._objects.forEach(this._restoreObjectState, this);\n      return this;\n    },\n\n    /**\n     * Realises the transform from this group onto the supplied object\n     * i.e. it tells you what would happen if the supplied object was in\n     * the group, and then the group was destroyed. It mutates the supplied\n     * object.\n     * @param {fabric.Object} object\n     * @return {fabric.Object} transformedObject\n     */\n    realizeTransform: function(object) {\n      var matrix = object.calcTransformMatrix(),\n          options = fabric.util.qrDecompose(matrix),\n          center = new fabric.Point(options.translateX, options.translateY);\n      object.flipX = false;\n      object.flipY = false;\n      object.set('scaleX', options.scaleX);\n      object.set('scaleY', options.scaleY);\n      object.skewX = options.skewX;\n      object.skewY = options.skewY;\n      object.angle = options.angle;\n      object.setPositionByOrigin(center, 'center', 'center');\n      return object;\n    },\n\n    /**\n     * Restores original state of a specified object in group\n     * @private\n     * @param {fabric.Object} object\n     * @return {fabric.Group} thisArg\n     */\n    _restoreObjectState: function(object) {\n      this.realizeTransform(object);\n      object.setCoords();\n      delete object.group;\n      return this;\n    },\n\n    /**\n     * Destroys a group (restoring state of its objects)\n     * @return {fabric.Group} thisArg\n     * @chainable\n     */\n    destroy: function() {\n      // when group is destroyed objects needs to get a repaint to be eventually\n      // displayed on canvas.\n      this._objects.forEach(function(object) {\n        object.set('dirty', true);\n      });\n      return this._restoreObjectsState();\n    },\n\n    /**\n     * make a group an active selection, remove the group from canvas\n     * the group has to be on canvas for this to work.\n     * @return {fabric.ActiveSelection} thisArg\n     * @chainable\n     */\n    toActiveSelection: function() {\n      if (!this.canvas) {\n        return;\n      }\n      var objects = this._objects, canvas = this.canvas;\n      this._objects = [];\n      var options = this.toObject();\n      delete options.objects;\n      var activeSelection = new fabric.ActiveSelection([]);\n      activeSelection.set(options);\n      activeSelection.type = 'activeSelection';\n      canvas.remove(this);\n      objects.forEach(function(object) {\n        object.group = activeSelection;\n        object.dirty = true;\n        canvas.add(object);\n      });\n      activeSelection.canvas = canvas;\n      activeSelection._objects = objects;\n      canvas._activeObject = activeSelection;\n      activeSelection.setCoords();\n      return activeSelection;\n    },\n\n    /**\n     * Destroys a group (restoring state of its objects)\n     * @return {fabric.Group} thisArg\n     * @chainable\n     */\n    ungroupOnCanvas: function() {\n      return this._restoreObjectsState();\n    },\n\n    /**\n     * Sets coordinates of all objects inside group\n     * @return {fabric.Group} thisArg\n     * @chainable\n     */\n    setObjectsCoords: function() {\n      var ignoreZoom = true, skipAbsolute = true;\n      this.forEachObject(function(object) {\n        object.setCoords(ignoreZoom, skipAbsolute);\n      });\n      return this;\n    },\n\n    /**\n     * @private\n     */\n    _calcBounds: function(onlyWidthHeight) {\n      var aX = [],\n          aY = [],\n          o, prop,\n          props = ['tr', 'br', 'bl', 'tl'],\n          i = 0, iLen = this._objects.length,\n          j, jLen = props.length,\n          ignoreZoom = true;\n\n      for ( ; i < iLen; ++i) {\n        o = this._objects[i];\n        o.setCoords(ignoreZoom);\n        for (j = 0; j < jLen; j++) {\n          prop = props[j];\n          aX.push(o.oCoords[prop].x);\n          aY.push(o.oCoords[prop].y);\n        }\n      }\n\n      this._getBounds(aX, aY, onlyWidthHeight);\n    },\n\n    /**\n     * @private\n     */\n    _getBounds: function(aX, aY, onlyWidthHeight) {\n      var minXY = new fabric.Point(min(aX), min(aY)),\n          maxXY = new fabric.Point(max(aX), max(aY)),\n          top = minXY.y || 0, left = minXY.x || 0,\n          width = (maxXY.x - minXY.x) || 0,\n          height = (maxXY.y - minXY.y) || 0;\n      this.width = width;\n      this.height = height;\n      if (!onlyWidthHeight) {\n        // the bounding box always finds the topleft most corner.\n        // whatever is the group origin, we set up here the left/top position.\n        this.setPositionByOrigin({ x: left, y: top }, 'left', 'top');\n      }\n    },\n\n    /* _TO_SVG_START_ */\n    /**\n     * Returns svg representation of an instance\n     * @param {Function} [reviver] Method for further parsing of svg representation.\n     * @return {String} svg representation of an instance\n     */\n    toSVG: function(reviver) {\n      var svgString = [];\n\n      for (var i = 0, len = this._objects.length; i < len; i++) {\n        svgString.push('\\t', this._objects[i].toSVG(reviver));\n      }\n\n      return this._createBaseSVGMarkup(\n        svgString,\n        { reviver: reviver, noStyle: true, withShadow: true });\n    },\n\n    /**\n     * Returns svg clipPath representation of an instance\n     * @param {Function} [reviver] Method for further parsing of svg representation.\n     * @return {String} svg representation of an instance\n     */\n    toClipPathSVG: function(reviver) {\n      var svgString = [];\n\n      for (var i = 0, len = this._objects.length; i < len; i++) {\n        svgString.push('\\t', this._objects[i].toClipPathSVG(reviver));\n      }\n\n      return this._createBaseClipPathSVGMarkup(svgString, { reviver: reviver });\n    },\n    /* _TO_SVG_END_ */\n  });\n\n  /**\n   * Returns {@link fabric.Group} instance from an object representation\n   * @static\n   * @memberOf fabric.Group\n   * @param {Object} object Object to create a group from\n   * @param {Function} [callback] Callback to invoke when an group instance is created\n   */\n  fabric.Group.fromObject = function(object, callback) {\n    fabric.util.enlivenObjects(object.objects, function(enlivenedObjects) {\n      fabric.util.enlivenObjects([object.clipPath], function(enlivedClipPath) {\n        var options = fabric.util.object.clone(object, true);\n        options.clipPath = enlivedClipPath[0];\n        delete options.objects;\n        callback && callback(new fabric.Group(enlivenedObjects, options, true));\n      });\n    });\n  };\n\n})(typeof exports !== 'undefined' ? exports : this);\n\n\n(function(global) {\n\n  'use strict';\n\n  var fabric = global.fabric || (global.fabric = { });\n\n  if (fabric.ActiveSelection) {\n    return;\n  }\n\n  /**\n   * Group class\n   * @class fabric.ActiveSelection\n   * @extends fabric.Group\n   * @tutorial {@link http://fabricjs.com/fabric-intro-part-3#groups}\n   * @see {@link fabric.ActiveSelection#initialize} for constructor definition\n   */\n  fabric.ActiveSelection = fabric.util.createClass(fabric.Group, /** @lends fabric.ActiveSelection.prototype */ {\n\n    /**\n     * Type of an object\n     * @type String\n     * @default\n     */\n    type: 'activeSelection',\n\n    /**\n     * Constructor\n     * @param {Object} objects ActiveSelection objects\n     * @param {Object} [options] Options object\n     * @return {Object} thisArg\n     */\n    initialize: function(objects, options) {\n      options = options || {};\n      this._objects = objects || [];\n      for (var i = this._objects.length; i--; ) {\n        this._objects[i].group = this;\n      }\n\n      if (options.originX) {\n        this.originX = options.originX;\n      }\n      if (options.originY) {\n        this.originY = options.originY;\n      }\n      this._calcBounds();\n      this._updateObjectsCoords();\n      fabric.Object.prototype.initialize.call(this, options);\n      this.setCoords();\n    },\n\n    /**\n     * Change te activeSelection to a normal group,\n     * High level function that automatically adds it to canvas as\n     * active object. no events fired.\n     * @since 2.0.0\n     * @return {fabric.Group}\n     */\n    toGroup: function() {\n      var objects = this._objects.concat();\n      this._objects = [];\n      var options = fabric.Object.prototype.toObject.call(this);\n      var newGroup = new fabric.Group([]);\n      delete options.type;\n      newGroup.set(options);\n      objects.forEach(function(object) {\n        object.canvas.remove(object);\n        object.group = newGroup;\n      });\n      newGroup._objects = objects;\n      if (!this.canvas) {\n        return newGroup;\n      }\n      var canvas = this.canvas;\n      canvas.add(newGroup);\n      canvas._activeObject = newGroup;\n      newGroup.setCoords();\n      return newGroup;\n    },\n\n    /**\n     * If returns true, deselection is cancelled.\n     * @since 2.0.0\n     * @return {Boolean} [cancel]\n     */\n    onDeselect: function() {\n      this.destroy();\n      return false;\n    },\n\n    /**\n     * Returns string representation of a group\n     * @return {String}\n     */\n    toString: function() {\n      return '#<fabric.ActiveSelection: (' + this.complexity() + ')>';\n    },\n\n    /**\n     * Decide if the object should cache or not. Create its own cache level\n     * objectCaching is a global flag, wins over everything\n     * needsItsOwnCache should be used when the object drawing method requires\n     * a cache step. None of the fabric classes requires it.\n     * Generally you do not cache objects in groups because the group outside is cached.\n     * @return {Boolean}\n     */\n    shouldCache: function() {\n      return false;\n    },\n\n    /**\n     * Check if this group or its parent group are caching, recursively up\n     * @return {Boolean}\n     */\n    isOnACache: function() {\n      return false;\n    },\n\n    /**\n     * Renders controls and borders for the object\n     * @param {CanvasRenderingContext2D} ctx Context to render on\n     * @param {Object} [styleOverride] properties to override the object style\n     * @param {Object} [childrenOverride] properties to override the children overrides\n     */\n    _renderControls: function(ctx, styleOverride, childrenOverride) {\n      ctx.save();\n      ctx.globalAlpha = this.isMoving ? this.borderOpacityWhenMoving : 1;\n      this.callSuper('_renderControls', ctx, styleOverride);\n      childrenOverride = childrenOverride || { };\n      if (typeof childrenOverride.hasControls === 'undefined') {\n        childrenOverride.hasControls = false;\n      }\n      if (typeof childrenOverride.hasRotatingPoint === 'undefined') {\n        childrenOverride.hasRotatingPoint = false;\n      }\n      childrenOverride.forActiveSelection = true;\n      for (var i = 0, len = this._objects.length; i < len; i++) {\n        this._objects[i]._renderControls(ctx, childrenOverride);\n      }\n      ctx.restore();\n    },\n  });\n\n  /**\n   * Returns {@link fabric.ActiveSelection} instance from an object representation\n   * @static\n   * @memberOf fabric.ActiveSelection\n   * @param {Object} object Object to create a group from\n   * @param {Function} [callback] Callback to invoke when an ActiveSelection instance is created\n   */\n  fabric.ActiveSelection.fromObject = function(object, callback) {\n    fabric.util.enlivenObjects(object.objects, function(enlivenedObjects) {\n      delete object.objects;\n      callback && callback(new fabric.ActiveSelection(enlivenedObjects, object, true));\n    });\n  };\n\n})(typeof exports !== 'undefined' ? exports : this);\n\n\n(function(global) {\n\n  'use strict';\n\n  var extend = fabric.util.object.extend;\n\n  if (!global.fabric) {\n    global.fabric = { };\n  }\n\n  if (global.fabric.Image) {\n    fabric.warn('fabric.Image is already defined.');\n    return;\n  }\n\n  /**\n   * Image class\n   * @class fabric.Image\n   * @extends fabric.Object\n   * @tutorial {@link http://fabricjs.com/fabric-intro-part-1#images}\n   * @see {@link fabric.Image#initialize} for constructor definition\n   */\n  fabric.Image = fabric.util.createClass(fabric.Object, /** @lends fabric.Image.prototype */ {\n\n    /**\n     * Type of an object\n     * @type String\n     * @default\n     */\n    type: 'image',\n\n    /**\n     * crossOrigin value (one of \"\", \"anonymous\", \"use-credentials\")\n     * @see https://developer.mozilla.org/en-US/docs/HTML/CORS_settings_attributes\n     * @type String\n     * @default\n     */\n    crossOrigin: '',\n\n    /**\n     * Width of a stroke.\n     * For image quality a stroke multiple of 2 gives better results.\n     * @type Number\n     * @default\n     */\n    strokeWidth: 0,\n\n    /**\n     * private\n     * contains last value of scaleX to detect\n     * if the Image got resized after the last Render\n     * @type Number\n     */\n    _lastScaleX: 1,\n\n    /**\n     * private\n     * contains last value of scaleY to detect\n     * if the Image got resized after the last Render\n     * @type Number\n     */\n    _lastScaleY: 1,\n\n    /**\n     * private\n     * contains last value of scaling applied by the apply filter chain\n     * @type Number\n     */\n    _filterScalingX: 1,\n\n    /**\n     * private\n     * contains last value of scaling applied by the apply filter chain\n     * @type Number\n     */\n    _filterScalingY: 1,\n\n    /**\n     * minimum scale factor under which any resizeFilter is triggered to resize the image\n     * 0 will disable the automatic resize. 1 will trigger automatically always.\n     * number bigger than 1 are not implemented yet.\n     * @type Number\n     */\n    minimumScaleTrigger: 0.5,\n\n    /**\n     * List of properties to consider when checking if\n     * state of an object is changed ({@link fabric.Object#hasStateChanged})\n     * as well as for history (undo/redo) purposes\n     * @type Array\n     */\n    stateProperties: fabric.Object.prototype.stateProperties.concat('cropX', 'cropY'),\n\n    /**\n     * key used to retrieve the texture representing this image\n     * since 2.0.0\n     * @type String\n     * @default\n     */\n    cacheKey: '',\n\n    /**\n     * Image crop in pixels from original image size.\n     * since 2.0.0\n     * @type Number\n     * @default\n     */\n    cropX: 0,\n\n    /**\n     * Image crop in pixels from original image size.\n     * since 2.0.0\n     * @type Number\n     * @default\n     */\n    cropY: 0,\n\n    /**\n     * Constructor\n     * @param {HTMLImageElement | String} element Image element\n     * @param {Object} [options] Options object\n     * @param {function} [callback] callback function to call after eventual filters applied.\n     * @return {fabric.Image} thisArg\n     */\n    initialize: function(element, options) {\n      options || (options = { });\n      this.filters = [];\n      this.cacheKey = 'texture' + fabric.Object.__uid++;\n      this.callSuper('initialize', options);\n      this._initElement(element, options);\n    },\n\n    /**\n     * Returns image element which this instance if based on\n     * @return {HTMLImageElement} Image element\n     */\n    getElement: function() {\n      return this._element || {};\n    },\n\n    /**\n     * Sets image element for this instance to a specified one.\n     * If filters defined they are applied to new image.\n     * You might need to call `canvas.renderAll` and `object.setCoords` after replacing, to render new image and update controls area.\n     * @param {HTMLImageElement} element\n     * @param {Object} [options] Options object\n     * @return {fabric.Image} thisArg\n     * @chainable\n     */\n    setElement: function(element, options) {\n      this.removeTexture(this.cacheKey);\n      this.removeTexture(this.cacheKey + '_filtered');\n      this._element = element;\n      this._originalElement = element;\n      this._initConfig(options);\n      if (this.filters.length !== 0) {\n        this.applyFilters();\n      }\n      // resizeFilters work on the already filtered copy.\n      // we need to apply resizeFilters AFTER normal filters.\n      // applyResizeFilters is run more often than normal fiters\n      // and is triggered by user interactions rather than dev code\n      if (this.resizeFilter) {\n        this.applyResizeFilters();\n      }\n      return this;\n    },\n\n    /**\n     * Delete a single texture if in webgl mode\n     */\n    removeTexture: function(key) {\n      var backend = fabric.filterBackend;\n      if (backend && backend.evictCachesForKey) {\n        backend.evictCachesForKey(key);\n      }\n    },\n\n    /**\n     * Delete textures, reference to elements and eventually JSDOM cleanup\n     */\n    dispose: function() {\n      this.removeTexture(this.cacheKey);\n      this.removeTexture(this.cacheKey + '_filtered');\n      this._cacheContext = undefined;\n      ['_originalElement', '_element', '_filteredEl', '_cacheCanvas'].forEach((function(element) {\n        fabric.util.cleanUpJsdomNode(this[element]);\n        this[element] = undefined;\n      }).bind(this));\n    },\n\n    /**\n     * Sets crossOrigin value (on an instance and corresponding image element)\n     * @return {fabric.Image} thisArg\n     * @chainable\n     */\n    setCrossOrigin: function(value) {\n      this.crossOrigin = value;\n      this._element.crossOrigin = value;\n\n      return this;\n    },\n\n    /**\n     * Returns original size of an image\n     * @return {Object} Object with \"width\" and \"height\" properties\n     */\n    getOriginalSize: function() {\n      var element = this.getElement();\n      return {\n        width: element.naturalWidth || element.width,\n        height: element.naturalHeight || element.height\n      };\n    },\n\n    /**\n     * @private\n     * @param {CanvasRenderingContext2D} ctx Context to render on\n     */\n    _stroke: function(ctx) {\n      if (!this.stroke || this.strokeWidth === 0) {\n        return;\n      }\n      var w = this.width / 2, h = this.height / 2;\n      ctx.beginPath();\n      ctx.moveTo(-w, -h);\n      ctx.lineTo(w, -h);\n      ctx.lineTo(w, h);\n      ctx.lineTo(-w, h);\n      ctx.lineTo(-w, -h);\n      ctx.closePath();\n    },\n\n    /**\n     * @private\n     * @param {CanvasRenderingContext2D} ctx Context to render on\n     */\n    _renderDashedStroke: function(ctx) {\n      var x = -this.width / 2,\n          y = -this.height / 2,\n          w = this.width,\n          h = this.height;\n\n      ctx.save();\n      this._setStrokeStyles(ctx, this);\n\n      ctx.beginPath();\n      fabric.util.drawDashedLine(ctx, x, y, x + w, y, this.strokeDashArray);\n      fabric.util.drawDashedLine(ctx, x + w, y, x + w, y + h, this.strokeDashArray);\n      fabric.util.drawDashedLine(ctx, x + w, y + h, x, y + h, this.strokeDashArray);\n      fabric.util.drawDashedLine(ctx, x, y + h, x, y, this.strokeDashArray);\n      ctx.closePath();\n      ctx.restore();\n    },\n\n    /**\n     * Returns object representation of an instance\n     * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output\n     * @return {Object} Object representation of an instance\n     */\n    toObject: function(propertiesToInclude) {\n      var filters = [];\n\n      this.filters.forEach(function(filterObj) {\n        if (filterObj) {\n          filters.push(filterObj.toObject());\n        }\n      });\n      var object = extend(\n        this.callSuper(\n          'toObject',\n          ['crossOrigin', 'cropX', 'cropY'].concat(propertiesToInclude)\n        ), {\n          src: this.getSrc(),\n          filters: filters,\n        });\n      if (this.resizeFilter) {\n        object.resizeFilter = this.resizeFilter.toObject();\n      }\n      return object;\n    },\n\n    /**\n     * Returns true if an image has crop applied, inspecting values of cropX,cropY,width,hight.\n     * @return {Boolean}\n     */\n    hasCrop: function() {\n      return this.cropX || this.cropY || this.width < this._element.width || this.height < this._element.height;\n    },\n\n    /* _TO_SVG_START_ */\n    /**\n     * Returns svg representation of an instance\n     * @return {Array} an array of strings with the specific svg representation\n     * of the instance\n     */\n    _toSVG: function() {\n      var svgString = [], imageMarkup = [], strokeSvg,\n          x = -this.width / 2, y = -this.height / 2, clipPath = '';\n      if (this.hasCrop()) {\n        var clipPathId = fabric.Object.__uid++;\n        svgString.push(\n          '<clipPath id=\"imageCrop_' + clipPathId + '\">\\n',\n          '\\t<rect x=\"' + x + '\" y=\"' + y + '\" width=\"' + this.width + '\" height=\"' + this.height + '\" />\\n',\n          '</clipPath>\\n'\n        );\n        clipPath = ' clip-path=\"url(#imageCrop_' + clipPathId + ')\" ';\n      }\n      imageMarkup.push('\\t<image ', 'COMMON_PARTS', 'xlink:href=\"', this.getSvgSrc(true),\n        '\" x=\"', x - this.cropX, '\" y=\"', y - this.cropY,\n        // we're essentially moving origin of transformation from top/left corner to the center of the shape\n        // by wrapping it in container <g> element with actual transformation, then offsetting object to the top/left\n        // so that object's center aligns with container's left/top\n        '\" width=\"', this._element.width || this._element.naturalWidth,\n        '\" height=\"', this._element.height || this._element.height,\n        '\"', clipPath,\n        '></image>\\n');\n\n      if (this.stroke || this.strokeDashArray) {\n        var origFill = this.fill;\n        this.fill = null;\n        strokeSvg = [\n          '\\t<rect ',\n          'x=\"', x, '\" y=\"', y,\n          '\" width=\"', this.width, '\" height=\"', this.height,\n          '\" style=\"', this.getSvgStyles(),\n          '\"/>\\n'\n        ];\n        this.fill = origFill;\n      }\n      if (this.paintFirst !== 'fill') {\n        svgString = svgString.concat(strokeSvg, imageMarkup);\n      }\n      else {\n        svgString = svgString.concat(imageMarkup, strokeSvg);\n      }\n      return svgString;\n    },\n    /* _TO_SVG_END_ */\n\n    /**\n     * Returns source of an image\n     * @param {Boolean} filtered indicates if the src is needed for svg\n     * @return {String} Source of an image\n     */\n    getSrc: function(filtered) {\n      var element = filtered ? this._element : this._originalElement;\n      if (element) {\n        if (element.toDataURL) {\n          return element.toDataURL();\n        }\n        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     * @return {fabric.Image} thisArg\n     * @chainable\n     */\n    setSrc: function(src, callback, options) {\n      fabric.util.loadImage(src, function(img) {\n        this.setElement(img, options);\n        this._setWidthHeight();\n        callback(this);\n      }, this, options && options.crossOrigin);\n      return this;\n    },\n\n    /**\n     * Returns string representation of an instance\n     * @return {String} String representation of an instance\n     */\n    toString: function() {\n      return '#<fabric.Image: { src: \"' + this.getSrc() + '\" }>';\n    },\n\n    applyResizeFilters: function() {\n      var filter = this.resizeFilter,\n          minimumScale = this.minimumScaleTrigger,\n          objectScale = this.getTotalObjectScaling(),\n          scaleX = objectScale.scaleX,\n          scaleY = objectScale.scaleY,\n          elementToFilter = this._filteredEl || this._originalElement;\n      if (this.group) {\n        this.set('dirty', true);\n      }\n      if (!filter || (scaleX > minimumScale && scaleY > minimumScale)) {\n        this._element = elementToFilter;\n        this._filterScalingX = 1;\n        this._filterScalingY = 1;\n        this._lastScaleX = scaleX;\n        this._lastScaleY = scaleY;\n        return;\n      }\n      if (!fabric.filterBackend) {\n        fabric.filterBackend = fabric.initFilterBackend();\n      }\n      var canvasEl = fabric.util.createCanvasElement(),\n          cacheKey = this._filteredEl ? (this.cacheKey + '_filtered') : this.cacheKey,\n          sourceWidth = elementToFilter.width, sourceHeight = elementToFilter.height;\n      canvasEl.width = sourceWidth;\n      canvasEl.height = sourceHeight;\n      this._element = canvasEl;\n      this._lastScaleX = filter.scaleX = scaleX;\n      this._lastScaleY = filter.scaleY = scaleY;\n      fabric.filterBackend.applyFilters(\n        [filter], elementToFilter, sourceWidth, sourceHeight, this._element, cacheKey);\n      this._filterScalingX = canvasEl.width / this._originalElement.width;\n      this._filterScalingY = canvasEl.height / this._originalElement.height;\n    },\n\n    /**\n     * Applies filters assigned to this image (from \"filters\" array) or from filter param\n     * @method applyFilters\n     * @param {Array} filters to be applied\n     * @param {Boolean} forResizing specify if the filter operation is a resize operation\n     * @return {thisArg} return the fabric.Image object\n     * @chainable\n     */\n    applyFilters: function(filters) {\n\n      filters = filters || this.filters || [];\n      filters = filters.filter(function(filter) { return filter && !filter.isNeutralState(); });\n      this.set('dirty', true);\n\n      // needs to clear out or WEBGL will not resize correctly\n      this.removeTexture(this.cacheKey + '_filtered');\n\n      if (filters.length === 0) {\n        this._element = this._originalElement;\n        this._filteredEl = null;\n        this._filterScalingX = 1;\n        this._filterScalingY = 1;\n        return this;\n      }\n\n      var imgElement = this._originalElement,\n          sourceWidth = imgElement.naturalWidth || imgElement.width,\n          sourceHeight = imgElement.naturalHeight || imgElement.height;\n\n      if (this._element === this._originalElement) {\n        // if the element is the same we need to create a new element\n        var canvasEl = fabric.util.createCanvasElement();\n        canvasEl.width = sourceWidth;\n        canvasEl.height = sourceHeight;\n        this._element = canvasEl;\n        this._filteredEl = canvasEl;\n      }\n      else {\n        // clear the existing element to get new filter data\n        // also dereference the eventual resized _element\n        this._element = this._filteredEl;\n        this._filteredEl.getContext('2d').clearRect(0, 0, sourceWidth, sourceHeight);\n        // we also need to resize again at next renderAll, so remove saved _lastScaleX/Y\n        this._lastScaleX = 1;\n        this._lastScaleY = 1;\n      }\n      if (!fabric.filterBackend) {\n        fabric.filterBackend = fabric.initFilterBackend();\n      }\n      fabric.filterBackend.applyFilters(\n        filters, this._originalElement, sourceWidth, sourceHeight, this._element, this.cacheKey);\n      if (this._originalElement.width !== this._element.width ||\n        this._originalElement.height !== this._element.height) {\n        this._filterScalingX = this._element.width / this._originalElement.width;\n        this._filterScalingY = this._element.height / this._originalElement.height;\n      }\n      return this;\n    },\n\n    /**\n     * @private\n     * @param {CanvasRenderingContext2D} ctx Context to render on\n     */\n    _render: function(ctx) {\n      if (this.isMoving !== true && this.resizeFilter && this._needsResize()) {\n        this.applyResizeFilters();\n      }\n      this._stroke(ctx);\n      this._renderPaintInOrder(ctx);\n    },\n\n    /**\n     * Decide if the object should cache or not. Create its own cache level\n     * 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     * This is the special image version where we would like to avoid caching where possible.\n     * Essentially images do not benefit from caching. They may require caching, and in that\n     * case we do it. Also caching an image usually ends in a loss of details.\n     * A full performance audit should be done.\n     * @return {Boolean}\n     */\n    shouldCache: function() {\n      this.ownCaching = this.objectCaching && this.needsItsOwnCache();\n      return this.ownCaching;\n    },\n\n    _renderFill: function(ctx) {\n      var w = this.width, h = this.height, sW = w * this._filterScalingX, sH = h * this._filterScalingY,\n          x = -w / 2, y = -h / 2, elementToDraw = this._element;\n      elementToDraw && ctx.drawImage(elementToDraw,\n        this.cropX * this._filterScalingX,\n        this.cropY * this._filterScalingY,\n        sW,\n        sH,\n        x, y, w, h);\n    },\n\n    /**\n     * @private, needed to check if image needs resize\n     */\n    _needsResize: function() {\n      var scale = this.getTotalObjectScaling();\n      return (scale.scaleX !== this._lastScaleX || scale.scaleY !== this._lastScaleY);\n    },\n\n    /**\n     * @private\n     */\n    _resetWidthHeight: function() {\n      this.set(this.getOriginalSize());\n    },\n\n    /**\n     * The Image class's initialization method. This method is automatically\n     * called by the constructor.\n     * @private\n     * @param {HTMLImageElement|String} element The element representing the image\n     * @param {Object} [options] Options object\n     */\n    _initElement: function(element, options) {\n      this.setElement(fabric.util.getById(element), options);\n      fabric.util.addClass(this.getElement(), fabric.Image.CSS_CANVAS);\n    },\n\n    /**\n     * @private\n     * @param {Object} [options] Options object\n     */\n    _initConfig: function(options) {\n      options || (options = { });\n      this.setOptions(options);\n      this._setWidthHeight(options);\n      if (this._element && this.crossOrigin) {\n        this._element.crossOrigin = this.crossOrigin;\n      }\n    },\n\n    /**\n     * @private\n     * @param {Array} filters to be initialized\n     * @param {Function} callback Callback to invoke when all fabric.Image.filters instances are created\n     */\n    _initFilters: function(filters, callback) {\n      if (filters && filters.length) {\n        fabric.util.enlivenObjects(filters, function(enlivenedObjects) {\n          callback && callback(enlivenedObjects);\n        }, 'fabric.Image.filters');\n      }\n      else {\n        callback && callback();\n      }\n    },\n\n    /**\n     * @private\n     * Set the width and the height of the image object, using the element or the\n     * options.\n     * @param {Object} [options] Object with width/height properties\n     */\n    _setWidthHeight: function(options) {\n      options || (options = { });\n      var el = this.getElement();\n      this.width = options.width || el.naturalWidth || el.width || 0;\n      this.height = options.height || el.naturalHeight || el.height || 0;\n    },\n\n    /**\n     * Calculate offset for center and scale factor for the image in order to respect\n     * the preserveAspectRatio attribute\n     * @private\n     * @return {Object}\n     */\n    parsePreserveAspectRatioAttribute: function() {\n      var pAR = fabric.util.parsePreserveAspectRatioAttribute(this.preserveAspectRatio || ''),\n          rWidth = this._element.width, rHeight = this._element.height,\n          scaleX = 1, scaleY = 1, offsetLeft = 0, offsetTop = 0, cropX = 0, cropY = 0,\n          offset, pWidth = this.width, pHeight = this.height, parsedAttributes = { width: pWidth, height: pHeight };\n      if (pAR && (pAR.alignX !== 'none' || pAR.alignY !== 'none')) {\n        if (pAR.meetOrSlice === 'meet') {\n          scaleX = scaleY = fabric.util.findScaleToFit(this._element, parsedAttributes);\n          offset = (pWidth - rWidth * scaleX) / 2;\n          if (pAR.alignX === 'Min') {\n            offsetLeft = -offset;\n          }\n          if (pAR.alignX === 'Max') {\n            offsetLeft = offset;\n          }\n          offset = (pHeight - rHeight * scaleY) / 2;\n          if (pAR.alignY === 'Min') {\n            offsetTop = -offset;\n          }\n          if (pAR.alignY === 'Max') {\n            offsetTop = offset;\n          }\n        }\n        if (pAR.meetOrSlice === 'slice') {\n          scaleX = scaleY = fabric.util.findScaleToCover(this._element, parsedAttributes);\n          offset = rWidth - pWidth / scaleX;\n          if (pAR.alignX === 'Mid') {\n            cropX = offset / 2;\n          }\n          if (pAR.alignX === 'Max') {\n            cropX = offset;\n          }\n          offset = rHeight - pHeight / scaleY;\n          if (pAR.alignY === 'Mid') {\n            cropY = offset / 2;\n          }\n          if (pAR.alignY === 'Max') {\n            cropY = offset;\n          }\n          rWidth = pWidth / scaleX;\n          rHeight = pHeight / scaleY;\n        }\n      }\n      else {\n        scaleX = pWidth / rWidth;\n        scaleY = pHeight / rHeight;\n      }\n      return {\n        width: rWidth,\n        height: rHeight,\n        scaleX: scaleX,\n        scaleY: scaleY,\n        offsetLeft: offsetLeft,\n        offsetTop: offsetTop,\n        cropX: cropX,\n        cropY: cropY\n      };\n    }\n  });\n\n  /**\n   * Default CSS class name for canvas\n   * @static\n   * @type String\n   * @default\n   */\n  fabric.Image.CSS_CANVAS = 'canvas-img';\n\n  /**\n   * Alias for getSrc\n   * @static\n   */\n  fabric.Image.prototype.getSvgSrc = fabric.Image.prototype.getSrc;\n\n  /**\n   * Creates an instance of fabric.Image from its object representation\n   * @static\n   * @param {Object} object Object to create an instance from\n   * @param {Function} callback Callback to invoke when an image instance is created\n   */\n  fabric.Image.fromObject = function(_object, callback) {\n    var object = fabric.util.object.clone(_object);\n    fabric.util.loadImage(object.src, function(img, error) {\n      if (error) {\n        callback && callback(null, error);\n        return;\n      }\n      fabric.Image.prototype._initFilters.call(object, object.filters, function(filters) {\n        object.filters = filters || [];\n        fabric.Image.prototype._initFilters.call(object, [object.resizeFilter], function(resizeFilters) {\n          object.resizeFilter = resizeFilters[0];\n          fabric.util.enlivenObjects([object.clipPath], function(enlivedProps) {\n            object.clipPath = enlivedProps[0];\n            var image = new fabric.Image(img, object);\n            callback(image);\n          });\n        });\n      });\n    }, null, object.crossOrigin);\n  };\n\n  /**\n   * Creates an instance of fabric.Image from an URL string\n   * @static\n   * @param {String} url URL to create an image from\n   * @param {Function} [callback] Callback to invoke when image is created (newly created image is passed as a first argument)\n   * @param {Object} [imgOptions] Options object\n   */\n  fabric.Image.fromURL = function(url, callback, imgOptions) {\n    fabric.util.loadImage(url, function(img) {\n      callback && callback(new fabric.Image(img, imgOptions));\n    }, null, imgOptions && imgOptions.crossOrigin);\n  };\n\n  /* _FROM_SVG_START_ */\n  /**\n   * List of attribute names to account for when parsing SVG element (used by {@link fabric.Image.fromElement})\n   * @static\n   * @see {@link http://www.w3.org/TR/SVG/struct.html#ImageElement}\n   */\n  fabric.Image.ATTRIBUTE_NAMES =\n    fabric.SHARED_ATTRIBUTES.concat('x y width height preserveAspectRatio xlink:href crossOrigin'.split(' '));\n\n  /**\n   * Returns {@link fabric.Image} instance from an SVG element\n   * @static\n   * @param {SVGElement} element Element to parse\n   * @param {Object} [options] Options object\n   * @param {Function} callback Callback to execute when fabric.Image object is created\n   * @return {fabric.Image} Instance of fabric.Image\n   */\n  fabric.Image.fromElement = function(element, callback, options) {\n    var parsedAttributes = fabric.parseAttributes(element, fabric.Image.ATTRIBUTE_NAMES);\n    fabric.Image.fromURL(parsedAttributes['xlink:href'], callback,\n      extend((options ? fabric.util.object.clone(options) : { }), parsedAttributes));\n  };\n  /* _FROM_SVG_END_ */\n\n})(typeof exports !== 'undefined' ? exports : this);\n\n\nfabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prototype */ {\n\n  /**\n   * @private\n   * @return {Number} angle value\n   */\n  _getAngleValueForStraighten: function() {\n    var angle = this.angle % 360;\n    if (angle > 0) {\n      return Math.round((angle - 1) / 90) * 90;\n    }\n    return Math.round(angle / 90) * 90;\n  },\n\n  /**\n   * Straightens an object (rotating it from current angle to one of 0, 90, 180, 270, etc. depending on which is closer)\n   * @return {fabric.Object} thisArg\n   * @chainable\n   */\n  straighten: function() {\n    this.rotate(this._getAngleValueForStraighten());\n    return this;\n  },\n\n  /**\n   * Same as {@link fabric.Object.prototype.straighten} but with animation\n   * @param {Object} callbacks Object with callback functions\n   * @param {Function} [callbacks.onComplete] Invoked on completion\n   * @param {Function} [callbacks.onChange] Invoked on every step of animation\n   * @return {fabric.Object} thisArg\n   * @chainable\n   */\n  fxStraighten: function(callbacks) {\n    callbacks = callbacks || { };\n\n    var empty = function() { },\n        onComplete = callbacks.onComplete || empty,\n        onChange = callbacks.onChange || empty,\n        _this = this;\n\n    fabric.util.animate({\n      startValue: this.get('angle'),\n      endValue: this._getAngleValueForStraighten(),\n      duration: this.FX_DURATION,\n      onChange: function(value) {\n        _this.rotate(value);\n        onChange();\n      },\n      onComplete: function() {\n        _this.setCoords();\n        onComplete();\n      },\n    });\n\n    return this;\n  }\n});\n\nfabric.util.object.extend(fabric.StaticCanvas.prototype, /** @lends fabric.StaticCanvas.prototype */ {\n\n  /**\n   * Straightens object, then rerenders canvas\n   * @param {fabric.Object} object Object to straighten\n   * @return {fabric.Canvas} thisArg\n   * @chainable\n   */\n  straightenObject: function (object) {\n    object.straighten();\n    this.requestRenderAll();\n    return this;\n  },\n\n  /**\n   * Same as {@link fabric.Canvas.prototype.straightenObject}, but animated\n   * @param {fabric.Object} object Object to straighten\n   * @return {fabric.Canvas} thisArg\n   * @chainable\n   */\n  fxStraightenObject: function (object) {\n    object.fxStraighten({\n      onChange: this.requestRenderAllBound\n    });\n    return this;\n  }\n});\n\n\n(function() {\n\n  'use strict';\n\n  /**\n   * Tests if webgl supports certain precision\n   * @param {WebGL} Canvas WebGL context to test on\n   * @param {String} Precision to test can be any of following: 'lowp', 'mediump', 'highp'\n   * @returns {Boolean} Whether the user's browser WebGL supports given precision.\n   */\n  function testPrecision(gl, precision){\n    var fragmentSource = 'precision ' + precision + ' float;\\nvoid main(){}';\n    var fragmentShader = gl.createShader(gl.FRAGMENT_SHADER);\n    gl.shaderSource(fragmentShader, fragmentSource);\n    gl.compileShader(fragmentShader);\n    if (!gl.getShaderParameter(fragmentShader, gl.COMPILE_STATUS)) {\n      return false;\n    }\n    return true;\n  }\n\n  /**\n   * Indicate whether this filtering backend is supported by the user's browser.\n   * @param {Number} tileSize check if the tileSize is supported\n   * @returns {Boolean} Whether the user's browser supports WebGL.\n   */\n  fabric.isWebglSupported = function(tileSize) {\n    if (fabric.isLikelyNode) {\n      return false;\n    }\n    tileSize = tileSize || fabric.WebglFilterBackend.prototype.tileSize;\n    var canvas = document.createElement('canvas');\n    var gl = canvas.getContext('webgl') || canvas.getContext('experimental-webgl');\n    var isSupported = false;\n    // eslint-disable-next-line\n    if (gl) {\n      fabric.maxTextureSize = gl.getParameter(gl.MAX_TEXTURE_SIZE);\n      isSupported = fabric.maxTextureSize >= tileSize;\n      var precisions = ['highp', 'mediump', 'lowp'];\n      for (var i = 0; i < 3; i++){\n        if (testPrecision(gl, precisions[i])){\n          fabric.webGlPrecision = precisions[i];\n          break;\n        };\n      }\n    }\n    this.isSupported = isSupported;\n    return isSupported;\n  };\n\n  fabric.WebglFilterBackend = WebglFilterBackend;\n\n  /**\n   * WebGL filter backend.\n   */\n  function WebglFilterBackend(options) {\n    if (options && options.tileSize) {\n      this.tileSize = options.tileSize;\n    }\n    this.setupGLContext(this.tileSize, this.tileSize);\n    this.captureGPUInfo();\n  };\n\n  WebglFilterBackend.prototype = /** @lends fabric.WebglFilterBackend.prototype */ {\n\n    tileSize: 2048,\n\n    /**\n     * Experimental. This object is a sort of repository of help layers used to avoid\n     * of recreating them during frequent filtering. If you are previewing a filter with\n     * a slider you problably do not want to create help layers every filter step.\n     * in this object there will be appended some canvases, created once, resized sometimes\n     * cleared never. Clearing is left to the developer.\n     **/\n    resources: {\n\n    },\n\n    /**\n     * Setup a WebGL context suitable for filtering, and bind any needed event handlers.\n     */\n    setupGLContext: function(width, height) {\n      this.dispose();\n      this.createWebGLCanvas(width, height);\n      // eslint-disable-next-line\n      this.aPosition = new Float32Array([0, 0, 0, 1, 1, 0, 1, 1]);\n      this.chooseFastestCopyGLTo2DMethod(width, height);\n    },\n\n    /**\n     * Pick a method to copy data from GL context to 2d canvas.  In some browsers using\n     * putImageData is faster than drawImage for that specific operation.\n     */\n    chooseFastestCopyGLTo2DMethod: function(width, height) {\n      var canMeasurePerf = typeof window.performance !== 'undefined';\n      var canUseImageData;\n      try {\n        new ImageData(1, 1);\n        canUseImageData = true;\n      }\n      catch (e) {\n        canUseImageData = false;\n      }\n      // eslint-disable-next-line no-undef\n      var canUseArrayBuffer = typeof ArrayBuffer !== 'undefined';\n      // eslint-disable-next-line no-undef\n      var canUseUint8Clamped = typeof Uint8ClampedArray !== 'undefined';\n\n      if (!(canMeasurePerf && canUseImageData && canUseArrayBuffer && canUseUint8Clamped)) {\n        return;\n      }\n\n      var targetCanvas = fabric.util.createCanvasElement();\n      // eslint-disable-next-line no-undef\n      var imageBuffer = new ArrayBuffer(width * height * 4);\n      var testContext = {\n        imageBuffer: imageBuffer,\n        destinationWidth: width,\n        destinationHeight: height,\n        targetCanvas: targetCanvas\n      };\n      var startTime, drawImageTime, putImageDataTime;\n      targetCanvas.width = width;\n      targetCanvas.height = height;\n\n      startTime = window.performance.now();\n      copyGLTo2DDrawImage.call(testContext, this.gl, testContext);\n      drawImageTime = window.performance.now() - startTime;\n\n      startTime = window.performance.now();\n      copyGLTo2DPutImageData.call(testContext, this.gl, testContext);\n      putImageDataTime = window.performance.now() - startTime;\n\n      if (drawImageTime > putImageDataTime) {\n        this.imageBuffer = imageBuffer;\n        this.copyGLTo2D = copyGLTo2DPutImageData;\n      }\n      else {\n        this.copyGLTo2D = copyGLTo2DDrawImage;\n      }\n    },\n\n    /**\n     * Create a canvas element and associated WebGL context and attaches them as\n     * class properties to the GLFilterBackend class.\n     */\n    createWebGLCanvas: function(width, height) {\n      var canvas = fabric.util.createCanvasElement();\n      canvas.width = width;\n      canvas.height = height;\n      var glOptions = {\n            alpha: true,\n            premultipliedAlpha: false,\n            depth: false,\n            stencil: false,\n            antialias: false\n          },\n          gl = canvas.getContext('webgl', glOptions);\n      if (!gl) {\n        gl = canvas.getContext('experimental-webgl', glOptions);\n      }\n      if (!gl) {\n        return;\n      }\n      gl.clearColor(0, 0, 0, 0);\n      // this canvas can fire webglcontextlost and webglcontextrestored\n      this.canvas = canvas;\n      this.gl = gl;\n    },\n\n    /**\n     * Attempts to apply the requested filters to the source provided, drawing the filtered output\n     * to the provided target canvas.\n     *\n     * @param {Array} filters The filters to apply.\n     * @param {HTMLImageElement|HTMLCanvasElement} source The source to be filtered.\n     * @param {Number} width The width of the source input.\n     * @param {Number} height The height of the source input.\n     * @param {HTMLCanvasElement} targetCanvas The destination for filtered output to be drawn.\n     * @param {String|undefined} cacheKey A key used to cache resources related to the source. If\n     * omitted, caching will be skipped.\n     */\n    applyFilters: function(filters, source, width, height, targetCanvas, cacheKey) {\n      var gl = this.gl;\n      var cachedTexture;\n      if (cacheKey) {\n        cachedTexture = this.getCachedTexture(cacheKey, source);\n      }\n      var pipelineState = {\n        originalWidth: source.width || source.originalWidth,\n        originalHeight: source.height || source.originalHeight,\n        sourceWidth: width,\n        sourceHeight: height,\n        destinationWidth: width,\n        destinationHeight: height,\n        context: gl,\n        sourceTexture: this.createTexture(gl, width, height, !cachedTexture && source),\n        targetTexture: this.createTexture(gl, width, height),\n        originalTexture: cachedTexture ||\n          this.createTexture(gl, width, height, !cachedTexture && source),\n        passes: filters.length,\n        webgl: true,\n        aPosition: this.aPosition,\n        programCache: this.programCache,\n        pass: 0,\n        filterBackend: this,\n        targetCanvas: targetCanvas\n      };\n      var tempFbo = gl.createFramebuffer();\n      gl.bindFramebuffer(gl.FRAMEBUFFER, tempFbo);\n      filters.forEach(function(filter) { filter && filter.applyTo(pipelineState); });\n      resizeCanvasIfNeeded(pipelineState);\n      this.copyGLTo2D(gl, pipelineState);\n      gl.bindTexture(gl.TEXTURE_2D, null);\n      gl.deleteTexture(pipelineState.sourceTexture);\n      gl.deleteTexture(pipelineState.targetTexture);\n      gl.deleteFramebuffer(tempFbo);\n      targetCanvas.getContext('2d').setTransform(1, 0, 0, 1, 0, 0);\n      return pipelineState;\n    },\n\n    /**\n     * The same as the applyFilter method but with additional logging of WebGL\n     * errors.\n     */\n    applyFiltersDebug: function(filters, source, width, height, targetCanvas, cacheKey) {\n      // The following code is useful when debugging a specific issue but adds ~10x slowdown.\n      var gl = this.gl;\n      var ret = this.applyFilters(filters, source, width, height, targetCanvas, cacheKey);\n      var glError = gl.getError();\n      if (glError !== gl.NO_ERROR) {\n        var errorString = this.glErrorToString(gl, glError);\n        var error = new Error('WebGL Error ' + errorString);\n        error.glErrorCode = glError;\n        throw error;\n      }\n      return ret;\n    },\n\n    glErrorToString: function(context, errorCode) {\n      if (!context) {\n        return 'Context undefined for error code: ' + errorCode;\n      }\n      else if (typeof errorCode !== 'number') {\n        return 'Error code is not a number';\n      }\n      switch (errorCode) {\n        case context.NO_ERROR:\n          return 'NO_ERROR';\n        case context.INVALID_ENUM:\n          return 'INVALID_ENUM';\n        case context.INVALID_VALUE:\n          return 'INVALID_VALUE';\n        case context.INVALID_OPERATION:\n          return 'INVALID_OPERATION';\n        case context.INVALID_FRAMEBUFFER_OPERATION:\n          return 'INVALID_FRAMEBUFFER_OPERATION';\n        case context.OUT_OF_MEMORY:\n          return 'OUT_OF_MEMORY';\n        case context.CONTEXT_LOST_WEBGL:\n          return 'CONTEXT_LOST_WEBGL';\n        default:\n          return 'UNKNOWN_ERROR';\n      }\n    },\n\n    /**\n     * Detach event listeners, remove references, and clean up caches.\n     */\n    dispose: function() {\n      if (this.canvas) {\n        this.canvas = null;\n        this.gl = null;\n      }\n      this.clearWebGLCaches();\n    },\n\n    /**\n     * Wipe out WebGL-related caches.\n     */\n    clearWebGLCaches: function() {\n      this.programCache = {};\n      this.textureCache = {};\n    },\n\n    /**\n     * Create a WebGL texture object.\n     *\n     * Accepts specific dimensions to initialize the textuer to or a source image.\n     *\n     * @param {WebGLRenderingContext} gl The GL context to use for creating the texture.\n     * @param {Number} width The width to initialize the texture at.\n     * @param {Number} height The height to initialize the texture.\n     * @param {HTMLImageElement|HTMLCanvasElement} textureImageSource A source for the texture data.\n     * @returns {WebGLTexture}\n     */\n    createTexture: function(gl, width, height, textureImageSource) {\n      var texture = gl.createTexture();\n      gl.bindTexture(gl.TEXTURE_2D, texture);\n      gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);\n      gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);\n      gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);\n      gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);\n      if (textureImageSource) {\n        gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, textureImageSource);\n      }\n      else {\n        gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, width, height, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);\n      }\n      return texture;\n    },\n\n    /**\n     * Can be optionally used to get a texture from the cache array\n     *\n     * If an existing texture is not found, a new texture is created and cached.\n     *\n     * @param {String} uniqueId A cache key to use to find an existing texture.\n     * @param {HTMLImageElement|HTMLCanvasElement} textureImageSource A source to use to create the\n     * texture cache entry if one does not already exist.\n     */\n    getCachedTexture: function(uniqueId, textureImageSource) {\n      if (this.textureCache[uniqueId]) {\n        return this.textureCache[uniqueId];\n      }\n      else {\n        var texture = this.createTexture(\n          this.gl, textureImageSource.width, textureImageSource.height, textureImageSource);\n        this.textureCache[uniqueId] = texture;\n        return texture;\n      }\n    },\n\n    /**\n     * Clear out cached resources related to a source image that has been\n     * filtered previously.\n     *\n     * @param {String} cacheKey The cache key provided when the source image was filtered.\n     */\n    evictCachesForKey: function(cacheKey) {\n      if (this.textureCache[cacheKey]) {\n        this.gl.deleteTexture(this.textureCache[cacheKey]);\n        delete this.textureCache[cacheKey];\n      }\n    },\n\n    copyGLTo2D: copyGLTo2DDrawImage,\n\n    /**\n     * Attempt to extract GPU information strings from a WebGL context.\n     *\n     * Useful information when debugging or blacklisting specific GPUs.\n     *\n     * @returns {Object} A GPU info object with renderer and vendor strings.\n     */\n    captureGPUInfo: function() {\n      if (this.gpuInfo) {\n        return this.gpuInfo;\n      }\n      var gl = this.gl;\n      var ext = gl.getExtension('WEBGL_debug_renderer_info');\n      var gpuInfo = { renderer: '', vendor: '' };\n      if (ext) {\n        var renderer = gl.getParameter(ext.UNMASKED_RENDERER_WEBGL);\n        var vendor = gl.getParameter(ext.UNMASKED_VENDOR_WEBGL);\n        if (renderer) {\n          gpuInfo.renderer = renderer.toLowerCase();\n        }\n        if (vendor) {\n          gpuInfo.vendor = vendor.toLowerCase();\n        }\n      }\n      this.gpuInfo = gpuInfo;\n      return gpuInfo;\n    },\n  };\n})();\n\nfunction resizeCanvasIfNeeded(pipelineState) {\n  var targetCanvas = pipelineState.targetCanvas,\n      width = targetCanvas.width, height = targetCanvas.height,\n      dWidth = pipelineState.destinationWidth,\n      dHeight = pipelineState.destinationHeight;\n\n  if (width !== dWidth || height !== dHeight) {\n    targetCanvas.width = dWidth;\n    targetCanvas.height = dHeight;\n  }\n}\n\n/**\n * Copy an input WebGL canvas on to an output 2D canvas.\n *\n * The WebGL canvas is assumed to be upside down, with the top-left pixel of the\n * desired output image appearing in the bottom-left corner of the WebGL canvas.\n *\n * @param {WebGLRenderingContext} sourceContext The WebGL context to copy from.\n * @param {HTMLCanvasElement} targetCanvas The 2D target canvas to copy on to.\n * @param {Object} pipelineState The 2D target canvas to copy on to.\n */\nfunction copyGLTo2DDrawImage(gl, pipelineState) {\n  var glCanvas = gl.canvas, targetCanvas = pipelineState.targetCanvas,\n      ctx = targetCanvas.getContext('2d');\n  ctx.translate(0, targetCanvas.height); // move it down again\n  ctx.scale(1, -1); // vertical flip\n  // where is my image on the big glcanvas?\n  var sourceY = glCanvas.height - targetCanvas.height;\n  ctx.drawImage(glCanvas, 0, sourceY, targetCanvas.width, targetCanvas.height, 0, 0,\n    targetCanvas.width, targetCanvas.height);\n}\n\n/**\n * Copy an input WebGL canvas on to an output 2D canvas using 2d canvas' putImageData\n * API. Measurably faster than using ctx.drawImage in Firefox (version 54 on OSX Sierra).\n *\n * @param {WebGLRenderingContext} sourceContext The WebGL context to copy from.\n * @param {HTMLCanvasElement} targetCanvas The 2D target canvas to copy on to.\n * @param {Object} pipelineState The 2D target canvas to copy on to.\n */\nfunction copyGLTo2DPutImageData(gl, pipelineState) {\n  var targetCanvas = pipelineState.targetCanvas, ctx = targetCanvas.getContext('2d'),\n      dWidth = pipelineState.destinationWidth,\n      dHeight = pipelineState.destinationHeight,\n      numBytes = dWidth * dHeight * 4;\n\n  // eslint-disable-next-line no-undef\n  var u8 = new Uint8Array(this.imageBuffer, 0, numBytes);\n  // eslint-disable-next-line no-undef\n  var u8Clamped = new Uint8ClampedArray(this.imageBuffer, 0, numBytes);\n\n  gl.readPixels(0, 0, dWidth, dHeight, gl.RGBA, gl.UNSIGNED_BYTE, u8);\n  var imgData = new ImageData(u8Clamped, dWidth, dHeight);\n  ctx.putImageData(imgData, 0, 0);\n}\n\n\n(function() {\n\n  'use strict';\n\n  var noop = function() {};\n\n  fabric.Canvas2dFilterBackend = Canvas2dFilterBackend;\n\n  /**\n   * Canvas 2D filter backend.\n   */\n  function Canvas2dFilterBackend() {};\n\n  Canvas2dFilterBackend.prototype = /** @lends fabric.Canvas2dFilterBackend.prototype */ {\n    evictCachesForKey: noop,\n    dispose: noop,\n    clearWebGLCaches: noop,\n\n    /**\n     * Experimental. This object is a sort of repository of help layers used to avoid\n     * of recreating them during frequent filtering. If you are previewing a filter with\n     * a slider you probably do not want to create help layers every filter step.\n     * in this object there will be appended some canvases, created once, resized sometimes\n     * cleared never. Clearing is left to the developer.\n     **/\n    resources: {\n\n    },\n\n    /**\n     * Apply a set of filters against a source image and draw the filtered output\n     * to the provided destination canvas.\n     *\n     * @param {EnhancedFilter} filters The filter to apply.\n     * @param {HTMLImageElement|HTMLCanvasElement} sourceElement The source to be filtered.\n     * @param {Number} sourceWidth The width of the source input.\n     * @param {Number} sourceHeight The height of the source input.\n     * @param {HTMLCanvasElement} targetCanvas The destination for filtered output to be drawn.\n     */\n    applyFilters: function(filters, sourceElement, sourceWidth, sourceHeight, targetCanvas) {\n      var ctx = targetCanvas.getContext('2d');\n      ctx.drawImage(sourceElement, 0, 0, sourceWidth, sourceHeight);\n      var imageData = ctx.getImageData(0, 0, sourceWidth, sourceHeight);\n      var originalImageData = ctx.getImageData(0, 0, sourceWidth, sourceHeight);\n      var pipelineState = {\n        sourceWidth: sourceWidth,\n        sourceHeight: sourceHeight,\n        imageData: imageData,\n        originalEl: sourceElement,\n        originalImageData: originalImageData,\n        canvasEl: targetCanvas,\n        ctx: ctx,\n        filterBackend: this,\n      };\n      filters.forEach(function(filter) { filter.applyTo(pipelineState); });\n      if (pipelineState.imageData.width !== sourceWidth || pipelineState.imageData.height !== sourceHeight) {\n        targetCanvas.width = pipelineState.imageData.width;\n        targetCanvas.height = pipelineState.imageData.height;\n      }\n      ctx.putImageData(pipelineState.imageData, 0, 0);\n      return pipelineState;\n    },\n\n  };\n})();\n\n\n/**\n * @namespace fabric.Image.filters\n * @memberOf fabric.Image\n * @tutorial {@link http://fabricjs.com/fabric-intro-part-2#image_filters}\n * @see {@link http://fabricjs.com/image-filters|ImageFilters demo}\n */\nfabric.Image = fabric.Image || { };\nfabric.Image.filters = fabric.Image.filters || { };\n\n/**\n * Root filter class from which all filter classes inherit from\n * @class fabric.Image.filters.BaseFilter\n * @memberOf fabric.Image.filters\n */\nfabric.Image.filters.BaseFilter = fabric.util.createClass(/** @lends fabric.Image.filters.BaseFilter.prototype */ {\n\n  /**\n   * Filter type\n   * @param {String} type\n   * @default\n   */\n  type: 'BaseFilter',\n\n  /**\n   * Array of attributes to send with buffers. do not modify\n   * @private\n   */\n\n  vertexSource: 'attribute vec2 aPosition;\\n' +\n    'varying vec2 vTexCoord;\\n' +\n    'void main() {\\n' +\n      'vTexCoord = aPosition;\\n' +\n      'gl_Position = vec4(aPosition * 2.0 - 1.0, 0.0, 1.0);\\n' +\n    '}',\n\n  fragmentSource: 'precision highp float;\\n' +\n    'varying vec2 vTexCoord;\\n' +\n    'uniform sampler2D uTexture;\\n' +\n    'void main() {\\n' +\n      'gl_FragColor = texture2D(uTexture, vTexCoord);\\n' +\n    '}',\n\n  /**\n   * Constructor\n   * @param {Object} [options] Options object\n   */\n  initialize: function(options) {\n    if (options) {\n      this.setOptions(options);\n    }\n  },\n\n  /**\n   * Sets filter's properties from options\n   * @param {Object} [options] Options object\n   */\n  setOptions: function(options) {\n    for (var prop in options) {\n      this[prop] = options[prop];\n    }\n  },\n\n  /**\n   * Compile this filter's shader program.\n   *\n   * @param {WebGLRenderingContext} gl The GL canvas context to use for shader compilation.\n   * @param {String} fragmentSource fragmentShader source for compilation\n   * @param {String} vertexSource vertexShader source for compilation\n   */\n  createProgram: function(gl, fragmentSource, vertexSource) {\n    fragmentSource = fragmentSource || this.fragmentSource;\n    vertexSource = vertexSource || this.vertexSource;\n    if (fabric.webGlPrecision !== 'highp'){\n      fragmentSource = fragmentSource.replace(\n        /precision highp float/g,\n        'precision ' + fabric.webGlPrecision + ' float'\n      );\n    }\n    var vertexShader = gl.createShader(gl.VERTEX_SHADER);\n    gl.shaderSource(vertexShader, vertexSource);\n    gl.compileShader(vertexShader);\n    if (!gl.getShaderParameter(vertexShader, gl.COMPILE_STATUS)) {\n      throw new Error(\n        // eslint-disable-next-line prefer-template\n        'Vertex shader compile error for ' + this.type + ': ' +\n        gl.getShaderInfoLog(vertexShader)\n      );\n    }\n\n    var fragmentShader = gl.createShader(gl.FRAGMENT_SHADER);\n    gl.shaderSource(fragmentShader, fragmentSource);\n    gl.compileShader(fragmentShader);\n    if (!gl.getShaderParameter(fragmentShader, gl.COMPILE_STATUS)) {\n      throw new Error(\n        // eslint-disable-next-line prefer-template\n        'Fragment shader compile error for ' + this.type + ': ' +\n        gl.getShaderInfoLog(fragmentShader)\n      );\n    }\n\n    var program = gl.createProgram();\n    gl.attachShader(program, vertexShader);\n    gl.attachShader(program, fragmentShader);\n    gl.linkProgram(program);\n    if (!gl.getProgramParameter(program, gl.LINK_STATUS)) {\n      throw new Error(\n        // eslint-disable-next-line prefer-template\n        'Shader link error for \"${this.type}\" ' +\n        gl.getProgramInfoLog(program)\n      );\n    }\n\n    var attributeLocations = this.getAttributeLocations(gl, program);\n    var uniformLocations = this.getUniformLocations(gl, program) || { };\n    uniformLocations.uStepW = gl.getUniformLocation(program, 'uStepW');\n    uniformLocations.uStepH = gl.getUniformLocation(program, 'uStepH');\n    return {\n      program: program,\n      attributeLocations: attributeLocations,\n      uniformLocations: uniformLocations\n    };\n  },\n\n  /**\n   * Return a map of attribute names to WebGLAttributeLocation objects.\n   *\n   * @param {WebGLRenderingContext} gl The canvas context used to compile the shader program.\n   * @param {WebGLShaderProgram} program The shader program from which to take attribute locations.\n   * @returns {Object} A map of attribute names to attribute locations.\n   */\n  getAttributeLocations: function(gl, program) {\n    return {\n      aPosition: gl.getAttribLocation(program, 'aPosition'),\n    };\n  },\n\n  /**\n   * Return a map of uniform names to WebGLUniformLocation objects.\n   *\n   * Intended to be overridden by subclasses.\n   *\n   * @param {WebGLRenderingContext} gl The canvas context used to compile the shader program.\n   * @param {WebGLShaderProgram} program The shader program from which to take uniform locations.\n   * @returns {Object} A map of uniform names to uniform locations.\n   */\n  getUniformLocations: function (/* gl, program */) {\n    // in case i do not need any special uniform i need to return an empty object\n    return { };\n  },\n\n  /**\n   * Send attribute data from this filter to its shader program on the GPU.\n   *\n   * @param {WebGLRenderingContext} gl The canvas context used to compile the shader program.\n   * @param {Object} attributeLocations A map of shader attribute names to their locations.\n   */\n  sendAttributeData: function(gl, attributeLocations, aPositionData) {\n    var attributeLocation = attributeLocations.aPosition;\n    var buffer = gl.createBuffer();\n    gl.bindBuffer(gl.ARRAY_BUFFER, buffer);\n    gl.enableVertexAttribArray(attributeLocation);\n    gl.vertexAttribPointer(attributeLocation, 2, gl.FLOAT, false, 0, 0);\n    gl.bufferData(gl.ARRAY_BUFFER, aPositionData, gl.STATIC_DRAW);\n  },\n\n  _setupFrameBuffer: function(options) {\n    var gl = options.context, width, height;\n    if (options.passes > 1) {\n      width = options.destinationWidth;\n      height = options.destinationHeight;\n      if (options.sourceWidth !== width || options.sourceHeight !== height) {\n        gl.deleteTexture(options.targetTexture);\n        options.targetTexture = options.filterBackend.createTexture(gl, width, height);\n      }\n      gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D,\n        options.targetTexture, 0);\n    }\n    else {\n      // draw last filter on canvas and not to framebuffer.\n      gl.bindFramebuffer(gl.FRAMEBUFFER, null);\n      gl.finish();\n    }\n  },\n\n  _swapTextures: function(options) {\n    options.passes--;\n    options.pass++;\n    var temp = options.targetTexture;\n    options.targetTexture = options.sourceTexture;\n    options.sourceTexture = temp;\n  },\n\n  /**\n   * Generic isNeutral implementation for one parameter based filters.\n   * Used only in image applyFilters to discard filters that will not have an effect\n   * on the image\n   * Other filters may need their own verison ( ColorMatrix, HueRotation, gamma, ComposedFilter )\n   * @param {Object} options\n   **/\n  isNeutralState: function(/* options */) {\n    var main = this.mainParameter,\n        _class = fabric.Image.filters[this.type].prototype;\n    if (main) {\n      if (Array.isArray(_class[main])) {\n        for (var i = _class[main].length; i--;) {\n          if (this[main][i] !== _class[main][i]) {\n            return false;\n          }\n        }\n        return true;\n      }\n      else {\n        return _class[main] === this[main];\n      }\n    }\n    else {\n      return false;\n    }\n  },\n\n  /**\n   * Apply this filter to the input image data provided.\n   *\n   * Determines whether to use WebGL or Canvas2D based on the options.webgl flag.\n   *\n   * @param {Object} options\n   * @param {Number} options.passes The number of filters remaining to be executed\n   * @param {Boolean} options.webgl Whether to use webgl to render the filter.\n   * @param {WebGLTexture} options.sourceTexture The texture setup as the source to be filtered.\n   * @param {WebGLTexture} options.targetTexture The texture where filtered output should be drawn.\n   * @param {WebGLRenderingContext} options.context The GL context used for rendering.\n   * @param {Object} options.programCache A map of compiled shader programs, keyed by filter type.\n   */\n  applyTo: function(options) {\n    if (options.webgl) {\n      this._setupFrameBuffer(options);\n      this.applyToWebGL(options);\n      this._swapTextures(options);\n    }\n    else {\n      this.applyTo2d(options);\n    }\n  },\n\n  /**\n   * Retrieves the cached shader.\n   * @param {Object} options\n   * @param {WebGLRenderingContext} options.context The GL context used for rendering.\n   * @param {Object} options.programCache A map of compiled shader programs, keyed by filter type.\n   */\n  retrieveShader: function(options) {\n    if (!options.programCache.hasOwnProperty(this.type)) {\n      options.programCache[this.type] = this.createProgram(options.context);\n    }\n    return options.programCache[this.type];\n  },\n\n  /**\n   * Apply this filter using webgl.\n   *\n   * @param {Object} options\n   * @param {Number} options.passes The number of filters remaining to be executed\n   * @param {Boolean} options.webgl Whether to use webgl to render the filter.\n   * @param {WebGLTexture} options.originalTexture The texture of the original input image.\n   * @param {WebGLTexture} options.sourceTexture The texture setup as the source to be filtered.\n   * @param {WebGLTexture} options.targetTexture The texture where filtered output should be drawn.\n   * @param {WebGLRenderingContext} options.context The GL context used for rendering.\n   * @param {Object} options.programCache A map of compiled shader programs, keyed by filter type.\n   */\n  applyToWebGL: function(options) {\n    var gl = options.context;\n    var shader = this.retrieveShader(options);\n    if (options.pass === 0 && options.originalTexture) {\n      gl.bindTexture(gl.TEXTURE_2D, options.originalTexture);\n    }\n    else {\n      gl.bindTexture(gl.TEXTURE_2D, options.sourceTexture);\n    }\n    gl.useProgram(shader.program);\n    this.sendAttributeData(gl, shader.attributeLocations, options.aPosition);\n\n    gl.uniform1f(shader.uniformLocations.uStepW, 1 / options.sourceWidth);\n    gl.uniform1f(shader.uniformLocations.uStepH, 1 / options.sourceHeight);\n\n    this.sendUniformData(gl, shader.uniformLocations);\n    gl.viewport(0, 0, options.destinationWidth, options.destinationHeight);\n    gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4);\n  },\n\n  bindAdditionalTexture: function(gl, texture, textureUnit) {\n    gl.activeTexture(textureUnit);\n    gl.bindTexture(gl.TEXTURE_2D, texture);\n    // reset active texture to 0 as usual\n    gl.activeTexture(gl.TEXTURE0);\n  },\n\n  unbindAdditionalTexture: function(gl, textureUnit) {\n    gl.activeTexture(textureUnit);\n    gl.bindTexture(gl.TEXTURE_2D, null);\n    gl.activeTexture(gl.TEXTURE0);\n  },\n\n  getMainParameter: function() {\n    return this[this.mainParameter];\n  },\n\n  setMainParameter: function(value) {\n    this[this.mainParameter] = value;\n  },\n\n  /**\n   * Send uniform data from this filter to its shader program on the GPU.\n   *\n   * Intended to be overridden by subclasses.\n   *\n   * @param {WebGLRenderingContext} gl The canvas context used to compile the shader program.\n   * @param {Object} uniformLocations A map of shader uniform names to their locations.\n   */\n  sendUniformData: function(/* gl, uniformLocations */) {\n    // Intentionally left blank.  Override me in subclasses.\n  },\n\n  /**\n   * If needed by a 2d filter, this functions can create an helper canvas to be used\n   * remember that options.targetCanvas is available for use till end of chain.\n   */\n  createHelpLayer: function(options) {\n    if (!options.helpLayer) {\n      var helpLayer = document.createElement('canvas');\n      helpLayer.width = options.sourceWidth;\n      helpLayer.height = options.sourceHeight;\n      options.helpLayer = helpLayer;\n    }\n  },\n\n  /**\n   * Returns object representation of an instance\n   * @return {Object} Object representation of an instance\n   */\n  toObject: function() {\n    var object = { type: this.type }, mainP = this.mainParameter;\n    if (mainP) {\n      object[mainP] = this[mainP];\n    }\n    return object;\n  },\n\n  /**\n   * Returns a JSON representation of an instance\n   * @return {Object} JSON\n   */\n  toJSON: function() {\n    // delegate, not alias\n    return this.toObject();\n  }\n});\n\nfabric.Image.filters.BaseFilter.fromObject = function(object, callback) {\n  var filter = new fabric.Image.filters[object.type](object);\n  callback && callback(filter);\n  return filter;\n};\n\n\n(function(global) {\n\n  'use strict';\n\n  var fabric  = global.fabric || (global.fabric = { }),\n      filters = fabric.Image.filters,\n      createClass = fabric.util.createClass;\n\n  /**\n   * Color Matrix filter class\n   * @class fabric.Image.filters.ColorMatrix\n   * @memberOf fabric.Image.filters\n   * @extends fabric.Image.filters.BaseFilter\n   * @see {@link fabric.Image.filters.ColorMatrix#initialize} for constructor definition\n   * @see {@link http://fabricjs.com/image-filters|ImageFilters demo}\n   * @see {@Link http://www.webwasp.co.uk/tutorials/219/Color_Matrix_Filter.php}\n   * @see {@Link http://phoboslab.org/log/2013/11/fast-image-filters-with-webgl}\n   * @example <caption>Kodachrome filter</caption>\n   * var filter = new fabric.Image.filters.ColorMatrix({\n   *  matrix: [\n       1.1285582396593525, -0.3967382283601348, -0.03992559172921793, 0, 63.72958762196502,\n       -0.16404339962244616, 1.0835251566291304, -0.05498805115633132, 0, 24.732407896706203,\n       -0.16786010706155763, -0.5603416277695248, 1.6014850761964943, 0, 35.62982807460946,\n       0, 0, 0, 1, 0\n      ]\n   * });\n   * object.filters.push(filter);\n   * object.applyFilters();\n   */\n  filters.ColorMatrix = createClass(filters.BaseFilter, /** @lends fabric.Image.filters.ColorMatrix.prototype */ {\n\n    /**\n     * Filter type\n     * @param {String} type\n     * @default\n     */\n    type: 'ColorMatrix',\n\n    fragmentSource: 'precision highp float;\\n' +\n      'uniform sampler2D uTexture;\\n' +\n      'varying vec2 vTexCoord;\\n' +\n      'uniform mat4 uColorMatrix;\\n' +\n      'uniform vec4 uConstants;\\n' +\n      'void main() {\\n' +\n        'vec4 color = texture2D(uTexture, vTexCoord);\\n' +\n        'color *= uColorMatrix;\\n' +\n        'color += uConstants;\\n' +\n        'gl_FragColor = color;\\n' +\n      '}',\n\n    /**\n     * Colormatrix for pixels.\n     * array of 20 floats. Numbers in positions 4, 9, 14, 19 loose meaning\n     * outside the -1, 1 range.\n     * 0.0039215686 is the part of 1 that get translated to 1 in 2d\n     * @param {Array} matrix array of 20 numbers.\n     * @default\n     */\n    matrix: [\n      1, 0, 0, 0, 0,\n      0, 1, 0, 0, 0,\n      0, 0, 1, 0, 0,\n      0, 0, 0, 1, 0\n    ],\n\n    mainParameter: 'matrix',\n\n    /**\n     * Lock the colormatrix on the color part, skipping alpha, manly for non webgl scenario\n     * to save some calculation\n     */\n    colorsOnly: true,\n\n    /**\n     * Constructor\n     * @param {Object} [options] Options object\n     */\n    initialize: function(options) {\n      this.callSuper('initialize', options);\n      // create a new array instead mutating the prototype with push\n      this.matrix = this.matrix.slice(0);\n    },\n\n    /**\n     * Apply the ColorMatrix operation to a Uint8Array representing the pixels of an image.\n     *\n     * @param {Object} options\n     * @param {ImageData} options.imageData The Uint8Array to be filtered.\n     */\n    applyTo2d: function(options) {\n      var imageData = options.imageData,\n          data = imageData.data,\n          iLen = data.length,\n          m = this.matrix,\n          r, g, b, a, i, colorsOnly = this.colorsOnly;\n\n      for (i = 0; i < iLen; i += 4) {\n        r = data[i];\n        g = data[i + 1];\n        b = data[i + 2];\n        if (colorsOnly) {\n          data[i] = r * m[0] + g * m[1] + b * m[2] + m[4] * 255;\n          data[i + 1] = r * m[5] + g * m[6] + b * m[7] + m[9] * 255;\n          data[i + 2] = r * m[10] + g * m[11] + b * m[12] + m[14] * 255;\n        }\n        else {\n          a = data[i + 3];\n          data[i] = r * m[0] + g * m[1] + b * m[2] + a * m[3] + m[4] * 255;\n          data[i + 1] = r * m[5] + g * m[6] + b * m[7] + a * m[8] + m[9] * 255;\n          data[i + 2] = r * m[10] + g * m[11] + b * m[12] + a * m[13] + m[14] * 255;\n          data[i + 3] = r * m[15] + g * m[16] + b * m[17] + a * m[18] + m[19] * 255;\n        }\n      }\n    },\n\n    /**\n     * Return WebGL uniform locations for this filter's shader.\n     *\n     * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader.\n     * @param {WebGLShaderProgram} program This filter's compiled shader program.\n     */\n    getUniformLocations: function(gl, program) {\n      return {\n        uColorMatrix: gl.getUniformLocation(program, 'uColorMatrix'),\n        uConstants: gl.getUniformLocation(program, 'uConstants'),\n      };\n    },\n\n    /**\n     * Send data from this filter to its shader program's uniforms.\n     *\n     * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader.\n     * @param {Object} uniformLocations A map of string uniform names to WebGLUniformLocation objects\n     */\n    sendUniformData: function(gl, uniformLocations) {\n      var m = this.matrix,\n          matrix = [\n            m[0], m[1], m[2], m[3],\n            m[5], m[6], m[7], m[8],\n            m[10], m[11], m[12], m[13],\n            m[15], m[16], m[17], m[18]\n          ],\n          constants = [m[4], m[9], m[14], m[19]];\n      gl.uniformMatrix4fv(uniformLocations.uColorMatrix, false, matrix);\n      gl.uniform4fv(uniformLocations.uConstants, constants);\n    },\n  });\n\n  /**\n   * Returns filter instance from an object representation\n   * @static\n   * @param {Object} object Object to create an instance from\n   * @param {function} [callback] function to invoke after filter creation\n   * @return {fabric.Image.filters.ColorMatrix} Instance of fabric.Image.filters.ColorMatrix\n   */\n  fabric.Image.filters.ColorMatrix.fromObject = fabric.Image.filters.BaseFilter.fromObject;\n})(typeof exports !== 'undefined' ? exports : this);\n\n\n(function(global) {\n\n  'use strict';\n\n  var fabric  = global.fabric || (global.fabric = { }),\n      filters = fabric.Image.filters,\n      createClass = fabric.util.createClass;\n\n  /**\n   * Brightness filter class\n   * @class fabric.Image.filters.Brightness\n   * @memberOf fabric.Image.filters\n   * @extends fabric.Image.filters.BaseFilter\n   * @see {@link fabric.Image.filters.Brightness#initialize} for constructor definition\n   * @see {@link http://fabricjs.com/image-filters|ImageFilters demo}\n   * @example\n   * var filter = new fabric.Image.filters.Brightness({\n   *   brightness: 0.05\n   * });\n   * object.filters.push(filter);\n   * object.applyFilters();\n   */\n  filters.Brightness = createClass(filters.BaseFilter, /** @lends fabric.Image.filters.Brightness.prototype */ {\n\n    /**\n     * Filter type\n     * @param {String} type\n     * @default\n     */\n    type: 'Brightness',\n\n    /**\n     * Fragment source for the brightness program\n     */\n    fragmentSource: 'precision highp float;\\n' +\n      'uniform sampler2D uTexture;\\n' +\n      'uniform float uBrightness;\\n' +\n      'varying vec2 vTexCoord;\\n' +\n      'void main() {\\n' +\n        'vec4 color = texture2D(uTexture, vTexCoord);\\n' +\n        'color.rgb += uBrightness;\\n' +\n        'gl_FragColor = color;\\n' +\n      '}',\n\n    /**\n     * Brightness value, from -1 to 1.\n     * translated to -255 to 255 for 2d\n     * 0.0039215686 is the part of 1 that get translated to 1 in 2d\n     * @param {Number} brightness\n     * @default\n     */\n    brightness: 0,\n\n    /**\n     * Describe the property that is the filter parameter\n     * @param {String} m\n     * @default\n     */\n    mainParameter: 'brightness',\n\n    /**\n    * Apply the Brightness operation to a Uint8ClampedArray representing the pixels of an image.\n    *\n    * @param {Object} options\n    * @param {ImageData} options.imageData The Uint8ClampedArray to be filtered.\n    */\n    applyTo2d: function(options) {\n      if (this.brightness === 0) {\n        return;\n      }\n      var imageData = options.imageData,\n          data = imageData.data, i, len = data.length,\n          brightness = Math.round(this.brightness * 255);\n      for (i = 0; i < len; i += 4) {\n        data[i] = data[i] + brightness;\n        data[i + 1] = data[i + 1] + brightness;\n        data[i + 2] = data[i + 2] + brightness;\n      }\n    },\n\n    /**\n     * Return WebGL uniform locations for this filter's shader.\n     *\n     * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader.\n     * @param {WebGLShaderProgram} program This filter's compiled shader program.\n     */\n    getUniformLocations: function(gl, program) {\n      return {\n        uBrightness: gl.getUniformLocation(program, 'uBrightness'),\n      };\n    },\n\n    /**\n     * Send data from this filter to its shader program's uniforms.\n     *\n     * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader.\n     * @param {Object} uniformLocations A map of string uniform names to WebGLUniformLocation objects\n     */\n    sendUniformData: function(gl, uniformLocations) {\n      gl.uniform1f(uniformLocations.uBrightness, this.brightness);\n    },\n  });\n\n  /**\n   * Returns filter instance from an object representation\n   * @static\n   * @param {Object} object Object to create an instance from\n   * @param {function} [callback] to be invoked after filter creation\n   * @return {fabric.Image.filters.Brightness} Instance of fabric.Image.filters.Brightness\n   */\n  fabric.Image.filters.Brightness.fromObject = fabric.Image.filters.BaseFilter.fromObject;\n\n})(typeof exports !== 'undefined' ? exports : this);\n\n\n(function(global) {\n\n  'use strict';\n\n  var fabric  = global.fabric || (global.fabric = { }),\n      extend = fabric.util.object.extend,\n      filters = fabric.Image.filters,\n      createClass = fabric.util.createClass;\n\n  /**\n   * Adapted from <a href=\"http://www.html5rocks.com/en/tutorials/canvas/imagefilters/\">html5rocks article</a>\n   * @class fabric.Image.filters.Convolute\n   * @memberOf fabric.Image.filters\n   * @extends fabric.Image.filters.BaseFilter\n   * @see {@link fabric.Image.filters.Convolute#initialize} for constructor definition\n   * @see {@link http://fabricjs.com/image-filters|ImageFilters demo}\n   * @example <caption>Sharpen filter</caption>\n   * var filter = new fabric.Image.filters.Convolute({\n   *   matrix: [ 0, -1,  0,\n   *            -1,  5, -1,\n   *             0, -1,  0 ]\n   * });\n   * object.filters.push(filter);\n   * object.applyFilters();\n   * canvas.renderAll();\n   * @example <caption>Blur filter</caption>\n   * var filter = new fabric.Image.filters.Convolute({\n   *   matrix: [ 1/9, 1/9, 1/9,\n   *             1/9, 1/9, 1/9,\n   *             1/9, 1/9, 1/9 ]\n   * });\n   * object.filters.push(filter);\n   * object.applyFilters();\n   * canvas.renderAll();\n   * @example <caption>Emboss filter</caption>\n   * var filter = new fabric.Image.filters.Convolute({\n   *   matrix: [ 1,   1,  1,\n   *             1, 0.7, -1,\n   *            -1,  -1, -1 ]\n   * });\n   * object.filters.push(filter);\n   * object.applyFilters();\n   * canvas.renderAll();\n   * @example <caption>Emboss filter with opaqueness</caption>\n   * var filter = new fabric.Image.filters.Convolute({\n   *   opaque: true,\n   *   matrix: [ 1,   1,  1,\n   *             1, 0.7, -1,\n   *            -1,  -1, -1 ]\n   * });\n   * object.filters.push(filter);\n   * object.applyFilters();\n   * canvas.renderAll();\n   */\n  filters.Convolute = createClass(filters.BaseFilter, /** @lends fabric.Image.filters.Convolute.prototype */ {\n\n    /**\n     * Filter type\n     * @param {String} type\n     * @default\n     */\n    type: 'Convolute',\n\n    /*\n     * Opaque value (true/false)\n     */\n    opaque: false,\n\n    /*\n     * matrix for the filter, max 9x9\n     */\n    matrix: [0, 0, 0, 0, 1, 0, 0, 0, 0],\n\n    /**\n     * Fragment source for the brightness program\n     */\n    fragmentSource: {\n      Convolute_3_1: 'precision highp float;\\n' +\n        'uniform sampler2D uTexture;\\n' +\n        'uniform float uMatrix[9];\\n' +\n        'uniform float uStepW;\\n' +\n        'uniform float uStepH;\\n' +\n        'varying vec2 vTexCoord;\\n' +\n        'void main() {\\n' +\n          'vec4 color = vec4(0, 0, 0, 0);\\n' +\n          'for (float h = 0.0; h < 3.0; h+=1.0) {\\n' +\n            'for (float w = 0.0; w < 3.0; w+=1.0) {\\n' +\n              'vec2 matrixPos = vec2(uStepW * (w - 1), uStepH * (h - 1));\\n' +\n              'color += texture2D(uTexture, vTexCoord + matrixPos) * uMatrix[int(h * 3.0 + w)];\\n' +\n            '}\\n' +\n          '}\\n' +\n          'gl_FragColor = color;\\n' +\n        '}',\n      Convolute_3_0: 'precision highp float;\\n' +\n        'uniform sampler2D uTexture;\\n' +\n        'uniform float uMatrix[9];\\n' +\n        'uniform float uStepW;\\n' +\n        'uniform float uStepH;\\n' +\n        'varying vec2 vTexCoord;\\n' +\n        'void main() {\\n' +\n          'vec4 color = vec4(0, 0, 0, 1);\\n' +\n          'for (float h = 0.0; h < 3.0; h+=1.0) {\\n' +\n            'for (float w = 0.0; w < 3.0; w+=1.0) {\\n' +\n              'vec2 matrixPos = vec2(uStepW * (w - 1.0), uStepH * (h - 1.0));\\n' +\n              'color.rgb += texture2D(uTexture, vTexCoord + matrixPos).rgb * uMatrix[int(h * 3.0 + w)];\\n' +\n            '}\\n' +\n          '}\\n' +\n          'float alpha = texture2D(uTexture, vTexCoord).a;\\n' +\n          'gl_FragColor = color;\\n' +\n          'gl_FragColor.a = alpha;\\n' +\n        '}',\n      Convolute_5_1: 'precision highp float;\\n' +\n        'uniform sampler2D uTexture;\\n' +\n        'uniform float uMatrix[25];\\n' +\n        'uniform float uStepW;\\n' +\n        'uniform float uStepH;\\n' +\n        'varying vec2 vTexCoord;\\n' +\n        'void main() {\\n' +\n          'vec4 color = vec4(0, 0, 0, 0);\\n' +\n          'for (float h = 0.0; h < 5.0; h+=1.0) {\\n' +\n            'for (float w = 0.0; w < 5.0; w+=1.0) {\\n' +\n              'vec2 matrixPos = vec2(uStepW * (w - 2.0), uStepH * (h - 2.0));\\n' +\n              'color += texture2D(uTexture, vTexCoord + matrixPos) * uMatrix[int(h * 5.0 + w)];\\n' +\n            '}\\n' +\n          '}\\n' +\n          'gl_FragColor = color;\\n' +\n        '}',\n      Convolute_5_0: 'precision highp float;\\n' +\n        'uniform sampler2D uTexture;\\n' +\n        'uniform float uMatrix[25];\\n' +\n        'uniform float uStepW;\\n' +\n        'uniform float uStepH;\\n' +\n        'varying vec2 vTexCoord;\\n' +\n        'void main() {\\n' +\n          'vec4 color = vec4(0, 0, 0, 1);\\n' +\n          'for (float h = 0.0; h < 5.0; h+=1.0) {\\n' +\n            'for (float w = 0.0; w < 5.0; w+=1.0) {\\n' +\n              'vec2 matrixPos = vec2(uStepW * (w - 2.0), uStepH * (h - 2.0));\\n' +\n              'color.rgb += texture2D(uTexture, vTexCoord + matrixPos).rgb * uMatrix[int(h * 5.0 + w)];\\n' +\n            '}\\n' +\n          '}\\n' +\n          'float alpha = texture2D(uTexture, vTexCoord).a;\\n' +\n          'gl_FragColor = color;\\n' +\n          'gl_FragColor.a = alpha;\\n' +\n        '}',\n      Convolute_7_1: 'precision highp float;\\n' +\n        'uniform sampler2D uTexture;\\n' +\n        'uniform float uMatrix[49];\\n' +\n        'uniform float uStepW;\\n' +\n        'uniform float uStepH;\\n' +\n        'varying vec2 vTexCoord;\\n' +\n        'void main() {\\n' +\n          'vec4 color = vec4(0, 0, 0, 0);\\n' +\n          'for (float h = 0.0; h < 7.0; h+=1.0) {\\n' +\n            'for (float w = 0.0; w < 7.0; w+=1.0) {\\n' +\n              'vec2 matrixPos = vec2(uStepW * (w - 3.0), uStepH * (h - 3.0));\\n' +\n              'color += texture2D(uTexture, vTexCoord + matrixPos) * uMatrix[int(h * 7.0 + w)];\\n' +\n            '}\\n' +\n          '}\\n' +\n          'gl_FragColor = color;\\n' +\n        '}',\n      Convolute_7_0: 'precision highp float;\\n' +\n        'uniform sampler2D uTexture;\\n' +\n        'uniform float uMatrix[49];\\n' +\n        'uniform float uStepW;\\n' +\n        'uniform float uStepH;\\n' +\n        'varying vec2 vTexCoord;\\n' +\n        'void main() {\\n' +\n          'vec4 color = vec4(0, 0, 0, 1);\\n' +\n          'for (float h = 0.0; h < 7.0; h+=1.0) {\\n' +\n            'for (float w = 0.0; w < 7.0; w+=1.0) {\\n' +\n              'vec2 matrixPos = vec2(uStepW * (w - 3.0), uStepH * (h - 3.0));\\n' +\n              'color.rgb += texture2D(uTexture, vTexCoord + matrixPos).rgb * uMatrix[int(h * 7.0 + w)];\\n' +\n            '}\\n' +\n          '}\\n' +\n          'float alpha = texture2D(uTexture, vTexCoord).a;\\n' +\n          'gl_FragColor = color;\\n' +\n          'gl_FragColor.a = alpha;\\n' +\n        '}',\n      Convolute_9_1: 'precision highp float;\\n' +\n        'uniform sampler2D uTexture;\\n' +\n        'uniform float uMatrix[81];\\n' +\n        'uniform float uStepW;\\n' +\n        'uniform float uStepH;\\n' +\n        'varying vec2 vTexCoord;\\n' +\n        'void main() {\\n' +\n          'vec4 color = vec4(0, 0, 0, 0);\\n' +\n          'for (float h = 0.0; h < 9.0; h+=1.0) {\\n' +\n            'for (float w = 0.0; w < 9.0; w+=1.0) {\\n' +\n              'vec2 matrixPos = vec2(uStepW * (w - 4.0), uStepH * (h - 4.0));\\n' +\n              'color += texture2D(uTexture, vTexCoord + matrixPos) * uMatrix[int(h * 9.0 + w)];\\n' +\n            '}\\n' +\n          '}\\n' +\n          'gl_FragColor = color;\\n' +\n        '}',\n      Convolute_9_0: 'precision highp float;\\n' +\n        'uniform sampler2D uTexture;\\n' +\n        'uniform float uMatrix[81];\\n' +\n        'uniform float uStepW;\\n' +\n        'uniform float uStepH;\\n' +\n        'varying vec2 vTexCoord;\\n' +\n        'void main() {\\n' +\n          'vec4 color = vec4(0, 0, 0, 1);\\n' +\n          'for (float h = 0.0; h < 9.0; h+=1.0) {\\n' +\n            'for (float w = 0.0; w < 9.0; w+=1.0) {\\n' +\n              'vec2 matrixPos = vec2(uStepW * (w - 4.0), uStepH * (h - 4.0));\\n' +\n              'color.rgb += texture2D(uTexture, vTexCoord + matrixPos).rgb * uMatrix[int(h * 9.0 + w)];\\n' +\n            '}\\n' +\n          '}\\n' +\n          'float alpha = texture2D(uTexture, vTexCoord).a;\\n' +\n          'gl_FragColor = color;\\n' +\n          'gl_FragColor.a = alpha;\\n' +\n        '}',\n    },\n\n    /**\n     * Constructor\n     * @memberOf fabric.Image.filters.Convolute.prototype\n     * @param {Object} [options] Options object\n     * @param {Boolean} [options.opaque=false] Opaque value (true/false)\n     * @param {Array} [options.matrix] Filter matrix\n     */\n\n\n    /**\n    * Retrieves the cached shader.\n    * @param {Object} options\n    * @param {WebGLRenderingContext} options.context The GL context used for rendering.\n    * @param {Object} options.programCache A map of compiled shader programs, keyed by filter type.\n    */\n    retrieveShader: function(options) {\n      var size = Math.sqrt(this.matrix.length);\n      var cacheKey = this.type + '_' + size + '_' + (this.opaque ? 1 : 0);\n      var shaderSource = this.fragmentSource[cacheKey];\n      if (!options.programCache.hasOwnProperty(cacheKey)) {\n        options.programCache[cacheKey] = this.createProgram(options.context, shaderSource);\n      }\n      return options.programCache[cacheKey];\n    },\n\n    /**\n     * Apply the Brightness operation to a Uint8ClampedArray representing the pixels of an image.\n     *\n     * @param {Object} options\n     * @param {ImageData} options.imageData The Uint8ClampedArray to be filtered.\n     */\n    applyTo2d: function(options) {\n      var imageData = options.imageData,\n          data = imageData.data,\n          weights = this.matrix,\n          side = Math.round(Math.sqrt(weights.length)),\n          halfSide = Math.floor(side / 2),\n          sw = imageData.width,\n          sh = imageData.height,\n          output = options.ctx.createImageData(sw, sh),\n          dst = output.data,\n          // go through the destination image pixels\n          alphaFac = this.opaque ? 1 : 0,\n          r, g, b, a, dstOff,\n          scx, scy, srcOff, wt,\n          x, y, cx, cy;\n\n      for (y = 0; y < sh; y++) {\n        for (x = 0; x < sw; x++) {\n          dstOff = (y * sw + x) * 4;\n          // calculate the weighed sum of the source image pixels that\n          // fall under the convolution matrix\n          r = 0; g = 0; b = 0; a = 0;\n\n          for (cy = 0; cy < side; cy++) {\n            for (cx = 0; cx < side; cx++) {\n              scy = y + cy - halfSide;\n              scx = x + cx - halfSide;\n\n              // eslint-disable-next-line max-depth\n              if (scy < 0 || scy > sh || scx < 0 || scx > sw) {\n                continue;\n              }\n\n              srcOff = (scy * sw + scx) * 4;\n              wt = weights[cy * side + cx];\n\n              r += data[srcOff] * wt;\n              g += data[srcOff + 1] * wt;\n              b += data[srcOff + 2] * wt;\n              // eslint-disable-next-line max-depth\n              if (!alphaFac) {\n                a += data[srcOff + 3] * wt;\n              }\n            }\n          }\n          dst[dstOff] = r;\n          dst[dstOff + 1] = g;\n          dst[dstOff + 2] = b;\n          if (!alphaFac) {\n            dst[dstOff + 3] = a;\n          }\n          else {\n            dst[dstOff + 3] = data[dstOff + 3];\n          }\n        }\n      }\n      options.imageData = output;\n    },\n\n    /**\n     * Return WebGL uniform locations for this filter's shader.\n     *\n     * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader.\n     * @param {WebGLShaderProgram} program This filter's compiled shader program.\n     */\n    getUniformLocations: function(gl, program) {\n      return {\n        uMatrix: gl.getUniformLocation(program, 'uMatrix'),\n        uOpaque: gl.getUniformLocation(program, 'uOpaque'),\n        uHalfSize: gl.getUniformLocation(program, 'uHalfSize'),\n        uSize: gl.getUniformLocation(program, 'uSize'),\n      };\n    },\n\n    /**\n     * Send data from this filter to its shader program's uniforms.\n     *\n     * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader.\n     * @param {Object} uniformLocations A map of string uniform names to WebGLUniformLocation objects\n     */\n    sendUniformData: function(gl, uniformLocations) {\n      gl.uniform1fv(uniformLocations.uMatrix, this.matrix);\n    },\n\n    /**\n     * Returns object representation of an instance\n     * @return {Object} Object representation of an instance\n     */\n    toObject: function() {\n      return extend(this.callSuper('toObject'), {\n        opaque: this.opaque,\n        matrix: this.matrix\n      });\n    }\n  });\n\n  /**\n   * Returns filter instance from an object representation\n   * @static\n   * @param {Object} object Object to create an instance from\n   * @param {function} [callback] to be invoked after filter creation\n   * @return {fabric.Image.filters.Convolute} Instance of fabric.Image.filters.Convolute\n   */\n  fabric.Image.filters.Convolute.fromObject = fabric.Image.filters.BaseFilter.fromObject;\n\n})(typeof exports !== 'undefined' ? exports : this);\n\n\n(function(global) {\n\n  'use strict';\n\n  var fabric  = global.fabric || (global.fabric = { }),\n      filters = fabric.Image.filters,\n      createClass = fabric.util.createClass;\n\n  /**\n   * Grayscale image filter class\n   * @class fabric.Image.filters.Grayscale\n   * @memberOf fabric.Image.filters\n   * @extends fabric.Image.filters.BaseFilter\n   * @see {@link http://fabricjs.com/image-filters|ImageFilters demo}\n   * @example\n   * var filter = new fabric.Image.filters.Grayscale();\n   * object.filters.push(filter);\n   * object.applyFilters();\n   */\n  filters.Grayscale = createClass(filters.BaseFilter, /** @lends fabric.Image.filters.Grayscale.prototype */ {\n\n    /**\n     * Filter type\n     * @param {String} type\n     * @default\n     */\n    type: 'Grayscale',\n\n    fragmentSource: {\n      average: 'precision highp float;\\n' +\n        'uniform sampler2D uTexture;\\n' +\n        'varying vec2 vTexCoord;\\n' +\n        'void main() {\\n' +\n          'vec4 color = texture2D(uTexture, vTexCoord);\\n' +\n          'float average = (color.r + color.b + color.g) / 3.0;\\n' +\n          'gl_FragColor = vec4(average, average, average, color.a);\\n' +\n        '}',\n      lightness: 'precision highp float;\\n' +\n        'uniform sampler2D uTexture;\\n' +\n        'uniform int uMode;\\n' +\n        'varying vec2 vTexCoord;\\n' +\n        'void main() {\\n' +\n          'vec4 col = texture2D(uTexture, vTexCoord);\\n' +\n          'float average = (max(max(col.r, col.g),col.b) + min(min(col.r, col.g),col.b)) / 2.0;\\n' +\n          'gl_FragColor = vec4(average, average, average, col.a);\\n' +\n        '}',\n      luminosity: 'precision highp float;\\n' +\n        'uniform sampler2D uTexture;\\n' +\n        'uniform int uMode;\\n' +\n        'varying vec2 vTexCoord;\\n' +\n        'void main() {\\n' +\n          'vec4 col = texture2D(uTexture, vTexCoord);\\n' +\n          'float average = 0.21 * col.r + 0.72 * col.g + 0.07 * col.b;\\n' +\n          'gl_FragColor = vec4(average, average, average, col.a);\\n' +\n        '}',\n    },\n\n\n    /**\n     * Grayscale mode, between 'average', 'lightness', 'luminosity'\n     * @param {String} type\n     * @default\n     */\n    mode: 'average',\n\n    mainParameter: 'mode',\n\n    /**\n     * Apply the Grayscale operation to a Uint8Array representing the pixels of an image.\n     *\n     * @param {Object} options\n     * @param {ImageData} options.imageData The Uint8Array to be filtered.\n     */\n    applyTo2d: function(options) {\n      var imageData = options.imageData,\n          data = imageData.data, i,\n          len = data.length, value,\n          mode = this.mode;\n      for (i = 0; i < len; i += 4) {\n        if (mode === 'average') {\n          value = (data[i] + data[i + 1] + data[i + 2]) / 3;\n        }\n        else if (mode === 'lightness') {\n          value = (Math.min(data[i], data[i + 1], data[i + 2]) +\n            Math.max(data[i], data[i + 1], data[i + 2])) / 2;\n        }\n        else if (mode === 'luminosity') {\n          value = 0.21 * data[i] + 0.72 * data[i + 1] + 0.07 * data[i + 2];\n        }\n        data[i] = value;\n        data[i + 1] = value;\n        data[i + 2] = value;\n      }\n    },\n\n    /**\n     * Retrieves the cached shader.\n     * @param {Object} options\n     * @param {WebGLRenderingContext} options.context The GL context used for rendering.\n     * @param {Object} options.programCache A map of compiled shader programs, keyed by filter type.\n     */\n    retrieveShader: function(options) {\n      var cacheKey = this.type + '_' + this.mode;\n      if (!options.programCache.hasOwnProperty(cacheKey)) {\n        var shaderSource = this.fragmentSource[this.mode];\n        options.programCache[cacheKey] = this.createProgram(options.context, shaderSource);\n      }\n      return options.programCache[cacheKey];\n    },\n\n    /**\n     * Return WebGL uniform locations for this filter's shader.\n     *\n     * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader.\n     * @param {WebGLShaderProgram} program This filter's compiled shader program.\n     */\n    getUniformLocations: function(gl, program) {\n      return {\n        uMode: gl.getUniformLocation(program, 'uMode'),\n      };\n    },\n\n    /**\n     * Send data from this filter to its shader program's uniforms.\n     *\n     * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader.\n     * @param {Object} uniformLocations A map of string uniform names to WebGLUniformLocation objects\n     */\n    sendUniformData: function(gl, uniformLocations) {\n      // default average mode.\n      var mode = 1;\n      gl.uniform1i(uniformLocations.uMode, mode);\n    },\n\n    /**\n     * Grayscale filter isNeutralState implementation\n     * The filter is never neutral\n     * on the image\n     **/\n    isNeutralState: function() {\n      return false;\n    },\n  });\n\n  /**\n   * Returns filter instance from an object representation\n   * @static\n   * @param {Object} object Object to create an instance from\n   * @param {function} [callback] to be invoked after filter creation\n   * @return {fabric.Image.filters.Grayscale} Instance of fabric.Image.filters.Grayscale\n   */\n  fabric.Image.filters.Grayscale.fromObject = fabric.Image.filters.BaseFilter.fromObject;\n\n})(typeof exports !== 'undefined' ? exports : this);\n\n\n(function(global) {\n\n  'use strict';\n\n  var fabric  = global.fabric || (global.fabric = { }),\n      filters = fabric.Image.filters,\n      createClass = fabric.util.createClass;\n\n  /**\n   * Invert filter class\n   * @class fabric.Image.filters.Invert\n   * @memberOf fabric.Image.filters\n   * @extends fabric.Image.filters.BaseFilter\n   * @see {@link http://fabricjs.com/image-filters|ImageFilters demo}\n   * @example\n   * var filter = new fabric.Image.filters.Invert();\n   * object.filters.push(filter);\n   * object.applyFilters(canvas.renderAll.bind(canvas));\n   */\n  filters.Invert = createClass(filters.BaseFilter, /** @lends fabric.Image.filters.Invert.prototype */ {\n\n    /**\n     * Filter type\n     * @param {String} type\n     * @default\n     */\n    type: 'Invert',\n\n    fragmentSource: 'precision highp float;\\n' +\n      'uniform sampler2D uTexture;\\n' +\n      'uniform int uInvert;\\n' +\n      'varying vec2 vTexCoord;\\n' +\n      'void main() {\\n' +\n        'vec4 color = texture2D(uTexture, vTexCoord);\\n' +\n        'if (uInvert == 1) {\\n' +\n          'gl_FragColor = vec4(1.0 - color.r,1.0 -color.g,1.0 -color.b,color.a);\\n' +\n        '} else {\\n' +\n          'gl_FragColor = color;\\n' +\n        '}\\n' +\n      '}',\n\n    /**\n     * Filter invert. if false, does nothing\n     * @param {Boolean} invert\n     * @default\n     */\n    invert: true,\n\n    mainParameter: 'invert',\n\n    /**\n     * Apply the Invert operation to a Uint8Array representing the pixels of an image.\n     *\n     * @param {Object} options\n     * @param {ImageData} options.imageData The Uint8Array to be filtered.\n     */\n    applyTo2d: function(options) {\n      var imageData = options.imageData,\n          data = imageData.data, i,\n          len = data.length;\n      for (i = 0; i < len; i += 4) {\n        data[i] = 255 - data[i];\n        data[i + 1] = 255 - data[i + 1];\n        data[i + 2] = 255 - data[i + 2];\n      }\n    },\n\n    /**\n     * Invert filter isNeutralState implementation\n     * Used only in image applyFilters to discard filters that will not have an effect\n     * on the image\n     * @param {Object} options\n     **/\n    isNeutralState: function() {\n      return !this.invert;\n    },\n\n    /**\n     * Return WebGL uniform locations for this filter's shader.\n     *\n     * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader.\n     * @param {WebGLShaderProgram} program This filter's compiled shader program.\n     */\n    getUniformLocations: function(gl, program) {\n      return {\n        uInvert: gl.getUniformLocation(program, 'uInvert'),\n      };\n    },\n\n    /**\n     * Send data from this filter to its shader program's uniforms.\n     *\n     * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader.\n     * @param {Object} uniformLocations A map of string uniform names to WebGLUniformLocation objects\n     */\n    sendUniformData: function(gl, uniformLocations) {\n      gl.uniform1i(uniformLocations.uInvert, this.invert);\n    },\n  });\n\n  /**\n   * Returns filter instance from an object representation\n   * @static\n   * @param {Object} object Object to create an instance from\n   * @param {function} [callback] to be invoked after filter creation\n   * @return {fabric.Image.filters.Invert} Instance of fabric.Image.filters.Invert\n   */\n  fabric.Image.filters.Invert.fromObject = fabric.Image.filters.BaseFilter.fromObject;\n\n\n})(typeof exports !== 'undefined' ? exports : this);\n\n\n(function(global) {\n\n  'use strict';\n\n  var fabric  = global.fabric || (global.fabric = { }),\n      extend = fabric.util.object.extend,\n      filters = fabric.Image.filters,\n      createClass = fabric.util.createClass;\n\n  /**\n   * Noise filter class\n   * @class fabric.Image.filters.Noise\n   * @memberOf fabric.Image.filters\n   * @extends fabric.Image.filters.BaseFilter\n   * @see {@link fabric.Image.filters.Noise#initialize} for constructor definition\n   * @see {@link http://fabricjs.com/image-filters|ImageFilters demo}\n   * @example\n   * var filter = new fabric.Image.filters.Noise({\n   *   noise: 700\n   * });\n   * object.filters.push(filter);\n   * object.applyFilters();\n   * canvas.renderAll();\n   */\n  filters.Noise = createClass(filters.BaseFilter, /** @lends fabric.Image.filters.Noise.prototype */ {\n\n    /**\n     * Filter type\n     * @param {String} type\n     * @default\n     */\n    type: 'Noise',\n\n    /**\n     * Fragment source for the noise program\n     */\n    fragmentSource: 'precision highp float;\\n' +\n      'uniform sampler2D uTexture;\\n' +\n      'uniform float uStepH;\\n' +\n      'uniform float uNoise;\\n' +\n      'uniform float uSeed;\\n' +\n      'varying vec2 vTexCoord;\\n' +\n      'float rand(vec2 co, float seed, float vScale) {\\n' +\n        'return fract(sin(dot(co.xy * vScale ,vec2(12.9898 , 78.233))) * 43758.5453 * (seed + 0.01) / 2.0);\\n' +\n      '}\\n' +\n      'void main() {\\n' +\n        'vec4 color = texture2D(uTexture, vTexCoord);\\n' +\n        'color.rgb += (0.5 - rand(vTexCoord, uSeed, 0.1 / uStepH)) * uNoise;\\n' +\n        'gl_FragColor = color;\\n' +\n      '}',\n\n    /**\n     * Describe the property that is the filter parameter\n     * @param {String} m\n     * @default\n     */\n    mainParameter: 'noise',\n\n    /**\n     * Noise value, from\n     * @param {Number} noise\n     * @default\n     */\n    noise: 0,\n\n    /**\n     * Apply the Brightness operation to a Uint8ClampedArray representing the pixels of an image.\n     *\n     * @param {Object} options\n     * @param {ImageData} options.imageData The Uint8ClampedArray to be filtered.\n     */\n    applyTo2d: function(options) {\n      if (this.noise === 0) {\n        return;\n      }\n      var imageData = options.imageData,\n          data = imageData.data, i, len = data.length,\n          noise = this.noise, rand;\n\n      for (i = 0, len = data.length; i < len; i += 4) {\n\n        rand = (0.5 - Math.random()) * noise;\n\n        data[i] += rand;\n        data[i + 1] += rand;\n        data[i + 2] += rand;\n      }\n    },\n\n    /**\n     * Return WebGL uniform locations for this filter's shader.\n     *\n     * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader.\n     * @param {WebGLShaderProgram} program This filter's compiled shader program.\n     */\n    getUniformLocations: function(gl, program) {\n      return {\n        uNoise: gl.getUniformLocation(program, 'uNoise'),\n        uSeed: gl.getUniformLocation(program, 'uSeed'),\n      };\n    },\n\n    /**\n     * Send data from this filter to its shader program's uniforms.\n     *\n     * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader.\n     * @param {Object} uniformLocations A map of string uniform names to WebGLUniformLocation objects\n     */\n    sendUniformData: function(gl, uniformLocations) {\n      gl.uniform1f(uniformLocations.uNoise, this.noise / 255);\n      gl.uniform1f(uniformLocations.uSeed, Math.random());\n    },\n\n    /**\n     * Returns object representation of an instance\n     * @return {Object} Object representation of an instance\n     */\n    toObject: function() {\n      return extend(this.callSuper('toObject'), {\n        noise: this.noise\n      });\n    }\n  });\n\n  /**\n   * Returns filter instance from an object representation\n   * @static\n   * @param {Object} object Object to create an instance from\n   * @param {Function} [callback] to be invoked after filter creation\n   * @return {fabric.Image.filters.Noise} Instance of fabric.Image.filters.Noise\n   */\n  fabric.Image.filters.Noise.fromObject = fabric.Image.filters.BaseFilter.fromObject;\n\n})(typeof exports !== 'undefined' ? exports : this);\n\n\n(function(global) {\n\n  'use strict';\n\n  var fabric  = global.fabric || (global.fabric = { }),\n      filters = fabric.Image.filters,\n      createClass = fabric.util.createClass;\n\n  /**\n   * Pixelate filter class\n   * @class fabric.Image.filters.Pixelate\n   * @memberOf fabric.Image.filters\n   * @extends fabric.Image.filters.BaseFilter\n   * @see {@link fabric.Image.filters.Pixelate#initialize} for constructor definition\n   * @see {@link http://fabricjs.com/image-filters|ImageFilters demo}\n   * @example\n   * var filter = new fabric.Image.filters.Pixelate({\n   *   blocksize: 8\n   * });\n   * object.filters.push(filter);\n   * object.applyFilters();\n   */\n  filters.Pixelate = createClass(filters.BaseFilter, /** @lends fabric.Image.filters.Pixelate.prototype */ {\n\n    /**\n     * Filter type\n     * @param {String} type\n     * @default\n     */\n    type: 'Pixelate',\n\n    blocksize: 4,\n\n    mainParameter: 'blocksize',\n\n    /**\n     * Fragment source for the Pixelate program\n     */\n    fragmentSource: 'precision highp float;\\n' +\n      'uniform sampler2D uTexture;\\n' +\n      'uniform float uBlocksize;\\n' +\n      'uniform float uStepW;\\n' +\n      'uniform float uStepH;\\n' +\n      'varying vec2 vTexCoord;\\n' +\n      'void main() {\\n' +\n        'float blockW = uBlocksize * uStepW;\\n' +\n        'float blockH = uBlocksize * uStepW;\\n' +\n        'int posX = int(vTexCoord.x / blockW);\\n' +\n        'int posY = int(vTexCoord.y / blockH);\\n' +\n        'float fposX = float(posX);\\n' +\n        'float fposY = float(posY);\\n' +\n        'vec2 squareCoords = vec2(fposX * blockW, fposY * blockH);\\n' +\n        'vec4 color = texture2D(uTexture, squareCoords);\\n' +\n        'gl_FragColor = color;\\n' +\n      '}',\n\n    /**\n     * Apply the Pixelate operation to a Uint8ClampedArray representing the pixels of an image.\n     *\n     * @param {Object} options\n     * @param {ImageData} options.imageData The Uint8ClampedArray to be filtered.\n     */\n    applyTo2d: function(options) {\n      var imageData = options.imageData,\n          data = imageData.data,\n          iLen = imageData.height,\n          jLen = imageData.width,\n          index, i, j, r, g, b, a,\n          _i, _j, _iLen, _jLen;\n\n      for (i = 0; i < iLen; i += this.blocksize) {\n        for (j = 0; j < jLen; j += this.blocksize) {\n\n          index = (i * 4) * jLen + (j * 4);\n\n          r = data[index];\n          g = data[index + 1];\n          b = data[index + 2];\n          a = data[index + 3];\n\n          _iLen = Math.min(i + this.blocksize, iLen);\n          _jLen = Math.min(j + this.blocksize, jLen);\n          for (_i = i; _i < _iLen; _i++) {\n            for (_j = j; _j < _jLen; _j++) {\n              index = (_i * 4) * jLen + (_j * 4);\n              data[index] = r;\n              data[index + 1] = g;\n              data[index + 2] = b;\n              data[index + 3] = a;\n            }\n          }\n        }\n      }\n    },\n\n    /**\n     * Indicate when the filter is not gonna apply changes to the image\n     **/\n    isNeutralState: function() {\n      return this.blocksize === 1;\n    },\n\n    /**\n     * Return WebGL uniform locations for this filter's shader.\n     *\n     * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader.\n     * @param {WebGLShaderProgram} program This filter's compiled shader program.\n     */\n    getUniformLocations: function(gl, program) {\n      return {\n        uBlocksize: gl.getUniformLocation(program, 'uBlocksize'),\n        uStepW: gl.getUniformLocation(program, 'uStepW'),\n        uStepH: gl.getUniformLocation(program, 'uStepH'),\n      };\n    },\n\n    /**\n     * Send data from this filter to its shader program's uniforms.\n     *\n     * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader.\n     * @param {Object} uniformLocations A map of string uniform names to WebGLUniformLocation objects\n     */\n    sendUniformData: function(gl, uniformLocations) {\n      gl.uniform1f(uniformLocations.uBlocksize, this.blocksize);\n    },\n  });\n\n  /**\n   * Returns filter instance from an object representation\n   * @static\n   * @param {Object} object Object to create an instance from\n   * @param {Function} [callback] to be invoked after filter creation\n   * @return {fabric.Image.filters.Pixelate} Instance of fabric.Image.filters.Pixelate\n   */\n  fabric.Image.filters.Pixelate.fromObject = fabric.Image.filters.BaseFilter.fromObject;\n\n})(typeof exports !== 'undefined' ? exports : this);\n\n\n(function(global) {\n\n  'use strict';\n\n  var fabric  = global.fabric || (global.fabric = { }),\n      extend = fabric.util.object.extend,\n      filters = fabric.Image.filters,\n      createClass = fabric.util.createClass;\n\n  /**\n   * Remove white filter class\n   * @class fabric.Image.filters.RemoveColor\n   * @memberOf fabric.Image.filters\n   * @extends fabric.Image.filters.BaseFilter\n   * @see {@link fabric.Image.filters.RemoveColor#initialize} for constructor definition\n   * @see {@link http://fabricjs.com/image-filters|ImageFilters demo}\n   * @example\n   * var filter = new fabric.Image.filters.RemoveColor({\n   *   threshold: 0.2,\n   * });\n   * object.filters.push(filter);\n   * object.applyFilters();\n   * canvas.renderAll();\n   */\n  filters.RemoveColor = createClass(filters.BaseFilter, /** @lends fabric.Image.filters.RemoveColor.prototype */ {\n\n    /**\n     * Filter type\n     * @param {String} type\n     * @default\n     */\n    type: 'RemoveColor',\n\n    /**\n     * Color to remove, in any format understood by fabric.Color.\n     * @param {String} type\n     * @default\n     */\n    color: '#FFFFFF',\n\n    /**\n     * Fragment source for the brightness program\n     */\n    fragmentSource: 'precision highp float;\\n' +\n      'uniform sampler2D uTexture;\\n' +\n      'uniform vec4 uLow;\\n' +\n      'uniform vec4 uHigh;\\n' +\n      'varying vec2 vTexCoord;\\n' +\n      'void main() {\\n' +\n        'gl_FragColor = texture2D(uTexture, vTexCoord);\\n' +\n        'if(all(greaterThan(gl_FragColor.rgb,uLow.rgb)) && all(greaterThan(uHigh.rgb,gl_FragColor.rgb))) {\\n' +\n          'gl_FragColor.a = 0.0;\\n' +\n        '}\\n' +\n      '}',\n\n    /**\n     * distance to actual color, as value up or down from each r,g,b\n     * between 0 and 1\n     **/\n    distance: 0.02,\n\n    /**\n     * For color to remove inside distance, use alpha channel for a smoother deletion\n     * NOT IMPLEMENTED YET\n     **/\n    useAlpha: false,\n\n    /**\n     * Constructor\n     * @memberOf fabric.Image.filters.RemoveWhite.prototype\n     * @param {Object} [options] Options object\n     * @param {Number} [options.color=#RRGGBB] Threshold value\n     * @param {Number} [options.distance=10] Distance value\n     */\n\n    /**\n     * Applies filter to canvas element\n     * @param {Object} canvasEl Canvas element to apply filter to\n     */\n    applyTo2d: function(options) {\n      var imageData = options.imageData,\n          data = imageData.data, i,\n          distance = this.distance * 255,\n          r, g, b,\n          source = new fabric.Color(this.color).getSource(),\n          lowC = [\n            source[0] - distance,\n            source[1] - distance,\n            source[2] - distance,\n          ],\n          highC = [\n            source[0] + distance,\n            source[1] + distance,\n            source[2] + distance,\n          ];\n\n\n      for (i = 0; i < data.length; i += 4) {\n        r = data[i];\n        g = data[i + 1];\n        b = data[i + 2];\n\n        if (r > lowC[0] &&\n            g > lowC[1] &&\n            b > lowC[2] &&\n            r < highC[0] &&\n            g < highC[1] &&\n            b < highC[2]) {\n          data[i + 3] = 0;\n        }\n      }\n    },\n\n    /**\n     * Return WebGL uniform locations for this filter's shader.\n     *\n     * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader.\n     * @param {WebGLShaderProgram} program This filter's compiled shader program.\n     */\n    getUniformLocations: function(gl, program) {\n      return {\n        uLow: gl.getUniformLocation(program, 'uLow'),\n        uHigh: gl.getUniformLocation(program, 'uHigh'),\n      };\n    },\n\n    /**\n     * Send data from this filter to its shader program's uniforms.\n     *\n     * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader.\n     * @param {Object} uniformLocations A map of string uniform names to WebGLUniformLocation objects\n     */\n    sendUniformData: function(gl, uniformLocations) {\n      var source = new fabric.Color(this.color).getSource(),\n          distance = parseFloat(this.distance),\n          lowC = [\n            0 + source[0] / 255 - distance,\n            0 + source[1] / 255 - distance,\n            0 + source[2] / 255 - distance,\n            1\n          ],\n          highC = [\n            source[0] / 255 + distance,\n            source[1] / 255 + distance,\n            source[2] / 255 + distance,\n            1\n          ];\n      gl.uniform4fv(uniformLocations.uLow, lowC);\n      gl.uniform4fv(uniformLocations.uHigh, highC);\n    },\n\n    /**\n     * Returns object representation of an instance\n     * @return {Object} Object representation of an instance\n     */\n    toObject: function() {\n      return extend(this.callSuper('toObject'), {\n        color: this.color,\n        distance: this.distance\n      });\n    }\n  });\n\n  /**\n   * Returns filter instance from an object representation\n   * @static\n   * @param {Object} object Object to create an instance from\n   * @param {Function} [callback] to be invoked after filter creation\n   * @return {fabric.Image.filters.RemoveColor} Instance of fabric.Image.filters.RemoveWhite\n   */\n  fabric.Image.filters.RemoveColor.fromObject = fabric.Image.filters.BaseFilter.fromObject;\n\n})(typeof exports !== 'undefined' ? exports : this);\n\n\n(function(global) {\n\n  'use strict';\n\n  var fabric  = global.fabric || (global.fabric = { }),\n      filters = fabric.Image.filters,\n      createClass = fabric.util.createClass;\n\n  var matrices = {\n    Brownie: [\n      0.59970,0.34553,-0.27082,0,0.186,\n      -0.03770,0.86095,0.15059,0,-0.1449,\n      0.24113,-0.07441,0.44972,0,-0.02965,\n      0,0,0,1,0\n    ],\n    Vintage: [\n      0.62793,0.32021,-0.03965,0,0.03784,\n      0.02578,0.64411,0.03259,0,0.02926,\n      0.04660,-0.08512,0.52416,0,0.02023,\n      0,0,0,1,0\n    ],\n    Kodachrome: [\n      1.12855,-0.39673,-0.03992,0,0.24991,\n      -0.16404,1.08352,-0.05498,0,0.09698,\n      -0.16786,-0.56034,1.60148,0,0.13972,\n      0,0,0,1,0\n    ],\n    Technicolor: [\n      1.91252,-0.85453,-0.09155,0,0.04624,\n      -0.30878,1.76589,-0.10601,0,-0.27589,\n      -0.23110,-0.75018,1.84759,0,0.12137,\n      0,0,0,1,0\n    ],\n    Polaroid: [\n      1.438,-0.062,-0.062,0,0,\n      -0.122,1.378,-0.122,0,0,\n      -0.016,-0.016,1.483,0,0,\n      0,0,0,1,0\n    ],\n    Sepia: [\n      0.393, 0.769, 0.189, 0, 0,\n      0.349, 0.686, 0.168, 0, 0,\n      0.272, 0.534, 0.131, 0, 0,\n      0, 0, 0, 1, 0\n    ],\n    BlackWhite: [\n      1.5, 1.5, 1.5, 0, -1,\n      1.5, 1.5, 1.5, 0, -1,\n      1.5, 1.5, 1.5, 0, -1,\n      0, 0, 0, 1, 0,\n    ]\n  };\n\n  for (var key in matrices) {\n    filters[key] = createClass(filters.ColorMatrix, /** @lends fabric.Image.filters.Sepia.prototype */ {\n\n      /**\n       * Filter type\n       * @param {String} type\n       * @default\n       */\n      type: key,\n\n      /**\n       * Colormatrix for the effect\n       * array of 20 floats. Numbers in positions 4, 9, 14, 19 loose meaning\n       * outside the -1, 1 range.\n       * @param {Array} matrix array of 20 numbers.\n       * @default\n       */\n      matrix: matrices[key],\n\n      /**\n       * Lock the matrix export for this kind of static, parameter less filters.\n       */\n      mainParameter: false,\n      /**\n       * Lock the colormatrix on the color part, skipping alpha\n       */\n      colorsOnly: true,\n\n    });\n    fabric.Image.filters[key].fromObject = fabric.Image.filters.BaseFilter.fromObject;\n  }\n})(typeof exports !== 'undefined' ? exports : this);\n\n\n(function(global) {\n  'use strict';\n\n  var fabric = global.fabric,\n      filters = fabric.Image.filters,\n      createClass = fabric.util.createClass;\n\n  /**\n   * Color Blend filter class\n   * @class fabric.Image.filter.BlendColor\n   * @memberOf fabric.Image.filters\n   * @extends fabric.Image.filters.BaseFilter\n   * @example\n   * var filter = new fabric.Image.filters.BlendColor({\n   *  color: '#000',\n   *  mode: 'multiply'\n   * });\n   *\n   * var filter = new fabric.Image.filters.BlendImage({\n   *  image: fabricImageObject,\n   *  mode: 'multiply',\n   *  alpha: 0.5\n   * });\n   * object.filters.push(filter);\n   * object.applyFilters();\n   * canvas.renderAll();\n   */\n\n  filters.BlendColor = createClass(filters.BaseFilter, /** @lends fabric.Image.filters.Blend.prototype */ {\n    type: 'BlendColor',\n\n    /**\n     * Color to make the blend operation with. default to a reddish color since black or white\n     * gives always strong result.\n     **/\n    color: '#F95C63',\n\n    /**\n     * Blend mode for the filter: one of multiply, add, diff, screen, subtract,\n     * darken, lighten, overlay, exclusion, tint.\n     **/\n    mode: 'multiply',\n\n    /**\n     * alpha value. represent the strength of the blend color operation.\n     **/\n    alpha: 1,\n\n    /**\n     * Fragment source for the Multiply program\n     */\n    fragmentSource: {\n      multiply: 'gl_FragColor.rgb *= uColor.rgb;\\n',\n      screen: 'gl_FragColor.rgb = 1.0 - (1.0 - gl_FragColor.rgb) * (1.0 - uColor.rgb);\\n',\n      add: 'gl_FragColor.rgb += uColor.rgb;\\n',\n      diff: 'gl_FragColor.rgb = abs(gl_FragColor.rgb - uColor.rgb);\\n',\n      subtract: 'gl_FragColor.rgb -= uColor.rgb;\\n',\n      lighten: 'gl_FragColor.rgb = max(gl_FragColor.rgb, uColor.rgb);\\n',\n      darken: 'gl_FragColor.rgb = min(gl_FragColor.rgb, uColor.rgb);\\n',\n      exclusion: 'gl_FragColor.rgb += uColor.rgb - 2.0 * (uColor.rgb * gl_FragColor.rgb);\\n',\n      overlay: 'if (uColor.r < 0.5) {\\n' +\n          'gl_FragColor.r *= 2.0 * uColor.r;\\n' +\n        '} else {\\n' +\n          'gl_FragColor.r = 1.0 - 2.0 * (1.0 - gl_FragColor.r) * (1.0 - uColor.r);\\n' +\n        '}\\n' +\n        'if (uColor.g < 0.5) {\\n' +\n          'gl_FragColor.g *= 2.0 * uColor.g;\\n' +\n        '} else {\\n' +\n          'gl_FragColor.g = 1.0 - 2.0 * (1.0 - gl_FragColor.g) * (1.0 - uColor.g);\\n' +\n        '}\\n' +\n        'if (uColor.b < 0.5) {\\n' +\n          'gl_FragColor.b *= 2.0 * uColor.b;\\n' +\n        '} else {\\n' +\n          'gl_FragColor.b = 1.0 - 2.0 * (1.0 - gl_FragColor.b) * (1.0 - uColor.b);\\n' +\n        '}\\n',\n      tint: 'gl_FragColor.rgb *= (1.0 - uColor.a);\\n' +\n        'gl_FragColor.rgb += uColor.rgb;\\n',\n    },\n\n    /**\n     * build the fragment source for the filters, joining the common part with\n     * the specific one.\n     * @param {String} mode the mode of the filter, a key of this.fragmentSource\n     * @return {String} the source to be compiled\n     * @private\n     */\n    buildSource: function(mode) {\n      return 'precision highp float;\\n' +\n        'uniform sampler2D uTexture;\\n' +\n        'uniform vec4 uColor;\\n' +\n        'varying vec2 vTexCoord;\\n' +\n        'void main() {\\n' +\n          'vec4 color = texture2D(uTexture, vTexCoord);\\n' +\n          'gl_FragColor = color;\\n' +\n          'if (color.a > 0.0) {\\n' +\n            this.fragmentSource[mode] +\n          '}\\n' +\n        '}';\n    },\n\n    /**\n     * Retrieves the cached shader.\n     * @param {Object} options\n     * @param {WebGLRenderingContext} options.context The GL context used for rendering.\n     * @param {Object} options.programCache A map of compiled shader programs, keyed by filter type.\n     */\n    retrieveShader: function(options) {\n      var cacheKey = this.type + '_' + this.mode, shaderSource;\n      if (!options.programCache.hasOwnProperty(cacheKey)) {\n        shaderSource = this.buildSource(this.mode);\n        options.programCache[cacheKey] = this.createProgram(options.context, shaderSource);\n      }\n      return options.programCache[cacheKey];\n    },\n\n    /**\n     * Apply the Blend operation to a Uint8ClampedArray representing the pixels of an image.\n     *\n     * @param {Object} options\n     * @param {ImageData} options.imageData The Uint8ClampedArray to be filtered.\n     */\n    applyTo2d: function(options) {\n      var imageData = options.imageData,\n          data = imageData.data, iLen = data.length,\n          tr, tg, tb,\n          r, g, b,\n          source, alpha1 = 1 - this.alpha;\n\n      source = new fabric.Color(this.color).getSource();\n      tr = source[0] * this.alpha;\n      tg = source[1] * this.alpha;\n      tb = source[2] * this.alpha;\n\n      for (var i = 0; i < iLen; i += 4) {\n\n        r = data[i];\n        g = data[i + 1];\n        b = data[i + 2];\n\n        switch (this.mode) {\n          case 'multiply':\n            data[i] = r * tr / 255;\n            data[i + 1] = g * tg / 255;\n            data[i + 2] = b * tb / 255;\n            break;\n          case 'screen':\n            data[i] = 255 - (255 - r) * (255 - tr) / 255;\n            data[i + 1] = 255 - (255 - g) * (255 - tg) / 255;\n            data[i + 2] = 255 - (255 - b) * (255 - tb) / 255;\n            break;\n          case 'add':\n            data[i] = r + tr;\n            data[i + 1] = g + tg;\n            data[i + 2] = b + tb;\n            break;\n          case 'diff':\n          case 'difference':\n            data[i] = Math.abs(r - tr);\n            data[i + 1] = Math.abs(g - tg);\n            data[i + 2] = Math.abs(b - tb);\n            break;\n          case 'subtract':\n            data[i] = r - tr;\n            data[i + 1] = g - tg;\n            data[i + 2] = b - tb;\n            break;\n          case 'darken':\n            data[i] = Math.min(r, tr);\n            data[i + 1] = Math.min(g, tg);\n            data[i + 2] = Math.min(b, tb);\n            break;\n          case 'lighten':\n            data[i] = Math.max(r, tr);\n            data[i + 1] = Math.max(g, tg);\n            data[i + 2] = Math.max(b, tb);\n            break;\n          case 'overlay':\n            data[i] = tr < 128 ? (2 * r * tr / 255) : (255 - 2 * (255 - r) * (255 - tr) / 255);\n            data[i + 1] = tg < 128 ? (2 * g * tg / 255) : (255 - 2 * (255 - g) * (255 - tg) / 255);\n            data[i + 2] = tb < 128 ? (2 * b * tb / 255) : (255 - 2 * (255 - b) * (255 - tb) / 255);\n            break;\n          case 'exclusion':\n            data[i] = tr + r - ((2 * tr * r) / 255);\n            data[i + 1] = tg + g - ((2 * tg * g) / 255);\n            data[i + 2] = tb + b - ((2 * tb * b) / 255);\n            break;\n          case 'tint':\n            data[i] = tr + r * alpha1;\n            data[i + 1] = tg + g * alpha1;\n            data[i + 2] = tb + b * alpha1;\n        }\n      }\n    },\n\n    /**\n     * Return WebGL uniform locations for this filter's shader.\n     *\n     * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader.\n     * @param {WebGLShaderProgram} program This filter's compiled shader program.\n     */\n    getUniformLocations: function(gl, program) {\n      return {\n        uColor: gl.getUniformLocation(program, 'uColor'),\n      };\n    },\n\n    /**\n     * Send data from this filter to its shader program's uniforms.\n     *\n     * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader.\n     * @param {Object} uniformLocations A map of string uniform names to WebGLUniformLocation objects\n     */\n    sendUniformData: function(gl, uniformLocations) {\n      var source = new fabric.Color(this.color).getSource();\n      source[0] = this.alpha * source[0] / 255;\n      source[1] = this.alpha * source[1] / 255;\n      source[2] = this.alpha * source[2] / 255;\n      source[3] = this.alpha;\n      gl.uniform4fv(uniformLocations.uColor, source);\n    },\n\n    /**\n     * Returns object representation of an instance\n     * @return {Object} Object representation of an instance\n     */\n    toObject: function() {\n      return {\n        type: this.type,\n        color: this.color,\n        mode: this.mode,\n        alpha: this.alpha\n      };\n    }\n  });\n\n  /**\n   * Returns filter instance from an object representation\n   * @static\n   * @param {Object} object Object to create an instance from\n   * @param {function} [callback] to be invoked after filter creation\n   * @return {fabric.Image.filters.BlendColor} Instance of fabric.Image.filters.BlendColor\n   */\n  fabric.Image.filters.BlendColor.fromObject = fabric.Image.filters.BaseFilter.fromObject;\n\n})(typeof exports !== 'undefined' ? exports : this);\n\n\n(function(global) {\n  'use strict';\n\n  var fabric = global.fabric,\n      filters = fabric.Image.filters,\n      createClass = fabric.util.createClass;\n\n  /**\n   * Image Blend filter class\n   * @class fabric.Image.filter.BlendImage\n   * @memberOf fabric.Image.filters\n   * @extends fabric.Image.filters.BaseFilter\n   * @example\n   * var filter = new fabric.Image.filters.BlendColor({\n   *  color: '#000',\n   *  mode: 'multiply'\n   * });\n   *\n   * var filter = new fabric.Image.filters.BlendImage({\n   *  image: fabricImageObject,\n   *  mode: 'multiply',\n   *  alpha: 0.5\n   * });\n   * object.filters.push(filter);\n   * object.applyFilters();\n   * canvas.renderAll();\n   */\n\n  filters.BlendImage = createClass(filters.BaseFilter, /** @lends fabric.Image.filters.BlendImage.prototype */ {\n    type: 'BlendImage',\n\n    /**\n     * Color to make the blend operation with. default to a reddish color since black or white\n     * gives always strong result.\n     **/\n    image: null,\n\n    /**\n     * Blend mode for the filter: one of multiply, add, diff, screen, subtract,\n     * darken, lighten, overlay, exclusion, tint.\n     **/\n    mode: 'multiply',\n\n    /**\n     * alpha value. represent the strength of the blend image operation.\n     * not implemented.\n     **/\n    alpha: 1,\n\n    vertexSource: 'attribute vec2 aPosition;\\n' +\n      'varying vec2 vTexCoord;\\n' +\n      'varying vec2 vTexCoord2;\\n' +\n      'uniform mat3 uTransformMatrix;\\n' +\n      'void main() {\\n' +\n        'vTexCoord = aPosition;\\n' +\n        'vTexCoord2 = (uTransformMatrix * vec3(aPosition, 1.0)).xy;\\n' +\n        'gl_Position = vec4(aPosition * 2.0 - 1.0, 0.0, 1.0);\\n' +\n      '}',\n\n    /**\n     * Fragment source for the Multiply program\n     */\n    fragmentSource: {\n      multiply: 'precision highp float;\\n' +\n        'uniform sampler2D uTexture;\\n' +\n        'uniform sampler2D uImage;\\n' +\n        'uniform vec4 uColor;\\n' +\n        'varying vec2 vTexCoord;\\n' +\n        'varying vec2 vTexCoord2;\\n' +\n        'void main() {\\n' +\n          'vec4 color = texture2D(uTexture, vTexCoord);\\n' +\n          'vec4 color2 = texture2D(uImage, vTexCoord2);\\n' +\n          'color.rgba *= color2.rgba;\\n' +\n          'gl_FragColor = color;\\n' +\n        '}',\n      mask: 'precision highp float;\\n' +\n        'uniform sampler2D uTexture;\\n' +\n        'uniform sampler2D uImage;\\n' +\n        'uniform vec4 uColor;\\n' +\n        'varying vec2 vTexCoord;\\n' +\n        'varying vec2 vTexCoord2;\\n' +\n        'void main() {\\n' +\n          'vec4 color = texture2D(uTexture, vTexCoord);\\n' +\n          'vec4 color2 = texture2D(uImage, vTexCoord2);\\n' +\n          'color.a = color2.a;\\n' +\n          'gl_FragColor = color;\\n' +\n        '}',\n    },\n\n    /**\n     * Retrieves the cached shader.\n     * @param {Object} options\n     * @param {WebGLRenderingContext} options.context The GL context used for rendering.\n     * @param {Object} options.programCache A map of compiled shader programs, keyed by filter type.\n     */\n    retrieveShader: function(options) {\n      var cacheKey = this.type + '_' + this.mode;\n      var shaderSource = this.fragmentSource[this.mode];\n      if (!options.programCache.hasOwnProperty(cacheKey)) {\n        options.programCache[cacheKey] = this.createProgram(options.context, shaderSource);\n      }\n      return options.programCache[cacheKey];\n    },\n\n    applyToWebGL: function(options) {\n      // load texture to blend.\n      var gl = options.context,\n          texture = this.createTexture(options.filterBackend, this.image);\n      this.bindAdditionalTexture(gl, texture, gl.TEXTURE1);\n      this.callSuper('applyToWebGL', options);\n      this.unbindAdditionalTexture(gl, gl.TEXTURE1);\n    },\n\n    createTexture: function(backend, image) {\n      return backend.getCachedTexture(image.cacheKey, image._element);\n    },\n\n    /**\n     * Calculate a transformMatrix to adapt the image to blend over\n     * @param {Object} options\n     * @param {WebGLRenderingContext} options.context The GL context used for rendering.\n     * @param {Object} options.programCache A map of compiled shader programs, keyed by filter type.\n     */\n    calculateMatrix: function() {\n      var image = this.image,\n          width = image._element.width,\n          height = image._element.height;\n      return [\n        1 / image.scaleX, 0, 0,\n        0, 1 / image.scaleY, 0,\n        -image.left / width, -image.top / height, 1\n      ];\n    },\n\n    /**\n     * Apply the Blend operation to a Uint8ClampedArray representing the pixels of an image.\n     *\n     * @param {Object} options\n     * @param {ImageData} options.imageData The Uint8ClampedArray to be filtered.\n     */\n    applyTo2d: function(options) {\n      var imageData = options.imageData,\n          resources = options.filterBackend.resources,\n          data = imageData.data, iLen = data.length,\n          width = imageData.width,\n          height = imageData.height,\n          tr, tg, tb, ta,\n          r, g, b, a,\n          canvas1, context, image = this.image, blendData;\n\n      if (!resources.blendImage) {\n        resources.blendImage = fabric.util.createCanvasElement();\n      }\n      canvas1 = resources.blendImage;\n      context = canvas1.getContext('2d');\n      if (canvas1.width !== width || canvas1.height !== height) {\n        canvas1.width = width;\n        canvas1.height = height;\n      }\n      else {\n        context.clearRect(0, 0, width, height);\n      }\n      context.setTransform(image.scaleX, 0, 0, image.scaleY, image.left, image.top);\n      context.drawImage(image._element, 0, 0, width, height);\n      blendData = context.getImageData(0, 0, width, height).data;\n      for (var i = 0; i < iLen; i += 4) {\n\n        r = data[i];\n        g = data[i + 1];\n        b = data[i + 2];\n        a = data[i + 3];\n\n        tr = blendData[i];\n        tg = blendData[i + 1];\n        tb = blendData[i + 2];\n        ta = blendData[i + 3];\n\n        switch (this.mode) {\n          case 'multiply':\n            data[i] = r * tr / 255;\n            data[i + 1] = g * tg / 255;\n            data[i + 2] = b * tb / 255;\n            data[i + 3] = a * ta / 255;\n            break;\n          case 'mask':\n            data[i + 3] = ta;\n            break;\n        }\n      }\n    },\n\n    /**\n     * Return WebGL uniform locations for this filter's shader.\n     *\n     * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader.\n     * @param {WebGLShaderProgram} program This filter's compiled shader program.\n     */\n    getUniformLocations: function(gl, program) {\n      return {\n        uTransformMatrix: gl.getUniformLocation(program, 'uTransformMatrix'),\n        uImage: gl.getUniformLocation(program, 'uImage'),\n      };\n    },\n\n    /**\n     * Send data from this filter to its shader program's uniforms.\n     *\n     * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader.\n     * @param {Object} uniformLocations A map of string uniform names to WebGLUniformLocation objects\n     */\n    sendUniformData: function(gl, uniformLocations) {\n      var matrix = this.calculateMatrix();\n      gl.uniform1i(uniformLocations.uImage, 1); // texture unit 1.\n      gl.uniformMatrix3fv(uniformLocations.uTransformMatrix, false, matrix);\n    },\n\n    /**\n     * Returns object representation of an instance\n     * @return {Object} Object representation of an instance\n     */\n    toObject: function() {\n      return {\n        type: this.type,\n        image: this.image && this.image.toObject(),\n        mode: this.mode,\n        alpha: this.alpha\n      };\n    }\n  });\n\n  /**\n   * Returns filter instance from an object representation\n   * @static\n   * @param {Object} object Object to create an instance from\n   * @param {function} callback to be invoked after filter creation\n   * @return {fabric.Image.filters.BlendImage} Instance of fabric.Image.filters.BlendImage\n   */\n  fabric.Image.filters.BlendImage.fromObject = function(object, callback) {\n    fabric.Image.fromObject(object.image, function(image) {\n      var options = fabric.util.object.clone(object);\n      options.image = image;\n      callback(new fabric.Image.filters.BlendImage(options));\n    });\n  };\n\n})(typeof exports !== 'undefined' ? exports : this);\n\n\n(function(global) {\n\n  'use strict';\n\n  var fabric  = global.fabric || (global.fabric = { }), pow = Math.pow, floor = Math.floor,\n      sqrt = Math.sqrt, abs = Math.abs, round = Math.round, sin = Math.sin,\n      ceil = Math.ceil,\n      filters = fabric.Image.filters,\n      createClass = fabric.util.createClass;\n\n  /**\n   * Resize image filter class\n   * @class fabric.Image.filters.Resize\n   * @memberOf fabric.Image.filters\n   * @extends fabric.Image.filters.BaseFilter\n   * @see {@link http://fabricjs.com/image-filters|ImageFilters demo}\n   * @example\n   * var filter = new fabric.Image.filters.Resize();\n   * object.filters.push(filter);\n   * object.applyFilters(canvas.renderAll.bind(canvas));\n   */\n  filters.Resize = createClass(filters.BaseFilter, /** @lends fabric.Image.filters.Resize.prototype */ {\n\n    /**\n     * Filter type\n     * @param {String} type\n     * @default\n     */\n    type: 'Resize',\n\n    /**\n     * Resize type\n     * for webgl resizeType is just lanczos, for canvas2d can be:\n     * bilinear, hermite, sliceHack, lanczos.\n     * @param {String} resizeType\n     * @default\n     */\n    resizeType: 'hermite',\n\n    /**\n     * Scale factor for resizing, x axis\n     * @param {Number} scaleX\n     * @default\n     */\n    scaleX: 1,\n\n    /**\n     * Scale factor for resizing, y axis\n     * @param {Number} scaleY\n     * @default\n     */\n    scaleY: 1,\n\n    /**\n     * LanczosLobes parameter for lanczos filter, valid for resizeType lanczos\n     * @param {Number} lanczosLobes\n     * @default\n     */\n    lanczosLobes: 3,\n\n\n    /**\n     * Return WebGL uniform locations for this filter's shader.\n     *\n     * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader.\n     * @param {WebGLShaderProgram} program This filter's compiled shader program.\n     */\n    getUniformLocations: function(gl, program) {\n      return {\n        uDelta: gl.getUniformLocation(program, 'uDelta'),\n        uTaps: gl.getUniformLocation(program, 'uTaps'),\n      };\n    },\n\n    /**\n     * Send data from this filter to its shader program's uniforms.\n     *\n     * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader.\n     * @param {Object} uniformLocations A map of string uniform names to WebGLUniformLocation objects\n     */\n    sendUniformData: function(gl, uniformLocations) {\n      gl.uniform2fv(uniformLocations.uDelta, this.horizontal ? [1 / this.width, 0] : [0, 1 / this.height]);\n      gl.uniform1fv(uniformLocations.uTaps, this.taps);\n    },\n\n    /**\n     * Retrieves the cached shader.\n     * @param {Object} options\n     * @param {WebGLRenderingContext} options.context The GL context used for rendering.\n     * @param {Object} options.programCache A map of compiled shader programs, keyed by filter type.\n     */\n    retrieveShader: function(options) {\n      var filterWindow = this.getFilterWindow(), cacheKey = this.type + '_' + filterWindow;\n      if (!options.programCache.hasOwnProperty(cacheKey)) {\n        var fragmentShader = this.generateShader(filterWindow);\n        options.programCache[cacheKey] = this.createProgram(options.context, fragmentShader);\n      }\n      return options.programCache[cacheKey];\n    },\n\n    getFilterWindow: function() {\n      var scale = this.tempScale;\n      return Math.ceil(this.lanczosLobes / scale);\n    },\n\n    getTaps: function() {\n      var lobeFunction = this.lanczosCreate(this.lanczosLobes), scale = this.tempScale,\n          filterWindow = this.getFilterWindow(), taps = new Array(filterWindow);\n      for (var i = 1; i <= filterWindow; i++) {\n        taps[i - 1] = lobeFunction(i * scale);\n      }\n      return taps;\n    },\n\n    /**\n     * Generate vertex and shader sources from the necessary steps numbers\n     * @param {Number} filterWindow\n     */\n    generateShader: function(filterWindow) {\n      var offsets = new Array(filterWindow),\n          fragmentShader = this.fragmentSourceTOP, filterWindow;\n\n      for (var i = 1; i <= filterWindow; i++) {\n        offsets[i - 1] = i + '.0 * uDelta';\n      }\n\n      fragmentShader += 'uniform float uTaps[' + filterWindow + '];\\n';\n      fragmentShader += 'void main() {\\n';\n      fragmentShader += '  vec4 color = texture2D(uTexture, vTexCoord);\\n';\n      fragmentShader += '  float sum = 1.0;\\n';\n\n      offsets.forEach(function(offset, i) {\n        fragmentShader += '  color += texture2D(uTexture, vTexCoord + ' + offset + ') * uTaps[' + i + '];\\n';\n        fragmentShader += '  color += texture2D(uTexture, vTexCoord - ' + offset + ') * uTaps[' + i + '];\\n';\n        fragmentShader += '  sum += 2.0 * uTaps[' + i + '];\\n';\n      });\n      fragmentShader += '  gl_FragColor = color / sum;\\n';\n      fragmentShader += '}';\n      return fragmentShader;\n    },\n\n    fragmentSourceTOP: 'precision highp float;\\n' +\n      'uniform sampler2D uTexture;\\n' +\n      'uniform vec2 uDelta;\\n' +\n      'varying vec2 vTexCoord;\\n',\n\n    /**\n     * Apply the resize filter to the image\n     * Determines whether to use WebGL or Canvas2D based on the options.webgl flag.\n     *\n     * @param {Object} options\n     * @param {Number} options.passes The number of filters remaining to be executed\n     * @param {Boolean} options.webgl Whether to use webgl to render the filter.\n     * @param {WebGLTexture} options.sourceTexture The texture setup as the source to be filtered.\n     * @param {WebGLTexture} options.targetTexture The texture where filtered output should be drawn.\n     * @param {WebGLRenderingContext} options.context The GL context used for rendering.\n     * @param {Object} options.programCache A map of compiled shader programs, keyed by filter type.\n     */\n    applyTo: function(options) {\n      if (options.webgl) {\n        options.passes++;\n        this.width = options.sourceWidth;\n        this.horizontal = true;\n        this.dW = Math.round(this.width * this.scaleX);\n        this.dH = options.sourceHeight;\n        this.tempScale = this.dW / this.width;\n        this.taps = this.getTaps();\n        options.destinationWidth = this.dW;\n        this._setupFrameBuffer(options);\n        this.applyToWebGL(options);\n        this._swapTextures(options);\n        options.sourceWidth = options.destinationWidth;\n\n        this.height = options.sourceHeight;\n        this.horizontal = false;\n        this.dH = Math.round(this.height * this.scaleY);\n        this.tempScale = this.dH / this.height;\n        this.taps = this.getTaps();\n        options.destinationHeight = this.dH;\n        this._setupFrameBuffer(options);\n        this.applyToWebGL(options);\n        this._swapTextures(options);\n        options.sourceHeight = options.destinationHeight;\n      }\n      else {\n        this.applyTo2d(options);\n      }\n    },\n\n    isNeutralState: function() {\n      return this.scaleX === 1 && this.scaleY === 1;\n    },\n\n    lanczosCreate: function(lobes) {\n      return function(x) {\n        if (x >= lobes || x <= -lobes) {\n          return 0.0;\n        }\n        if (x < 1.19209290E-07 && x > -1.19209290E-07) {\n          return 1.0;\n        }\n        x *= Math.PI;\n        var xx = x / lobes;\n        return (sin(x) / x) * sin(xx) / xx;\n      };\n    },\n\n    /**\n     * Applies filter to canvas element\n     * @memberOf fabric.Image.filters.Resize.prototype\n     * @param {Object} canvasEl Canvas element to apply filter to\n     * @param {Number} scaleX\n     * @param {Number} scaleY\n     */\n    applyTo2d: function(options) {\n      var imageData = options.imageData,\n          scaleX = this.scaleX,\n          scaleY = this.scaleY;\n\n      this.rcpScaleX = 1 / scaleX;\n      this.rcpScaleY = 1 / scaleY;\n\n      var oW = imageData.width, oH = imageData.height,\n          dW = round(oW * scaleX), dH = round(oH * scaleY),\n          newData;\n\n      if (this.resizeType === 'sliceHack') {\n        newData = this.sliceByTwo(options, oW, oH, dW, dH);\n      }\n      else if (this.resizeType === 'hermite') {\n        newData = this.hermiteFastResize(options, oW, oH, dW, dH);\n      }\n      else if (this.resizeType === 'bilinear') {\n        newData = this.bilinearFiltering(options, oW, oH, dW, dH);\n      }\n      else if (this.resizeType === 'lanczos') {\n        newData = this.lanczosResize(options, oW, oH, dW, dH);\n      }\n      options.imageData = newData;\n    },\n\n    /**\n     * Filter sliceByTwo\n     * @param {Object} canvasEl Canvas element to apply filter to\n     * @param {Number} oW Original Width\n     * @param {Number} oH Original Height\n     * @param {Number} dW Destination Width\n     * @param {Number} dH Destination Height\n     * @returns {ImageData}\n     */\n    sliceByTwo: function(options, oW, oH, dW, dH) {\n      var imageData = options.imageData,\n          mult = 0.5, doneW = false, doneH = false, stepW = oW * mult,\n          stepH = oH * mult, resources = fabric.filterBackend.resources,\n          tmpCanvas, ctx, sX = 0, sY = 0, dX = oW, dY = 0;\n      if (!resources.sliceByTwo) {\n        resources.sliceByTwo = document.createElement('canvas');\n      }\n      tmpCanvas = resources.sliceByTwo;\n      if (tmpCanvas.width < oW * 1.5 || tmpCanvas.height < oH) {\n        tmpCanvas.width = oW * 1.5;\n        tmpCanvas.height = oH;\n      }\n      ctx = tmpCanvas.getContext('2d');\n      ctx.clearRect(0, 0, oW * 1.5, oH);\n      ctx.putImageData(imageData, 0, 0);\n\n      dW = floor(dW);\n      dH = floor(dH);\n\n      while (!doneW || !doneH) {\n        oW = stepW;\n        oH = stepH;\n        if (dW < floor(stepW * mult)) {\n          stepW = floor(stepW * mult);\n        }\n        else {\n          stepW = dW;\n          doneW = true;\n        }\n        if (dH < floor(stepH * mult)) {\n          stepH = floor(stepH * mult);\n        }\n        else {\n          stepH = dH;\n          doneH = true;\n        }\n        ctx.drawImage(tmpCanvas, sX, sY, oW, oH, dX, dY, stepW, stepH);\n        sX = dX;\n        sY = dY;\n        dY += stepH;\n      }\n      return ctx.getImageData(sX, sY, dW, dH);\n    },\n\n    /**\n     * Filter lanczosResize\n     * @param {Object} canvasEl Canvas element to apply filter to\n     * @param {Number} oW Original Width\n     * @param {Number} oH Original Height\n     * @param {Number} dW Destination Width\n     * @param {Number} dH Destination Height\n     * @returns {ImageData}\n     */\n    lanczosResize: function(options, oW, oH, dW, dH) {\n\n      function process(u) {\n        var v, i, weight, idx, a, red, green,\n            blue, alpha, fX, fY;\n        center.x = (u + 0.5) * ratioX;\n        icenter.x = floor(center.x);\n        for (v = 0; v < dH; v++) {\n          center.y = (v + 0.5) * ratioY;\n          icenter.y = floor(center.y);\n          a = 0; red = 0; green = 0; blue = 0; alpha = 0;\n          for (i = icenter.x - range2X; i <= icenter.x + range2X; i++) {\n            if (i < 0 || i >= oW) {\n              continue;\n            }\n            fX = floor(1000 * abs(i - center.x));\n            if (!cacheLanc[fX]) {\n              cacheLanc[fX] = { };\n            }\n            for (var j = icenter.y - range2Y; j <= icenter.y + range2Y; j++) {\n              if (j < 0 || j >= oH) {\n                continue;\n              }\n              fY = floor(1000 * abs(j - center.y));\n              if (!cacheLanc[fX][fY]) {\n                cacheLanc[fX][fY] = lanczos(sqrt(pow(fX * rcpRatioX, 2) + pow(fY * rcpRatioY, 2)) / 1000);\n              }\n              weight = cacheLanc[fX][fY];\n              if (weight > 0) {\n                idx = (j * oW + i) * 4;\n                a += weight;\n                red += weight * srcData[idx];\n                green += weight * srcData[idx + 1];\n                blue += weight * srcData[idx + 2];\n                alpha += weight * srcData[idx + 3];\n              }\n            }\n          }\n          idx = (v * dW + u) * 4;\n          destData[idx] = red / a;\n          destData[idx + 1] = green / a;\n          destData[idx + 2] = blue / a;\n          destData[idx + 3] = alpha / a;\n        }\n\n        if (++u < dW) {\n          return process(u);\n        }\n        else {\n          return destImg;\n        }\n      }\n\n      var srcData = options.imageData.data,\n          destImg = options.ctx.createImageData(dW, dH),\n          destData = destImg.data,\n          lanczos = this.lanczosCreate(this.lanczosLobes),\n          ratioX = this.rcpScaleX, ratioY = this.rcpScaleY,\n          rcpRatioX = 2 / this.rcpScaleX, rcpRatioY = 2 / this.rcpScaleY,\n          range2X = ceil(ratioX * this.lanczosLobes / 2),\n          range2Y = ceil(ratioY * this.lanczosLobes / 2),\n          cacheLanc = { }, center = { }, icenter = { };\n\n      return process(0);\n    },\n\n    /**\n     * bilinearFiltering\n     * @param {Object} canvasEl Canvas element to apply filter to\n     * @param {Number} oW Original Width\n     * @param {Number} oH Original Height\n     * @param {Number} dW Destination Width\n     * @param {Number} dH Destination Height\n     * @returns {ImageData}\n     */\n    bilinearFiltering: function(options, oW, oH, dW, dH) {\n      var a, b, c, d, x, y, i, j, xDiff, yDiff, chnl,\n          color, offset = 0, origPix, ratioX = this.rcpScaleX,\n          ratioY = this.rcpScaleY,\n          w4 = 4 * (oW - 1), img = options.imageData,\n          pixels = img.data, destImage = options.ctx.createImageData(dW, dH),\n          destPixels = destImage.data;\n      for (i = 0; i < dH; i++) {\n        for (j = 0; j < dW; j++) {\n          x = floor(ratioX * j);\n          y = floor(ratioY * i);\n          xDiff = ratioX * j - x;\n          yDiff = ratioY * i - y;\n          origPix = 4 * (y * oW + x);\n\n          for (chnl = 0; chnl < 4; chnl++) {\n            a = pixels[origPix + chnl];\n            b = pixels[origPix + 4 + chnl];\n            c = pixels[origPix + w4 + chnl];\n            d = pixels[origPix + w4 + 4 + chnl];\n            color = a * (1 - xDiff) * (1 - yDiff) + b * xDiff * (1 - yDiff) +\n                    c * yDiff * (1 - xDiff) + d * xDiff * yDiff;\n            destPixels[offset++] = color;\n          }\n        }\n      }\n      return destImage;\n    },\n\n    /**\n     * hermiteFastResize\n     * @param {Object} canvasEl Canvas element to apply filter to\n     * @param {Number} oW Original Width\n     * @param {Number} oH Original Height\n     * @param {Number} dW Destination Width\n     * @param {Number} dH Destination Height\n     * @returns {ImageData}\n     */\n    hermiteFastResize: function(options, oW, oH, dW, dH) {\n      var ratioW = this.rcpScaleX, ratioH = this.rcpScaleY,\n          ratioWHalf = ceil(ratioW / 2),\n          ratioHHalf = ceil(ratioH / 2),\n          img = options.imageData, data = img.data,\n          img2 = options.ctx.createImageData(dW, dH), data2 = img2.data;\n      for (var j = 0; j < dH; j++) {\n        for (var i = 0; i < dW; i++) {\n          var x2 = (i + j * dW) * 4, weight = 0, weights = 0, weightsAlpha = 0,\n              gxR = 0, gxG = 0, gxB = 0, gxA = 0, centerY = (j + 0.5) * ratioH;\n          for (var yy = floor(j * ratioH); yy < (j + 1) * ratioH; yy++) {\n            var dy = abs(centerY - (yy + 0.5)) / ratioHHalf,\n                centerX = (i + 0.5) * ratioW, w0 = dy * dy;\n            for (var xx = floor(i * ratioW); xx < (i + 1) * ratioW; xx++) {\n              var dx = abs(centerX - (xx + 0.5)) / ratioWHalf,\n                  w = sqrt(w0 + dx * dx);\n              /* eslint-disable max-depth */\n              if (w > 1 && w < -1) {\n                continue;\n              }\n              //hermite filter\n              weight = 2 * w * w * w - 3 * w * w + 1;\n              if (weight > 0) {\n                dx = 4 * (xx + yy * oW);\n                //alpha\n                gxA += weight * data[dx + 3];\n                weightsAlpha += weight;\n                //colors\n                if (data[dx + 3] < 255) {\n                  weight = weight * data[dx + 3] / 250;\n                }\n                gxR += weight * data[dx];\n                gxG += weight * data[dx + 1];\n                gxB += weight * data[dx + 2];\n                weights += weight;\n              }\n              /* eslint-enable max-depth */\n            }\n          }\n          data2[x2] = gxR / weights;\n          data2[x2 + 1] = gxG / weights;\n          data2[x2 + 2] = gxB / weights;\n          data2[x2 + 3] = gxA / weightsAlpha;\n        }\n      }\n      return img2;\n    },\n\n    /**\n     * Returns object representation of an instance\n     * @return {Object} Object representation of an instance\n     */\n    toObject: function() {\n      return {\n        type: this.type,\n        scaleX: this.scaleX,\n        scaleY: this.scaleY,\n        resizeType: this.resizeType,\n        lanczosLobes: this.lanczosLobes\n      };\n    }\n  });\n\n  /**\n   * Returns filter instance from an object representation\n   * @static\n   * @param {Object} object Object to create an instance from\n   * @param {Function} [callback] to be invoked after filter creation\n   * @return {fabric.Image.filters.Resize} Instance of fabric.Image.filters.Resize\n   */\n  fabric.Image.filters.Resize.fromObject = fabric.Image.filters.BaseFilter.fromObject;\n\n})(typeof exports !== 'undefined' ? exports : this);\n\n\n(function(global) {\n\n  'use strict';\n\n  var fabric  = global.fabric || (global.fabric = { }),\n      filters = fabric.Image.filters,\n      createClass = fabric.util.createClass;\n\n  /**\n   * Contrast filter class\n   * @class fabric.Image.filters.Contrast\n   * @memberOf fabric.Image.filters\n   * @extends fabric.Image.filters.BaseFilter\n   * @see {@link fabric.Image.filters.Contrast#initialize} for constructor definition\n   * @see {@link http://fabricjs.com/image-filters|ImageFilters demo}\n   * @example\n   * var filter = new fabric.Image.filters.Contrast({\n   *   contrast: 40\n   * });\n   * object.filters.push(filter);\n   * object.applyFilters();\n   */\n  filters.Contrast = createClass(filters.BaseFilter, /** @lends fabric.Image.filters.Contrast.prototype */ {\n\n    /**\n     * Filter type\n     * @param {String} type\n     * @default\n     */\n    type: 'Contrast',\n\n    fragmentSource: 'precision highp float;\\n' +\n      'uniform sampler2D uTexture;\\n' +\n      'uniform float uContrast;\\n' +\n      'varying vec2 vTexCoord;\\n' +\n      'void main() {\\n' +\n        'vec4 color = texture2D(uTexture, vTexCoord);\\n' +\n        'float contrastF = 1.015 * (uContrast + 1.0) / (1.0 * (1.015 - uContrast));\\n' +\n        'color.rgb = contrastF * (color.rgb - 0.5) + 0.5;\\n' +\n        'gl_FragColor = color;\\n' +\n      '}',\n\n    contrast: 0,\n\n    mainParameter: 'contrast',\n\n    /**\n     * Constructor\n     * @memberOf fabric.Image.filters.Contrast.prototype\n     * @param {Object} [options] Options object\n     * @param {Number} [options.contrast=0] Value to contrast the image up (-1...1)\n     */\n\n    /**\n      * Apply the Contrast operation to a Uint8Array representing the pixels of an image.\n      *\n      * @param {Object} options\n      * @param {ImageData} options.imageData The Uint8Array to be filtered.\n      */\n    applyTo2d: function(options) {\n      if (this.contrast === 0) {\n        return;\n      }\n      var imageData = options.imageData, i, len,\n          data = imageData.data, len = data.length,\n          contrast = Math.floor(this.contrast * 255),\n          contrastF = 259 * (contrast + 255) / (255 * (259 - contrast));\n\n      for (i = 0; i < len; i += 4) {\n        data[i] = contrastF * (data[i] - 128) + 128;\n        data[i + 1] = contrastF * (data[i + 1] - 128) + 128;\n        data[i + 2] = contrastF * (data[i + 2] - 128) + 128;\n      }\n    },\n\n    /**\n     * Return WebGL uniform locations for this filter's shader.\n     *\n     * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader.\n     * @param {WebGLShaderProgram} program This filter's compiled shader program.\n     */\n    getUniformLocations: function(gl, program) {\n      return {\n        uContrast: gl.getUniformLocation(program, 'uContrast'),\n      };\n    },\n\n    /**\n     * Send data from this filter to its shader program's uniforms.\n     *\n     * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader.\n     * @param {Object} uniformLocations A map of string uniform names to WebGLUniformLocation objects\n     */\n    sendUniformData: function(gl, uniformLocations) {\n      gl.uniform1f(uniformLocations.uContrast, this.contrast);\n    },\n  });\n\n  /**\n   * Returns filter instance from an object representation\n   * @static\n   * @param {Object} object Object to create an instance from\n   * @param {function} [callback] to be invoked after filter creation\n   * @return {fabric.Image.filters.Contrast} Instance of fabric.Image.filters.Contrast\n   */\n  fabric.Image.filters.Contrast.fromObject = fabric.Image.filters.BaseFilter.fromObject;\n\n})(typeof exports !== 'undefined' ? exports : this);\n\n\n(function(global) {\n\n  'use strict';\n\n  var fabric  = global.fabric || (global.fabric = { }),\n      filters = fabric.Image.filters,\n      createClass = fabric.util.createClass;\n\n  /**\n   * Saturate filter class\n   * @class fabric.Image.filters.Saturation\n   * @memberOf fabric.Image.filters\n   * @extends fabric.Image.filters.BaseFilter\n   * @see {@link fabric.Image.filters.Saturation#initialize} for constructor definition\n   * @see {@link http://fabricjs.com/image-filters|ImageFilters demo}\n   * @example\n   * var filter = new fabric.Image.filters.Saturation({\n   *   saturation: 100\n   * });\n   * object.filters.push(filter);\n   * object.applyFilters();\n   */\n  filters.Saturation = createClass(filters.BaseFilter, /** @lends fabric.Image.filters.Saturation.prototype */ {\n\n    /**\n     * Filter type\n     * @param {String} type\n     * @default\n     */\n    type: 'Saturation',\n\n    fragmentSource: 'precision highp float;\\n' +\n      'uniform sampler2D uTexture;\\n' +\n      'uniform float uSaturation;\\n' +\n      'varying vec2 vTexCoord;\\n' +\n      'void main() {\\n' +\n        'vec4 color = texture2D(uTexture, vTexCoord);\\n' +\n        'float rgMax = max(color.r, color.g);\\n' +\n        'float rgbMax = max(rgMax, color.b);\\n' +\n        'color.r += rgbMax != color.r ? (rgbMax - color.r) * uSaturation : 0.00;\\n' +\n        'color.g += rgbMax != color.g ? (rgbMax - color.g) * uSaturation : 0.00;\\n' +\n        'color.b += rgbMax != color.b ? (rgbMax - color.b) * uSaturation : 0.00;\\n' +\n        'gl_FragColor = color;\\n' +\n      '}',\n\n    saturation: 0,\n\n    mainParameter: 'saturation',\n\n    /**\n     * Constructor\n     * @memberOf fabric.Image.filters.Saturate.prototype\n     * @param {Object} [options] Options object\n     * @param {Number} [options.saturate=0] Value to saturate the image (-1...1)\n     */\n\n    /**\n     * Apply the Saturation operation to a Uint8ClampedArray representing the pixels of an image.\n     *\n     * @param {Object} options\n     * @param {ImageData} options.imageData The Uint8ClampedArray to be filtered.\n     */\n    applyTo2d: function(options) {\n      if (this.saturation === 0) {\n        return;\n      }\n      var imageData = options.imageData,\n          data = imageData.data, len = data.length,\n          adjust = -this.saturation, i, max;\n\n      for (i = 0; i < len; i += 4) {\n        max = Math.max(data[i], data[i + 1], data[i + 2]);\n        data[i] += max !== data[i] ? (max - data[i]) * adjust : 0;\n        data[i + 1] += max !== data[i + 1] ? (max - data[i + 1]) * adjust : 0;\n        data[i + 2] += max !== data[i + 2] ? (max - data[i + 2]) * adjust : 0;\n      }\n    },\n\n    /**\n     * Return WebGL uniform locations for this filter's shader.\n     *\n     * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader.\n     * @param {WebGLShaderProgram} program This filter's compiled shader program.\n     */\n    getUniformLocations: function(gl, program) {\n      return {\n        uSaturation: gl.getUniformLocation(program, 'uSaturation'),\n      };\n    },\n\n    /**\n     * Send data from this filter to its shader program's uniforms.\n     *\n     * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader.\n     * @param {Object} uniformLocations A map of string uniform names to WebGLUniformLocation objects\n     */\n    sendUniformData: function(gl, uniformLocations) {\n      gl.uniform1f(uniformLocations.uSaturation, -this.saturation);\n    },\n  });\n\n  /**\n   * Returns filter instance from an object representation\n   * @static\n   * @param {Object} object Object to create an instance from\n   * @param {Function} [callback] to be invoked after filter creation\n   * @return {fabric.Image.filters.Saturation} Instance of fabric.Image.filters.Saturate\n   */\n  fabric.Image.filters.Saturation.fromObject = fabric.Image.filters.BaseFilter.fromObject;\n\n})(typeof exports !== 'undefined' ? exports : this);\n\n\n(function(global) {\n\n  'use strict';\n\n  var fabric  = global.fabric || (global.fabric = { }),\n      filters = fabric.Image.filters,\n      createClass = fabric.util.createClass;\n\n  /**\n   * Blur filter class\n   * @class fabric.Image.filters.Blur\n   * @memberOf fabric.Image.filters\n   * @extends fabric.Image.filters.BaseFilter\n   * @see {@link fabric.Image.filters.Blur#initialize} for constructor definition\n   * @see {@link http://fabricjs.com/image-filters|ImageFilters demo}\n   * @example\n   * var filter = new fabric.Image.filters.Blur({\n   *   blur: 0.5\n   * });\n   * object.filters.push(filter);\n   * object.applyFilters();\n   * canvas.renderAll();\n   */\n  filters.Blur = createClass(filters.BaseFilter, /** @lends fabric.Image.filters.Blur.prototype */ {\n\n    type: 'Blur',\n\n    /*\n'gl_FragColor = vec4(0.0);',\n'gl_FragColor += texture2D(texture, vTexCoord + -7 * uDelta)*0.0044299121055113265;',\n'gl_FragColor += texture2D(texture, vTexCoord + -6 * uDelta)*0.00895781211794;',\n'gl_FragColor += texture2D(texture, vTexCoord + -5 * uDelta)*0.0215963866053;',\n'gl_FragColor += texture2D(texture, vTexCoord + -4 * uDelta)*0.0443683338718;',\n'gl_FragColor += texture2D(texture, vTexCoord + -3 * uDelta)*0.0776744219933;',\n'gl_FragColor += texture2D(texture, vTexCoord + -2 * uDelta)*0.115876621105;',\n'gl_FragColor += texture2D(texture, vTexCoord + -1 * uDelta)*0.147308056121;',\n'gl_FragColor += texture2D(texture, vTexCoord              )*0.159576912161;',\n'gl_FragColor += texture2D(texture, vTexCoord + 1 * uDelta)*0.147308056121;',\n'gl_FragColor += texture2D(texture, vTexCoord + 2 * uDelta)*0.115876621105;',\n'gl_FragColor += texture2D(texture, vTexCoord + 3 * uDelta)*0.0776744219933;',\n'gl_FragColor += texture2D(texture, vTexCoord + 4 * uDelta)*0.0443683338718;',\n'gl_FragColor += texture2D(texture, vTexCoord + 5 * uDelta)*0.0215963866053;',\n'gl_FragColor += texture2D(texture, vTexCoord + 6 * uDelta)*0.00895781211794;',\n'gl_FragColor += texture2D(texture, vTexCoord + 7 * uDelta)*0.0044299121055113265;',\n*/\n\n    /* eslint-disable max-len */\n    fragmentSource: 'precision highp float;\\n' +\n      'uniform sampler2D uTexture;\\n' +\n      'uniform vec2 uDelta;\\n' +\n      'varying vec2 vTexCoord;\\n' +\n      'const float nSamples = 15.0;\\n' +\n      'vec3 v3offset = vec3(12.9898, 78.233, 151.7182);\\n' +\n      'float random(vec3 scale) {\\n' +\n        /* use the fragment position for a different seed per-pixel */\n        'return fract(sin(dot(gl_FragCoord.xyz, scale)) * 43758.5453);\\n' +\n      '}\\n' +\n      'void main() {\\n' +\n        'vec4 color = vec4(0.0);\\n' +\n        'float total = 0.0;\\n' +\n        'float offset = random(v3offset);\\n' +\n        'for (float t = -nSamples; t <= nSamples; t++) {\\n' +\n          'float percent = (t + offset - 0.5) / nSamples;\\n' +\n          'float weight = 1.0 - abs(percent);\\n' +\n          'color += texture2D(uTexture, vTexCoord + uDelta * percent) * weight;\\n' +\n          'total += weight;\\n' +\n        '}\\n' +\n        'gl_FragColor = color / total;\\n' +\n      '}',\n    /* eslint-enable max-len */\n\n    /**\n     * blur value, in percentage of image dimensions.\n     * specific to keep the image blur constant at different resolutions\n     * range bewteen 0 and 1.\n     */\n    blur: 0,\n\n    mainParameter: 'blur',\n\n    applyTo: function(options) {\n      if (options.webgl) {\n        // this aspectRatio is used to give the same blur to vertical and horizontal\n        this.aspectRatio = options.sourceWidth / options.sourceHeight;\n        options.passes++;\n        this._setupFrameBuffer(options);\n        this.horizontal = true;\n        this.applyToWebGL(options);\n        this._swapTextures(options);\n        this._setupFrameBuffer(options);\n        this.horizontal = false;\n        this.applyToWebGL(options);\n        this._swapTextures(options);\n      }\n      else {\n        this.applyTo2d(options);\n      }\n    },\n\n    applyTo2d: function(options) {\n      // paint canvasEl with current image data.\n      //options.ctx.putImageData(options.imageData, 0, 0);\n      options.imageData = this.simpleBlur(options);\n    },\n\n    simpleBlur: function(options) {\n      var resources = options.filterBackend.resources, canvas1, canvas2,\n          width = options.imageData.width,\n          height = options.imageData.height;\n\n      if (!resources.blurLayer1) {\n        resources.blurLayer1 = fabric.util.createCanvasElement();\n        resources.blurLayer2 = fabric.util.createCanvasElement();\n      }\n      canvas1 = resources.blurLayer1;\n      canvas2 = resources.blurLayer2;\n      if (canvas1.width !== width || canvas1.height !== height) {\n        canvas2.width = canvas1.width = width;\n        canvas2.height = canvas1.height = height;\n      }\n      var ctx1 = canvas1.getContext('2d'),\n          ctx2 = canvas2.getContext('2d'),\n          nSamples = 15,\n          random, percent, j, i,\n          blur = this.blur * 0.06 * 0.5;\n\n      // load first canvas\n      ctx1.putImageData(options.imageData, 0, 0);\n      ctx2.clearRect(0, 0, width, height);\n\n      for (i = -nSamples; i <= nSamples; i++) {\n        random = (Math.random() - 0.5) / 4;\n        percent = i / nSamples;\n        j = blur * percent * width + random;\n        ctx2.globalAlpha = 1 - Math.abs(percent);\n        ctx2.drawImage(canvas1, j, random);\n        ctx1.drawImage(canvas2, 0, 0);\n        ctx2.globalAlpha = 1;\n        ctx2.clearRect(0, 0, canvas2.width, canvas2.height);\n      }\n      for (i = -nSamples; i <= nSamples; i++) {\n        random = (Math.random() - 0.5) / 4;\n        percent = i / nSamples;\n        j = blur * percent * height + random;\n        ctx2.globalAlpha = 1 - Math.abs(percent);\n        ctx2.drawImage(canvas1, random, j);\n        ctx1.drawImage(canvas2, 0, 0);\n        ctx2.globalAlpha = 1;\n        ctx2.clearRect(0, 0, canvas2.width, canvas2.height);\n      }\n      options.ctx.drawImage(canvas1, 0, 0);\n      var newImageData = options.ctx.getImageData(0, 0, canvas1.width, canvas1.height);\n      ctx1.globalAlpha = 1;\n      ctx1.clearRect(0, 0, canvas1.width, canvas1.height);\n      return newImageData;\n    },\n\n    /**\n     * Return WebGL uniform locations for this filter's shader.\n     *\n     * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader.\n     * @param {WebGLShaderProgram} program This filter's compiled shader program.\n     */\n    getUniformLocations: function(gl, program) {\n      return {\n        delta: gl.getUniformLocation(program, 'uDelta'),\n      };\n    },\n\n    /**\n     * Send data from this filter to its shader program's uniforms.\n     *\n     * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader.\n     * @param {Object} uniformLocations A map of string uniform names to WebGLUniformLocation objects\n     */\n    sendUniformData: function(gl, uniformLocations) {\n      var delta = this.chooseRightDelta();\n      gl.uniform2fv(uniformLocations.delta, delta);\n    },\n\n    /**\n     * choose right value of image percentage to blur with\n     * @returns {Array} a numeric array with delta values\n     */\n    chooseRightDelta: function() {\n      var blurScale = 1, delta = [0, 0], blur;\n      if (this.horizontal) {\n        if (this.aspectRatio > 1) {\n          // image is wide, i want to shrink radius horizontal\n          blurScale = 1 / this.aspectRatio;\n        }\n      }\n      else {\n        if (this.aspectRatio < 1) {\n          // image is tall, i want to shrink radius vertical\n          blurScale = this.aspectRatio;\n        }\n      }\n      blur = blurScale * this.blur * 0.12;\n      if (this.horizontal) {\n        delta[0] = blur;\n      }\n      else {\n        delta[1] = blur;\n      }\n      return delta;\n    },\n  });\n\n  /**\n   * Deserialize a JSON definition of a BlurFilter into a concrete instance.\n   */\n  filters.Blur.fromObject = fabric.Image.filters.BaseFilter.fromObject;\n\n})(typeof exports !== 'undefined' ? exports : this);\n\n\n(function(global) {\n\n  'use strict';\n\n  var fabric  = global.fabric || (global.fabric = { }),\n      filters = fabric.Image.filters,\n      createClass = fabric.util.createClass;\n\n  /**\n   * Gamma filter class\n   * @class fabric.Image.filters.Gamma\n   * @memberOf fabric.Image.filters\n   * @extends fabric.Image.filters.BaseFilter\n   * @see {@link fabric.Image.filters.Gamma#initialize} for constructor definition\n   * @see {@link http://fabricjs.com/image-filters|ImageFilters demo}\n   * @example\n   * var filter = new fabric.Image.filters.Gamma({\n   *   brightness: 200\n   * });\n   * object.filters.push(filter);\n   * object.applyFilters();\n   */\n  filters.Gamma = createClass(filters.BaseFilter, /** @lends fabric.Image.filters.Gamma.prototype */ {\n\n    /**\n     * Filter type\n     * @param {String} type\n     * @default\n     */\n    type: 'Gamma',\n\n    fragmentSource: 'precision highp float;\\n' +\n      'uniform sampler2D uTexture;\\n' +\n      'uniform vec3 uGamma;\\n' +\n      'varying vec2 vTexCoord;\\n' +\n      'void main() {\\n' +\n        'vec4 color = texture2D(uTexture, vTexCoord);\\n' +\n        'vec3 correction = (1.0 / uGamma);\\n' +\n        'color.r = pow(color.r, correction.r);\\n' +\n        'color.g = pow(color.g, correction.g);\\n' +\n        'color.b = pow(color.b, correction.b);\\n' +\n        'gl_FragColor = color;\\n' +\n        'gl_FragColor.rgb *= color.a;\\n' +\n      '}',\n\n    /**\n     * Gamma array value, from 0.01 to 2.2.\n     * @param {Array} gamma\n     * @default\n     */\n    gamma: [1, 1, 1],\n\n    /**\n     * Describe the property that is the filter parameter\n     * @param {String} m\n     * @default\n     */\n    mainParameter: 'gamma',\n\n    /**\n     * Constructor\n     * @param {Object} [options] Options object\n     */\n    initialize: function(options) {\n      this.gamma = [1, 1, 1];\n      filters.BaseFilter.prototype.initialize.call(this, options);\n    },\n\n    /**\n     * Apply the Gamma operation to a Uint8Array representing the pixels of an image.\n     *\n     * @param {Object} options\n     * @param {ImageData} options.imageData The Uint8Array to be filtered.\n     */\n    applyTo2d: function(options) {\n      var imageData = options.imageData, data = imageData.data,\n          gamma = this.gamma, len = data.length,\n          rInv = 1 / gamma[0], gInv = 1 / gamma[1],\n          bInv = 1 / gamma[2], i;\n\n      if (!this.rVals) {\n        // eslint-disable-next-line\n        this.rVals = new Uint8Array(256);\n        // eslint-disable-next-line\n        this.gVals = new Uint8Array(256);\n        // eslint-disable-next-line\n        this.bVals = new Uint8Array(256);\n      }\n\n      // This is an optimization - pre-compute a look-up table for each color channel\n      // instead of performing these pow calls for each pixel in the image.\n      for (i = 0, len = 256; i < len; i++) {\n        this.rVals[i] = Math.pow(i / 255, rInv) * 255;\n        this.gVals[i] = Math.pow(i / 255, gInv) * 255;\n        this.bVals[i] = Math.pow(i / 255, bInv) * 255;\n      }\n      for (i = 0, len = data.length; i < len; i += 4) {\n        data[i] = this.rVals[data[i]];\n        data[i + 1] = this.gVals[data[i + 1]];\n        data[i + 2] = this.bVals[data[i + 2]];\n      }\n    },\n\n    /**\n     * Return WebGL uniform locations for this filter's shader.\n     *\n     * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader.\n     * @param {WebGLShaderProgram} program This filter's compiled shader program.\n     */\n    getUniformLocations: function(gl, program) {\n      return {\n        uGamma: gl.getUniformLocation(program, 'uGamma'),\n      };\n    },\n\n    /**\n     * Send data from this filter to its shader program's uniforms.\n     *\n     * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader.\n     * @param {Object} uniformLocations A map of string uniform names to WebGLUniformLocation objects\n     */\n    sendUniformData: function(gl, uniformLocations) {\n      gl.uniform3fv(uniformLocations.uGamma, this.gamma);\n    },\n  });\n\n  /**\n   * Returns filter instance from an object representation\n   * @static\n   * @param {Object} object Object to create an instance from\n   * @param {function} [callback] to be invoked after filter creation\n   * @return {fabric.Image.filters.Gamma} Instance of fabric.Image.filters.Gamma\n   */\n  fabric.Image.filters.Gamma.fromObject = fabric.Image.filters.BaseFilter.fromObject;\n\n})(typeof exports !== 'undefined' ? exports : this);\n\n\n(function(global) {\n\n  'use strict';\n\n  var fabric  = global.fabric || (global.fabric = { }),\n      filters = fabric.Image.filters,\n      createClass = fabric.util.createClass;\n\n  /**\n   * A container class that knows how to apply a sequence of filters to an input image.\n   */\n  filters.Composed = createClass(filters.BaseFilter, /** @lends fabric.Image.filters.Composed.prototype */ {\n\n    type: 'Composed',\n\n    /**\n     * A non sparse array of filters to apply\n     */\n    subFilters: [],\n\n    /**\n     * Constructor\n     * @param {Object} [options] Options object\n     */\n    initialize: function(options) {\n      this.callSuper('initialize', options);\n      // create a new array instead mutating the prototype with push\n      this.subFilters = this.subFilters.slice(0);\n    },\n\n    /**\n     * Apply this container's filters to the input image provided.\n     *\n     * @param {Object} options\n     * @param {Number} options.passes The number of filters remaining to be applied.\n     */\n    applyTo: function(options) {\n      options.passes += this.subFilters.length - 1;\n      this.subFilters.forEach(function(filter) {\n        filter.applyTo(options);\n      });\n    },\n\n    /**\n     * Serialize this filter into JSON.\n     *\n     * @returns {Object} A JSON representation of this filter.\n     */\n    toObject: function() {\n      return fabric.util.object.extend(this.callSuper('toObject'), {\n        subFilters: this.subFilters.map(function(filter) { return filter.toObject(); }),\n      });\n    },\n\n    isNeutralState: function() {\n      return !this.subFilters.some(function(filter) { return !filter.isNeutralState(); });\n    }\n  });\n\n  /**\n   * Deserialize a JSON definition of a ComposedFilter into a concrete instance.\n   */\n  fabric.Image.filters.Composed.fromObject = function(object, callback) {\n    var filters = object.subFilters || [],\n        subFilters = filters.map(function(filter) {\n          return new fabric.Image.filters[filter.type](filter);\n        }),\n        instance = new fabric.Image.filters.Composed({ subFilters: subFilters });\n    callback && callback(instance);\n    return instance;\n  };\n})(typeof exports !== 'undefined' ? exports : this);\n\n\n(function(global) {\n\n  'use strict';\n\n  var fabric  = global.fabric || (global.fabric = { }),\n      filters = fabric.Image.filters,\n      createClass = fabric.util.createClass;\n\n  /**\n   * HueRotation filter class\n   * @class fabric.Image.filters.HueRotation\n   * @memberOf fabric.Image.filters\n   * @extends fabric.Image.filters.BaseFilter\n   * @see {@link fabric.Image.filters.HueRotation#initialize} for constructor definition\n   * @see {@link http://fabricjs.com/image-filters|ImageFilters demo}\n   * @example\n   * var filter = new fabric.Image.filters.HueRotation({\n   *   rotation: -0.5\n   * });\n   * object.filters.push(filter);\n   * object.applyFilters();\n   */\n  filters.HueRotation = createClass(filters.ColorMatrix, /** @lends fabric.Image.filters.HueRotation.prototype */ {\n\n    /**\n     * Filter type\n     * @param {String} type\n     * @default\n     */\n    type: 'HueRotation',\n\n    /**\n     * HueRotation value, from -1 to 1.\n     * the unit is radians\n     * @param {Number} myParameter\n     * @default\n     */\n    rotation: 0,\n\n    /**\n     * Describe the property that is the filter parameter\n     * @param {String} m\n     * @default\n     */\n    mainParameter: 'rotation',\n\n    calculateMatrix: function() {\n      var rad = this.rotation * Math.PI, cos = fabric.util.cos(rad), sin = fabric.util.sin(rad),\n          aThird = 1 / 3, aThirdSqtSin = Math.sqrt(aThird) * sin, OneMinusCos = 1 - cos;\n      this.matrix = [\n        1, 0, 0, 0, 0,\n        0, 1, 0, 0, 0,\n        0, 0, 1, 0, 0,\n        0, 0, 0, 1, 0\n      ];\n      this.matrix[0] = cos + OneMinusCos / 3;\n      this.matrix[1] = aThird * OneMinusCos - aThirdSqtSin;\n      this.matrix[2] = aThird * OneMinusCos + aThirdSqtSin;\n      this.matrix[5] = aThird * OneMinusCos + aThirdSqtSin;\n      this.matrix[6] = cos + aThird * OneMinusCos;\n      this.matrix[7] = aThird * OneMinusCos - aThirdSqtSin;\n      this.matrix[10] = aThird * OneMinusCos - aThirdSqtSin;\n      this.matrix[11] = aThird * OneMinusCos + aThirdSqtSin;\n      this.matrix[12] = cos + aThird * OneMinusCos;\n    },\n\n    /**\n     * HueRotation isNeutralState implementation\n     * Used only in image applyFilters to discard filters that will not have an effect\n     * on the image\n     * @param {Object} options\n     **/\n    isNeutralState: function(options) {\n      this.calculateMatrix();\n      return filters.BaseFilter.prototype.isNeutralState.call(this, options);\n    },\n\n    /**\n     * Apply this filter to the input image data provided.\n     *\n     * Determines whether to use WebGL or Canvas2D based on the options.webgl flag.\n     *\n     * @param {Object} options\n     * @param {Number} options.passes The number of filters remaining to be executed\n     * @param {Boolean} options.webgl Whether to use webgl to render the filter.\n     * @param {WebGLTexture} options.sourceTexture The texture setup as the source to be filtered.\n     * @param {WebGLTexture} options.targetTexture The texture where filtered output should be drawn.\n     * @param {WebGLRenderingContext} options.context The GL context used for rendering.\n     * @param {Object} options.programCache A map of compiled shader programs, keyed by filter type.\n     */\n    applyTo: function(options) {\n      this.calculateMatrix();\n      filters.BaseFilter.prototype.applyTo.call(this, options);\n    },\n\n  });\n\n  /**\n   * Returns filter instance from an object representation\n   * @static\n   * @param {Object} object Object to create an instance from\n   * @param {function} [callback] to be invoked after filter creation\n   * @return {fabric.Image.filters.HueRotation} Instance of fabric.Image.filters.HueRotation\n   */\n  fabric.Image.filters.HueRotation.fromObject = fabric.Image.filters.BaseFilter.fromObject;\n\n})(typeof exports !== 'undefined' ? exports : this);\n\n\n(function(global) {\n\n  'use strict';\n\n  var fabric = global.fabric || (global.fabric = { }),\n      clone = fabric.util.object.clone;\n\n  if (fabric.Text) {\n    fabric.warn('fabric.Text is already defined');\n    return;\n  }\n\n  /**\n   * Text class\n   * @class fabric.Text\n   * @extends fabric.Object\n   * @return {fabric.Text} thisArg\n   * @tutorial {@link http://fabricjs.com/fabric-intro-part-2#text}\n   * @see {@link fabric.Text#initialize} for constructor definition\n   */\n  fabric.Text = fabric.util.createClass(fabric.Object, /** @lends fabric.Text.prototype */ {\n\n    /**\n     * Properties which when set cause object to change dimensions\n     * @type Array\n     * @private\n     */\n    _dimensionAffectingProps: [\n      'fontSize',\n      'fontWeight',\n      'fontFamily',\n      'fontStyle',\n      'lineHeight',\n      'text',\n      'charSpacing',\n      'textAlign',\n      'styles',\n    ],\n\n    /**\n     * @private\n     */\n    _reNewline: /\\r?\\n/,\n\n    /**\n     * Use this regular expression to filter for whitespaces that is not a new line.\n     * Mostly used when text is 'justify' aligned.\n     * @private\n     */\n    _reSpacesAndTabs: /[ \\t\\r]/g,\n\n    /**\n     * Use this regular expression to filter for whitespace that is not a new line.\n     * Mostly used when text is 'justify' aligned.\n     * @private\n     */\n    _reSpaceAndTab: /[ \\t\\r]/,\n\n    /**\n     * Use this regular expression to filter consecutive groups of non spaces.\n     * Mostly used when text is 'justify' aligned.\n     * @private\n     */\n    _reWords: /\\S+/g,\n\n    /**\n     * Type of an object\n     * @type String\n     * @default\n     */\n    type:                 'text',\n\n    /**\n     * Font size (in pixels)\n     * @type Number\n     * @default\n     */\n    fontSize:             40,\n\n    /**\n     * Font weight (e.g. bold, normal, 400, 600, 800)\n     * @type {(Number|String)}\n     * @default\n     */\n    fontWeight:           'normal',\n\n    /**\n     * Font family\n     * @type String\n     * @default\n     */\n    fontFamily:           'Times New Roman',\n\n    /**\n     * Text decoration underline.\n     * @type Boolean\n     * @default\n     */\n    underline:       false,\n\n    /**\n     * Text decoration overline.\n     * @type Boolean\n     * @default\n     */\n    overline:       false,\n\n    /**\n     * Text decoration linethrough.\n     * @type Boolean\n     * @default\n     */\n    linethrough:       false,\n\n    /**\n     * Text alignment. Possible values: \"left\", \"center\", \"right\", \"justify\",\n     * \"justify-left\", \"justify-center\" or \"justify-right\".\n     * @type String\n     * @default\n     */\n    textAlign:            'left',\n\n    /**\n     * Font style . Possible values: \"\", \"normal\", \"italic\" or \"oblique\".\n     * @type String\n     * @default\n     */\n    fontStyle:            'normal',\n\n    /**\n     * Line height\n     * @type Number\n     * @default\n     */\n    lineHeight:           1.16,\n\n    /**\n     * Superscript schema object (minimum overlap)\n     * @type {Object}\n     * @default\n     */\n    superscript: {\n      size:      0.60, // fontSize factor\n      baseline: -0.35  // baseline-shift factor (upwards)\n    },\n\n    /**\n     * Subscript schema object (minimum overlap)\n     * @type {Object}\n     * @default\n     */\n    subscript: {\n      size:      0.60, // fontSize factor\n      baseline:  0.11  // baseline-shift factor (downwards)\n    },\n\n    /**\n     * Background color of text lines\n     * @type String\n     * @default\n     */\n    textBackgroundColor:  '',\n\n    /**\n     * List of properties to consider when checking if\n     * state of an object is changed ({@link fabric.Object#hasStateChanged})\n     * as well as for history (undo/redo) purposes\n     * @type Array\n     */\n    stateProperties: fabric.Object.prototype.stateProperties.concat('fontFamily',\n      'fontWeight',\n      'fontSize',\n      'text',\n      'underline',\n      'overline',\n      'linethrough',\n      'textAlign',\n      'fontStyle',\n      'lineHeight',\n      'textBackgroundColor',\n      'charSpacing',\n      'styles'),\n\n    /**\n     * List of properties to consider when checking if cache needs refresh\n     * @type Array\n     */\n    cacheProperties: fabric.Object.prototype.cacheProperties.concat('fontFamily',\n      'fontWeight',\n      'fontSize',\n      'text',\n      'underline',\n      'overline',\n      'linethrough',\n      'textAlign',\n      'fontStyle',\n      'lineHeight',\n      'textBackgroundColor',\n      'charSpacing',\n      'styles'),\n\n    /**\n     * When defined, an object is rendered via stroke and this property specifies its color.\n     * <b>Backwards incompatibility note:</b> This property was named \"strokeStyle\" until v1.1.6\n     * @type String\n     * @default\n     */\n    stroke:               null,\n\n    /**\n     * Shadow object representing shadow of this shape.\n     * <b>Backwards incompatibility note:</b> This property was named \"textShadow\" (String) until v1.2.11\n     * @type fabric.Shadow\n     * @default\n     */\n    shadow:               null,\n\n    /**\n     * @private\n     */\n    _fontSizeFraction: 0.222,\n\n    /**\n     * @private\n     */\n    offsets: {\n      underline: 0.10,\n      linethrough: -0.315,\n      overline: -0.88\n    },\n\n    /**\n     * Text Line proportion to font Size (in pixels)\n     * @type Number\n     * @default\n     */\n    _fontSizeMult:             1.13,\n\n    /**\n     * additional space between characters\n     * expressed in thousands of em unit\n     * @type Number\n     * @default\n     */\n    charSpacing:             0,\n\n    /**\n     * Object containing character styles - top-level properties -> line numbers,\n     * 2nd-level properties - charater numbers\n     * @type Object\n     * @default\n     */\n    styles: null,\n\n    /**\n     * Reference to a context to measure text char or couple of chars\n     * the cacheContext of the canvas will be used or a freshly created one if the object is not on canvas\n     * once created it will be referenced on fabric._measuringContext to avoide creating a canvas for every\n     * text object created.\n     * @type {CanvasRenderingContext2D}\n     * @default\n     */\n    _measuringContext: null,\n\n    /**\n     * Baseline shift, stlyes only, keep at 0 for the main text object\n     * @type {Number}\n     * @default\n     */\n    deltaY: 0,\n\n    /**\n     * Array of properties that define a style unit (of 'styles').\n     * @type {Array}\n     * @default\n     */\n    _styleProperties: [\n      'stroke',\n      'strokeWidth',\n      'fill',\n      'fontFamily',\n      'fontSize',\n      'fontWeight',\n      'fontStyle',\n      'underline',\n      'overline',\n      'linethrough',\n      'deltaY',\n      'textBackgroundColor',\n    ],\n\n    /**\n     * contains characters bounding boxes\n     */\n    __charBounds: [],\n\n    /**\n     * use this size when measuring text. To avoid IE11 rounding errors\n     * @type {Number}\n     * @default\n     * @readonly\n     * @private\n     */\n    CACHE_FONT_SIZE: 400,\n\n    /**\n     * contains the min text width to avoid getting 0\n     * @type {Number}\n     * @default\n     */\n    MIN_TEXT_WIDTH: 2,\n\n    /**\n     * Constructor\n     * @param {String} text Text string\n     * @param {Object} [options] Options object\n     * @return {fabric.Text} thisArg\n     */\n    initialize: function(text, options) {\n      this.styles = options ? (options.styles || { }) : { };\n      this.text = text;\n      this.__skipDimension = true;\n      this.callSuper('initialize', options);\n      this.__skipDimension = false;\n      this.initDimensions();\n      this.setCoords();\n      this.setupState({ propertySet: '_dimensionAffectingProps' });\n    },\n\n    /**\n     * Return a contex for measurement of text string.\n     * if created it gets stored for reuse\n     * @param {String} text Text string\n     * @param {Object} [options] Options object\n     * @return {fabric.Text} thisArg\n     */\n    getMeasuringContext: function() {\n      // if we did not return we have to measure something.\n      if (!fabric._measuringContext) {\n        fabric._measuringContext = this.canvas && this.canvas.contextCache ||\n          fabric.util.createCanvasElement().getContext('2d');\n      }\n      return fabric._measuringContext;\n    },\n\n    /**\n     * @private\n     * Divides text into lines of text and lines of graphemes.\n     */\n    _splitText: function() {\n      var newLines = this._splitTextIntoLines(this.text);\n      this.textLines = newLines.lines;\n      this._textLines = newLines.graphemeLines;\n      this._unwrappedTextLines = newLines._unwrappedLines;\n      this._text = newLines.graphemeText;\n      return newLines;\n    },\n\n    /**\n     * Initialize or update text dimensions.\n     * Updates this.width and this.height with the proper values.\n     * Does not return dimensions.\n     */\n    initDimensions: function() {\n      if (this.__skipDimension) {\n        return;\n      }\n      this._splitText();\n      this._clearCache();\n      this.width = this.calcTextWidth() || this.cursorWidth || this.MIN_TEXT_WIDTH;\n      if (this.textAlign.indexOf('justify') !== -1) {\n        // once text is measured we need to make space fatter to make justified text.\n        this.enlargeSpaces();\n      }\n      this.height = this.calcTextHeight();\n      this.saveState({ propertySet: '_dimensionAffectingProps' });\n    },\n\n    /**\n     * Enlarge space boxes and shift the others\n     */\n    enlargeSpaces: function() {\n      var diffSpace, currentLineWidth, numberOfSpaces, accumulatedSpace, line, charBound, spaces;\n      for (var i = 0, len = this._textLines.length; i < len; i++) {\n        if (this.textAlign !== 'justify' && (i === len - 1 || this.isEndOfWrapping(i))) {\n          continue;\n        }\n        accumulatedSpace = 0;\n        line = this._textLines[i];\n        currentLineWidth = this.getLineWidth(i);\n        if (currentLineWidth < this.width && (spaces = this.textLines[i].match(this._reSpacesAndTabs))) {\n          numberOfSpaces = spaces.length;\n          diffSpace = (this.width - currentLineWidth) / numberOfSpaces;\n          for (var j = 0, jlen = line.length; j <= jlen; j++) {\n            charBound = this.__charBounds[i][j];\n            if (this._reSpaceAndTab.test(line[j])) {\n              charBound.width += diffSpace;\n              charBound.kernedWidth += diffSpace;\n              charBound.left += accumulatedSpace;\n              accumulatedSpace += diffSpace;\n            }\n            else {\n              charBound.left += accumulatedSpace;\n            }\n          }\n        }\n      }\n    },\n\n    /**\n     * Detect if the text line is ended with an hard break\n     * text and itext do not have wrapping, return false\n     * @return {Boolean}\n     */\n    isEndOfWrapping: function(lineIndex) {\n      return lineIndex === this._textLines.length - 1;\n    },\n\n    /**\n     * Returns string representation of an instance\n     * @return {String} String representation of text object\n     */\n    toString: function() {\n      return '#<fabric.Text (' + this.complexity() +\n        '): { \"text\": \"' + this.text + '\", \"fontFamily\": \"' + this.fontFamily + '\" }>';\n    },\n\n    /**\n     * Return the dimension and the zoom level needed to create a cache canvas\n     * big enough to host the object to be cached.\n     * @private\n     * @param {Object} dim.x width of object to be cached\n     * @param {Object} dim.y height of object to be cached\n     * @return {Object}.width width of canvas\n     * @return {Object}.height height of canvas\n     * @return {Object}.zoomX zoomX zoom value to unscale the canvas before drawing cache\n     * @return {Object}.zoomY zoomY zoom value to unscale the canvas before drawing cache\n     */\n    _getCacheCanvasDimensions: function() {\n      var dims = this.callSuper('_getCacheCanvasDimensions');\n      var fontSize = this.fontSize;\n      dims.width += fontSize * dims.zoomX;\n      dims.height += fontSize * dims.zoomY;\n      return dims;\n    },\n\n    /**\n     * @private\n     * @param {CanvasRenderingContext2D} ctx Context to render on\n     */\n    _render: function(ctx) {\n      this._setTextStyles(ctx);\n      this._renderTextLinesBackground(ctx);\n      this._renderTextDecoration(ctx, 'underline');\n      this._renderText(ctx);\n      this._renderTextDecoration(ctx, 'overline');\n      this._renderTextDecoration(ctx, 'linethrough');\n    },\n\n    /**\n     * @private\n     * @param {CanvasRenderingContext2D} ctx Context to render on\n     */\n    _renderText: function(ctx) {\n      if (this.paintFirst === 'stroke') {\n        this._renderTextStroke(ctx);\n        this._renderTextFill(ctx);\n      }\n      else {\n        this._renderTextFill(ctx);\n        this._renderTextStroke(ctx);\n      }\n    },\n\n    /**\n     * Set the font parameter of the context with the object properties or with charStyle\n     * @private\n     * @param {CanvasRenderingContext2D} ctx Context to render on\n     * @param {Object} [charStyle] object with font style properties\n     * @param {String} [charStyle.fontFamily] Font Family\n     * @param {Number} [charStyle.fontSize] Font size in pixels. ( without px suffix )\n     * @param {String} [charStyle.fontWeight] Font weight\n     * @param {String} [charStyle.fontStyle] Font style (italic|normal)\n     */\n    _setTextStyles: function(ctx, charStyle, forMeasuring) {\n      ctx.textBaseline = 'alphabetic';\n      ctx.font = this._getFontDeclaration(charStyle, forMeasuring);\n    },\n\n    /**\n     * calculate and return the text Width measuring each line.\n     * @private\n     * @param {CanvasRenderingContext2D} ctx Context to render on\n     * @return {Number} Maximum width of fabric.Text object\n     */\n    calcTextWidth: function() {\n      var maxWidth = this.getLineWidth(0);\n\n      for (var i = 1, len = this._textLines.length; i < len; i++) {\n        var currentLineWidth = this.getLineWidth(i);\n        if (currentLineWidth > maxWidth) {\n          maxWidth = currentLineWidth;\n        }\n      }\n      return maxWidth;\n    },\n\n    /**\n     * @private\n     * @param {String} method Method name (\"fillText\" or \"strokeText\")\n     * @param {CanvasRenderingContext2D} ctx Context to render on\n     * @param {String} line Text to render\n     * @param {Number} left Left position of text\n     * @param {Number} top Top position of text\n     * @param {Number} lineIndex Index of a line in a text\n     */\n    _renderTextLine: function(method, ctx, line, left, top, lineIndex) {\n      this._renderChars(method, ctx, line, left, top, lineIndex);\n    },\n\n    /**\n     * Renders the text background for lines, taking care of style\n     * @private\n     * @param {CanvasRenderingContext2D} ctx Context to render on\n     */\n    _renderTextLinesBackground: function(ctx) {\n      if (!this.textBackgroundColor && !this.styleHas('textBackgroundColor')) {\n        return;\n      }\n      var lineTopOffset = 0, heightOfLine,\n          lineLeftOffset, originalFill = ctx.fillStyle,\n          line, lastColor,\n          leftOffset = this._getLeftOffset(),\n          topOffset = this._getTopOffset(),\n          boxStart = 0, boxWidth = 0, charBox, currentColor;\n\n      for (var i = 0, len = this._textLines.length; i < len; i++) {\n        heightOfLine = this.getHeightOfLine(i);\n        if (!this.textBackgroundColor && !this.styleHas('textBackgroundColor', i)) {\n          lineTopOffset += heightOfLine;\n          continue;\n        }\n        line = this._textLines[i];\n        lineLeftOffset = this._getLineLeftOffset(i);\n        boxWidth = 0;\n        boxStart = 0;\n        lastColor = this.getValueOfPropertyAt(i, 0, 'textBackgroundColor');\n        for (var j = 0, jlen = line.length; j < jlen; j++) {\n          charBox = this.__charBounds[i][j];\n          currentColor = this.getValueOfPropertyAt(i, j, 'textBackgroundColor');\n          if (currentColor !== lastColor) {\n            ctx.fillStyle = lastColor;\n            lastColor && ctx.fillRect(\n              leftOffset + lineLeftOffset + boxStart,\n              topOffset + lineTopOffset,\n              boxWidth,\n              heightOfLine / this.lineHeight\n            );\n            boxStart = charBox.left;\n            boxWidth = charBox.width;\n            lastColor = currentColor;\n          }\n          else {\n            boxWidth += charBox.kernedWidth;\n          }\n        }\n        if (currentColor) {\n          ctx.fillStyle = currentColor;\n          ctx.fillRect(\n            leftOffset + lineLeftOffset + boxStart,\n            topOffset + lineTopOffset,\n            boxWidth,\n            heightOfLine / this.lineHeight\n          );\n        }\n        lineTopOffset += heightOfLine;\n      }\n      ctx.fillStyle = originalFill;\n      // if there is text background color no\n      // other shadows should be casted\n      this._removeShadow(ctx);\n    },\n\n    /**\n     * @private\n     * @param {Object} decl style declaration for cache\n     * @param {String} decl.fontFamily fontFamily\n     * @param {String} decl.fontStyle fontStyle\n     * @param {String} decl.fontWeight fontWeight\n     * @return {Object} reference to cache\n     */\n    getFontCache: function(decl) {\n      var fontFamily = decl.fontFamily.toLowerCase();\n      if (!fabric.charWidthsCache[fontFamily]) {\n        fabric.charWidthsCache[fontFamily] = { };\n      }\n      var cache = fabric.charWidthsCache[fontFamily],\n          cacheProp = decl.fontStyle.toLowerCase() + '_' + (decl.fontWeight + '').toLowerCase();\n      if (!cache[cacheProp]) {\n        cache[cacheProp] = { };\n      }\n      return cache[cacheProp];\n    },\n\n    /**\n     * apply all the character style to canvas for rendering\n     * @private\n     * @param {String} _char\n     * @param {Number} lineIndex\n     * @param {Number} charIndex\n     * @param {Object} [decl]\n     */\n    _applyCharStyles: function(method, ctx, lineIndex, charIndex, styleDeclaration) {\n\n      this._setFillStyles(ctx, styleDeclaration);\n      this._setStrokeStyles(ctx, styleDeclaration);\n\n      ctx.font = this._getFontDeclaration(styleDeclaration);\n    },\n\n    /**\n     * measure and return the width of a single character.\n     * possibly overridden to accommodate different measure logic or\n     * to hook some external lib for character measurement\n     * @private\n     * @param {String} char to be measured\n     * @param {Object} charStyle style of char to be measured\n     * @param {String} [previousChar] previous char\n     * @param {Object} [prevCharStyle] style of previous char\n     */\n    _measureChar: function(_char, charStyle, previousChar, prevCharStyle) {\n      // first i try to return from cache\n      var fontCache = this.getFontCache(charStyle), fontDeclaration = this._getFontDeclaration(charStyle),\n          previousFontDeclaration = this._getFontDeclaration(prevCharStyle), couple = previousChar + _char,\n          stylesAreEqual = fontDeclaration === previousFontDeclaration, width, coupleWidth, previousWidth,\n          fontMultiplier = charStyle.fontSize / this.CACHE_FONT_SIZE, kernedWidth;\n\n      if (previousChar && fontCache[previousChar] !== undefined) {\n        previousWidth = fontCache[previousChar];\n      }\n      if (fontCache[_char] !== undefined) {\n        kernedWidth = width = fontCache[_char];\n      }\n      if (stylesAreEqual && fontCache[couple] !== undefined) {\n        coupleWidth = fontCache[couple];\n        kernedWidth = coupleWidth - previousWidth;\n      }\n      if (width === undefined || previousWidth === undefined || coupleWidth === undefined) {\n        var ctx = this.getMeasuringContext();\n        // send a TRUE to specify measuring font size CACHE_FONT_SIZE\n        this._setTextStyles(ctx, charStyle, true);\n      }\n      if (width === undefined) {\n        kernedWidth = width = ctx.measureText(_char).width;\n        fontCache[_char] = width;\n      }\n      if (previousWidth === undefined && stylesAreEqual && previousChar) {\n        previousWidth = ctx.measureText(previousChar).width;\n        fontCache[previousChar] = previousWidth;\n      }\n      if (stylesAreEqual && coupleWidth === undefined) {\n        // we can measure the kerning couple and subtract the width of the previous character\n        coupleWidth = ctx.measureText(couple).width;\n        fontCache[couple] = coupleWidth;\n        kernedWidth = coupleWidth - previousWidth;\n      }\n      return { width: width * fontMultiplier, kernedWidth: kernedWidth * fontMultiplier };\n    },\n\n    /**\n     * Computes height of character at given position\n     * @param {Number} line the line number\n     * @param {Number} char the character number\n     * @return {Number} fontSize of the character\n     */\n    getHeightOfChar: function(line, char) {\n      return this.getValueOfPropertyAt(line, char, 'fontSize');\n    },\n\n    /**\n     * measure a text line measuring all characters.\n     * @param {Number} lineIndex line number\n     * @return {Number} Line width\n     */\n    measureLine: function(lineIndex) {\n      var lineInfo = this._measureLine(lineIndex);\n      if (this.charSpacing !== 0) {\n        lineInfo.width -= this._getWidthOfCharSpacing();\n      }\n      if (lineInfo.width < 0) {\n        lineInfo.width = 0;\n      }\n      return lineInfo;\n    },\n\n    /**\n     * measure every grapheme of a line, populating __charBounds\n     * @param {Number} lineIndex\n     * @return {Object} object.width total width of characters\n     * @return {Object} object.widthOfSpaces length of chars that match this._reSpacesAndTabs\n     */\n    _measureLine: function(lineIndex) {\n      var width = 0, i, grapheme, line = this._textLines[lineIndex], prevGrapheme,\n          graphemeInfo, numOfSpaces = 0, lineBounds = new Array(line.length);\n\n      this.__charBounds[lineIndex] = lineBounds;\n      for (i = 0; i < line.length; i++) {\n        grapheme = line[i];\n        graphemeInfo = this._getGraphemeBox(grapheme, lineIndex, i, prevGrapheme);\n        lineBounds[i] = graphemeInfo;\n        width += graphemeInfo.kernedWidth;\n        prevGrapheme = grapheme;\n      }\n      // this latest bound box represent the last character of the line\n      // to simplify cursor handling in interactive mode.\n      lineBounds[i] = {\n        left: graphemeInfo ? graphemeInfo.left + graphemeInfo.width : 0,\n        width: 0,\n        kernedWidth: 0,\n        height: this.fontSize\n      };\n      return { width: width, numOfSpaces: numOfSpaces };\n    },\n\n    /**\n     * Measure and return the info of a single grapheme.\n     * needs the the info of previous graphemes already filled\n     * @private\n     * @param {String} grapheme to be measured\n     * @param {Number} lineIndex index of the line where the char is\n     * @param {Number} charIndex position in the line\n     * @param {String} [prevGrapheme] character preceding the one to be measured\n     */\n    _getGraphemeBox: function(grapheme, lineIndex, charIndex, prevGrapheme, skipLeft) {\n      var style = this.getCompleteStyleDeclaration(lineIndex, charIndex),\n          prevStyle = prevGrapheme ? this.getCompleteStyleDeclaration(lineIndex, charIndex - 1) : { },\n          info = this._measureChar(grapheme, style, prevGrapheme, prevStyle),\n          kernedWidth = info.kernedWidth,\n          width = info.width, charSpacing;\n\n      if (this.charSpacing !== 0) {\n        charSpacing = this._getWidthOfCharSpacing();\n        width += charSpacing;\n        kernedWidth += charSpacing;\n      }\n\n      var box = {\n        width: width,\n        left: 0,\n        height: style.fontSize,\n        kernedWidth: kernedWidth,\n        deltaY: style.deltaY,\n      };\n      if (charIndex > 0 && !skipLeft) {\n        var previousBox = this.__charBounds[lineIndex][charIndex - 1];\n        box.left = previousBox.left + previousBox.width + info.kernedWidth - info.width;\n      }\n      return box;\n    },\n\n    /**\n     * Calculate height of line at 'lineIndex'\n     * @param {Number} lineIndex index of line to calculate\n     * @return {Number}\n     */\n    getHeightOfLine: function(lineIndex) {\n      if (this.__lineHeights[lineIndex]) {\n        return this.__lineHeights[lineIndex];\n      }\n\n      var line = this._textLines[lineIndex],\n          // char 0 is measured before the line cycle because it nneds to char\n          // emptylines\n          maxHeight = this.getHeightOfChar(lineIndex, 0);\n      for (var i = 1, len = line.length; i < len; i++) {\n        maxHeight = Math.max(this.getHeightOfChar(lineIndex, i), maxHeight);\n      }\n\n      return this.__lineHeights[lineIndex] = maxHeight * this.lineHeight * this._fontSizeMult;\n    },\n\n    /**\n     * Calculate text box height\n     */\n    calcTextHeight: function() {\n      var lineHeight, height = 0;\n      for (var i = 0, len = this._textLines.length; i < len; i++) {\n        lineHeight = this.getHeightOfLine(i);\n        height += (i === len - 1 ? lineHeight / this.lineHeight : lineHeight);\n      }\n      return height;\n    },\n\n    /**\n     * @private\n     * @return {Number} Left offset\n     */\n    _getLeftOffset: function() {\n      return -this.width / 2;\n    },\n\n    /**\n     * @private\n     * @return {Number} Top offset\n     */\n    _getTopOffset: function() {\n      return -this.height / 2;\n    },\n\n    /**\n     * @private\n     * @param {CanvasRenderingContext2D} ctx Context to render on\n     * @param {String} method Method name (\"fillText\" or \"strokeText\")\n     */\n    _renderTextCommon: function(ctx, method) {\n      ctx.save();\n      var lineHeights = 0, left = this._getLeftOffset(), top = this._getTopOffset(),\n          offsets = this._applyPatternGradientTransform(ctx, method === 'fillText' ? this.fill : this.stroke);\n      for (var i = 0, len = this._textLines.length; i < len; i++) {\n        var heightOfLine = this.getHeightOfLine(i),\n            maxHeight = heightOfLine / this.lineHeight,\n            leftOffset = this._getLineLeftOffset(i);\n        this._renderTextLine(\n          method,\n          ctx,\n          this._textLines[i],\n          left + leftOffset - offsets.offsetX,\n          top + lineHeights + maxHeight - offsets.offsetY,\n          i\n        );\n        lineHeights += heightOfLine;\n      }\n      ctx.restore();\n    },\n\n    /**\n     * @private\n     * @param {CanvasRenderingContext2D} ctx Context to render on\n     */\n    _renderTextFill: function(ctx) {\n      if (!this.fill && !this.styleHas('fill')) {\n        return;\n      }\n\n      this._renderTextCommon(ctx, 'fillText');\n    },\n\n    /**\n     * @private\n     * @param {CanvasRenderingContext2D} ctx Context to render on\n     */\n    _renderTextStroke: function(ctx) {\n      if ((!this.stroke || this.strokeWidth === 0) && this.isEmptyStyles()) {\n        return;\n      }\n\n      if (this.shadow && !this.shadow.affectStroke) {\n        this._removeShadow(ctx);\n      }\n\n      ctx.save();\n      this._setLineDash(ctx, this.strokeDashArray);\n      ctx.beginPath();\n      this._renderTextCommon(ctx, 'strokeText');\n      ctx.closePath();\n      ctx.restore();\n    },\n\n    /**\n     * @private\n     * @param {String} method\n     * @param {CanvasRenderingContext2D} ctx Context to render on\n     * @param {String} line Content of the line\n     * @param {Number} left\n     * @param {Number} top\n     * @param {Number} lineIndex\n     * @param {Number} charOffset\n     */\n    _renderChars: function(method, ctx, line, left, top, lineIndex) {\n      // set proper line offset\n      var lineHeight = this.getHeightOfLine(lineIndex),\n          isJustify = this.textAlign.indexOf('justify') !== -1,\n          actualStyle,\n          nextStyle,\n          charsToRender = '',\n          charBox,\n          boxWidth = 0,\n          timeToRender,\n          shortCut = !isJustify && this.charSpacing === 0 && this.isEmptyStyles(lineIndex);\n\n      ctx.save();\n      top -= lineHeight * this._fontSizeFraction / this.lineHeight;\n      if (shortCut) {\n        // render all the line in one pass without checking\n        this._renderChar(method, ctx, lineIndex, 0, this.textLines[lineIndex], left, top, lineHeight);\n        ctx.restore();\n        return;\n      }\n      for (var i = 0, len = line.length - 1; i <= len; i++) {\n        timeToRender = i === len || this.charSpacing;\n        charsToRender += line[i];\n        charBox = this.__charBounds[lineIndex][i];\n        if (boxWidth === 0) {\n          left += charBox.kernedWidth - charBox.width;\n          boxWidth += charBox.width;\n        }\n        else {\n          boxWidth += charBox.kernedWidth;\n        }\n        if (isJustify && !timeToRender) {\n          if (this._reSpaceAndTab.test(line[i])) {\n            timeToRender = true;\n          }\n        }\n        if (!timeToRender) {\n          // if we have charSpacing, we render char by char\n          actualStyle = actualStyle || this.getCompleteStyleDeclaration(lineIndex, i);\n          nextStyle = this.getCompleteStyleDeclaration(lineIndex, i + 1);\n          timeToRender = this._hasStyleChanged(actualStyle, nextStyle);\n        }\n        if (timeToRender) {\n          this._renderChar(method, ctx, lineIndex, i, charsToRender, left, top, lineHeight);\n          charsToRender = '';\n          actualStyle = nextStyle;\n          left += boxWidth;\n          boxWidth = 0;\n        }\n      }\n      ctx.restore();\n    },\n\n    /**\n     * @private\n     * @param {String} method\n     * @param {CanvasRenderingContext2D} ctx Context to render on\n     * @param {Number} lineIndex\n     * @param {Number} charIndex\n     * @param {String} _char\n     * @param {Number} left Left coordinate\n     * @param {Number} top Top coordinate\n     * @param {Number} lineHeight Height of the line\n     */\n    _renderChar: function(method, ctx, lineIndex, charIndex, _char, left, top) {\n      var decl = this._getStyleDeclaration(lineIndex, charIndex),\n          fullDecl = this.getCompleteStyleDeclaration(lineIndex, charIndex),\n          shouldFill = method === 'fillText' && fullDecl.fill,\n          shouldStroke = method === 'strokeText' && fullDecl.stroke && fullDecl.strokeWidth;\n\n      if (!shouldStroke && !shouldFill) {\n        return;\n      }\n      decl && ctx.save();\n\n      this._applyCharStyles(method, ctx, lineIndex, charIndex, fullDecl);\n\n      if (decl && decl.textBackgroundColor) {\n        this._removeShadow(ctx);\n      }\n      if (decl && decl.deltaY) {\n        top += decl.deltaY;\n      }\n\n      shouldFill && ctx.fillText(_char, left, top);\n      shouldStroke && ctx.strokeText(_char, left, top);\n      decl && ctx.restore();\n    },\n\n    /**\n     * Turns the character into a 'superior figure' (i.e. 'superscript')\n     * @param {Number} start selection start\n     * @param {Number} end selection end\n     * @returns {fabric.Text} thisArg\n     * @chainable\n     */\n    setSuperscript: function(start, end) {\n      return this._setScript(start, end, this.superscript);\n    },\n\n    /**\n     * Turns the character into an 'inferior figure' (i.e. 'subscript')\n     * @param {Number} start selection start\n     * @param {Number} end selection end\n     * @returns {fabric.Text} thisArg\n     * @chainable\n     */\n    setSubscript: function(start, end) {\n      return this._setScript(start, end, this.subscript);\n    },\n\n    /**\n     * Applies 'schema' at given position\n     * @private\n     * @param {Number} start selection start\n     * @param {Number} end selection end\n     * @param {Number} schema\n     * @returns {fabric.Text} thisArg\n     * @chainable\n     */\n    _setScript: function(start, end, schema) {\n      var loc = this.get2DCursorLocation(start, true),\n          fontSize = this.getValueOfPropertyAt(loc.lineIndex, loc.charIndex, 'fontSize'),\n          dy = this.getValueOfPropertyAt(loc.lineIndex, loc.charIndex, 'deltaY'),\n          style = { fontSize: fontSize * schema.size, deltaY: dy + fontSize * schema.baseline };\n      this.setSelectionStyles(style, start, end);\n      return this;\n    },\n\n    /**\n     * @private\n     * @param {Object} prevStyle\n     * @param {Object} thisStyle\n     */\n    _hasStyleChanged: function(prevStyle, thisStyle) {\n      return prevStyle.fill !== thisStyle.fill ||\n              prevStyle.stroke !== thisStyle.stroke ||\n              prevStyle.strokeWidth !== thisStyle.strokeWidth ||\n              prevStyle.fontSize !== thisStyle.fontSize ||\n              prevStyle.fontFamily !== thisStyle.fontFamily ||\n              prevStyle.fontWeight !== thisStyle.fontWeight ||\n              prevStyle.fontStyle !== thisStyle.fontStyle ||\n              prevStyle.deltaY !== thisStyle.deltaY;\n    },\n\n    /**\n     * @private\n     * @param {Object} prevStyle\n     * @param {Object} thisStyle\n     */\n    _hasStyleChangedForSvg: function(prevStyle, thisStyle) {\n      return this._hasStyleChanged(prevStyle, thisStyle) ||\n        prevStyle.overline !== thisStyle.overline ||\n        prevStyle.underline !== thisStyle.underline ||\n        prevStyle.linethrough !== thisStyle.linethrough;\n    },\n\n    /**\n     * @private\n     * @param {Number} lineIndex index text line\n     * @return {Number} Line left offset\n     */\n    _getLineLeftOffset: function(lineIndex) {\n      var lineWidth = this.getLineWidth(lineIndex);\n      if (this.textAlign === 'center') {\n        return (this.width - lineWidth) / 2;\n      }\n      if (this.textAlign === 'right') {\n        return this.width - lineWidth;\n      }\n      if (this.textAlign === 'justify-center' && this.isEndOfWrapping(lineIndex)) {\n        return (this.width - lineWidth) / 2;\n      }\n      if (this.textAlign === 'justify-right' && this.isEndOfWrapping(lineIndex)) {\n        return this.width - lineWidth;\n      }\n      return 0;\n    },\n\n    /**\n     * @private\n     */\n    _clearCache: function() {\n      this.__lineWidths = [];\n      this.__lineHeights = [];\n      this.__charBounds = [];\n    },\n\n    /**\n     * @private\n     */\n    _shouldClearDimensionCache: function() {\n      var shouldClear = this._forceClearCache;\n      shouldClear || (shouldClear = this.hasStateChanged('_dimensionAffectingProps'));\n      if (shouldClear) {\n        this.dirty = true;\n        this._forceClearCache = false;\n      }\n      return shouldClear;\n    },\n\n    /**\n     * Measure a single line given its index. Used to calculate the initial\n     * text bounding box. The values are calculated and stored in __lineWidths cache.\n     * @private\n     * @param {Number} lineIndex line number\n     * @return {Number} Line width\n     */\n    getLineWidth: function(lineIndex) {\n      if (this.__lineWidths[lineIndex]) {\n        return this.__lineWidths[lineIndex];\n      }\n\n      var width, line = this._textLines[lineIndex], lineInfo;\n\n      if (line === '') {\n        width = 0;\n      }\n      else {\n        lineInfo = this.measureLine(lineIndex);\n        width = lineInfo.width;\n      }\n      this.__lineWidths[lineIndex] = width;\n      return width;\n    },\n\n    _getWidthOfCharSpacing: function() {\n      if (this.charSpacing !== 0) {\n        return this.fontSize * this.charSpacing / 1000;\n      }\n      return 0;\n    },\n\n    /**\n     * Retrieves the value of property at given character position\n     * @param {Number} lineIndex the line number\n     * @param {Number} charIndex the charater number\n     * @param {String} property the property name\n     * @returns the value of 'property'\n     */\n    getValueOfPropertyAt: function(lineIndex, charIndex, property) {\n      var charStyle = this._getStyleDeclaration(lineIndex, charIndex);\n      if (charStyle && typeof charStyle[property] !== 'undefined') {\n        return charStyle[property];\n      }\n      return this[property];\n    },\n\n    /**\n     * @private\n     * @param {CanvasRenderingContext2D} ctx Context to render on\n     */\n    _renderTextDecoration: function(ctx, type) {\n      if (!this[type] && !this.styleHas(type)) {\n        return;\n      }\n      var heightOfLine, size, _size,\n          lineLeftOffset, dy, _dy,\n          line, lastDecoration,\n          leftOffset = this._getLeftOffset(),\n          topOffset = this._getTopOffset(), top,\n          boxStart, boxWidth, charBox, currentDecoration,\n          maxHeight, currentFill, lastFill,\n          charSpacing = this._getWidthOfCharSpacing();\n\n      for (var i = 0, len = this._textLines.length; i < len; i++) {\n        heightOfLine = this.getHeightOfLine(i);\n        if (!this[type] && !this.styleHas(type, i)) {\n          topOffset += heightOfLine;\n          continue;\n        }\n        line = this._textLines[i];\n        maxHeight = heightOfLine / this.lineHeight;\n        lineLeftOffset = this._getLineLeftOffset(i);\n        boxStart = 0;\n        boxWidth = 0;\n        lastDecoration = this.getValueOfPropertyAt(i, 0, type);\n        lastFill = this.getValueOfPropertyAt(i, 0, 'fill');\n        top = topOffset + maxHeight * (1 - this._fontSizeFraction);\n        size = this.getHeightOfChar(i, 0);\n        dy = this.getValueOfPropertyAt(i, 0, 'deltaY');\n        for (var j = 0, jlen = line.length; j < jlen; j++) {\n          charBox = this.__charBounds[i][j];\n          currentDecoration = this.getValueOfPropertyAt(i, j, type);\n          currentFill = this.getValueOfPropertyAt(i, j, 'fill');\n          _size = this.getHeightOfChar(i, j);\n          _dy = this.getValueOfPropertyAt(i, j, 'deltaY');\n          if ((currentDecoration !== lastDecoration || currentFill !== lastFill || _size !== size || _dy !== dy) &&\n              boxWidth > 0) {\n            ctx.fillStyle = lastFill;\n            lastDecoration && lastFill && ctx.fillRect(\n              leftOffset + lineLeftOffset + boxStart,\n              top + this.offsets[type] * size + dy,\n              boxWidth,\n              this.fontSize / 15\n            );\n            boxStart = charBox.left;\n            boxWidth = charBox.width;\n            lastDecoration = currentDecoration;\n            lastFill = currentFill;\n            size = _size;\n            dy = _dy;\n          }\n          else {\n            boxWidth += charBox.kernedWidth;\n          }\n        }\n        ctx.fillStyle = currentFill;\n        currentDecoration && currentFill && ctx.fillRect(\n          leftOffset + lineLeftOffset + boxStart,\n          top + this.offsets[type] * size + dy,\n          boxWidth - charSpacing,\n          this.fontSize / 15\n        );\n        topOffset += heightOfLine;\n      }\n      // if there is text background color no\n      // other shadows should be casted\n      this._removeShadow(ctx);\n    },\n\n    /**\n     * return font declaration string for canvas context\n     * @param {Object} [styleObject] object\n     * @returns {String} font declaration formatted for canvas context.\n     */\n    _getFontDeclaration: function(styleObject, forMeasuring) {\n      var style = styleObject || this, family = this.fontFamily,\n          fontIsGeneric = fabric.Text.genericFonts.indexOf(family.toLowerCase()) > -1;\n      var fontFamily = family === undefined ||\n      family.indexOf('\\'') > -1 ||\n      family.indexOf('\"') > -1 || fontIsGeneric\n        ? style.fontFamily : '\"' + style.fontFamily + '\"';\n      return [\n        // node-canvas needs \"weight style\", while browsers need \"style weight\"\n        (fabric.isLikelyNode ? style.fontWeight : style.fontStyle),\n        (fabric.isLikelyNode ? style.fontStyle : style.fontWeight),\n        forMeasuring ? this.CACHE_FONT_SIZE + 'px' : style.fontSize + 'px',\n        fontFamily\n      ].join(' ');\n    },\n\n    /**\n     * Renders text instance on a specified context\n     * @param {CanvasRenderingContext2D} ctx Context to render on\n     */\n    render: function(ctx) {\n      // do not render if object is not visible\n      if (!this.visible) {\n        return;\n      }\n      if (this.canvas && this.canvas.skipOffscreen && !this.group && !this.isOnScreen()) {\n        return;\n      }\n      if (this._shouldClearDimensionCache()) {\n        this.initDimensions();\n      }\n      this.callSuper('render', ctx);\n    },\n\n    /**\n     * Returns the text as an array of lines.\n     * @param {String} text text to split\n     * @returns {Array} Lines in the text\n     */\n    _splitTextIntoLines: function(text) {\n      var lines = text.split(this._reNewline),\n          newLines = new Array(lines.length),\n          newLine = ['\\n'],\n          newText = [];\n      for (var i = 0; i < lines.length; i++) {\n        newLines[i] = fabric.util.string.graphemeSplit(lines[i]);\n        newText = newText.concat(newLines[i], newLine);\n      }\n      newText.pop();\n      return { _unwrappedLines: newLines, lines: lines, graphemeText: newText, graphemeLines: newLines };\n    },\n\n    /**\n     * Returns object representation of an instance\n     * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output\n     * @return {Object} Object representation of an instance\n     */\n    toObject: function(propertiesToInclude) {\n      var additionalProperties = [\n        'text',\n        'fontSize',\n        'fontWeight',\n        'fontFamily',\n        'fontStyle',\n        'lineHeight',\n        'underline',\n        'overline',\n        'linethrough',\n        'textAlign',\n        'textBackgroundColor',\n        'charSpacing',\n      ].concat(propertiesToInclude);\n      var obj = this.callSuper('toObject', additionalProperties);\n      obj.styles = clone(this.styles, true);\n      return obj;\n    },\n\n    /**\n     * Sets property to a given value. When changing position/dimension -related properties (left, top, scale, angle, etc.) `set` does not update position of object's borders/controls. If you need to update those, call `setCoords()`.\n     * @param {String|Object} key Property name or object (if object, iterate over the object properties)\n     * @param {Object|Function} value Property value (if function, the value is passed into it and its return value is used as a new one)\n     * @return {fabric.Object} thisArg\n     * @chainable\n     */\n    set: function(key, value) {\n      this.callSuper('set', key, value);\n      var needsDims = false;\n      if (typeof key === 'object') {\n        for (var _key in key) {\n          needsDims = needsDims || this._dimensionAffectingProps.indexOf(_key) !== -1;\n        }\n      }\n      else {\n        needsDims = this._dimensionAffectingProps.indexOf(key) !== -1;\n      }\n      if (needsDims) {\n        this.initDimensions();\n        this.setCoords();\n      }\n      return this;\n    },\n\n    /**\n     * Returns complexity of an instance\n     * @return {Number} complexity\n     */\n    complexity: function() {\n      return 1;\n    }\n  });\n\n  /* _FROM_SVG_START_ */\n  /**\n   * List of attribute names to account for when parsing SVG element (used by {@link fabric.Text.fromElement})\n   * @static\n   * @memberOf fabric.Text\n   * @see: http://www.w3.org/TR/SVG/text.html#TextElement\n   */\n  fabric.Text.ATTRIBUTE_NAMES = fabric.SHARED_ATTRIBUTES.concat(\n    'x y dx dy font-family font-style font-weight font-size letter-spacing text-decoration text-anchor'.split(' '));\n\n  /**\n   * Default SVG font size\n   * @static\n   * @memberOf fabric.Text\n   */\n  fabric.Text.DEFAULT_SVG_FONT_SIZE = 16;\n\n  /**\n   * Returns fabric.Text instance from an SVG element (<b>not yet implemented</b>)\n   * @static\n   * @memberOf fabric.Text\n   * @param {SVGElement} element Element to parse\n   * @param {Function} callback callback function invoked after parsing\n   * @param {Object} [options] Options object\n   */\n  fabric.Text.fromElement = function(element, callback, options) {\n    if (!element) {\n      return callback(null);\n    }\n\n    var parsedAttributes = fabric.parseAttributes(element, fabric.Text.ATTRIBUTE_NAMES),\n        parsedAnchor = parsedAttributes.textAnchor || 'left';\n    options = fabric.util.object.extend((options ? clone(options) : { }), parsedAttributes);\n\n    options.top = options.top || 0;\n    options.left = options.left || 0;\n    if (parsedAttributes.textDecoration) {\n      var textDecoration = parsedAttributes.textDecoration;\n      if (textDecoration.indexOf('underline') !== -1) {\n        options.underline = true;\n      }\n      if (textDecoration.indexOf('overline') !== -1) {\n        options.overline = true;\n      }\n      if (textDecoration.indexOf('line-through') !== -1) {\n        options.linethrough = true;\n      }\n      delete options.textDecoration;\n    }\n    if ('dx' in parsedAttributes) {\n      options.left += parsedAttributes.dx;\n    }\n    if ('dy' in parsedAttributes) {\n      options.top += parsedAttributes.dy;\n    }\n    if (!('fontSize' in options)) {\n      options.fontSize = fabric.Text.DEFAULT_SVG_FONT_SIZE;\n    }\n\n    var textContent = '';\n\n    // The XML is not properly parsed in IE9 so a workaround to get\n    // textContent is through firstChild.data. Another workaround would be\n    // to convert XML loaded from a file to be converted using DOMParser (same way loadSVGFromString() does)\n    if (!('textContent' in element)) {\n      if ('firstChild' in element && element.firstChild !== null) {\n        if ('data' in element.firstChild && element.firstChild.data !== null) {\n          textContent = element.firstChild.data;\n        }\n      }\n    }\n    else {\n      textContent = element.textContent;\n    }\n\n    textContent = textContent.replace(/^\\s+|\\s+$|\\n+/g, '').replace(/\\s+/g, ' ');\n    var originalStrokeWidth = options.strokeWidth;\n    options.strokeWidth = 0;\n\n    var text = new fabric.Text(textContent, options),\n        textHeightScaleFactor = text.getScaledHeight() / text.height,\n        lineHeightDiff = (text.height + text.strokeWidth) * text.lineHeight - text.height,\n        scaledDiff = lineHeightDiff * textHeightScaleFactor,\n        textHeight = text.getScaledHeight() + scaledDiff,\n        offX = 0;\n    /*\n      Adjust positioning:\n        x/y attributes in SVG correspond to the bottom-left corner of text bounding box\n        fabric output by default at top, left.\n    */\n    if (parsedAnchor === 'center') {\n      offX = text.getScaledWidth() / 2;\n    }\n    if (parsedAnchor === 'right') {\n      offX = text.getScaledWidth();\n    }\n    text.set({\n      left: text.left - offX,\n      top: text.top - (textHeight - text.fontSize * (0.07 + text._fontSizeFraction)) / text.lineHeight,\n      strokeWidth: typeof originalStrokeWidth !== 'undefined' ? originalStrokeWidth : 1,\n    });\n    callback(text);\n  };\n  /* _FROM_SVG_END_ */\n\n  /**\n   * Returns fabric.Text instance from an object representation\n   * @static\n   * @memberOf fabric.Text\n   * @param {Object} object Object to create an instance from\n   * @param {Function} [callback] Callback to invoke when an fabric.Text instance is created\n   */\n  fabric.Text.fromObject = function(object, callback) {\n    return fabric.Object._fromObject('Text', object, callback, 'text');\n  };\n\n  fabric.Text.genericFonts = ['sans-serif', 'serif', 'cursive', 'fantasy', 'monospace'];\n\n  fabric.util.createAccessors && fabric.util.createAccessors(fabric.Text);\n\n})(typeof exports !== 'undefined' ? exports : this);\n\n\n(function() {\n  fabric.util.object.extend(fabric.Text.prototype, /** @lends fabric.Text.prototype */ {\n    /**\n     * Returns true if object has no styling or no styling in a line\n     * @param {Number} lineIndex , lineIndex is on wrapped lines.\n     * @return {Boolean}\n     */\n    isEmptyStyles: function(lineIndex) {\n      if (!this.styles) {\n        return true;\n      }\n      if (typeof lineIndex !== 'undefined' && !this.styles[lineIndex]) {\n        return true;\n      }\n      var obj = typeof lineIndex === 'undefined' ? this.styles : { line: this.styles[lineIndex] };\n      for (var p1 in obj) {\n        for (var p2 in obj[p1]) {\n          // eslint-disable-next-line no-unused-vars\n          for (var p3 in obj[p1][p2]) {\n            return false;\n          }\n        }\n      }\n      return true;\n    },\n\n    /**\n     * Returns true if object has a style property or has it ina specified line\n     * @param {Number} lineIndex\n     * @return {Boolean}\n     */\n    styleHas: function(property, lineIndex) {\n      if (!this.styles || !property || property === '') {\n        return false;\n      }\n      if (typeof lineIndex !== 'undefined' && !this.styles[lineIndex]) {\n        return false;\n      }\n      var obj = typeof lineIndex === 'undefined' ? this.styles : { line: this.styles[lineIndex] };\n      // eslint-disable-next-line\n      for (var p1 in obj) {\n        // eslint-disable-next-line\n        for (var p2 in obj[p1]) {\n          if (typeof obj[p1][p2][property] !== 'undefined') {\n            return true;\n          }\n        }\n      }\n      return false;\n    },\n\n    /**\n     * Check if characters in a text have a value for a property\n     * whose value matches the textbox's value for that property.  If so,\n     * the character-level property is deleted.  If the character\n     * has no other properties, then it is also deleted.  Finally,\n     * if the line containing that character has no other characters\n     * then it also is deleted.\n     *\n     * @param {string} property The property to compare between characters and text.\n     */\n    cleanStyle: function(property) {\n      if (!this.styles || !property || property === '') {\n        return false;\n      }\n      var obj = this.styles, stylesCount = 0, letterCount, stylePropertyValue,\n          allStyleObjectPropertiesMatch = true, graphemeCount = 0, styleObject;\n      // eslint-disable-next-line\n      for (var p1 in obj) {\n        letterCount = 0;\n        // eslint-disable-next-line\n        for (var p2 in obj[p1]) {\n          var styleObject = obj[p1][p2],\n              stylePropertyHasBeenSet = styleObject.hasOwnProperty(property);\n\n          stylesCount++;\n\n          if (stylePropertyHasBeenSet) {\n            if (!stylePropertyValue) {\n              stylePropertyValue = styleObject[property];\n            }\n            else if (styleObject[property] !== stylePropertyValue) {\n              allStyleObjectPropertiesMatch = false;\n            }\n\n            if (styleObject[property] === this[property]) {\n              delete styleObject[property];\n            }\n          }\n          else {\n            allStyleObjectPropertiesMatch = false;\n          }\n\n          if (Object.keys(styleObject).length !== 0) {\n            letterCount++;\n          }\n          else {\n            delete obj[p1][p2];\n          }\n        }\n\n        if (letterCount === 0) {\n          delete obj[p1];\n        }\n      }\n      // if every grapheme has the same style set then\n      // delete those styles and set it on the parent\n      for (var i = 0; i < this._textLines.length; i++) {\n        graphemeCount += this._textLines[i].length;\n      }\n      if (allStyleObjectPropertiesMatch && stylesCount === graphemeCount) {\n        this[property] = stylePropertyValue;\n        this.removeStyle(property);\n      }\n    },\n\n    /**\n     * Remove a style property or properties from all individual character styles\n     * in a text object.  Deletes the character style object if it contains no other style\n     * props.  Deletes a line style object if it contains no other character styles.\n     *\n     * @param {String} props The property to remove from character styles.\n     */\n    removeStyle: function(property) {\n      if (!this.styles || !property || property === '') {\n        return;\n      }\n      var obj = this.styles, line, lineNum, charNum;\n      for (lineNum in obj) {\n        line = obj[lineNum];\n        for (charNum in line) {\n          delete line[charNum][property];\n          if (Object.keys(line[charNum]).length === 0) {\n            delete line[charNum];\n          }\n        }\n        if (Object.keys(line).length === 0) {\n          delete obj[lineNum];\n        }\n      }\n    },\n\n    /**\n     * @private\n     */\n    _extendStyles: function(index, styles) {\n      var loc = this.get2DCursorLocation(index);\n\n      if (!this._getLineStyle(loc.lineIndex)) {\n        this._setLineStyle(loc.lineIndex, {});\n      }\n\n      if (!this._getStyleDeclaration(loc.lineIndex, loc.charIndex)) {\n        this._setStyleDeclaration(loc.lineIndex, loc.charIndex, {});\n      }\n\n      fabric.util.object.extend(this._getStyleDeclaration(loc.lineIndex, loc.charIndex), styles);\n    },\n\n    /**\n     * Returns 2d representation (lineIndex and charIndex) of cursor (or selection start)\n     * @param {Number} [selectionStart] Optional index. When not given, current selectionStart is used.\n     * @param {Boolean} [skipWrapping] consider the location for unwrapped lines. usefull to manage styles.\n     */\n    get2DCursorLocation: function(selectionStart, skipWrapping) {\n      if (typeof selectionStart === 'undefined') {\n        selectionStart = this.selectionStart;\n      }\n      var lines = skipWrapping ? this._unwrappedTextLines : this._textLines;\n      var len = lines.length;\n      for (var i = 0; i < len; i++) {\n        if (selectionStart <= lines[i].length) {\n          return {\n            lineIndex: i,\n            charIndex: selectionStart\n          };\n        }\n        selectionStart -= lines[i].length + 1;\n      }\n      return {\n        lineIndex: i - 1,\n        charIndex: lines[i - 1].length < selectionStart ? lines[i - 1].length : selectionStart\n      };\n    },\n\n    /**\n     * Gets style of a current selection/cursor (at the start position)\n     * if startIndex or endIndex are not provided, slectionStart or selectionEnd will be used.\n     * @param {Number} [startIndex] Start index to get styles at\n     * @param {Number} [endIndex] End index to get styles at, if not specified selectionEnd or startIndex + 1\n     * @param {Boolean} [complete] get full style or not\n     * @return {Array} styles an array with one, zero or more Style objects\n     */\n    getSelectionStyles: function(startIndex, endIndex, complete) {\n      if (typeof startIndex === 'undefined') {\n        startIndex = this.selectionStart || 0;\n      }\n      if (typeof endIndex === 'undefined') {\n        endIndex = this.selectionEnd || startIndex;\n      }\n      var styles = [];\n      for (var i = startIndex; i < endIndex; i++) {\n        styles.push(this.getStyleAtPosition(i, complete));\n      }\n      return styles;\n    },\n\n    /**\n     * Gets style of a current selection/cursor position\n     * @param {Number} position  to get styles at\n     * @param {Boolean} [complete] full style if true\n     * @return {Object} style Style object at a specified index\n     * @private\n     */\n    getStyleAtPosition: function(position, complete) {\n      var loc = this.get2DCursorLocation(position),\n          style = complete ? this.getCompleteStyleDeclaration(loc.lineIndex, loc.charIndex) :\n            this._getStyleDeclaration(loc.lineIndex, loc.charIndex);\n      return style || {};\n    },\n\n    /**\n     * Sets style of a current selection, if no selection exist, do not set anything.\n     * @param {Object} [styles] Styles object\n     * @param {Number} [startIndex] Start index to get styles at\n     * @param {Number} [endIndex] End index to get styles at, if not specified selectionEnd or startIndex + 1\n     * @return {fabric.IText} thisArg\n     * @chainable\n     */\n    setSelectionStyles: function(styles, startIndex, endIndex) {\n      if (typeof startIndex === 'undefined') {\n        startIndex = this.selectionStart || 0;\n      }\n      if (typeof endIndex === 'undefined') {\n        endIndex = this.selectionEnd || startIndex;\n      }\n      for (var i = startIndex; i < endIndex; i++) {\n        this._extendStyles(i, styles);\n      }\n      /* not included in _extendStyles to avoid clearing cache more than once */\n      this._forceClearCache = true;\n      return this;\n    },\n\n    /**\n     * get the reference, not a clone, of the style object for a given character\n     * @param {Number} lineIndex\n     * @param {Number} charIndex\n     * @return {Object} style object\n     */\n    _getStyleDeclaration: function(lineIndex, charIndex) {\n      var lineStyle = this.styles && this.styles[lineIndex];\n      if (!lineStyle) {\n        return null;\n      }\n      return lineStyle[charIndex];\n    },\n\n    /**\n     * return a new object that contains all the style property for a character\n     * the object returned is newly created\n     * @param {Number} lineIndex of the line where the character is\n     * @param {Number} charIndex position of the character on the line\n     * @return {Object} style object\n     */\n    getCompleteStyleDeclaration: function(lineIndex, charIndex) {\n      var style = this._getStyleDeclaration(lineIndex, charIndex) || { },\n          styleObject = { }, prop;\n      for (var i = 0; i < this._styleProperties.length; i++) {\n        prop = this._styleProperties[i];\n        styleObject[prop] = typeof style[prop] === 'undefined' ? this[prop] : style[prop];\n      }\n      return styleObject;\n    },\n\n    /**\n     * @param {Number} lineIndex\n     * @param {Number} charIndex\n     * @param {Object} style\n     * @private\n     */\n    _setStyleDeclaration: function(lineIndex, charIndex, style) {\n      this.styles[lineIndex][charIndex] = style;\n    },\n\n    /**\n     *\n     * @param {Number} lineIndex\n     * @param {Number} charIndex\n     * @private\n     */\n    _deleteStyleDeclaration: function(lineIndex, charIndex) {\n      delete this.styles[lineIndex][charIndex];\n    },\n\n    /**\n     * @param {Number} lineIndex\n     * @private\n     */\n    _getLineStyle: function(lineIndex) {\n      return this.styles[lineIndex];\n    },\n\n    /**\n     * @param {Number} lineIndex\n     * @param {Object} style\n     * @private\n     */\n    _setLineStyle: function(lineIndex, style) {\n      this.styles[lineIndex] = style;\n    },\n\n    /**\n     * @param {Number} lineIndex\n     * @private\n     */\n    _deleteLineStyle: function(lineIndex) {\n      delete this.styles[lineIndex];\n    }\n  });\n})();\n\n\n(function() {\n\n  function parseDecoration(object) {\n    if (object.textDecoration) {\n      object.textDecoration.indexOf('underline') > -1 && (object.underline = true);\n      object.textDecoration.indexOf('line-through') > -1 && (object.linethrough = true);\n      object.textDecoration.indexOf('overline') > -1 && (object.overline = true);\n      delete object.textDecoration;\n    }\n  }\n\n  /**\n   * IText class (introduced in <b>v1.4</b>) Events are also fired with \"text:\"\n   * prefix when observing canvas.\n   * @class fabric.IText\n   * @extends fabric.Text\n   * @mixes fabric.Observable\n   *\n   * @fires changed\n   * @fires selection:changed\n   * @fires editing:entered\n   * @fires editing:exited\n   *\n   * @return {fabric.IText} thisArg\n   * @see {@link fabric.IText#initialize} for constructor definition\n   *\n   * <p>Supported key combinations:</p>\n   * <pre>\n   *   Move cursor:                    left, right, up, down\n   *   Select character:               shift + left, shift + right\n   *   Select text vertically:         shift + up, shift + down\n   *   Move cursor by word:            alt + left, alt + right\n   *   Select words:                   shift + alt + left, shift + alt + right\n   *   Move cursor to line start/end:  cmd + left, cmd + right or home, end\n   *   Select till start/end of line:  cmd + shift + left, cmd + shift + right or shift + home, shift + end\n   *   Jump to start/end of text:      cmd + up, cmd + down\n   *   Select till start/end of text:  cmd + shift + up, cmd + shift + down or shift + pgUp, shift + pgDown\n   *   Delete character:               backspace\n   *   Delete word:                    alt + backspace\n   *   Delete line:                    cmd + backspace\n   *   Forward delete:                 delete\n   *   Copy text:                      ctrl/cmd + c\n   *   Paste text:                     ctrl/cmd + v\n   *   Cut text:                       ctrl/cmd + x\n   *   Select entire text:             ctrl/cmd + a\n   *   Quit editing                    tab or esc\n   * </pre>\n   *\n   * <p>Supported mouse/touch combination</p>\n   * <pre>\n   *   Position cursor:                click/touch\n   *   Create selection:               click/touch & drag\n   *   Create selection:               click & shift + click\n   *   Select word:                    double click\n   *   Select line:                    triple click\n   * </pre>\n   */\n  fabric.IText = fabric.util.createClass(fabric.Text, fabric.Observable, /** @lends fabric.IText.prototype */ {\n\n    /**\n     * Type of an object\n     * @type String\n     * @default\n     */\n    type: 'i-text',\n\n    /**\n     * Index where text selection starts (or where cursor is when there is no selection)\n     * @type Number\n     * @default\n     */\n    selectionStart: 0,\n\n    /**\n     * Index where text selection ends\n     * @type Number\n     * @default\n     */\n    selectionEnd: 0,\n\n    /**\n     * Color of text selection\n     * @type String\n     * @default\n     */\n    selectionColor: 'rgba(17,119,255,0.3)',\n\n    /**\n     * Indicates whether text is in editing mode\n     * @type Boolean\n     * @default\n     */\n    isEditing: false,\n\n    /**\n     * Indicates whether a text can be edited\n     * @type Boolean\n     * @default\n     */\n    editable: true,\n\n    /**\n     * Border color of text object while it's in editing mode\n     * @type String\n     * @default\n     */\n    editingBorderColor: 'rgba(102,153,255,0.25)',\n\n    /**\n     * Width of cursor (in px)\n     * @type Number\n     * @default\n     */\n    cursorWidth: 2,\n\n    /**\n     * Color of default cursor (when not overwritten by character style)\n     * @type String\n     * @default\n     */\n    cursorColor: '#333',\n\n    /**\n     * Delay between cursor blink (in ms)\n     * @type Number\n     * @default\n     */\n    cursorDelay: 1000,\n\n    /**\n     * Duration of cursor fadein (in ms)\n     * @type Number\n     * @default\n     */\n    cursorDuration: 600,\n\n    /**\n     * Indicates whether internal text char widths can be cached\n     * @type Boolean\n     * @default\n     */\n    caching: true,\n\n    /**\n     * @private\n     */\n    _reSpace: /\\s|\\n/,\n\n    /**\n     * @private\n     */\n    _currentCursorOpacity: 0,\n\n    /**\n     * @private\n     */\n    _selectionDirection: null,\n\n    /**\n     * @private\n     */\n    _abortCursorAnimation: false,\n\n    /**\n     * @private\n     */\n    __widthOfSpace: [],\n\n    /**\n     * Helps determining when the text is in composition, so that the cursor\n     * rendering is altered.\n     */\n    inCompositionMode: false,\n\n    /**\n     * Constructor\n     * @param {String} text Text string\n     * @param {Object} [options] Options object\n     * @return {fabric.IText} thisArg\n     */\n    initialize: function(text, options) {\n      this.callSuper('initialize', text, options);\n      this.initBehavior();\n    },\n\n    /**\n     * Sets selection start (left boundary of a selection)\n     * @param {Number} index Index to set selection start to\n     */\n    setSelectionStart: function(index) {\n      index = Math.max(index, 0);\n      this._updateAndFire('selectionStart', index);\n    },\n\n    /**\n     * Sets selection end (right boundary of a selection)\n     * @param {Number} index Index to set selection end to\n     */\n    setSelectionEnd: function(index) {\n      index = Math.min(index, this.text.length);\n      this._updateAndFire('selectionEnd', index);\n    },\n\n    /**\n     * @private\n     * @param {String} property 'selectionStart' or 'selectionEnd'\n     * @param {Number} index new position of property\n     */\n    _updateAndFire: function(property, index) {\n      if (this[property] !== index) {\n        this._fireSelectionChanged();\n        this[property] = index;\n      }\n      this._updateTextarea();\n    },\n\n    /**\n     * Fires the even of selection changed\n     * @private\n     */\n    _fireSelectionChanged: function() {\n      this.fire('selection:changed');\n      this.canvas && this.canvas.fire('text:selection:changed', { target: this });\n    },\n\n    /**\n     * Initialize text dimensions. Render all text on given context\n     * or on a offscreen canvas to get the text width with measureText.\n     * Updates this.width and this.height with the proper values.\n     * Does not return dimensions.\n     * @private\n     */\n    initDimensions: function() {\n      this.isEditing && this.initDelayedCursor();\n      this.clearContextTop();\n      this.callSuper('initDimensions');\n    },\n\n    /**\n     * @private\n     * @param {CanvasRenderingContext2D} ctx Context to render on\n     */\n    render: function(ctx) {\n      this.clearContextTop();\n      this.callSuper('render', ctx);\n      // clear the cursorOffsetCache, so we ensure to calculate once per renderCursor\n      // the correct position but not at every cursor animation.\n      this.cursorOffsetCache = { };\n      this.renderCursorOrSelection();\n    },\n\n    /**\n     * @private\n     * @param {CanvasRenderingContext2D} ctx Context to render on\n     */\n    _render: function(ctx) {\n      this.callSuper('_render', ctx);\n    },\n\n    /**\n     * Prepare and clean the contextTop\n     */\n    clearContextTop: function(skipRestore) {\n      if (!this.isEditing) {\n        return;\n      }\n      if (this.canvas && this.canvas.contextTop) {\n        var ctx = this.canvas.contextTop, v = this.canvas.viewportTransform;\n        ctx.save();\n        ctx.transform(v[0], v[1], v[2], v[3], v[4], v[5]);\n        this.transform(ctx);\n        this.transformMatrix && ctx.transform.apply(ctx, this.transformMatrix);\n        this._clearTextArea(ctx);\n        skipRestore || ctx.restore();\n      }\n    },\n\n    /**\n     * Renders cursor or selection (depending on what exists)\n     */\n    renderCursorOrSelection: function() {\n      if (!this.isEditing || !this.canvas) {\n        return;\n      }\n      var boundaries = this._getCursorBoundaries(), ctx;\n      if (this.canvas && this.canvas.contextTop) {\n        ctx = this.canvas.contextTop;\n        this.clearContextTop(true);\n      }\n      else {\n        ctx = this.canvas.contextContainer;\n        ctx.save();\n      }\n      if (this.selectionStart === this.selectionEnd) {\n        this.renderCursor(boundaries, ctx);\n      }\n      else {\n        this.renderSelection(boundaries, ctx);\n      }\n      ctx.restore();\n    },\n\n    _clearTextArea: function(ctx) {\n      // we add 4 pixel, to be sure to do not leave any pixel out\n      var width = this.width + 4, height = this.height + 4;\n      ctx.clearRect(-width / 2, -height / 2, width, height);\n    },\n\n    /**\n     * Returns cursor boundaries (left, top, leftOffset, topOffset)\n     * @private\n     * @param {Array} chars Array of characters\n     * @param {String} typeOfBoundaries\n     */\n    _getCursorBoundaries: function(position) {\n\n      // left/top are left/top of entire text box\n      // leftOffset/topOffset are offset from that left/top point of a text box\n\n      if (typeof position === 'undefined') {\n        position = this.selectionStart;\n      }\n\n      var left = this._getLeftOffset(),\n          top = this._getTopOffset(),\n          offsets = this._getCursorBoundariesOffsets(position);\n\n      return {\n        left: left,\n        top: top,\n        leftOffset: offsets.left,\n        topOffset: offsets.top\n      };\n    },\n\n    /**\n     * @private\n     */\n    _getCursorBoundariesOffsets: function(position) {\n      if (this.cursorOffsetCache && 'top' in this.cursorOffsetCache) {\n        return this.cursorOffsetCache;\n      }\n      var lineLeftOffset,\n          lineIndex,\n          charIndex,\n          topOffset = 0,\n          leftOffset = 0,\n          boundaries,\n          cursorPosition = this.get2DCursorLocation(position);\n      charIndex = cursorPosition.charIndex;\n      lineIndex = cursorPosition.lineIndex;\n      for (var i = 0; i < lineIndex; i++) {\n        topOffset += this.getHeightOfLine(i);\n      }\n      lineLeftOffset = this._getLineLeftOffset(lineIndex);\n      var bound = this.__charBounds[lineIndex][charIndex];\n      bound && (leftOffset = bound.left);\n      if (this.charSpacing !== 0 && charIndex === this._textLines[lineIndex].length) {\n        leftOffset -= this._getWidthOfCharSpacing();\n      }\n      boundaries = {\n        top: topOffset,\n        left: lineLeftOffset + (leftOffset > 0 ? leftOffset : 0),\n      };\n      this.cursorOffsetCache = boundaries;\n      return this.cursorOffsetCache;\n    },\n\n    /**\n     * Renders cursor\n     * @param {Object} boundaries\n     * @param {CanvasRenderingContext2D} ctx transformed context to draw on\n     */\n    renderCursor: function(boundaries, ctx) {\n      var cursorLocation = this.get2DCursorLocation(),\n          lineIndex = cursorLocation.lineIndex,\n          charIndex = cursorLocation.charIndex > 0 ? cursorLocation.charIndex - 1 : 0,\n          charHeight = this.getValueOfPropertyAt(lineIndex, charIndex, 'fontSize'),\n          multiplier = this.scaleX * this.canvas.getZoom(),\n          cursorWidth = this.cursorWidth / multiplier,\n          topOffset = boundaries.topOffset,\n          dy = this.getValueOfPropertyAt(lineIndex, charIndex, 'deltaY');\n\n      topOffset += (1 - this._fontSizeFraction) * this.getHeightOfLine(lineIndex) / this.lineHeight\n        - charHeight * (1 - this._fontSizeFraction);\n\n      if (this.inCompositionMode) {\n        this.renderSelection(boundaries, ctx);\n      }\n\n      ctx.fillStyle = this.getValueOfPropertyAt(lineIndex, charIndex, 'fill');\n      ctx.globalAlpha = this.__isMousedown ? 1 : this._currentCursorOpacity;\n      ctx.fillRect(\n        boundaries.left + boundaries.leftOffset - cursorWidth / 2,\n        topOffset + boundaries.top + dy,\n        cursorWidth,\n        charHeight);\n    },\n\n    /**\n     * Renders text selection\n     * @param {Object} boundaries Object with left/top/leftOffset/topOffset\n     * @param {CanvasRenderingContext2D} ctx transformed context to draw on\n     */\n    renderSelection: function(boundaries, ctx) {\n\n      var selectionStart = this.inCompositionMode ? this.hiddenTextarea.selectionStart : this.selectionStart,\n          selectionEnd = this.inCompositionMode ? this.hiddenTextarea.selectionEnd : this.selectionEnd,\n          isJustify = this.textAlign.indexOf('justify') !== -1,\n          start = this.get2DCursorLocation(selectionStart),\n          end = this.get2DCursorLocation(selectionEnd),\n          startLine = start.lineIndex,\n          endLine = end.lineIndex,\n          startChar = start.charIndex < 0 ? 0 : start.charIndex,\n          endChar = end.charIndex < 0 ? 0 : end.charIndex;\n\n      for (var i = startLine; i <= endLine; i++) {\n        var lineOffset = this._getLineLeftOffset(i) || 0,\n            lineHeight = this.getHeightOfLine(i),\n            realLineHeight = 0, boxStart = 0, boxEnd = 0;\n\n        if (i === startLine) {\n          boxStart = this.__charBounds[startLine][startChar].left;\n        }\n        if (i >= startLine && i < endLine) {\n          boxEnd = isJustify && !this.isEndOfWrapping(i) ? this.width : this.getLineWidth(i) || 5; // WTF is this 5?\n        }\n        else if (i === endLine) {\n          if (endChar === 0) {\n            boxEnd = this.__charBounds[endLine][endChar].left;\n          }\n          else {\n            var charSpacing = this._getWidthOfCharSpacing();\n            boxEnd = this.__charBounds[endLine][endChar - 1].left\n              + this.__charBounds[endLine][endChar - 1].width - charSpacing;\n          }\n        }\n        realLineHeight = lineHeight;\n        if (this.lineHeight < 1 || (i === endLine && this.lineHeight > 1)) {\n          lineHeight /= this.lineHeight;\n        }\n        if (this.inCompositionMode) {\n          ctx.fillStyle = this.compositionColor || 'black';\n          ctx.fillRect(\n            boundaries.left + lineOffset + boxStart,\n            boundaries.top + boundaries.topOffset + lineHeight,\n            boxEnd - boxStart,\n            1);\n        }\n        else {\n          ctx.fillStyle = this.selectionColor;\n          ctx.fillRect(\n            boundaries.left + lineOffset + boxStart,\n            boundaries.top + boundaries.topOffset,\n            boxEnd - boxStart,\n            lineHeight);\n        }\n\n\n        boundaries.topOffset += realLineHeight;\n      }\n    },\n\n    /**\n     * High level function to know the height of the cursor.\n     * the currentChar is the one that precedes the cursor\n     * Returns fontSize of char at the current cursor\n     * @return {Number} Character font size\n     */\n    getCurrentCharFontSize: function() {\n      var cp = this._getCurrentCharIndex();\n      return this.getValueOfPropertyAt(cp.l, cp.c, 'fontSize');\n    },\n\n    /**\n     * High level function to know the color of the cursor.\n     * the currentChar is the one that precedes the cursor\n     * Returns color (fill) of char at the current cursor\n     * @return {String} Character color (fill)\n     */\n    getCurrentCharColor: function() {\n      var cp = this._getCurrentCharIndex();\n      return this.getValueOfPropertyAt(cp.l, cp.c, 'fill');\n    },\n\n    /**\n     * Returns the cursor position for the getCurrent.. functions\n     * @private\n     */\n    _getCurrentCharIndex: function() {\n      var cursorPosition = this.get2DCursorLocation(this.selectionStart, true),\n          charIndex = cursorPosition.charIndex > 0 ? cursorPosition.charIndex - 1 : 0;\n      return { l: cursorPosition.lineIndex, c: charIndex };\n    }\n  });\n\n  /**\n   * Returns fabric.IText instance from an object representation\n   * @static\n   * @memberOf fabric.IText\n   * @param {Object} object Object to create an instance from\n   * @param {function} [callback] invoked with new instance as argument\n   */\n  fabric.IText.fromObject = function(object, callback) {\n    parseDecoration(object);\n    if (object.styles) {\n      for (var i in object.styles) {\n        for (var j in object.styles[i]) {\n          parseDecoration(object.styles[i][j]);\n        }\n      }\n    }\n    fabric.Object._fromObject('IText', object, callback, 'text');\n  };\n})();\n\n\n(function() {\n\n  var clone = fabric.util.object.clone;\n\n  fabric.util.object.extend(fabric.IText.prototype, /** @lends fabric.IText.prototype */ {\n\n    /**\n     * Initializes all the interactive behavior of IText\n     */\n    initBehavior: function() {\n      this.initAddedHandler();\n      this.initRemovedHandler();\n      this.initCursorSelectionHandlers();\n      this.initDoubleClickSimulation();\n      this.mouseMoveHandler = this.mouseMoveHandler.bind(this);\n    },\n\n    onDeselect: function() {\n      this.isEditing && this.exitEditing();\n      this.selected = false;\n    },\n\n    /**\n     * Initializes \"added\" event handler\n     */\n    initAddedHandler: function() {\n      var _this = this;\n      this.on('added', function() {\n        var canvas = _this.canvas;\n        if (canvas) {\n          if (!canvas._hasITextHandlers) {\n            canvas._hasITextHandlers = true;\n            _this._initCanvasHandlers(canvas);\n          }\n          canvas._iTextInstances = canvas._iTextInstances || [];\n          canvas._iTextInstances.push(_this);\n        }\n      });\n    },\n\n    initRemovedHandler: function() {\n      var _this = this;\n      this.on('removed', function() {\n        var canvas = _this.canvas;\n        if (canvas) {\n          canvas._iTextInstances = canvas._iTextInstances || [];\n          fabric.util.removeFromArray(canvas._iTextInstances, _this);\n          if (canvas._iTextInstances.length === 0) {\n            canvas._hasITextHandlers = false;\n            _this._removeCanvasHandlers(canvas);\n          }\n        }\n      });\n    },\n\n    /**\n     * register canvas event to manage exiting on other instances\n     * @private\n     */\n    _initCanvasHandlers: function(canvas) {\n      canvas._mouseUpITextHandler = function() {\n        if (canvas._iTextInstances) {\n          canvas._iTextInstances.forEach(function(obj) {\n            obj.__isMousedown = false;\n          });\n        }\n      };\n      canvas.on('mouse:up', canvas._mouseUpITextHandler);\n    },\n\n    /**\n     * remove canvas event to manage exiting on other instances\n     * @private\n     */\n    _removeCanvasHandlers: function(canvas) {\n      canvas.off('mouse:up', canvas._mouseUpITextHandler);\n    },\n\n    /**\n     * @private\n     */\n    _tick: function() {\n      this._currentTickState = this._animateCursor(this, 1, this.cursorDuration, '_onTickComplete');\n    },\n\n    /**\n     * @private\n     */\n    _animateCursor: function(obj, targetOpacity, duration, completeMethod) {\n\n      var tickState;\n\n      tickState = {\n        isAborted: false,\n        abort: function() {\n          this.isAborted = true;\n        },\n      };\n\n      obj.animate('_currentCursorOpacity', targetOpacity, {\n        duration: duration,\n        onComplete: function() {\n          if (!tickState.isAborted) {\n            obj[completeMethod]();\n          }\n        },\n        onChange: function() {\n          // we do not want to animate a selection, only cursor\n          if (obj.canvas && obj.selectionStart === obj.selectionEnd) {\n            obj.renderCursorOrSelection();\n          }\n        },\n        abort: function() {\n          return tickState.isAborted;\n        }\n      });\n      return tickState;\n    },\n\n    /**\n     * @private\n     */\n    _onTickComplete: function() {\n\n      var _this = this;\n\n      if (this._cursorTimeout1) {\n        clearTimeout(this._cursorTimeout1);\n      }\n      this._cursorTimeout1 = setTimeout(function() {\n        _this._currentTickCompleteState = _this._animateCursor(_this, 0, this.cursorDuration / 2, '_tick');\n      }, 100);\n    },\n\n    /**\n     * Initializes delayed cursor\n     */\n    initDelayedCursor: function(restart) {\n      var _this = this,\n          delay = restart ? 0 : this.cursorDelay;\n\n      this.abortCursorAnimation();\n      this._currentCursorOpacity = 1;\n      this._cursorTimeout2 = setTimeout(function() {\n        _this._tick();\n      }, delay);\n    },\n\n    /**\n     * Aborts cursor animation and clears all timeouts\n     */\n    abortCursorAnimation: function() {\n      var shouldClear = this._currentTickState || this._currentTickCompleteState,\n          canvas = this.canvas;\n      this._currentTickState && this._currentTickState.abort();\n      this._currentTickCompleteState && this._currentTickCompleteState.abort();\n\n      clearTimeout(this._cursorTimeout1);\n      clearTimeout(this._cursorTimeout2);\n\n      this._currentCursorOpacity = 0;\n      // to clear just itext area we need to transform the context\n      // it may not be worth it\n      if (shouldClear && canvas) {\n        canvas.clearContext(canvas.contextTop || canvas.contextContainer);\n      }\n\n    },\n\n    /**\n     * Selects entire text\n     * @return {fabric.IText} thisArg\n     * @chainable\n     */\n    selectAll: function() {\n      this.selectionStart = 0;\n      this.selectionEnd = this._text.length;\n      this._fireSelectionChanged();\n      this._updateTextarea();\n      return this;\n    },\n\n    /**\n     * Returns selected text\n     * @return {String}\n     */\n    getSelectedText: function() {\n      return this._text.slice(this.selectionStart, this.selectionEnd).join('');\n    },\n\n    /**\n     * Find new selection index representing start of current word according to current selection index\n     * @param {Number} startFrom Surrent selection index\n     * @return {Number} New selection index\n     */\n    findWordBoundaryLeft: function(startFrom) {\n      var offset = 0, index = startFrom - 1;\n\n      // remove space before cursor first\n      if (this._reSpace.test(this._text[index])) {\n        while (this._reSpace.test(this._text[index])) {\n          offset++;\n          index--;\n        }\n      }\n      while (/\\S/.test(this._text[index]) && index > -1) {\n        offset++;\n        index--;\n      }\n\n      return startFrom - offset;\n    },\n\n    /**\n     * Find new selection index representing end of current word according to current selection index\n     * @param {Number} startFrom Current selection index\n     * @return {Number} New selection index\n     */\n    findWordBoundaryRight: function(startFrom) {\n      var offset = 0, index = startFrom;\n\n      // remove space after cursor first\n      if (this._reSpace.test(this._text[index])) {\n        while (this._reSpace.test(this._text[index])) {\n          offset++;\n          index++;\n        }\n      }\n      while (/\\S/.test(this._text[index]) && index < this.text.length) {\n        offset++;\n        index++;\n      }\n\n      return startFrom + offset;\n    },\n\n    /**\n     * Find new selection index representing start of current line according to current selection index\n     * @param {Number} startFrom Current selection index\n     * @return {Number} New selection index\n     */\n    findLineBoundaryLeft: function(startFrom) {\n      var offset = 0, index = startFrom - 1;\n\n      while (!/\\n/.test(this._text[index]) && index > -1) {\n        offset++;\n        index--;\n      }\n\n      return startFrom - offset;\n    },\n\n    /**\n     * Find new selection index representing end of current line according to current selection index\n     * @param {Number} startFrom Current selection index\n     * @return {Number} New selection index\n     */\n    findLineBoundaryRight: function(startFrom) {\n      var offset = 0, index = startFrom;\n\n      while (!/\\n/.test(this._text[index]) && index < this.text.length) {\n        offset++;\n        index++;\n      }\n\n      return startFrom + offset;\n    },\n\n    /**\n     * Finds index corresponding to beginning or end of a word\n     * @param {Number} selectionStart Index of a character\n     * @param {Number} direction 1 or -1\n     * @return {Number} Index of the beginning or end of a word\n     */\n    searchWordBoundary: function(selectionStart, direction) {\n      var index     = this._reSpace.test(this.text.charAt(selectionStart)) ? selectionStart - 1 : selectionStart,\n          _char     = this.text.charAt(index),\n          reNonWord = /[ \\n\\.,;!\\?\\-]/;\n\n      while (!reNonWord.test(_char) && index > 0 && index < this.text.length) {\n        index += direction;\n        _char = this.text.charAt(index);\n      }\n      if (reNonWord.test(_char) && _char !== '\\n') {\n        index += direction === 1 ? 0 : 1;\n      }\n      return index;\n    },\n\n    /**\n     * Selects a word based on the index\n     * @param {Number} selectionStart Index of a character\n     */\n    selectWord: function(selectionStart) {\n      selectionStart = selectionStart || this.selectionStart;\n      var newSelectionStart = this.searchWordBoundary(selectionStart, -1), /* search backwards */\n          newSelectionEnd = this.searchWordBoundary(selectionStart, 1); /* search forward */\n\n      this.selectionStart = newSelectionStart;\n      this.selectionEnd = newSelectionEnd;\n      this._fireSelectionChanged();\n      this._updateTextarea();\n      this.renderCursorOrSelection();\n    },\n\n    /**\n     * Selects a line based on the index\n     * @param {Number} selectionStart Index of a character\n     * @return {fabric.IText} thisArg\n     * @chainable\n     */\n    selectLine: function(selectionStart) {\n      selectionStart = selectionStart || this.selectionStart;\n      var newSelectionStart = this.findLineBoundaryLeft(selectionStart),\n          newSelectionEnd = this.findLineBoundaryRight(selectionStart);\n\n      this.selectionStart = newSelectionStart;\n      this.selectionEnd = newSelectionEnd;\n      this._fireSelectionChanged();\n      this._updateTextarea();\n      return this;\n    },\n\n    /**\n     * Enters editing state\n     * @return {fabric.IText} thisArg\n     * @chainable\n     */\n    enterEditing: function(e) {\n      if (this.isEditing || !this.editable) {\n        return;\n      }\n\n      if (this.canvas) {\n        this.canvas.calcOffset();\n        this.exitEditingOnOthers(this.canvas);\n      }\n\n      this.isEditing = true;\n\n      this.initHiddenTextarea(e);\n      this.hiddenTextarea.focus();\n      this.hiddenTextarea.value = this.text;\n      this._updateTextarea();\n      this._saveEditingProps();\n      this._setEditingProps();\n      this._textBeforeEdit = this.text;\n\n      this._tick();\n      this.fire('editing:entered');\n      this._fireSelectionChanged();\n      if (!this.canvas) {\n        return this;\n      }\n      this.canvas.fire('text:editing:entered', { target: this });\n      this.initMouseMoveHandler();\n      this.canvas.requestRenderAll();\n      return this;\n    },\n\n    exitEditingOnOthers: function(canvas) {\n      if (canvas._iTextInstances) {\n        canvas._iTextInstances.forEach(function(obj) {\n          obj.selected = false;\n          if (obj.isEditing) {\n            obj.exitEditing();\n          }\n        });\n      }\n    },\n\n    /**\n     * Initializes \"mousemove\" event handler\n     */\n    initMouseMoveHandler: function() {\n      this.canvas.on('mouse:move', this.mouseMoveHandler);\n    },\n\n    /**\n     * @private\n     */\n    mouseMoveHandler: function(options) {\n      if (!this.__isMousedown || !this.isEditing) {\n        return;\n      }\n\n      var newSelectionStart = this.getSelectionStartFromPointer(options.e),\n          currentStart = this.selectionStart,\n          currentEnd = this.selectionEnd;\n      if (\n        (newSelectionStart !== this.__selectionStartOnMouseDown || currentStart === currentEnd)\n        &&\n        (currentStart === newSelectionStart || currentEnd === newSelectionStart)\n      ) {\n        return;\n      }\n      if (newSelectionStart > this.__selectionStartOnMouseDown) {\n        this.selectionStart = this.__selectionStartOnMouseDown;\n        this.selectionEnd = newSelectionStart;\n      }\n      else {\n        this.selectionStart = newSelectionStart;\n        this.selectionEnd = this.__selectionStartOnMouseDown;\n      }\n      if (this.selectionStart !== currentStart || this.selectionEnd !== currentEnd) {\n        this.restartCursorIfNeeded();\n        this._fireSelectionChanged();\n        this._updateTextarea();\n        this.renderCursorOrSelection();\n      }\n    },\n\n    /**\n     * @private\n     */\n    _setEditingProps: function() {\n      this.hoverCursor = 'text';\n\n      if (this.canvas) {\n        this.canvas.defaultCursor = this.canvas.moveCursor = 'text';\n      }\n\n      this.borderColor = this.editingBorderColor;\n\n      this.hasControls = this.selectable = false;\n      this.lockMovementX = this.lockMovementY = true;\n    },\n\n    /**\n     * convert from textarea to grapheme indexes\n     */\n    fromStringToGraphemeSelection: function(start, end, text) {\n      var smallerTextStart = text.slice(0, start),\n          graphemeStart = fabric.util.string.graphemeSplit(smallerTextStart).length;\n      if (start === end) {\n        return { selectionStart: graphemeStart, selectionEnd: graphemeStart };\n      }\n      var smallerTextEnd = text.slice(start, end),\n          graphemeEnd = fabric.util.string.graphemeSplit(smallerTextEnd).length;\n      return { selectionStart: graphemeStart, selectionEnd: graphemeStart + graphemeEnd };\n    },\n\n    /**\n     * convert from fabric to textarea values\n     */\n    fromGraphemeToStringSelection: function(start, end, _text) {\n      var smallerTextStart = _text.slice(0, start),\n          graphemeStart = smallerTextStart.join('').length;\n      if (start === end) {\n        return { selectionStart: graphemeStart, selectionEnd: graphemeStart };\n      }\n      var smallerTextEnd = _text.slice(start, end),\n          graphemeEnd = smallerTextEnd.join('').length;\n      return { selectionStart: graphemeStart, selectionEnd: graphemeStart + graphemeEnd };\n    },\n\n    /**\n     * @private\n     */\n    _updateTextarea: function() {\n      this.cursorOffsetCache = { };\n      if (!this.hiddenTextarea) {\n        return;\n      }\n      if (!this.inCompositionMode) {\n        var newSelection = this.fromGraphemeToStringSelection(this.selectionStart, this.selectionEnd, this._text);\n        this.hiddenTextarea.selectionStart = newSelection.selectionStart;\n        this.hiddenTextarea.selectionEnd = newSelection.selectionEnd;\n      }\n      this.updateTextareaPosition();\n    },\n\n    /**\n     * @private\n     */\n    updateFromTextArea: function() {\n      if (!this.hiddenTextarea) {\n        return;\n      }\n      this.cursorOffsetCache = { };\n      this.text = this.hiddenTextarea.value;\n      if (this._shouldClearDimensionCache()) {\n        this.initDimensions();\n        this.setCoords();\n      }\n      var newSelection = this.fromStringToGraphemeSelection(\n        this.hiddenTextarea.selectionStart, this.hiddenTextarea.selectionEnd, this.hiddenTextarea.value);\n      this.selectionEnd = this.selectionStart = newSelection.selectionEnd;\n      if (!this.inCompositionMode) {\n        this.selectionStart = newSelection.selectionStart;\n      }\n      this.updateTextareaPosition();\n    },\n\n    /**\n     * @private\n     */\n    updateTextareaPosition: function() {\n      if (this.selectionStart === this.selectionEnd) {\n        var style = this._calcTextareaPosition();\n        this.hiddenTextarea.style.left = style.left;\n        this.hiddenTextarea.style.top = style.top;\n      }\n    },\n\n    /**\n     * @private\n     * @return {Object} style contains style for hiddenTextarea\n     */\n    _calcTextareaPosition: function() {\n      if (!this.canvas) {\n        return { x: 1, y: 1 };\n      }\n      var desiredPostion = this.inCompositionMode ? this.compositionStart : this.selectionStart,\n          boundaries = this._getCursorBoundaries(desiredPostion),\n          cursorLocation = this.get2DCursorLocation(desiredPostion),\n          lineIndex = cursorLocation.lineIndex,\n          charIndex = cursorLocation.charIndex,\n          charHeight = this.getValueOfPropertyAt(lineIndex, charIndex, 'fontSize') * this.lineHeight,\n          leftOffset = boundaries.leftOffset,\n          m = this.calcTransformMatrix(),\n          p = {\n            x: boundaries.left + leftOffset,\n            y: boundaries.top + boundaries.topOffset + charHeight\n          },\n          upperCanvas = this.canvas.upperCanvasEl,\n          upperCanvasWidth = upperCanvas.width,\n          upperCanvasHeight = upperCanvas.height,\n          maxWidth = upperCanvasWidth - charHeight,\n          maxHeight = upperCanvasHeight - charHeight,\n          scaleX = upperCanvas.clientWidth / upperCanvasWidth,\n          scaleY = upperCanvas.clientHeight / upperCanvasHeight;\n\n      p = fabric.util.transformPoint(p, m);\n      p = fabric.util.transformPoint(p, this.canvas.viewportTransform);\n      p.x *= scaleX;\n      p.y *= scaleY;\n      if (p.x < 0) {\n        p.x = 0;\n      }\n      if (p.x > maxWidth) {\n        p.x = maxWidth;\n      }\n      if (p.y < 0) {\n        p.y = 0;\n      }\n      if (p.y > maxHeight) {\n        p.y = maxHeight;\n      }\n\n      // add canvas offset on document\n      p.x += this.canvas._offset.left;\n      p.y += this.canvas._offset.top;\n\n      return { left: p.x + 'px', top: p.y + 'px', fontSize: charHeight + 'px', charHeight: charHeight };\n    },\n\n    /**\n     * @private\n     */\n    _saveEditingProps: function() {\n      this._savedProps = {\n        hasControls: this.hasControls,\n        borderColor: this.borderColor,\n        lockMovementX: this.lockMovementX,\n        lockMovementY: this.lockMovementY,\n        hoverCursor: this.hoverCursor,\n        defaultCursor: this.canvas && this.canvas.defaultCursor,\n        moveCursor: this.canvas && this.canvas.moveCursor\n      };\n    },\n\n    /**\n     * @private\n     */\n    _restoreEditingProps: function() {\n      if (!this._savedProps) {\n        return;\n      }\n\n      this.hoverCursor = this._savedProps.hoverCursor;\n      this.hasControls = this._savedProps.hasControls;\n      this.borderColor = this._savedProps.borderColor;\n      this.lockMovementX = this._savedProps.lockMovementX;\n      this.lockMovementY = this._savedProps.lockMovementY;\n\n      if (this.canvas) {\n        this.canvas.defaultCursor = this._savedProps.defaultCursor;\n        this.canvas.moveCursor = this._savedProps.moveCursor;\n      }\n    },\n\n    /**\n     * Exits from editing state\n     * @return {fabric.IText} thisArg\n     * @chainable\n     */\n    exitEditing: function() {\n      var isTextChanged = (this._textBeforeEdit !== this.text);\n      this.selected = false;\n      this.isEditing = false;\n      this.selectable = true;\n\n      this.selectionEnd = this.selectionStart;\n\n      if (this.hiddenTextarea) {\n        this.hiddenTextarea.blur && this.hiddenTextarea.blur();\n        this.canvas && this.hiddenTextarea.parentNode.removeChild(this.hiddenTextarea);\n        this.hiddenTextarea = null;\n      }\n\n      this.abortCursorAnimation();\n      this._restoreEditingProps();\n      this._currentCursorOpacity = 0;\n      if (this._shouldClearDimensionCache()) {\n        this.initDimensions();\n        this.setCoords();\n      }\n      this.fire('editing:exited');\n      isTextChanged && this.fire('modified');\n      if (this.canvas) {\n        this.canvas.off('mouse:move', this.mouseMoveHandler);\n        this.canvas.fire('text:editing:exited', { target: this });\n        isTextChanged && this.canvas.fire('object:modified', { target: this });\n      }\n      return this;\n    },\n\n    /**\n     * @private\n     */\n    _removeExtraneousStyles: function() {\n      for (var prop in this.styles) {\n        if (!this._textLines[prop]) {\n          delete this.styles[prop];\n        }\n      }\n    },\n\n    /**\n     * remove and reflow a style block from start to end.\n     * @param {Number} start linear start position for removal (included in removal)\n     * @param {Number} end linear end position for removal ( excluded from removal )\n     */\n    removeStyleFromTo: function(start, end) {\n      var cursorStart = this.get2DCursorLocation(start, true),\n          cursorEnd = this.get2DCursorLocation(end, true),\n          lineStart = cursorStart.lineIndex,\n          charStart = cursorStart.charIndex,\n          lineEnd = cursorEnd.lineIndex,\n          charEnd = cursorEnd.charIndex,\n          i, styleObj;\n      if (lineStart !== lineEnd) {\n        // step1 remove the trailing of lineStart\n        if (this.styles[lineStart]) {\n          for (i = charStart; i < this._unwrappedTextLines[lineStart].length; i++) {\n            delete this.styles[lineStart][i];\n          }\n        }\n        // step2 move the trailing of lineEnd to lineStart if needed\n        if (this.styles[lineEnd]) {\n          for (i = charEnd; i < this._unwrappedTextLines[lineEnd].length; i++) {\n            styleObj = this.styles[lineEnd][i];\n            if (styleObj) {\n              this.styles[lineStart] || (this.styles[lineStart] = { });\n              this.styles[lineStart][charStart + i - charEnd] = styleObj;\n            }\n          }\n        }\n        // step3 detects lines will be completely removed.\n        for (i = lineStart + 1; i <= lineEnd; i++) {\n          delete this.styles[i];\n        }\n        // step4 shift remaining lines.\n        this.shiftLineStyles(lineEnd, lineStart - lineEnd);\n      }\n      else {\n        // remove and shift left on the same line\n        if (this.styles[lineStart]) {\n          styleObj = this.styles[lineStart];\n          var diff = charEnd - charStart, numericChar, _char;\n          for (i = charStart; i < charEnd; i++) {\n            delete styleObj[i];\n          }\n          for (_char in this.styles[lineStart]) {\n            numericChar = parseInt(_char, 10);\n            if (numericChar >= charEnd) {\n              styleObj[numericChar - diff] = styleObj[_char];\n              delete styleObj[_char];\n            }\n          }\n        }\n      }\n    },\n\n    /**\n     * Shifts line styles up or down\n     * @param {Number} lineIndex Index of a line\n     * @param {Number} offset Can any number?\n     */\n    shiftLineStyles: function(lineIndex, offset) {\n      // shift all line styles by offset upward or downward\n      // do not clone deep. we need new array, not new style objects\n      var clonedStyles = clone(this.styles);\n      for (var line in this.styles) {\n        var numericLine = parseInt(line, 10);\n        if (numericLine > lineIndex) {\n          this.styles[numericLine + offset] = clonedStyles[numericLine];\n          if (!clonedStyles[numericLine - offset]) {\n            delete this.styles[numericLine];\n          }\n        }\n      }\n    },\n\n    restartCursorIfNeeded: function() {\n      if (!this._currentTickState || this._currentTickState.isAborted\n        || !this._currentTickCompleteState || this._currentTickCompleteState.isAborted\n      ) {\n        this.initDelayedCursor();\n      }\n    },\n\n    /**\n     * Inserts new style object\n     * @param {Number} lineIndex Index of a line\n     * @param {Number} charIndex Index of a char\n     * @param {Number} qty number of lines to add\n     * @param {Array} copiedStyle Array of objects styles\n     */\n    insertNewlineStyleObject: function(lineIndex, charIndex, qty, copiedStyle) {\n      var currentCharStyle,\n          newLineStyles = {},\n          somethingAdded = false;\n\n      qty || (qty = 1);\n      this.shiftLineStyles(lineIndex, qty);\n      if (this.styles[lineIndex]) {\n        currentCharStyle = this.styles[lineIndex][charIndex === 0 ? charIndex : charIndex - 1];\n      }\n\n      // we clone styles of all chars\n      // after cursor onto the current line\n      for (var index in this.styles[lineIndex]) {\n        var numIndex = parseInt(index, 10);\n        if (numIndex >= charIndex) {\n          somethingAdded = true;\n          newLineStyles[numIndex - charIndex] = this.styles[lineIndex][index];\n          // remove lines from the previous line since they're on a new line now\n          delete this.styles[lineIndex][index];\n        }\n      }\n      if (somethingAdded) {\n        this.styles[lineIndex + qty] = newLineStyles;\n      }\n      else {\n        delete this.styles[lineIndex + qty];\n      }\n      // for the other lines\n      // we clone current char style onto the next (otherwise empty) line\n      while (qty > 1) {\n        qty--;\n        if (copiedStyle && copiedStyle[qty]) {\n          this.styles[lineIndex + qty] = { 0: clone(copiedStyle[qty]) };\n        }\n        else if (currentCharStyle) {\n          this.styles[lineIndex + qty] = { 0: clone(currentCharStyle) };\n        }\n        else {\n          delete this.styles[lineIndex + qty];\n        }\n      }\n      this._forceClearCache = true;\n    },\n\n    /**\n     * Inserts style object for a given line/char index\n     * @param {Number} lineIndex Index of a line\n     * @param {Number} charIndex Index of a char\n     * @param {Number} quantity number Style object to insert, if given\n     * @param {Array} copiedStyle array of style objecs\n     */\n    insertCharStyleObject: function(lineIndex, charIndex, quantity, copiedStyle) {\n      if (!this.styles) {\n        this.styles = {};\n      }\n      var currentLineStyles       = this.styles[lineIndex],\n          currentLineStylesCloned = currentLineStyles ? clone(currentLineStyles) : {};\n\n      quantity || (quantity = 1);\n      // shift all char styles by quantity forward\n      // 0,1,2,3 -> (charIndex=2) -> 0,1,3,4 -> (insert 2) -> 0,1,2,3,4\n      for (var index in currentLineStylesCloned) {\n        var numericIndex = parseInt(index, 10);\n        if (numericIndex >= charIndex) {\n          currentLineStyles[numericIndex + quantity] = currentLineStylesCloned[numericIndex];\n          // only delete the style if there was nothing moved there\n          if (!currentLineStylesCloned[numericIndex - quantity]) {\n            delete currentLineStyles[numericIndex];\n          }\n        }\n      }\n      this._forceClearCache = true;\n      if (copiedStyle) {\n        while (quantity--) {\n          if (!Object.keys(copiedStyle[quantity]).length) {\n            continue;\n          }\n          if (!this.styles[lineIndex]) {\n            this.styles[lineIndex] = {};\n          }\n          this.styles[lineIndex][charIndex + quantity] = clone(copiedStyle[quantity]);\n        }\n        return;\n      }\n      if (!currentLineStyles) {\n        return;\n      }\n      var newStyle = currentLineStyles[charIndex ? charIndex - 1 : 1];\n      while (newStyle && quantity--) {\n        this.styles[lineIndex][charIndex + quantity] = clone(newStyle);\n      }\n    },\n\n    /**\n     * Inserts style object(s)\n     * @param {Array} insertedText Characters at the location where style is inserted\n     * @param {Number} start cursor index for inserting style\n     * @param {Array} [copiedStyle] array of style objects to insert.\n     */\n    insertNewStyleBlock: function(insertedText, start, copiedStyle) {\n      var cursorLoc = this.get2DCursorLocation(start, true),\n          addedLines = [0], linesLenght = 0;\n      for (var i = 0; i < insertedText.length; i++) {\n        if (insertedText[i] === '\\n') {\n          linesLenght++;\n          addedLines[linesLenght] = 0;\n        }\n        else {\n          addedLines[linesLenght]++;\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      linesLenght && this.insertNewlineStyleObject(\n        cursorLoc.lineIndex, cursorLoc.charIndex + addedLines[0], linesLenght);\n      for (var i = 1; i < linesLenght; i++) {\n        if (addedLines[i] > 0) {\n          this.insertCharStyleObject(cursorLoc.lineIndex + i, 0, addedLines[i], copiedStyle);\n        }\n        else if (copiedStyle) {\n          this.styles[cursorLoc.lineIndex + i][0] = copiedStyle[0];\n        }\n        copiedStyle = copiedStyle && copiedStyle.slice(addedLines[i] + 1);\n      }\n      // we use i outside the loop to get it like linesLength\n      if (addedLines[i] > 0) {\n        this.insertCharStyleObject(cursorLoc.lineIndex + i, 0, addedLines[i], copiedStyle);\n      }\n    },\n\n    /**\n     * Set the selectionStart and selectionEnd according to the ne postion of cursor\n     * mimic the key - mouse navigation when shift is pressed.\n     */\n    setSelectionStartEndWithShift: function(start, end, newSelection) {\n      if (newSelection <= start) {\n        if (end === start) {\n          this._selectionDirection = 'left';\n        }\n        else if (this._selectionDirection === 'right') {\n          this._selectionDirection = 'left';\n          this.selectionEnd = start;\n        }\n        this.selectionStart = newSelection;\n      }\n      else if (newSelection > start && newSelection < end) {\n        if (this._selectionDirection === 'right') {\n          this.selectionEnd = newSelection;\n        }\n        else {\n          this.selectionStart = newSelection;\n        }\n      }\n      else {\n        // newSelection is > selection start and end\n        if (end === start) {\n          this._selectionDirection = 'right';\n        }\n        else if (this._selectionDirection === 'left') {\n          this._selectionDirection = 'right';\n          this.selectionStart = end;\n        }\n        this.selectionEnd = newSelection;\n      }\n    },\n\n    setSelectionInBoundaries: function() {\n      var length = this.text.length;\n      if (this.selectionStart > length) {\n        this.selectionStart = length;\n      }\n      else if (this.selectionStart < 0) {\n        this.selectionStart = 0;\n      }\n      if (this.selectionEnd > length) {\n        this.selectionEnd = length;\n      }\n      else if (this.selectionEnd < 0) {\n        this.selectionEnd = 0;\n      }\n    }\n  });\n})();\n\n\nfabric.util.object.extend(fabric.IText.prototype, /** @lends fabric.IText.prototype */ {\n  /**\n   * Initializes \"dbclick\" event handler\n   */\n  initDoubleClickSimulation: function() {\n\n    // for double click\n    this.__lastClickTime = +new Date();\n\n    // for triple click\n    this.__lastLastClickTime = +new Date();\n\n    this.__lastPointer = { };\n\n    this.on('mousedown', this.onMouseDown);\n  },\n\n  /**\n   * Default event handler to simulate triple click\n   * @private\n   */\n  onMouseDown: function(options) {\n    if (!this.canvas) {\n      return;\n    }\n    this.__newClickTime = +new Date();\n    var newPointer = options.pointer;\n    if (this.isTripleClick(newPointer)) {\n      this.fire('tripleclick', options);\n      this._stopEvent(options.e);\n    }\n    this.__lastLastClickTime = this.__lastClickTime;\n    this.__lastClickTime = this.__newClickTime;\n    this.__lastPointer = newPointer;\n    this.__lastIsEditing = this.isEditing;\n    this.__lastSelected = this.selected;\n  },\n\n  isTripleClick: function(newPointer) {\n    return this.__newClickTime - this.__lastClickTime < 500 &&\n        this.__lastClickTime - this.__lastLastClickTime < 500 &&\n        this.__lastPointer.x === newPointer.x &&\n        this.__lastPointer.y === newPointer.y;\n  },\n\n  /**\n   * @private\n   */\n  _stopEvent: function(e) {\n    e.preventDefault && e.preventDefault();\n    e.stopPropagation && e.stopPropagation();\n  },\n\n  /**\n   * Initializes event handlers related to cursor or selection\n   */\n  initCursorSelectionHandlers: function() {\n    this.initMousedownHandler();\n    this.initMouseupHandler();\n    this.initClicks();\n  },\n\n  /**\n   * Initializes double and triple click event handlers\n   */\n  initClicks: function() {\n    this.on('mousedblclick', function(options) {\n      this.selectWord(this.getSelectionStartFromPointer(options.e));\n    });\n    this.on('tripleclick', function(options) {\n      this.selectLine(this.getSelectionStartFromPointer(options.e));\n    });\n  },\n\n  /**\n   * Default event handler for the basic functionalities needed on _mouseDown\n   * can be overridden to do something different.\n   * Scope of this implementation is: find the click position, set selectionStart\n   * find selectionEnd, initialize the drawing of either cursor or selection area\n   */\n  _mouseDownHandler: function(options) {\n    if (!this.canvas || !this.editable || (options.e.button && options.e.button !== 1)) {\n      return;\n    }\n\n    this.__isMousedown = true;\n\n    if (this.selected) {\n      this.setCursorByClick(options.e);\n    }\n\n    if (this.isEditing) {\n      this.__selectionStartOnMouseDown = this.selectionStart;\n      if (this.selectionStart === this.selectionEnd) {\n        this.abortCursorAnimation();\n      }\n      this.renderCursorOrSelection();\n    }\n  },\n\n  /**\n   * Default event handler for the basic functionalities needed on mousedown:before\n   * can be overridden to do something different.\n   * Scope of this implementation is: verify the object is already selected when mousing down\n   */\n  _mouseDownHandlerBefore: function(options) {\n    if (!this.canvas || !this.editable || (options.e.button && options.e.button !== 1)) {\n      return;\n    }\n    if (this === this.canvas._activeObject) {\n      this.selected = true;\n    }\n  },\n\n  /**\n   * Initializes \"mousedown\" event handler\n   */\n  initMousedownHandler: function() {\n    this.on('mousedown', this._mouseDownHandler);\n    this.on('mousedown:before', this._mouseDownHandlerBefore);\n  },\n\n  /**\n   * Initializes \"mouseup\" event handler\n   */\n  initMouseupHandler: function() {\n    this.on('mouseup', this.mouseUpHandler);\n  },\n\n  /**\n   * standard hander for mouse up, overridable\n   * @private\n   */\n  mouseUpHandler: function(options) {\n    this.__isMousedown = false;\n    if (!this.editable || this.group ||\n      (options.transform && options.transform.actionPerformed) ||\n      (options.e.button && options.e.button !== 1)) {\n      return;\n    }\n\n    if (this.canvas) {\n      var currentActive = this.canvas._activeObject;\n      if (currentActive && currentActive !== this) {\n        // avoid running this logic when there is an active object\n        // this because is possible with shift click and fast clicks,\n        // to rapidly deselect and reselect this object and trigger an enterEdit\n        return;\n      }\n    }\n\n    if (this.__lastSelected && !this.__corner) {\n      this.selected = false;\n      this.__lastSelected = false;\n      this.enterEditing(options.e);\n      if (this.selectionStart === this.selectionEnd) {\n        this.initDelayedCursor(true);\n      }\n      else {\n        this.renderCursorOrSelection();\n      }\n    }\n    else {\n      this.selected = true;\n    }\n  },\n\n  /**\n   * Changes cursor location in a text depending on passed pointer (x/y) object\n   * @param {Event} e Event object\n   */\n  setCursorByClick: function(e) {\n    var newSelection = this.getSelectionStartFromPointer(e),\n        start = this.selectionStart, end = this.selectionEnd;\n    if (e.shiftKey) {\n      this.setSelectionStartEndWithShift(start, end, newSelection);\n    }\n    else {\n      this.selectionStart = newSelection;\n      this.selectionEnd = newSelection;\n    }\n    if (this.isEditing) {\n      this._fireSelectionChanged();\n      this._updateTextarea();\n    }\n  },\n\n  /**\n   * Returns index of a character corresponding to where an object was clicked\n   * @param {Event} e Event object\n   * @return {Number} Index of a character\n   */\n  getSelectionStartFromPointer: function(e) {\n    var mouseOffset = this.getLocalPointer(e),\n        prevWidth = 0,\n        width = 0,\n        height = 0,\n        charIndex = 0,\n        lineIndex = 0,\n        lineLeftOffset,\n        line;\n\n    for (var i = 0, len = this._textLines.length; i < len; i++) {\n      if (height <= mouseOffset.y) {\n        height += this.getHeightOfLine(i) * this.scaleY;\n        lineIndex = i;\n        if (i > 0) {\n          charIndex += this._textLines[i - 1].length + 1;\n        }\n      }\n      else {\n        break;\n      }\n    }\n    lineLeftOffset = this._getLineLeftOffset(lineIndex);\n    width = lineLeftOffset * this.scaleX;\n    line = this._textLines[lineIndex];\n    for (var j = 0, jlen = line.length; j < jlen; j++) {\n      prevWidth = width;\n      // i removed something about flipX here, check.\n      width += this.__charBounds[lineIndex][j].kernedWidth * this.scaleX;\n      if (width <= mouseOffset.x) {\n        charIndex++;\n      }\n      else {\n        break;\n      }\n    }\n    return this._getNewSelectionStartFromOffset(mouseOffset, prevWidth, width, charIndex, jlen);\n  },\n\n  /**\n   * @private\n   */\n  _getNewSelectionStartFromOffset: function(mouseOffset, prevWidth, width, index, jlen) {\n    // we need Math.abs because when width is after the last char, the offset is given as 1, while is 0\n    var distanceBtwLastCharAndCursor = mouseOffset.x - prevWidth,\n        distanceBtwNextCharAndCursor = width - mouseOffset.x,\n        offset = distanceBtwNextCharAndCursor > distanceBtwLastCharAndCursor ||\n          distanceBtwNextCharAndCursor < 0 ? 0 : 1,\n        newSelectionStart = index + offset;\n    // if object is horizontally flipped, mirror cursor location from the end\n    if (this.flipX) {\n      newSelectionStart = jlen - newSelectionStart;\n    }\n\n    if (newSelectionStart > this._text.length) {\n      newSelectionStart = this._text.length;\n    }\n\n    return newSelectionStart;\n  }\n});\n\n\nfabric.util.object.extend(fabric.IText.prototype, /** @lends fabric.IText.prototype */ {\n\n  /**\n   * Initializes hidden textarea (needed to bring up keyboard in iOS)\n   */\n  initHiddenTextarea: function() {\n    this.hiddenTextarea = fabric.document.createElement('textarea');\n    this.hiddenTextarea.setAttribute('autocapitalize', 'off');\n    this.hiddenTextarea.setAttribute('autocorrect', 'off');\n    this.hiddenTextarea.setAttribute('autocomplete', 'off');\n    this.hiddenTextarea.setAttribute('spellcheck', 'false');\n    this.hiddenTextarea.setAttribute('data-fabric-hiddentextarea', '');\n    this.hiddenTextarea.setAttribute('wrap', 'off');\n    var style = this._calcTextareaPosition();\n    // line-height: 1px; was removed from the style to fix this:\n    // https://bugs.chromium.org/p/chromium/issues/detail?id=870966\n    this.hiddenTextarea.style.cssText = 'position: absolute; top: ' + style.top +\n    '; left: ' + style.left + '; z-index: -999; opacity: 0; width: 1px; height: 1px; font-size: 1px;' +\n    ' paddingｰtop: ' + style.fontSize + ';';\n    fabric.document.body.appendChild(this.hiddenTextarea);\n\n    fabric.util.addListener(this.hiddenTextarea, 'keydown', this.onKeyDown.bind(this));\n    fabric.util.addListener(this.hiddenTextarea, 'keyup', this.onKeyUp.bind(this));\n    fabric.util.addListener(this.hiddenTextarea, 'input', this.onInput.bind(this));\n    fabric.util.addListener(this.hiddenTextarea, 'copy', this.copy.bind(this));\n    fabric.util.addListener(this.hiddenTextarea, 'cut', this.copy.bind(this));\n    fabric.util.addListener(this.hiddenTextarea, 'paste', this.paste.bind(this));\n    fabric.util.addListener(this.hiddenTextarea, 'compositionstart', this.onCompositionStart.bind(this));\n    fabric.util.addListener(this.hiddenTextarea, 'compositionupdate', this.onCompositionUpdate.bind(this));\n    fabric.util.addListener(this.hiddenTextarea, 'compositionend', this.onCompositionEnd.bind(this));\n\n    if (!this._clickHandlerInitialized && this.canvas) {\n      fabric.util.addListener(this.canvas.upperCanvasEl, 'click', this.onClick.bind(this));\n      this._clickHandlerInitialized = true;\n    }\n  },\n\n  /**\n   * For functionalities on keyDown\n   * Map a special key to a function of the instance/prototype\n   * If you need different behaviour for ESC or TAB or arrows, you have to change\n   * this map setting the name of a function that you build on the fabric.Itext or\n   * your prototype.\n   * the map change will affect all Instances unless you need for only some text Instances\n   * in that case you have to clone this object and assign your Instance.\n   * this.keysMap = fabric.util.object.clone(this.keysMap);\n   * The function must be in fabric.Itext.prototype.myFunction And will receive event as args[0]\n   */\n  keysMap: {\n    9:  'exitEditing',\n    27: 'exitEditing',\n    33: 'moveCursorUp',\n    34: 'moveCursorDown',\n    35: 'moveCursorRight',\n    36: 'moveCursorLeft',\n    37: 'moveCursorLeft',\n    38: 'moveCursorUp',\n    39: 'moveCursorRight',\n    40: 'moveCursorDown',\n  },\n\n  /**\n   * For functionalities on keyUp + ctrl || cmd\n   */\n  ctrlKeysMapUp: {\n    67: 'copy',\n    88: 'cut'\n  },\n\n  /**\n   * For functionalities on keyDown + ctrl || cmd\n   */\n  ctrlKeysMapDown: {\n    65: 'selectAll'\n  },\n\n  onClick: function() {\n    // No need to trigger click event here, focus is enough to have the keyboard appear on Android\n    this.hiddenTextarea && this.hiddenTextarea.focus();\n  },\n\n  /**\n   * Handles keyup event\n   * @param {Event} e Event object\n   */\n  onKeyDown: function(e) {\n    if (!this.isEditing || this.inCompositionMode) {\n      return;\n    }\n    if (e.keyCode in this.keysMap) {\n      this[this.keysMap[e.keyCode]](e);\n    }\n    else if ((e.keyCode in this.ctrlKeysMapDown) && (e.ctrlKey || e.metaKey)) {\n      this[this.ctrlKeysMapDown[e.keyCode]](e);\n    }\n    else {\n      return;\n    }\n    e.stopImmediatePropagation();\n    e.preventDefault();\n    if (e.keyCode >= 33 && e.keyCode <= 40) {\n      // if i press an arrow key just update selection\n      this.clearContextTop();\n      this.renderCursorOrSelection();\n    }\n    else {\n      this.canvas && this.canvas.requestRenderAll();\n    }\n  },\n\n  /**\n   * Handles keyup event\n   * We handle KeyUp because ie11 and edge have difficulties copy/pasting\n   * if a copy/cut event fired, keyup is dismissed\n   * @param {Event} e Event object\n   */\n  onKeyUp: function(e) {\n    if (!this.isEditing || this._copyDone || this.inCompositionMode) {\n      this._copyDone = false;\n      return;\n    }\n    if ((e.keyCode in this.ctrlKeysMapUp) && (e.ctrlKey || e.metaKey)) {\n      this[this.ctrlKeysMapUp[e.keyCode]](e);\n    }\n    else {\n      return;\n    }\n    e.stopImmediatePropagation();\n    e.preventDefault();\n    this.canvas && this.canvas.requestRenderAll();\n  },\n\n  /**\n   * Handles onInput event\n   * @param {Event} e Event object\n   */\n  onInput: function(e) {\n    var fromPaste = this.fromPaste;\n    this.fromPaste = false;\n    e && e.stopPropagation();\n    if (!this.isEditing) {\n      return;\n    }\n    // decisions about style changes.\n    var nextText = this._splitTextIntoLines(this.hiddenTextarea.value).graphemeText,\n        charCount = this._text.length,\n        nextCharCount = nextText.length,\n        removedText, insertedText,\n        charDiff = nextCharCount - charCount;\n    if (this.hiddenTextarea.value === '') {\n      this.styles = { };\n      this.updateFromTextArea();\n      this.fire('changed');\n      if (this.canvas) {\n        this.canvas.fire('text:changed', { target: this });\n        this.canvas.requestRenderAll();\n      }\n      return;\n    }\n\n    var textareaSelection = this.fromStringToGraphemeSelection(\n      this.hiddenTextarea.selectionStart,\n      this.hiddenTextarea.selectionEnd,\n      this.hiddenTextarea.value\n    );\n    var backDelete = this.selectionStart > textareaSelection.selectionStart;\n\n    if (this.selectionStart !== this.selectionEnd) {\n      removedText = this._text.slice(this.selectionStart, this.selectionEnd);\n      charDiff += this.selectionEnd - this.selectionStart;\n    }\n    else if (nextCharCount < charCount) {\n      if (backDelete) {\n        removedText = this._text.slice(this.selectionEnd + charDiff, this.selectionEnd);\n      }\n      else {\n        removedText = this._text.slice(this.selectionStart, this.selectionStart - charDiff);\n      }\n    }\n    insertedText = nextText.slice(textareaSelection.selectionEnd - charDiff, textareaSelection.selectionEnd);\n    if (removedText && removedText.length) {\n      if (this.selectionStart !== this.selectionEnd) {\n        this.removeStyleFromTo(this.selectionStart, this.selectionEnd);\n      }\n      else if (backDelete) {\n        // detect differencies between forwardDelete and backDelete\n        this.removeStyleFromTo(this.selectionEnd - removedText.length, this.selectionEnd);\n      }\n      else {\n        this.removeStyleFromTo(this.selectionEnd, this.selectionEnd + removedText.length);\n      }\n    }\n    if (insertedText.length) {\n      if (fromPaste && insertedText.join('') === fabric.copiedText) {\n        this.insertNewStyleBlock(insertedText, this.selectionStart, fabric.copiedTextStyle);\n      }\n      else {\n        this.insertNewStyleBlock(insertedText, this.selectionStart);\n      }\n    }\n    this.updateFromTextArea();\n    this.fire('changed');\n    if (this.canvas) {\n      this.canvas.fire('text:changed', { target: this });\n      this.canvas.requestRenderAll();\n    }\n  },\n  /**\n   * Composition start\n   */\n  onCompositionStart: function() {\n    this.inCompositionMode = true;\n  },\n\n  /**\n   * Composition end\n   */\n  onCompositionEnd: function() {\n    this.inCompositionMode = false;\n  },\n\n  // /**\n  //  * Composition update\n  //  */\n  onCompositionUpdate: function(e) {\n    this.compositionStart = e.target.selectionStart;\n    this.compositionEnd = e.target.selectionEnd;\n    this.updateTextareaPosition();\n  },\n\n  /**\n   * Copies selected text\n   * @param {Event} e Event object\n   */\n  copy: function() {\n    if (this.selectionStart === this.selectionEnd) {\n      //do not cut-copy if no selection\n      return;\n    }\n\n    fabric.copiedText = this.getSelectedText();\n    fabric.copiedTextStyle = this.getSelectionStyles(this.selectionStart, this.selectionEnd, true);\n    this._copyDone = true;\n  },\n\n  /**\n   * Pastes text\n   * @param {Event} e Event object\n   */\n  paste: function() {\n    this.fromPaste = true;\n  },\n\n  /**\n   * @private\n   * @param {Event} e Event object\n   * @return {Object} Clipboard data object\n   */\n  _getClipboardData: function(e) {\n    return (e && e.clipboardData) || fabric.window.clipboardData;\n  },\n\n  /**\n   * Finds the width in pixels before the cursor on the same line\n   * @private\n   * @param {Number} lineIndex\n   * @param {Number} charIndex\n   * @return {Number} widthBeforeCursor width before cursor\n   */\n  _getWidthBeforeCursor: function(lineIndex, charIndex) {\n    var widthBeforeCursor = this._getLineLeftOffset(lineIndex), bound;\n\n    if (charIndex > 0) {\n      bound = this.__charBounds[lineIndex][charIndex - 1];\n      widthBeforeCursor += bound.left + bound.width;\n    }\n    return widthBeforeCursor;\n  },\n\n  /**\n   * Gets start offset of a selection\n   * @param {Event} e Event object\n   * @param {Boolean} isRight\n   * @return {Number}\n   */\n  getDownCursorOffset: function(e, isRight) {\n    var selectionProp = this._getSelectionForOffset(e, isRight),\n        cursorLocation = this.get2DCursorLocation(selectionProp),\n        lineIndex = cursorLocation.lineIndex;\n    // if on last line, down cursor goes to end of line\n    if (lineIndex === this._textLines.length - 1 || e.metaKey || e.keyCode === 34) {\n      // move to the end of a text\n      return this._text.length - selectionProp;\n    }\n    var charIndex = cursorLocation.charIndex,\n        widthBeforeCursor = this._getWidthBeforeCursor(lineIndex, charIndex),\n        indexOnOtherLine = this._getIndexOnLine(lineIndex + 1, widthBeforeCursor),\n        textAfterCursor = this._textLines[lineIndex].slice(charIndex);\n    return textAfterCursor.length + indexOnOtherLine + 2;\n  },\n\n  /**\n   * private\n   * Helps finding if the offset should be counted from Start or End\n   * @param {Event} e Event object\n   * @param {Boolean} isRight\n   * @return {Number}\n   */\n  _getSelectionForOffset: function(e, isRight) {\n    if (e.shiftKey && this.selectionStart !== this.selectionEnd && isRight) {\n      return this.selectionEnd;\n    }\n    else {\n      return this.selectionStart;\n    }\n  },\n\n  /**\n   * @param {Event} e Event object\n   * @param {Boolean} isRight\n   * @return {Number}\n   */\n  getUpCursorOffset: function(e, isRight) {\n    var selectionProp = this._getSelectionForOffset(e, isRight),\n        cursorLocation = this.get2DCursorLocation(selectionProp),\n        lineIndex = cursorLocation.lineIndex;\n    if (lineIndex === 0 || e.metaKey || e.keyCode === 33) {\n      // if on first line, up cursor goes to start of line\n      return -selectionProp;\n    }\n    var charIndex = cursorLocation.charIndex,\n        widthBeforeCursor = this._getWidthBeforeCursor(lineIndex, charIndex),\n        indexOnOtherLine = this._getIndexOnLine(lineIndex - 1, widthBeforeCursor),\n        textBeforeCursor = this._textLines[lineIndex].slice(0, charIndex);\n    // return a negative offset\n    return -this._textLines[lineIndex - 1].length + indexOnOtherLine - textBeforeCursor.length;\n  },\n\n  /**\n   * for a given width it founds the matching character.\n   * @private\n   */\n  _getIndexOnLine: function(lineIndex, width) {\n\n    var line = this._textLines[lineIndex],\n        lineLeftOffset = this._getLineLeftOffset(lineIndex),\n        widthOfCharsOnLine = lineLeftOffset,\n        indexOnLine = 0, charWidth, foundMatch;\n\n    for (var j = 0, jlen = line.length; j < jlen; j++) {\n      charWidth = this.__charBounds[lineIndex][j].width;\n      widthOfCharsOnLine += charWidth;\n      if (widthOfCharsOnLine > width) {\n        foundMatch = true;\n        var leftEdge = widthOfCharsOnLine - charWidth,\n            rightEdge = widthOfCharsOnLine,\n            offsetFromLeftEdge = Math.abs(leftEdge - width),\n            offsetFromRightEdge = Math.abs(rightEdge - width);\n\n        indexOnLine = offsetFromRightEdge < offsetFromLeftEdge ? j : (j - 1);\n        break;\n      }\n    }\n\n    // reached end\n    if (!foundMatch) {\n      indexOnLine = line.length - 1;\n    }\n\n    return indexOnLine;\n  },\n\n\n  /**\n   * Moves cursor down\n   * @param {Event} e Event object\n   */\n  moveCursorDown: function(e) {\n    if (this.selectionStart >= this._text.length && this.selectionEnd >= this._text.length) {\n      return;\n    }\n    this._moveCursorUpOrDown('Down', e);\n  },\n\n  /**\n   * Moves cursor up\n   * @param {Event} e Event object\n   */\n  moveCursorUp: function(e) {\n    if (this.selectionStart === 0 && this.selectionEnd === 0) {\n      return;\n    }\n    this._moveCursorUpOrDown('Up', e);\n  },\n\n  /**\n   * Moves cursor up or down, fires the events\n   * @param {String} direction 'Up' or 'Down'\n   * @param {Event} e Event object\n   */\n  _moveCursorUpOrDown: function(direction, e) {\n    // getUpCursorOffset\n    // getDownCursorOffset\n    var action = 'get' + direction + 'CursorOffset',\n        offset = this[action](e, this._selectionDirection === 'right');\n    if (e.shiftKey) {\n      this.moveCursorWithShift(offset);\n    }\n    else {\n      this.moveCursorWithoutShift(offset);\n    }\n    if (offset !== 0) {\n      this.setSelectionInBoundaries();\n      this.abortCursorAnimation();\n      this._currentCursorOpacity = 1;\n      this.initDelayedCursor();\n      this._fireSelectionChanged();\n      this._updateTextarea();\n    }\n  },\n\n  /**\n   * Moves cursor with shift\n   * @param {Number} offset\n   */\n  moveCursorWithShift: function(offset) {\n    var newSelection = this._selectionDirection === 'left'\n      ? this.selectionStart + offset\n      : this.selectionEnd + offset;\n    this.setSelectionStartEndWithShift(this.selectionStart, this.selectionEnd, newSelection);\n    return offset !== 0;\n  },\n\n  /**\n   * Moves cursor up without shift\n   * @param {Number} offset\n   */\n  moveCursorWithoutShift: function(offset) {\n    if (offset < 0) {\n      this.selectionStart += offset;\n      this.selectionEnd = this.selectionStart;\n    }\n    else {\n      this.selectionEnd += offset;\n      this.selectionStart = this.selectionEnd;\n    }\n    return offset !== 0;\n  },\n\n  /**\n   * Moves cursor left\n   * @param {Event} e Event object\n   */\n  moveCursorLeft: function(e) {\n    if (this.selectionStart === 0 && this.selectionEnd === 0) {\n      return;\n    }\n    this._moveCursorLeftOrRight('Left', e);\n  },\n\n  /**\n   * @private\n   * @return {Boolean} true if a change happened\n   */\n  _move: function(e, prop, direction) {\n    var newValue;\n    if (e.altKey) {\n      newValue = this['findWordBoundary' + direction](this[prop]);\n    }\n    else if (e.metaKey || e.keyCode === 35 ||  e.keyCode === 36 ) {\n      newValue = this['findLineBoundary' + direction](this[prop]);\n    }\n    else {\n      this[prop] += direction === 'Left' ? -1 : 1;\n      return true;\n    }\n    if (typeof newValue !== undefined && this[prop] !== newValue) {\n      this[prop] = newValue;\n      return true;\n    }\n  },\n\n  /**\n   * @private\n   */\n  _moveLeft: function(e, prop) {\n    return this._move(e, prop, 'Left');\n  },\n\n  /**\n   * @private\n   */\n  _moveRight: function(e, prop) {\n    return this._move(e, prop, 'Right');\n  },\n\n  /**\n   * Moves cursor left without keeping selection\n   * @param {Event} e\n   */\n  moveCursorLeftWithoutShift: function(e) {\n    var change = true;\n    this._selectionDirection = 'left';\n\n    // only move cursor when there is no selection,\n    // otherwise we discard it, and leave cursor on same place\n    if (this.selectionEnd === this.selectionStart && this.selectionStart !== 0) {\n      change = this._moveLeft(e, 'selectionStart');\n\n    }\n    this.selectionEnd = this.selectionStart;\n    return change;\n  },\n\n  /**\n   * Moves cursor left while keeping selection\n   * @param {Event} e\n   */\n  moveCursorLeftWithShift: function(e) {\n    if (this._selectionDirection === 'right' && this.selectionStart !== this.selectionEnd) {\n      return this._moveLeft(e, 'selectionEnd');\n    }\n    else if (this.selectionStart !== 0){\n      this._selectionDirection = 'left';\n      return this._moveLeft(e, 'selectionStart');\n    }\n  },\n\n  /**\n   * Moves cursor right\n   * @param {Event} e Event object\n   */\n  moveCursorRight: function(e) {\n    if (this.selectionStart >= this._text.length && this.selectionEnd >= this._text.length) {\n      return;\n    }\n    this._moveCursorLeftOrRight('Right', e);\n  },\n\n  /**\n   * Moves cursor right or Left, fires event\n   * @param {String} direction 'Left', 'Right'\n   * @param {Event} e Event object\n   */\n  _moveCursorLeftOrRight: function(direction, e) {\n    var actionName = 'moveCursor' + direction + 'With';\n    this._currentCursorOpacity = 1;\n\n    if (e.shiftKey) {\n      actionName += 'Shift';\n    }\n    else {\n      actionName += 'outShift';\n    }\n    if (this[actionName](e)) {\n      this.abortCursorAnimation();\n      this.initDelayedCursor();\n      this._fireSelectionChanged();\n      this._updateTextarea();\n    }\n  },\n\n  /**\n   * Moves cursor right while keeping selection\n   * @param {Event} e\n   */\n  moveCursorRightWithShift: function(e) {\n    if (this._selectionDirection === 'left' && this.selectionStart !== this.selectionEnd) {\n      return this._moveRight(e, 'selectionStart');\n    }\n    else if (this.selectionEnd !== this._text.length) {\n      this._selectionDirection = 'right';\n      return this._moveRight(e, 'selectionEnd');\n    }\n  },\n\n  /**\n   * Moves cursor right without keeping selection\n   * @param {Event} e Event object\n   */\n  moveCursorRightWithoutShift: function(e) {\n    var changed = true;\n    this._selectionDirection = 'right';\n\n    if (this.selectionStart === this.selectionEnd) {\n      changed = this._moveRight(e, 'selectionStart');\n      this.selectionEnd = this.selectionStart;\n    }\n    else {\n      this.selectionStart = this.selectionEnd;\n    }\n    return changed;\n  },\n\n  /**\n   * Removes characters from start/end\n   * start/end ar per grapheme position in _text array.\n   *\n   * @param {Number} start\n   * @param {Number} end default to start + 1\n   */\n  removeChars: function(start, end) {\n    if (typeof end === 'undefined') {\n      end = start + 1;\n    }\n    this.removeStyleFromTo(start, end);\n    this._text.splice(start, end - start);\n    this.text = this._text.join('');\n    this.set('dirty', true);\n    if (this._shouldClearDimensionCache()) {\n      this.initDimensions();\n      this.setCoords();\n    }\n    this._removeExtraneousStyles();\n  },\n\n  /**\n   * insert characters at start position, before start position.\n   * start  equal 1 it means the text get inserted between actual grapheme 0 and 1\n   * if style array is provided, it must be as the same length of text in graphemes\n   * if end is provided and is bigger than start, old text is replaced.\n   * start/end ar per grapheme position in _text array.\n   *\n   * @param {String} text text to insert\n   * @param {Array} style array of style objects\n   * @param {Number} start\n   * @param {Number} end default to start + 1\n   */\n  insertChars: function(text, style, start, end) {\n    if (typeof end === 'undefined') {\n      end = start;\n    }\n    if (end > start) {\n      this.removeStyleFromTo(start, end);\n    }\n    var graphemes = fabric.util.string.graphemeSplit(text);\n    this.insertNewStyleBlock(graphemes, start, style);\n    this._text = [].concat(this._text.slice(0, start), graphemes, this._text.slice(end));\n    this.text = this._text.join('');\n    this.set('dirty', true);\n    if (this._shouldClearDimensionCache()) {\n      this.initDimensions();\n      this.setCoords();\n    }\n    this._removeExtraneousStyles();\n  },\n\n});\n\n\n/* _TO_SVG_START_ */\n(function() {\n  var toFixed = fabric.util.toFixed,\n      multipleSpacesRegex = /  +/g;\n\n  fabric.util.object.extend(fabric.Text.prototype, /** @lends fabric.Text.prototype */ {\n\n    /**\n     * Returns SVG representation of an instance\n     * @param {Function} [reviver] Method for further parsing of svg representation.\n     * @return {String} svg representation of an instance\n     */\n    toSVG: function(reviver) {\n      var offsets = this._getSVGLeftTopOffsets(),\n          textAndBg = this._getSVGTextAndBg(offsets.textTop, offsets.textLeft),\n          internalMarkup = this._wrapSVGTextAndBg(textAndBg);\n      return this._createBaseSVGMarkup(\n        internalMarkup, { reviver: reviver, noStyle: true, withShadow: true });\n    },\n\n    /**\n     * @private\n     */\n    _getSVGLeftTopOffsets: function() {\n      return {\n        textLeft: -this.width / 2,\n        textTop: -this.height / 2,\n        lineTop: this.getHeightOfLine(0)\n      };\n    },\n\n    /**\n     * @private\n     */\n    _wrapSVGTextAndBg: function(textAndBg) {\n      var noShadow = true,\n          textDecoration = this.getSvgTextDecoration(this);\n      return [\n        textAndBg.textBgRects.join(''),\n        '\\t\\t<text xml:space=\"preserve\" ',\n        (this.fontFamily ? 'font-family=\"' + this.fontFamily.replace(/\"/g, '\\'') + '\" ' : ''),\n        (this.fontSize ? 'font-size=\"' + this.fontSize + '\" ' : ''),\n        (this.fontStyle ? 'font-style=\"' + this.fontStyle + '\" ' : ''),\n        (this.fontWeight ? 'font-weight=\"' + this.fontWeight + '\" ' : ''),\n        (textDecoration ? 'text-decoration=\"' + textDecoration + '\" ' : ''),\n        'style=\"', this.getSvgStyles(noShadow), '\"', this.addPaintOrder(), ' >',\n        textAndBg.textSpans.join(''),\n        '</text>\\n'\n      ];\n    },\n\n    /**\n     * @private\n     * @param {Number} textTopOffset Text top offset\n     * @param {Number} textLeftOffset Text left offset\n     * @return {Object}\n     */\n    _getSVGTextAndBg: function(textTopOffset, textLeftOffset) {\n      var textSpans = [],\n          textBgRects = [],\n          height = textTopOffset, lineOffset;\n      // bounding-box background\n      this._setSVGBg(textBgRects);\n\n      // text and text-background\n      for (var i = 0, len = this._textLines.length; i < len; i++) {\n        lineOffset = this._getLineLeftOffset(i);\n        if (this.textBackgroundColor || this.styleHas('textBackgroundColor', i)) {\n          this._setSVGTextLineBg(textBgRects, i, textLeftOffset + lineOffset, height);\n        }\n        this._setSVGTextLineText(textSpans, i, textLeftOffset + lineOffset, height);\n        height += this.getHeightOfLine(i);\n      }\n\n      return {\n        textSpans: textSpans,\n        textBgRects: textBgRects\n      };\n    },\n\n    /**\n     * @private\n     */\n    _createTextCharSpan: function(_char, styleDecl, left, top) {\n      var shouldUseWhitespace = _char !== _char.trim() || _char.match(multipleSpacesRegex),\n          styleProps = this.getSvgSpanStyles(styleDecl, shouldUseWhitespace),\n          fillStyles = styleProps ? 'style=\"' + styleProps + '\"' : '',\n          dy = styleDecl.deltaY, dySpan = '',\n          NUM_FRACTION_DIGITS = fabric.Object.NUM_FRACTION_DIGITS;\n      if (dy) {\n        dySpan = ' dy=\"' + toFixed(dy, NUM_FRACTION_DIGITS) + '\" ';\n      }\n      return [\n        '<tspan x=\"', toFixed(left, NUM_FRACTION_DIGITS), '\" y=\"',\n        toFixed(top, NUM_FRACTION_DIGITS), '\" ', dySpan,\n        fillStyles, '>',\n        fabric.util.string.escapeXml(_char),\n        '</tspan>'\n      ].join('');\n    },\n\n    _setSVGTextLineText: function(textSpans, lineIndex, textLeftOffset, textTopOffset) {\n      // set proper line offset\n      var lineHeight = this.getHeightOfLine(lineIndex),\n          isJustify = this.textAlign.indexOf('justify') !== -1,\n          actualStyle,\n          nextStyle,\n          charsToRender = '',\n          charBox, style,\n          boxWidth = 0,\n          line = this._textLines[lineIndex],\n          timeToRender;\n\n      textTopOffset += lineHeight * (1 - this._fontSizeFraction) / this.lineHeight;\n      for (var i = 0, len = line.length - 1; i <= len; i++) {\n        timeToRender = i === len || this.charSpacing;\n        charsToRender += line[i];\n        charBox = this.__charBounds[lineIndex][i];\n        if (boxWidth === 0) {\n          textLeftOffset += charBox.kernedWidth - charBox.width;\n          boxWidth += charBox.width;\n        }\n        else {\n          boxWidth += charBox.kernedWidth;\n        }\n        if (isJustify && !timeToRender) {\n          if (this._reSpaceAndTab.test(line[i])) {\n            timeToRender = true;\n          }\n        }\n        if (!timeToRender) {\n          // if we have charSpacing, we render char by char\n          actualStyle = actualStyle || this.getCompleteStyleDeclaration(lineIndex, i);\n          nextStyle = this.getCompleteStyleDeclaration(lineIndex, i + 1);\n          timeToRender = this._hasStyleChangedForSvg(actualStyle, nextStyle);\n        }\n        if (timeToRender) {\n          style = this._getStyleDeclaration(lineIndex, i) || { };\n          textSpans.push(this._createTextCharSpan(charsToRender, style, textLeftOffset, textTopOffset));\n          charsToRender = '';\n          actualStyle = nextStyle;\n          textLeftOffset += boxWidth;\n          boxWidth = 0;\n        }\n      }\n    },\n\n    _pushTextBgRect: function(textBgRects, color, left, top, width, height) {\n      var NUM_FRACTION_DIGITS = fabric.Object.NUM_FRACTION_DIGITS;\n      textBgRects.push(\n        '\\t\\t<rect ',\n        this._getFillAttributes(color),\n        ' x=\"',\n        toFixed(left, NUM_FRACTION_DIGITS),\n        '\" y=\"',\n        toFixed(top, NUM_FRACTION_DIGITS),\n        '\" width=\"',\n        toFixed(width, NUM_FRACTION_DIGITS),\n        '\" height=\"',\n        toFixed(height, NUM_FRACTION_DIGITS),\n        '\"></rect>\\n');\n    },\n\n    _setSVGTextLineBg: function(textBgRects, i, leftOffset, textTopOffset) {\n      var line = this._textLines[i],\n          heightOfLine = this.getHeightOfLine(i) / this.lineHeight,\n          boxWidth = 0,\n          boxStart = 0,\n          charBox, currentColor,\n          lastColor = this.getValueOfPropertyAt(i, 0, 'textBackgroundColor');\n      for (var j = 0, jlen = line.length; j < jlen; j++) {\n        charBox = this.__charBounds[i][j];\n        currentColor = this.getValueOfPropertyAt(i, j, 'textBackgroundColor');\n        if (currentColor !== lastColor) {\n          lastColor && this._pushTextBgRect(textBgRects, lastColor, leftOffset + boxStart,\n            textTopOffset, boxWidth, heightOfLine);\n          boxStart = charBox.left;\n          boxWidth = charBox.width;\n          lastColor = currentColor;\n        }\n        else {\n          boxWidth += charBox.kernedWidth;\n        }\n      }\n      currentColor && this._pushTextBgRect(textBgRects, currentColor, leftOffset + boxStart,\n        textTopOffset, boxWidth, heightOfLine);\n    },\n\n    /**\n     * Adobe Illustrator (at least CS5) is unable to render rgba()-based fill values\n     * we work around it by \"moving\" alpha channel into opacity attribute and setting fill's alpha to 1\n     *\n     * @private\n     * @param {*} value\n     * @return {String}\n     */\n    _getFillAttributes: function(value) {\n      var fillColor = (value && typeof value === 'string') ? new fabric.Color(value) : '';\n      if (!fillColor || !fillColor.getSource() || fillColor.getAlpha() === 1) {\n        return 'fill=\"' + value + '\"';\n      }\n      return 'opacity=\"' + fillColor.getAlpha() + '\" fill=\"' + fillColor.setAlpha(1).toRgb() + '\"';\n    },\n\n    /**\n     * @private\n     */\n    _getSVGLineTopOffset: function(lineIndex) {\n      var lineTopOffset = 0, lastHeight = 0;\n      for (var j = 0; j < lineIndex; j++) {\n        lineTopOffset += this.getHeightOfLine(j);\n      }\n      lastHeight = this.getHeightOfLine(j);\n      return {\n        lineTop: lineTopOffset,\n        offset: (this._fontSizeMult - this._fontSizeFraction) * lastHeight / (this.lineHeight * this._fontSizeMult)\n      };\n    },\n\n    /**\n     * Returns styles-string for svg-export\n     * @param {Boolean} skipShadow a boolean to skip shadow filter output\n     * @return {String}\n     */\n    getSvgStyles: function(skipShadow) {\n      var svgStyle = fabric.Object.prototype.getSvgStyles.call(this, skipShadow);\n      return svgStyle + ' white-space: pre;';\n    },\n  });\n})();\n/* _TO_SVG_END_ */\n\n\n(function(global) {\n\n  'use strict';\n\n  var fabric = global.fabric || (global.fabric = {});\n\n  /**\n   * Textbox class, based on IText, allows the user to resize the text rectangle\n   * and wraps lines automatically. Textboxes have their Y scaling locked, the\n   * user can only change width. Height is adjusted automatically based on the\n   * wrapping of lines.\n   * @class fabric.Textbox\n   * @extends fabric.IText\n   * @mixes fabric.Observable\n   * @return {fabric.Textbox} thisArg\n   * @see {@link fabric.Textbox#initialize} for constructor definition\n   */\n  fabric.Textbox = fabric.util.createClass(fabric.IText, fabric.Observable, {\n\n    /**\n     * Type of an object\n     * @type String\n     * @default\n     */\n    type: 'textbox',\n\n    /**\n     * Minimum width of textbox, in pixels.\n     * @type Number\n     * @default\n     */\n    minWidth: 20,\n\n    /**\n     * Minimum calculated width of a textbox, in pixels.\n     * fixed to 2 so that an empty textbox cannot go to 0\n     * and is still selectable without text.\n     * @type Number\n     * @default\n     */\n    dynamicMinWidth: 2,\n\n    /**\n     * Cached array of text wrapping.\n     * @type Array\n     */\n    __cachedLines: null,\n\n    /**\n     * Override standard Object class values\n     */\n    lockScalingFlip: true,\n\n    /**\n     * Override standard Object class values\n     * Textbox needs this on false\n     */\n    noScaleCache: false,\n\n    /**\n     * Properties which when set cause object to change dimensions\n     * @type Object\n     * @private\n     */\n    _dimensionAffectingProps: fabric.Text.prototype._dimensionAffectingProps.concat('width'),\n\n    /**\n     * Unlike superclass's version of this function, Textbox does not update\n     * its width.\n     * @private\n     * @override\n     */\n    initDimensions: function() {\n      if (this.__skipDimension) {\n        return;\n      }\n      this.isEditing && this.initDelayedCursor();\n      this.clearContextTop();\n      this._clearCache();\n      // clear dynamicMinWidth as it will be different after we re-wrap line\n      this.dynamicMinWidth = 0;\n      // wrap lines\n      this._styleMap = this._generateStyleMap(this._splitText());\n      // if after wrapping, the width is smaller than dynamicMinWidth, change the width and re-wrap\n      if (this.dynamicMinWidth > this.width) {\n        this._set('width', this.dynamicMinWidth);\n      }\n      if (this.textAlign.indexOf('justify') !== -1) {\n        // once text is measured we need to make space fatter to make justified text.\n        this.enlargeSpaces();\n      }\n      // clear cache and re-calculate height\n      this.height = this.calcTextHeight();\n      this.saveState({ propertySet: '_dimensionAffectingProps' });\n    },\n\n    /**\n     * Generate an object that translates the style object so that it is\n     * broken up by visual lines (new lines and automatic wrapping).\n     * The original text styles object is broken up by actual lines (new lines only),\n     * which is only sufficient for Text / IText\n     * @private\n     */\n    _generateStyleMap: function(textInfo) {\n      var realLineCount     = 0,\n          realLineCharCount = 0,\n          charCount         = 0,\n          map               = {};\n\n      for (var i = 0; i < textInfo.graphemeLines.length; i++) {\n        if (textInfo.graphemeText[charCount] === '\\n' && i > 0) {\n          realLineCharCount = 0;\n          charCount++;\n          realLineCount++;\n        }\n        else if (this._reSpaceAndTab.test(textInfo.graphemeText[charCount]) && i > 0) {\n          // this case deals with space's that are removed from end of lines when wrapping\n          realLineCharCount++;\n          charCount++;\n        }\n\n        map[i] = { line: realLineCount, offset: realLineCharCount };\n\n        charCount += textInfo.graphemeLines[i].length;\n        realLineCharCount += textInfo.graphemeLines[i].length;\n      }\n\n      return map;\n    },\n\n    /**\n     * Returns true if object has a style property or has it ina specified line\n     * @param {Number} lineIndex\n     * @return {Boolean}\n     */\n    styleHas: function(property, lineIndex) {\n      if (this._styleMap && !this.isWrapping) {\n        var map = this._styleMap[lineIndex];\n        if (map) {\n          lineIndex = map.line;\n        }\n      }\n      return fabric.Text.prototype.styleHas.call(this, property, lineIndex);\n    },\n\n    /**\n     * Returns true if object has no styling or no styling in a line\n     * @param {Number} lineIndex , lineIndex is on wrapped lines.\n     * @return {Boolean}\n     */\n    isEmptyStyles: function(lineIndex) {\n      var offset = 0, nextLineIndex = lineIndex + 1, nextOffset, obj, shouldLimit = false;\n      var map = this._styleMap[lineIndex];\n      var mapNextLine = this._styleMap[lineIndex + 1];\n      if (map) {\n        lineIndex = map.line;\n        offset = map.offset;\n      }\n      if (mapNextLine) {\n        nextLineIndex = mapNextLine.line;\n        shouldLimit = nextLineIndex === lineIndex;\n        nextOffset = mapNextLine.offset;\n      }\n      obj = typeof lineIndex === 'undefined' ? this.styles : { line: this.styles[lineIndex] };\n      for (var p1 in obj) {\n        for (var p2 in obj[p1]) {\n          if (p2 >= offset && (!shouldLimit || p2 < nextOffset)) {\n            // eslint-disable-next-line no-unused-vars\n            for (var p3 in obj[p1][p2]) {\n              return false;\n            }\n          }\n        }\n      }\n      return true;\n    },\n\n    /**\n     * @param {Number} lineIndex\n     * @param {Number} charIndex\n     * @private\n     */\n    _getStyleDeclaration: function(lineIndex, charIndex) {\n      if (this._styleMap && !this.isWrapping) {\n        var map = this._styleMap[lineIndex];\n        if (!map) {\n          return null;\n        }\n        lineIndex = map.line;\n        charIndex = map.offset + charIndex;\n      }\n      return this.callSuper('_getStyleDeclaration', lineIndex, charIndex);\n    },\n\n    /**\n     * @param {Number} lineIndex\n     * @param {Number} charIndex\n     * @param {Object} style\n     * @private\n     */\n    _setStyleDeclaration: function(lineIndex, charIndex, style) {\n      var map = this._styleMap[lineIndex];\n      lineIndex = map.line;\n      charIndex = map.offset + charIndex;\n\n      this.styles[lineIndex][charIndex] = style;\n    },\n\n    /**\n     * @param {Number} lineIndex\n     * @param {Number} charIndex\n     * @private\n     */\n    _deleteStyleDeclaration: function(lineIndex, charIndex) {\n      var map = this._styleMap[lineIndex];\n      lineIndex = map.line;\n      charIndex = map.offset + charIndex;\n\n      delete this.styles[lineIndex][charIndex];\n    },\n\n    /**\n    * probably broken need a fix\n     * @param {Number} lineIndex\n     * @private\n     */\n    _getLineStyle: function(lineIndex) {\n      var map = this._styleMap[lineIndex];\n      return this.styles[map.line];\n    },\n\n    /**\n     * probably broken need a fix\n     * @param {Number} lineIndex\n     * @param {Object} style\n     * @private\n     */\n    _setLineStyle: function(lineIndex, style) {\n      var map = this._styleMap[lineIndex];\n      this.styles[map.line] = style;\n    },\n\n    /**\n     * probably broken need a fix\n     * @param {Number} lineIndex\n     * @private\n     */\n    _deleteLineStyle: function(lineIndex) {\n      var map = this._styleMap[lineIndex];\n      delete this.styles[map.line];\n    },\n\n    /**\n     * Wraps text using the 'width' property of Textbox. First this function\n     * splits text on newlines, so we preserve newlines entered by the user.\n     * Then it wraps each line using the width of the Textbox by calling\n     * _wrapLine().\n     * @param {Array} lines The string array of text that is split into lines\n     * @param {Number} desiredWidth width you want to wrap to\n     * @returns {Array} Array of lines\n     */\n    _wrapText: function(lines, desiredWidth) {\n      var wrapped = [], i;\n      this.isWrapping = true;\n      for (i = 0; i < lines.length; i++) {\n        wrapped = wrapped.concat(this._wrapLine(lines[i], i, desiredWidth));\n      }\n      this.isWrapping = false;\n      return wrapped;\n    },\n\n    /**\n     * Helper function to measure a string of text, given its lineIndex and charIndex offset\n     * it gets called when charBounds are not available yet.\n     * @param {CanvasRenderingContext2D} ctx\n     * @param {String} text\n     * @param {number} lineIndex\n     * @param {number} charOffset\n     * @returns {number}\n     * @private\n     */\n    _measureWord: function(word, lineIndex, charOffset) {\n      var width = 0, prevGrapheme, skipLeft = true;\n      charOffset = charOffset || 0;\n      for (var i = 0, len = word.length; i < len; i++) {\n        var box = this._getGraphemeBox(word[i], lineIndex, i + charOffset, prevGrapheme, skipLeft);\n        width += box.kernedWidth;\n        prevGrapheme = word[i];\n      }\n      return width;\n    },\n\n    /**\n     * Wraps a line of text using the width of the Textbox and a context.\n     * @param {Array} line The grapheme array that represent the line\n     * @param {Number} lineIndex\n     * @param {Number} desiredWidth width you want to wrap the line to\n     * @param {Number} reservedSpace space to remove from wrapping for custom functionalities\n     * @returns {Array} Array of line(s) into which the given text is wrapped\n     * to.\n     */\n    _wrapLine: function(_line, lineIndex, desiredWidth, reservedSpace) {\n      var lineWidth        = 0,\n          graphemeLines    = [],\n          line             = [],\n          // spaces in different languges?\n          words            = _line.split(this._reSpaceAndTab),\n          word             = '',\n          offset           = 0,\n          infix            = ' ',\n          wordWidth        = 0,\n          infixWidth       = 0,\n          largestWordWidth = 0,\n          lineJustStarted = true,\n          additionalSpace = this._getWidthOfCharSpacing(),\n          reservedSpace = reservedSpace || 0;\n\n      desiredWidth -= reservedSpace;\n      for (var i = 0; i < words.length; i++) {\n        // i would avoid resplitting the graphemes\n        word = fabric.util.string.graphemeSplit(words[i]);\n        wordWidth = this._measureWord(word, lineIndex, offset);\n        offset += word.length;\n\n        lineWidth += infixWidth + wordWidth - additionalSpace;\n\n        if (lineWidth >= desiredWidth && !lineJustStarted) {\n          graphemeLines.push(line);\n          line = [];\n          lineWidth = wordWidth;\n          lineJustStarted = true;\n        }\n        else {\n          lineWidth += additionalSpace;\n        }\n\n        if (!lineJustStarted) {\n          line.push(infix);\n        }\n        line = line.concat(word);\n\n        infixWidth = this._measureWord([infix], lineIndex, offset);\n        offset++;\n        lineJustStarted = false;\n        // keep track of largest word\n        if (wordWidth > largestWordWidth) {\n          largestWordWidth = wordWidth;\n        }\n      }\n\n      i && graphemeLines.push(line);\n\n      if (largestWordWidth + reservedSpace > this.dynamicMinWidth) {\n        this.dynamicMinWidth = largestWordWidth - additionalSpace + reservedSpace;\n      }\n\n      return graphemeLines;\n    },\n\n    /**\n     * Detect if the text line is ended with an hard break\n     * text and itext do not have wrapping, return false\n     * @param {Number} lineIndex text to split\n     * @return {Boolean}\n     */\n    isEndOfWrapping: function(lineIndex) {\n      if (!this._styleMap[lineIndex + 1]) {\n        // is last line, return true;\n        return true;\n      }\n      if (this._styleMap[lineIndex + 1].line !== this._styleMap[lineIndex].line) {\n        // this is last line before a line break, return true;\n        return true;\n      }\n      return false;\n    },\n\n    /**\n    * Gets lines of text to render in the Textbox. This function calculates\n    * text wrapping on the fly every time it is called.\n    * @param {String} text text to split\n    * @returns {Array} Array of lines in the Textbox.\n    * @override\n    */\n    _splitTextIntoLines: function(text) {\n      var newText = fabric.Text.prototype._splitTextIntoLines.call(this, text),\n          graphemeLines = this._wrapText(newText.lines, this.width),\n          lines = new Array(graphemeLines.length);\n\n      for (var i = 0; i < graphemeLines.length; i++) {\n        lines[i] = graphemeLines[i].join('');\n      }\n      newText.lines = lines;\n      newText.graphemeLines = graphemeLines;\n      return newText;\n    },\n\n    getMinWidth: function() {\n      return Math.max(this.minWidth, this.dynamicMinWidth);\n    },\n\n    /**\n     * Returns object representation of an instance\n     * @method toObject\n     * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output\n     * @return {Object} object representation of an instance\n     */\n    toObject: function(propertiesToInclude) {\n      return this.callSuper('toObject', ['minWidth'].concat(propertiesToInclude));\n    }\n  });\n\n  /**\n   * Returns fabric.Textbox instance from an object representation\n   * @static\n   * @memberOf fabric.Textbox\n   * @param {Object} object Object to create an instance from\n   * @param {Function} [callback] Callback to invoke when an fabric.Textbox instance is created\n   */\n  fabric.Textbox.fromObject = function(object, callback) {\n    return fabric.Object._fromObject('Textbox', object, callback, 'text');\n  };\n})(typeof exports !== 'undefined' ? exports : this);\n\n\n(function() {\n\n  /**\n   * Override _setObjectScale and add Textbox specific resizing behavior. Resizing\n   * a Textbox doesn't scale text, it only changes width and makes text wrap automatically.\n   */\n  var setObjectScaleOverridden = fabric.Canvas.prototype._setObjectScale;\n\n  fabric.Canvas.prototype._setObjectScale = function(localMouse, transform,\n    lockScalingX, lockScalingY, by, lockScalingFlip, _dim) {\n\n    var t = transform.target;\n    if (by === 'x' && t instanceof fabric.Textbox) {\n      var tw = t._getTransformedDimensions().x;\n      var w = t.width * (localMouse.x / tw);\n      if (w >= t.getMinWidth()) {\n        t.set('width', w);\n        return true;\n      }\n    }\n    else {\n      return setObjectScaleOverridden.call(fabric.Canvas.prototype, localMouse, transform,\n        lockScalingX, lockScalingY, by, lockScalingFlip, _dim);\n    }\n  };\n\n  fabric.util.object.extend(fabric.Textbox.prototype, /** @lends fabric.IText.prototype */ {\n    /**\n     * @private\n     */\n    _removeExtraneousStyles: function() {\n      for (var prop in this._styleMap) {\n        if (!this._textLines[prop]) {\n          delete this.styles[this._styleMap[prop].line];\n        }\n      }\n    },\n\n  });\n})();\n\n","/*!\n * hotkeys-js v3.3.8\n * A simple micro-library for defining and dispatching keyboard shortcuts. It has no dependencies.\n * \n * Copyright (c) 2018 kenny wong <wowohoo@qq.com>\n * http://jaywcjlove.github.io/hotkeys\n * \n * Licensed under the MIT license.\n */\n\nvar isff = typeof navigator !== 'undefined' ? navigator.userAgent.toLowerCase().indexOf('firefox') > 0 : false;\n\n// 绑定事件\nfunction addEvent(object, event, method) {\n  if (object.addEventListener) {\n    object.addEventListener(event, method, false);\n  } else if (object.attachEvent) {\n    object.attachEvent('on' + event, function () {\n      method(window.event);\n    });\n  }\n}\n\n// 修饰键转换成对应的键码\nfunction getMods(modifier, key) {\n  var mods = key.slice(0, key.length - 1);\n  for (var i = 0; i < mods.length; i++) {\n    mods[i] = modifier[mods[i].toLowerCase()];\n  }return mods;\n}\n\n// 处理传的key字符串转换成数组\nfunction getKeys(key) {\n  if (!key) key = '';\n\n  key = key.replace(/\\s/g, ''); // 匹配任何空白字符,包括空格、制表符、换页符等等\n  var keys = key.split(','); // 同时设置多个快捷键，以','分割\n  var index = keys.lastIndexOf('');\n\n  // 快捷键可能包含','，需特殊处理\n  for (; index >= 0;) {\n    keys[index - 1] += ',';\n    keys.splice(index, 1);\n    index = keys.lastIndexOf('');\n  }\n\n  return keys;\n}\n\n// 比较修饰键的数组\nfunction compareArray(a1, a2) {\n  var arr1 = a1.length >= a2.length ? a1 : a2;\n  var arr2 = a1.length >= a2.length ? a2 : a1;\n  var isIndex = true;\n\n  for (var i = 0; i < arr1.length; i++) {\n    if (arr2.indexOf(arr1[i]) === -1) isIndex = false;\n  }\n  return isIndex;\n}\n\nvar _keyMap = { // 特殊键\n  backspace: 8,\n  tab: 9,\n  clear: 12,\n  enter: 13,\n  return: 13,\n  esc: 27,\n  escape: 27,\n  space: 32,\n  left: 37,\n  up: 38,\n  right: 39,\n  down: 40,\n  del: 46,\n  delete: 46,\n  ins: 45,\n  insert: 45,\n  home: 36,\n  end: 35,\n  pageup: 33,\n  pagedown: 34,\n  capslock: 20,\n  '⇪': 20,\n  ',': 188,\n  '.': 190,\n  '/': 191,\n  '`': 192,\n  '-': isff ? 173 : 189,\n  '=': isff ? 61 : 187,\n  ';': isff ? 59 : 186,\n  '\\'': 222,\n  '[': 219,\n  ']': 221,\n  '\\\\': 220\n};\n\nvar _modifier = { // 修饰键\n  '⇧': 16,\n  shift: 16,\n  '⌥': 18,\n  alt: 18,\n  option: 18,\n  '⌃': 17,\n  ctrl: 17,\n  control: 17,\n  '⌘': isff ? 224 : 91,\n  cmd: isff ? 224 : 91,\n  command: isff ? 224 : 91\n};\nvar _downKeys = []; // 记录摁下的绑定键\nvar modifierMap = {\n  16: 'shiftKey',\n  18: 'altKey',\n  17: 'ctrlKey'\n};\nvar _mods = { 16: false, 18: false, 17: false };\nvar _handlers = {};\n\n// F1~F12 特殊键\nfor (var k = 1; k < 20; k++) {\n  _keyMap['f' + k] = 111 + k;\n}\n\n// 兼容Firefox处理\nmodifierMap[isff ? 224 : 91] = 'metaKey';\n_mods[isff ? 224 : 91] = false;\n\nvar _scope = 'all'; // 默认热键范围\nvar isBindElement = false; // 是否绑定节点\n\n// 返回键码\nvar code = function code(x) {\n  return _keyMap[x.toLowerCase()] || _modifier[x.toLowerCase()] || x.toUpperCase().charCodeAt(0);\n};\n\n// 设置获取当前范围（默认为'所有'）\nfunction setScope(scope) {\n  _scope = scope || 'all';\n}\n// 获取当前范围\nfunction getScope() {\n  return _scope || 'all';\n}\n// 获取摁下绑定键的键值\nfunction getPressedKeyCodes() {\n  return _downKeys.slice(0);\n}\n\n// 表单控件控件判断 返回 Boolean\nfunction filter(event) {\n  var target = event.target || event.srcElement;\n  var tagName = target.tagName;\n  // 忽略这些情况下快捷键无效\n\n  return !(tagName === 'INPUT' || tagName === 'SELECT' || tagName === 'TEXTAREA' || target.isContentEditable);\n}\n\n// 判断摁下的键是否为某个键，返回true或者false\nfunction isPressed(keyCode) {\n  if (typeof keyCode === 'string') {\n    keyCode = code(keyCode); // 转换成键码\n  }\n  return _downKeys.indexOf(keyCode) !== -1;\n}\n\n// 循环删除handlers中的所有 scope(范围)\nfunction deleteScope(scope, newScope) {\n  var handlers = void 0;\n  var i = void 0;\n\n  // 没有指定scope，获取scope\n  if (!scope) scope = getScope();\n\n  for (var key in _handlers) {\n    if (Object.prototype.hasOwnProperty.call(_handlers, key)) {\n      handlers = _handlers[key];\n      for (i = 0; i < handlers.length;) {\n        if (handlers[i].scope === scope) handlers.splice(i, 1);else i++;\n      }\n    }\n  }\n\n  // 如果scope被删除，将scope重置为all\n  if (getScope() === scope) setScope(newScope || 'all');\n}\n\n// 清除修饰键\nfunction clearModifier(event) {\n  var key = event.keyCode || event.which || event.charCode;\n  var i = _downKeys.indexOf(key);\n\n  // 从列表中清除按压过的键\n  if (i >= 0) _downKeys.splice(i, 1);\n\n  // 修饰键 shiftKey altKey ctrlKey (command||metaKey) 清除\n  if (key === 93 || key === 224) key = 91;\n  if (key in _mods) {\n    _mods[key] = false;\n\n    // 将修饰键重置为false\n    for (var k in _modifier) {\n      if (_modifier[k] === key) hotkeys[k] = false;\n    }\n  }\n}\n\n// 解除绑定某个范围的快捷键\nfunction unbind(key, scope) {\n  var multipleKeys = getKeys(key);\n  var keys = void 0;\n  var mods = [];\n  var obj = void 0;\n\n  for (var i = 0; i < multipleKeys.length; i++) {\n    // 将组合快捷键拆分为数组\n    keys = multipleKeys[i].split('+');\n\n    // 记录每个组合键中的修饰键的键码 返回数组\n    if (keys.length > 1) mods = getMods(_modifier, keys);\n\n    // 获取除修饰键外的键值key\n    key = keys[keys.length - 1];\n    key = key === '*' ? '*' : code(key);\n\n    // 判断是否传入范围，没有就获取范围\n    if (!scope) scope = getScope();\n\n    // 如何key不在 _handlers 中返回不做处理\n    if (!_handlers[key]) return;\n\n    // 清空 handlers 中数据，\n    // 让触发快捷键键之后没有事件执行到达解除快捷键绑定的目的\n    for (var r = 0; r < _handlers[key].length; r++) {\n      obj = _handlers[key][r];\n      // 判断是否在范围内并且键值相同\n      if (obj.scope === scope && compareArray(obj.mods, mods)) {\n        _handlers[key][r] = {};\n      }\n    }\n  }\n}\n\n// 对监听对应快捷键的回调函数进行处理\nfunction eventHandler(event, handler, scope) {\n  var modifiersMatch = void 0;\n\n  // 看它是否在当前范围\n  if (handler.scope === scope || handler.scope === 'all') {\n    // 检查是否匹配修饰符（如果有返回true）\n    modifiersMatch = handler.mods.length > 0;\n\n    for (var y in _mods) {\n      if (Object.prototype.hasOwnProperty.call(_mods, y)) {\n        if (!_mods[y] && handler.mods.indexOf(+y) > -1 || _mods[y] && handler.mods.indexOf(+y) === -1) modifiersMatch = false;\n      }\n    }\n\n    // 调用处理程序，如果是修饰键不做处理\n    if (handler.mods.length === 0 && !_mods[16] && !_mods[18] && !_mods[17] && !_mods[91] || modifiersMatch || handler.shortcut === '*') {\n      if (handler.method(event, handler) === false) {\n        if (event.preventDefault) event.preventDefault();else event.returnValue = false;\n        if (event.stopPropagation) event.stopPropagation();\n        if (event.cancelBubble) event.cancelBubble = true;\n      }\n    }\n  }\n}\n\n// 处理keydown事件\nfunction dispatch(event) {\n  var asterisk = _handlers['*'];\n  var key = event.keyCode || event.which || event.charCode;\n\n  // 搜集绑定的键\n  if (_downKeys.indexOf(key) === -1) _downKeys.push(key);\n\n  // Gecko(Firefox)的command键值224，在Webkit(Chrome)中保持一致\n  // Webkit左右command键值不一样\n  if (key === 93 || key === 224) key = 91;\n\n  if (key in _mods) {\n    _mods[key] = true;\n\n    // 将特殊字符的key注册到 hotkeys 上\n    for (var k in _modifier) {\n      if (_modifier[k] === key) hotkeys[k] = true;\n    }\n\n    if (!asterisk) return;\n  }\n\n  // 将modifierMap里面的修饰键绑定到event中\n  for (var e in _mods) {\n    if (Object.prototype.hasOwnProperty.call(_mods, e)) {\n      _mods[e] = event[modifierMap[e]];\n    }\n  }\n\n  // 表单控件过滤 默认表单控件不触发快捷键\n  if (!hotkeys.filter.call(this, event)) return;\n\n  // 获取范围 默认为all\n  var scope = getScope();\n\n  // 对任何快捷键都需要做的处理\n  if (asterisk) {\n    for (var i = 0; i < asterisk.length; i++) {\n      if (asterisk[i].scope === scope) eventHandler(event, asterisk[i], scope);\n    }\n  }\n  // key 不在_handlers中返回\n  if (!(key in _handlers)) return;\n\n  for (var _i = 0; _i < _handlers[key].length; _i++) {\n    // 找到处理内容\n    eventHandler(event, _handlers[key][_i], scope);\n  }\n}\n\nfunction hotkeys(key, option, method) {\n  var keys = getKeys(key); // 需要处理的快捷键列表\n  var mods = [];\n  var scope = 'all'; // scope默认为all，所有范围都有效\n  var element = document; // 快捷键事件绑定节点\n  var i = 0;\n\n  // 对为设定范围的判断\n  if (method === undefined && typeof option === 'function') {\n    method = option;\n  }\n\n  if (Object.prototype.toString.call(option) === '[object Object]') {\n    if (option.scope) scope = option.scope; // eslint-disable-line\n    if (option.element) element = option.element; // eslint-disable-line\n  }\n\n  if (typeof option === 'string') scope = option;\n\n  // 对于每个快捷键进行处理\n  for (; i < keys.length; i++) {\n    key = keys[i].split('+'); // 按键列表\n    mods = [];\n\n    // 如果是组合快捷键取得组合快捷键\n    if (key.length > 1) mods = getMods(_modifier, key);\n\n    // 将非修饰键转化为键码\n    key = key[key.length - 1];\n    key = key === '*' ? '*' : code(key); // *表示匹配所有快捷键\n\n    // 判断key是否在_handlers中，不在就赋一个空数组\n    if (!(key in _handlers)) _handlers[key] = [];\n\n    _handlers[key].push({\n      scope: scope,\n      mods: mods,\n      shortcut: keys[i],\n      method: method,\n      key: keys[i]\n    });\n  }\n  // 在全局document上设置快捷键\n  if (typeof element !== 'undefined' && !isBindElement) {\n    isBindElement = true;\n    addEvent(element, 'keydown', function (e) {\n      dispatch(e);\n    });\n    addEvent(element, 'keyup', function (e) {\n      clearModifier(e);\n    });\n  }\n}\n\nvar _api = {\n  setScope: setScope,\n  getScope: getScope,\n  deleteScope: deleteScope,\n  getPressedKeyCodes: getPressedKeyCodes,\n  isPressed: isPressed,\n  filter: filter,\n  unbind: unbind\n};\nfor (var a in _api) {\n  if (Object.prototype.hasOwnProperty.call(_api, a)) {\n    hotkeys[a] = _api[a];\n  }\n}\n\nif (typeof window !== 'undefined') {\n  var _hotkeys = window.hotkeys;\n  hotkeys.noConflict = function (deep) {\n    if (deep && window.hotkeys === hotkeys) {\n      window.hotkeys = _hotkeys;\n    }\n    return hotkeys;\n  };\n  window.hotkeys = hotkeys;\n}\n\nexport default hotkeys;\n","/**\n * @license\n * Lodash <https://lodash.com/>\n * Copyright JS Foundation and other contributors <https://js.foundation/>\n * Released under MIT license <https://lodash.com/license>\n * Based on Underscore.js 1.8.3 <http://underscorejs.org/LICENSE>\n * Copyright Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors\n */\n;(function() {\n\n  /** Used as a safe reference for `undefined` in pre-ES5 environments. */\n  var undefined;\n\n  /** Used as the semantic version number. */\n  var VERSION = '4.17.11';\n\n  /** Used as the size to enable large array optimizations. */\n  var LARGE_ARRAY_SIZE = 200;\n\n  /** Error message constants. */\n  var CORE_ERROR_TEXT = 'Unsupported core-js use. Try https://npms.io/search?q=ponyfill.',\n      FUNC_ERROR_TEXT = 'Expected a function';\n\n  /** Used to stand-in for `undefined` hash values. */\n  var HASH_UNDEFINED = '__lodash_hash_undefined__';\n\n  /** Used as the maximum memoize cache size. */\n  var MAX_MEMOIZE_SIZE = 500;\n\n  /** Used as the internal argument placeholder. */\n  var PLACEHOLDER = '__lodash_placeholder__';\n\n  /** Used to compose bitmasks for cloning. */\n  var CLONE_DEEP_FLAG = 1,\n      CLONE_FLAT_FLAG = 2,\n      CLONE_SYMBOLS_FLAG = 4;\n\n  /** Used to compose bitmasks for value comparisons. */\n  var COMPARE_PARTIAL_FLAG = 1,\n      COMPARE_UNORDERED_FLAG = 2;\n\n  /** Used to compose bitmasks for function metadata. */\n  var WRAP_BIND_FLAG = 1,\n      WRAP_BIND_KEY_FLAG = 2,\n      WRAP_CURRY_BOUND_FLAG = 4,\n      WRAP_CURRY_FLAG = 8,\n      WRAP_CURRY_RIGHT_FLAG = 16,\n      WRAP_PARTIAL_FLAG = 32,\n      WRAP_PARTIAL_RIGHT_FLAG = 64,\n      WRAP_ARY_FLAG = 128,\n      WRAP_REARG_FLAG = 256,\n      WRAP_FLIP_FLAG = 512;\n\n  /** Used as default options for `_.truncate`. */\n  var DEFAULT_TRUNC_LENGTH = 30,\n      DEFAULT_TRUNC_OMISSION = '...';\n\n  /** Used to detect hot functions by number of calls within a span of milliseconds. */\n  var HOT_COUNT = 800,\n      HOT_SPAN = 16;\n\n  /** Used to indicate the type of lazy iteratees. */\n  var LAZY_FILTER_FLAG = 1,\n      LAZY_MAP_FLAG = 2,\n      LAZY_WHILE_FLAG = 3;\n\n  /** Used as references for various `Number` constants. */\n  var INFINITY = 1 / 0,\n      MAX_SAFE_INTEGER = 9007199254740991,\n      MAX_INTEGER = 1.7976931348623157e+308,\n      NAN = 0 / 0;\n\n  /** Used as references for the maximum length and index of an array. */\n  var MAX_ARRAY_LENGTH = 4294967295,\n      MAX_ARRAY_INDEX = MAX_ARRAY_LENGTH - 1,\n      HALF_MAX_ARRAY_LENGTH = MAX_ARRAY_LENGTH >>> 1;\n\n  /** Used to associate wrap methods with their bit flags. */\n  var wrapFlags = [\n    ['ary', WRAP_ARY_FLAG],\n    ['bind', WRAP_BIND_FLAG],\n    ['bindKey', WRAP_BIND_KEY_FLAG],\n    ['curry', WRAP_CURRY_FLAG],\n    ['curryRight', WRAP_CURRY_RIGHT_FLAG],\n    ['flip', WRAP_FLIP_FLAG],\n    ['partial', WRAP_PARTIAL_FLAG],\n    ['partialRight', WRAP_PARTIAL_RIGHT_FLAG],\n    ['rearg', WRAP_REARG_FLAG]\n  ];\n\n  /** `Object#toString` result references. */\n  var argsTag = '[object Arguments]',\n      arrayTag = '[object Array]',\n      asyncTag = '[object AsyncFunction]',\n      boolTag = '[object Boolean]',\n      dateTag = '[object Date]',\n      domExcTag = '[object DOMException]',\n      errorTag = '[object Error]',\n      funcTag = '[object Function]',\n      genTag = '[object GeneratorFunction]',\n      mapTag = '[object Map]',\n      numberTag = '[object Number]',\n      nullTag = '[object Null]',\n      objectTag = '[object Object]',\n      promiseTag = '[object Promise]',\n      proxyTag = '[object Proxy]',\n      regexpTag = '[object RegExp]',\n      setTag = '[object Set]',\n      stringTag = '[object String]',\n      symbolTag = '[object Symbol]',\n      undefinedTag = '[object Undefined]',\n      weakMapTag = '[object WeakMap]',\n      weakSetTag = '[object WeakSet]';\n\n  var arrayBufferTag = '[object ArrayBuffer]',\n      dataViewTag = '[object DataView]',\n      float32Tag = '[object Float32Array]',\n      float64Tag = '[object Float64Array]',\n      int8Tag = '[object Int8Array]',\n      int16Tag = '[object Int16Array]',\n      int32Tag = '[object Int32Array]',\n      uint8Tag = '[object Uint8Array]',\n      uint8ClampedTag = '[object Uint8ClampedArray]',\n      uint16Tag = '[object Uint16Array]',\n      uint32Tag = '[object Uint32Array]';\n\n  /** Used to match empty string literals in compiled template source. */\n  var reEmptyStringLeading = /\\b__p \\+= '';/g,\n      reEmptyStringMiddle = /\\b(__p \\+=) '' \\+/g,\n      reEmptyStringTrailing = /(__e\\(.*?\\)|\\b__t\\)) \\+\\n'';/g;\n\n  /** Used to match HTML entities and HTML characters. */\n  var reEscapedHtml = /&(?:amp|lt|gt|quot|#39);/g,\n      reUnescapedHtml = /[&<>\"']/g,\n      reHasEscapedHtml = RegExp(reEscapedHtml.source),\n      reHasUnescapedHtml = RegExp(reUnescapedHtml.source);\n\n  /** Used to match template delimiters. */\n  var reEscape = /<%-([\\s\\S]+?)%>/g,\n      reEvaluate = /<%([\\s\\S]+?)%>/g,\n      reInterpolate = /<%=([\\s\\S]+?)%>/g;\n\n  /** Used to match property names within property paths. */\n  var reIsDeepProp = /\\.|\\[(?:[^[\\]]*|([\"'])(?:(?!\\1)[^\\\\]|\\\\.)*?\\1)\\]/,\n      reIsPlainProp = /^\\w*$/,\n      rePropName = /[^.[\\]]+|\\[(?:(-?\\d+(?:\\.\\d+)?)|([\"'])((?:(?!\\2)[^\\\\]|\\\\.)*?)\\2)\\]|(?=(?:\\.|\\[\\])(?:\\.|\\[\\]|$))/g;\n\n  /**\n   * Used to match `RegExp`\n   * [syntax characters](http://ecma-international.org/ecma-262/7.0/#sec-patterns).\n   */\n  var reRegExpChar = /[\\\\^$.*+?()[\\]{}|]/g,\n      reHasRegExpChar = RegExp(reRegExpChar.source);\n\n  /** Used to match leading and trailing whitespace. */\n  var reTrim = /^\\s+|\\s+$/g,\n      reTrimStart = /^\\s+/,\n      reTrimEnd = /\\s+$/;\n\n  /** Used to match wrap detail comments. */\n  var reWrapComment = /\\{(?:\\n\\/\\* \\[wrapped with .+\\] \\*\\/)?\\n?/,\n      reWrapDetails = /\\{\\n\\/\\* \\[wrapped with (.+)\\] \\*/,\n      reSplitDetails = /,? & /;\n\n  /** Used to match words composed of alphanumeric characters. */\n  var reAsciiWord = /[^\\x00-\\x2f\\x3a-\\x40\\x5b-\\x60\\x7b-\\x7f]+/g;\n\n  /** Used to match backslashes in property paths. */\n  var reEscapeChar = /\\\\(\\\\)?/g;\n\n  /**\n   * Used to match\n   * [ES template delimiters](http://ecma-international.org/ecma-262/7.0/#sec-template-literal-lexical-components).\n   */\n  var reEsTemplate = /\\$\\{([^\\\\}]*(?:\\\\.[^\\\\}]*)*)\\}/g;\n\n  /** Used to match `RegExp` flags from their coerced string values. */\n  var reFlags = /\\w*$/;\n\n  /** Used to detect bad signed hexadecimal string values. */\n  var reIsBadHex = /^[-+]0x[0-9a-f]+$/i;\n\n  /** Used to detect binary string values. */\n  var reIsBinary = /^0b[01]+$/i;\n\n  /** Used to detect host constructors (Safari). */\n  var reIsHostCtor = /^\\[object .+?Constructor\\]$/;\n\n  /** Used to detect octal string values. */\n  var reIsOctal = /^0o[0-7]+$/i;\n\n  /** Used to detect unsigned integer values. */\n  var reIsUint = /^(?:0|[1-9]\\d*)$/;\n\n  /** Used to match Latin Unicode letters (excluding mathematical operators). */\n  var reLatin = /[\\xc0-\\xd6\\xd8-\\xf6\\xf8-\\xff\\u0100-\\u017f]/g;\n\n  /** Used to ensure capturing order of template delimiters. */\n  var reNoMatch = /($^)/;\n\n  /** Used to match unescaped characters in compiled string literals. */\n  var reUnescapedString = /['\\n\\r\\u2028\\u2029\\\\]/g;\n\n  /** Used to compose unicode character classes. */\n  var rsAstralRange = '\\\\ud800-\\\\udfff',\n      rsComboMarksRange = '\\\\u0300-\\\\u036f',\n      reComboHalfMarksRange = '\\\\ufe20-\\\\ufe2f',\n      rsComboSymbolsRange = '\\\\u20d0-\\\\u20ff',\n      rsComboRange = rsComboMarksRange + reComboHalfMarksRange + rsComboSymbolsRange,\n      rsDingbatRange = '\\\\u2700-\\\\u27bf',\n      rsLowerRange = 'a-z\\\\xdf-\\\\xf6\\\\xf8-\\\\xff',\n      rsMathOpRange = '\\\\xac\\\\xb1\\\\xd7\\\\xf7',\n      rsNonCharRange = '\\\\x00-\\\\x2f\\\\x3a-\\\\x40\\\\x5b-\\\\x60\\\\x7b-\\\\xbf',\n      rsPunctuationRange = '\\\\u2000-\\\\u206f',\n      rsSpaceRange = ' \\\\t\\\\x0b\\\\f\\\\xa0\\\\ufeff\\\\n\\\\r\\\\u2028\\\\u2029\\\\u1680\\\\u180e\\\\u2000\\\\u2001\\\\u2002\\\\u2003\\\\u2004\\\\u2005\\\\u2006\\\\u2007\\\\u2008\\\\u2009\\\\u200a\\\\u202f\\\\u205f\\\\u3000',\n      rsUpperRange = 'A-Z\\\\xc0-\\\\xd6\\\\xd8-\\\\xde',\n      rsVarRange = '\\\\ufe0e\\\\ufe0f',\n      rsBreakRange = rsMathOpRange + rsNonCharRange + rsPunctuationRange + rsSpaceRange;\n\n  /** Used to compose unicode capture groups. */\n  var rsApos = \"['\\u2019]\",\n      rsAstral = '[' + rsAstralRange + ']',\n      rsBreak = '[' + rsBreakRange + ']',\n      rsCombo = '[' + rsComboRange + ']',\n      rsDigits = '\\\\d+',\n      rsDingbat = '[' + rsDingbatRange + ']',\n      rsLower = '[' + rsLowerRange + ']',\n      rsMisc = '[^' + rsAstralRange + rsBreakRange + rsDigits + rsDingbatRange + rsLowerRange + rsUpperRange + ']',\n      rsFitz = '\\\\ud83c[\\\\udffb-\\\\udfff]',\n      rsModifier = '(?:' + rsCombo + '|' + rsFitz + ')',\n      rsNonAstral = '[^' + rsAstralRange + ']',\n      rsRegional = '(?:\\\\ud83c[\\\\udde6-\\\\uddff]){2}',\n      rsSurrPair = '[\\\\ud800-\\\\udbff][\\\\udc00-\\\\udfff]',\n      rsUpper = '[' + rsUpperRange + ']',\n      rsZWJ = '\\\\u200d';\n\n  /** Used to compose unicode regexes. */\n  var rsMiscLower = '(?:' + rsLower + '|' + rsMisc + ')',\n      rsMiscUpper = '(?:' + rsUpper + '|' + rsMisc + ')',\n      rsOptContrLower = '(?:' + rsApos + '(?:d|ll|m|re|s|t|ve))?',\n      rsOptContrUpper = '(?:' + rsApos + '(?:D|LL|M|RE|S|T|VE))?',\n      reOptMod = rsModifier + '?',\n      rsOptVar = '[' + rsVarRange + ']?',\n      rsOptJoin = '(?:' + rsZWJ + '(?:' + [rsNonAstral, rsRegional, rsSurrPair].join('|') + ')' + rsOptVar + reOptMod + ')*',\n      rsOrdLower = '\\\\d*(?:1st|2nd|3rd|(?![123])\\\\dth)(?=\\\\b|[A-Z_])',\n      rsOrdUpper = '\\\\d*(?:1ST|2ND|3RD|(?![123])\\\\dTH)(?=\\\\b|[a-z_])',\n      rsSeq = rsOptVar + reOptMod + rsOptJoin,\n      rsEmoji = '(?:' + [rsDingbat, rsRegional, rsSurrPair].join('|') + ')' + rsSeq,\n      rsSymbol = '(?:' + [rsNonAstral + rsCombo + '?', rsCombo, rsRegional, rsSurrPair, rsAstral].join('|') + ')';\n\n  /** Used to match apostrophes. */\n  var reApos = RegExp(rsApos, 'g');\n\n  /**\n   * Used to match [combining diacritical marks](https://en.wikipedia.org/wiki/Combining_Diacritical_Marks) and\n   * [combining diacritical marks for symbols](https://en.wikipedia.org/wiki/Combining_Diacritical_Marks_for_Symbols).\n   */\n  var reComboMark = RegExp(rsCombo, 'g');\n\n  /** Used to match [string symbols](https://mathiasbynens.be/notes/javascript-unicode). */\n  var reUnicode = RegExp(rsFitz + '(?=' + rsFitz + ')|' + rsSymbol + rsSeq, 'g');\n\n  /** Used to match complex or compound words. */\n  var reUnicodeWord = RegExp([\n    rsUpper + '?' + rsLower + '+' + rsOptContrLower + '(?=' + [rsBreak, rsUpper, '$'].join('|') + ')',\n    rsMiscUpper + '+' + rsOptContrUpper + '(?=' + [rsBreak, rsUpper + rsMiscLower, '$'].join('|') + ')',\n    rsUpper + '?' + rsMiscLower + '+' + rsOptContrLower,\n    rsUpper + '+' + rsOptContrUpper,\n    rsOrdUpper,\n    rsOrdLower,\n    rsDigits,\n    rsEmoji\n  ].join('|'), 'g');\n\n  /** Used to detect strings with [zero-width joiners or code points from the astral planes](http://eev.ee/blog/2015/09/12/dark-corners-of-unicode/). */\n  var reHasUnicode = RegExp('[' + rsZWJ + rsAstralRange  + rsComboRange + rsVarRange + ']');\n\n  /** Used to detect strings that need a more robust regexp to match words. */\n  var reHasUnicodeWord = /[a-z][A-Z]|[A-Z]{2}[a-z]|[0-9][a-zA-Z]|[a-zA-Z][0-9]|[^a-zA-Z0-9 ]/;\n\n  /** Used to assign default `context` object properties. */\n  var contextProps = [\n    'Array', 'Buffer', 'DataView', 'Date', 'Error', 'Float32Array', 'Float64Array',\n    'Function', 'Int8Array', 'Int16Array', 'Int32Array', 'Map', 'Math', 'Object',\n    'Promise', 'RegExp', 'Set', 'String', 'Symbol', 'TypeError', 'Uint8Array',\n    'Uint8ClampedArray', 'Uint16Array', 'Uint32Array', 'WeakMap',\n    '_', 'clearTimeout', 'isFinite', 'parseInt', 'setTimeout'\n  ];\n\n  /** Used to make template sourceURLs easier to identify. */\n  var templateCounter = -1;\n\n  /** Used to identify `toStringTag` values of typed arrays. */\n  var typedArrayTags = {};\n  typedArrayTags[float32Tag] = typedArrayTags[float64Tag] =\n  typedArrayTags[int8Tag] = typedArrayTags[int16Tag] =\n  typedArrayTags[int32Tag] = typedArrayTags[uint8Tag] =\n  typedArrayTags[uint8ClampedTag] = typedArrayTags[uint16Tag] =\n  typedArrayTags[uint32Tag] = true;\n  typedArrayTags[argsTag] = typedArrayTags[arrayTag] =\n  typedArrayTags[arrayBufferTag] = typedArrayTags[boolTag] =\n  typedArrayTags[dataViewTag] = typedArrayTags[dateTag] =\n  typedArrayTags[errorTag] = typedArrayTags[funcTag] =\n  typedArrayTags[mapTag] = typedArrayTags[numberTag] =\n  typedArrayTags[objectTag] = typedArrayTags[regexpTag] =\n  typedArrayTags[setTag] = typedArrayTags[stringTag] =\n  typedArrayTags[weakMapTag] = false;\n\n  /** Used to identify `toStringTag` values supported by `_.clone`. */\n  var cloneableTags = {};\n  cloneableTags[argsTag] = cloneableTags[arrayTag] =\n  cloneableTags[arrayBufferTag] = cloneableTags[dataViewTag] =\n  cloneableTags[boolTag] = cloneableTags[dateTag] =\n  cloneableTags[float32Tag] = cloneableTags[float64Tag] =\n  cloneableTags[int8Tag] = cloneableTags[int16Tag] =\n  cloneableTags[int32Tag] = cloneableTags[mapTag] =\n  cloneableTags[numberTag] = cloneableTags[objectTag] =\n  cloneableTags[regexpTag] = cloneableTags[setTag] =\n  cloneableTags[stringTag] = cloneableTags[symbolTag] =\n  cloneableTags[uint8Tag] = cloneableTags[uint8ClampedTag] =\n  cloneableTags[uint16Tag] = cloneableTags[uint32Tag] = true;\n  cloneableTags[errorTag] = cloneableTags[funcTag] =\n  cloneableTags[weakMapTag] = false;\n\n  /** Used to map Latin Unicode letters to basic Latin letters. */\n  var deburredLetters = {\n    // Latin-1 Supplement block.\n    '\\xc0': 'A',  '\\xc1': 'A', '\\xc2': 'A', '\\xc3': 'A', '\\xc4': 'A', '\\xc5': 'A',\n    '\\xe0': 'a',  '\\xe1': 'a', '\\xe2': 'a', '\\xe3': 'a', '\\xe4': 'a', '\\xe5': 'a',\n    '\\xc7': 'C',  '\\xe7': 'c',\n    '\\xd0': 'D',  '\\xf0': 'd',\n    '\\xc8': 'E',  '\\xc9': 'E', '\\xca': 'E', '\\xcb': 'E',\n    '\\xe8': 'e',  '\\xe9': 'e', '\\xea': 'e', '\\xeb': 'e',\n    '\\xcc': 'I',  '\\xcd': 'I', '\\xce': 'I', '\\xcf': 'I',\n    '\\xec': 'i',  '\\xed': 'i', '\\xee': 'i', '\\xef': 'i',\n    '\\xd1': 'N',  '\\xf1': 'n',\n    '\\xd2': 'O',  '\\xd3': 'O', '\\xd4': 'O', '\\xd5': 'O', '\\xd6': 'O', '\\xd8': 'O',\n    '\\xf2': 'o',  '\\xf3': 'o', '\\xf4': 'o', '\\xf5': 'o', '\\xf6': 'o', '\\xf8': 'o',\n    '\\xd9': 'U',  '\\xda': 'U', '\\xdb': 'U', '\\xdc': 'U',\n    '\\xf9': 'u',  '\\xfa': 'u', '\\xfb': 'u', '\\xfc': 'u',\n    '\\xdd': 'Y',  '\\xfd': 'y', '\\xff': 'y',\n    '\\xc6': 'Ae', '\\xe6': 'ae',\n    '\\xde': 'Th', '\\xfe': 'th',\n    '\\xdf': 'ss',\n    // Latin Extended-A block.\n    '\\u0100': 'A',  '\\u0102': 'A', '\\u0104': 'A',\n    '\\u0101': 'a',  '\\u0103': 'a', '\\u0105': 'a',\n    '\\u0106': 'C',  '\\u0108': 'C', '\\u010a': 'C', '\\u010c': 'C',\n    '\\u0107': 'c',  '\\u0109': 'c', '\\u010b': 'c', '\\u010d': 'c',\n    '\\u010e': 'D',  '\\u0110': 'D', '\\u010f': 'd', '\\u0111': 'd',\n    '\\u0112': 'E',  '\\u0114': 'E', '\\u0116': 'E', '\\u0118': 'E', '\\u011a': 'E',\n    '\\u0113': 'e',  '\\u0115': 'e', '\\u0117': 'e', '\\u0119': 'e', '\\u011b': 'e',\n    '\\u011c': 'G',  '\\u011e': 'G', '\\u0120': 'G', '\\u0122': 'G',\n    '\\u011d': 'g',  '\\u011f': 'g', '\\u0121': 'g', '\\u0123': 'g',\n    '\\u0124': 'H',  '\\u0126': 'H', '\\u0125': 'h', '\\u0127': 'h',\n    '\\u0128': 'I',  '\\u012a': 'I', '\\u012c': 'I', '\\u012e': 'I', '\\u0130': 'I',\n    '\\u0129': 'i',  '\\u012b': 'i', '\\u012d': 'i', '\\u012f': 'i', '\\u0131': 'i',\n    '\\u0134': 'J',  '\\u0135': 'j',\n    '\\u0136': 'K',  '\\u0137': 'k', '\\u0138': 'k',\n    '\\u0139': 'L',  '\\u013b': 'L', '\\u013d': 'L', '\\u013f': 'L', '\\u0141': 'L',\n    '\\u013a': 'l',  '\\u013c': 'l', '\\u013e': 'l', '\\u0140': 'l', '\\u0142': 'l',\n    '\\u0143': 'N',  '\\u0145': 'N', '\\u0147': 'N', '\\u014a': 'N',\n    '\\u0144': 'n',  '\\u0146': 'n', '\\u0148': 'n', '\\u014b': 'n',\n    '\\u014c': 'O',  '\\u014e': 'O', '\\u0150': 'O',\n    '\\u014d': 'o',  '\\u014f': 'o', '\\u0151': 'o',\n    '\\u0154': 'R',  '\\u0156': 'R', '\\u0158': 'R',\n    '\\u0155': 'r',  '\\u0157': 'r', '\\u0159': 'r',\n    '\\u015a': 'S',  '\\u015c': 'S', '\\u015e': 'S', '\\u0160': 'S',\n    '\\u015b': 's',  '\\u015d': 's', '\\u015f': 's', '\\u0161': 's',\n    '\\u0162': 'T',  '\\u0164': 'T', '\\u0166': 'T',\n    '\\u0163': 't',  '\\u0165': 't', '\\u0167': 't',\n    '\\u0168': 'U',  '\\u016a': 'U', '\\u016c': 'U', '\\u016e': 'U', '\\u0170': 'U', '\\u0172': 'U',\n    '\\u0169': 'u',  '\\u016b': 'u', '\\u016d': 'u', '\\u016f': 'u', '\\u0171': 'u', '\\u0173': 'u',\n    '\\u0174': 'W',  '\\u0175': 'w',\n    '\\u0176': 'Y',  '\\u0177': 'y', '\\u0178': 'Y',\n    '\\u0179': 'Z',  '\\u017b': 'Z', '\\u017d': 'Z',\n    '\\u017a': 'z',  '\\u017c': 'z', '\\u017e': 'z',\n    '\\u0132': 'IJ', '\\u0133': 'ij',\n    '\\u0152': 'Oe', '\\u0153': 'oe',\n    '\\u0149': \"'n\", '\\u017f': 's'\n  };\n\n  /** Used to map characters to HTML entities. */\n  var htmlEscapes = {\n    '&': '&amp;',\n    '<': '&lt;',\n    '>': '&gt;',\n    '\"': '&quot;',\n    \"'\": '&#39;'\n  };\n\n  /** Used to map HTML entities to characters. */\n  var htmlUnescapes = {\n    '&amp;': '&',\n    '&lt;': '<',\n    '&gt;': '>',\n    '&quot;': '\"',\n    '&#39;': \"'\"\n  };\n\n  /** Used to escape characters for inclusion in compiled string literals. */\n  var stringEscapes = {\n    '\\\\': '\\\\',\n    \"'\": \"'\",\n    '\\n': 'n',\n    '\\r': 'r',\n    '\\u2028': 'u2028',\n    '\\u2029': 'u2029'\n  };\n\n  /** Built-in method references without a dependency on `root`. */\n  var freeParseFloat = parseFloat,\n      freeParseInt = parseInt;\n\n  /** Detect free variable `global` from Node.js. */\n  var freeGlobal = typeof global == 'object' && global && global.Object === Object && global;\n\n  /** Detect free variable `self`. */\n  var freeSelf = typeof self == 'object' && self && self.Object === Object && self;\n\n  /** Used as a reference to the global object. */\n  var root = freeGlobal || freeSelf || Function('return this')();\n\n  /** Detect free variable `exports`. */\n  var freeExports = typeof exports == 'object' && exports && !exports.nodeType && exports;\n\n  /** Detect free variable `module`. */\n  var freeModule = freeExports && typeof module == 'object' && module && !module.nodeType && module;\n\n  /** Detect the popular CommonJS extension `module.exports`. */\n  var moduleExports = freeModule && freeModule.exports === freeExports;\n\n  /** Detect free variable `process` from Node.js. */\n  var freeProcess = moduleExports && freeGlobal.process;\n\n  /** Used to access faster Node.js helpers. */\n  var nodeUtil = (function() {\n    try {\n      // Use `util.types` for Node.js 10+.\n      var types = freeModule && freeModule.require && freeModule.require('util').types;\n\n      if (types) {\n        return types;\n      }\n\n      // Legacy `process.binding('util')` for Node.js < 10.\n      return freeProcess && freeProcess.binding && freeProcess.binding('util');\n    } catch (e) {}\n  }());\n\n  /* Node.js helper references. */\n  var nodeIsArrayBuffer = nodeUtil && nodeUtil.isArrayBuffer,\n      nodeIsDate = nodeUtil && nodeUtil.isDate,\n      nodeIsMap = nodeUtil && nodeUtil.isMap,\n      nodeIsRegExp = nodeUtil && nodeUtil.isRegExp,\n      nodeIsSet = nodeUtil && nodeUtil.isSet,\n      nodeIsTypedArray = nodeUtil && nodeUtil.isTypedArray;\n\n  /*--------------------------------------------------------------------------*/\n\n  /**\n   * A faster alternative to `Function#apply`, this function invokes `func`\n   * with the `this` binding of `thisArg` and the arguments of `args`.\n   *\n   * @private\n   * @param {Function} func The function to invoke.\n   * @param {*} thisArg The `this` binding of `func`.\n   * @param {Array} args The arguments to invoke `func` with.\n   * @returns {*} Returns the result of `func`.\n   */\n  function apply(func, thisArg, args) {\n    switch (args.length) {\n      case 0: return func.call(thisArg);\n      case 1: return func.call(thisArg, args[0]);\n      case 2: return func.call(thisArg, args[0], args[1]);\n      case 3: return func.call(thisArg, args[0], args[1], args[2]);\n    }\n    return func.apply(thisArg, args);\n  }\n\n  /**\n   * A specialized version of `baseAggregator` for arrays.\n   *\n   * @private\n   * @param {Array} [array] The array to iterate over.\n   * @param {Function} setter The function to set `accumulator` values.\n   * @param {Function} iteratee The iteratee to transform keys.\n   * @param {Object} accumulator The initial aggregated object.\n   * @returns {Function} Returns `accumulator`.\n   */\n  function arrayAggregator(array, setter, iteratee, accumulator) {\n    var index = -1,\n        length = array == null ? 0 : array.length;\n\n    while (++index < length) {\n      var value = array[index];\n      setter(accumulator, value, iteratee(value), array);\n    }\n    return accumulator;\n  }\n\n  /**\n   * A specialized version of `_.forEach` for arrays without support for\n   * iteratee shorthands.\n   *\n   * @private\n   * @param {Array} [array] The array to iterate over.\n   * @param {Function} iteratee The function invoked per iteration.\n   * @returns {Array} Returns `array`.\n   */\n  function arrayEach(array, iteratee) {\n    var index = -1,\n        length = array == null ? 0 : array.length;\n\n    while (++index < length) {\n      if (iteratee(array[index], index, array) === false) {\n        break;\n      }\n    }\n    return array;\n  }\n\n  /**\n   * A specialized version of `_.forEachRight` for arrays without support for\n   * iteratee shorthands.\n   *\n   * @private\n   * @param {Array} [array] The array to iterate over.\n   * @param {Function} iteratee The function invoked per iteration.\n   * @returns {Array} Returns `array`.\n   */\n  function arrayEachRight(array, iteratee) {\n    var length = array == null ? 0 : array.length;\n\n    while (length--) {\n      if (iteratee(array[length], length, array) === false) {\n        break;\n      }\n    }\n    return array;\n  }\n\n  /**\n   * A specialized version of `_.every` for arrays without support for\n   * iteratee shorthands.\n   *\n   * @private\n   * @param {Array} [array] The array to iterate over.\n   * @param {Function} predicate The function invoked per iteration.\n   * @returns {boolean} Returns `true` if all elements pass the predicate check,\n   *  else `false`.\n   */\n  function arrayEvery(array, predicate) {\n    var index = -1,\n        length = array == null ? 0 : array.length;\n\n    while (++index < length) {\n      if (!predicate(array[index], index, array)) {\n        return false;\n      }\n    }\n    return true;\n  }\n\n  /**\n   * A specialized version of `_.filter` for arrays without support for\n   * iteratee shorthands.\n   *\n   * @private\n   * @param {Array} [array] The array to iterate over.\n   * @param {Function} predicate The function invoked per iteration.\n   * @returns {Array} Returns the new filtered array.\n   */\n  function arrayFilter(array, predicate) {\n    var index = -1,\n        length = array == null ? 0 : array.length,\n        resIndex = 0,\n        result = [];\n\n    while (++index < length) {\n      var value = array[index];\n      if (predicate(value, index, array)) {\n        result[resIndex++] = value;\n      }\n    }\n    return result;\n  }\n\n  /**\n   * A specialized version of `_.includes` for arrays without support for\n   * specifying an index to search from.\n   *\n   * @private\n   * @param {Array} [array] The array to inspect.\n   * @param {*} target The value to search for.\n   * @returns {boolean} Returns `true` if `target` is found, else `false`.\n   */\n  function arrayIncludes(array, value) {\n    var length = array == null ? 0 : array.length;\n    return !!length && baseIndexOf(array, value, 0) > -1;\n  }\n\n  /**\n   * This function is like `arrayIncludes` except that it accepts a comparator.\n   *\n   * @private\n   * @param {Array} [array] The array to inspect.\n   * @param {*} target The value to search for.\n   * @param {Function} comparator The comparator invoked per element.\n   * @returns {boolean} Returns `true` if `target` is found, else `false`.\n   */\n  function arrayIncludesWith(array, value, comparator) {\n    var index = -1,\n        length = array == null ? 0 : array.length;\n\n    while (++index < length) {\n      if (comparator(value, array[index])) {\n        return true;\n      }\n    }\n    return false;\n  }\n\n  /**\n   * A specialized version of `_.map` for arrays without support for iteratee\n   * shorthands.\n   *\n   * @private\n   * @param {Array} [array] The array to iterate over.\n   * @param {Function} iteratee The function invoked per iteration.\n   * @returns {Array} Returns the new mapped array.\n   */\n  function arrayMap(array, iteratee) {\n    var index = -1,\n        length = array == null ? 0 : array.length,\n        result = Array(length);\n\n    while (++index < length) {\n      result[index] = iteratee(array[index], index, array);\n    }\n    return result;\n  }\n\n  /**\n   * Appends the elements of `values` to `array`.\n   *\n   * @private\n   * @param {Array} array The array to modify.\n   * @param {Array} values The values to append.\n   * @returns {Array} Returns `array`.\n   */\n  function arrayPush(array, values) {\n    var index = -1,\n        length = values.length,\n        offset = array.length;\n\n    while (++index < length) {\n      array[offset + index] = values[index];\n    }\n    return array;\n  }\n\n  /**\n   * A specialized version of `_.reduce` for arrays without support for\n   * iteratee shorthands.\n   *\n   * @private\n   * @param {Array} [array] The array to iterate over.\n   * @param {Function} iteratee The function invoked per iteration.\n   * @param {*} [accumulator] The initial value.\n   * @param {boolean} [initAccum] Specify using the first element of `array` as\n   *  the initial value.\n   * @returns {*} Returns the accumulated value.\n   */\n  function arrayReduce(array, iteratee, accumulator, initAccum) {\n    var index = -1,\n        length = array == null ? 0 : array.length;\n\n    if (initAccum && length) {\n      accumulator = array[++index];\n    }\n    while (++index < length) {\n      accumulator = iteratee(accumulator, array[index], index, array);\n    }\n    return accumulator;\n  }\n\n  /**\n   * A specialized version of `_.reduceRight` for arrays without support for\n   * iteratee shorthands.\n   *\n   * @private\n   * @param {Array} [array] The array to iterate over.\n   * @param {Function} iteratee The function invoked per iteration.\n   * @param {*} [accumulator] The initial value.\n   * @param {boolean} [initAccum] Specify using the last element of `array` as\n   *  the initial value.\n   * @returns {*} Returns the accumulated value.\n   */\n  function arrayReduceRight(array, iteratee, accumulator, initAccum) {\n    var length = array == null ? 0 : array.length;\n    if (initAccum && length) {\n      accumulator = array[--length];\n    }\n    while (length--) {\n      accumulator = iteratee(accumulator, array[length], length, array);\n    }\n    return accumulator;\n  }\n\n  /**\n   * A specialized version of `_.some` for arrays without support for iteratee\n   * shorthands.\n   *\n   * @private\n   * @param {Array} [array] The array to iterate over.\n   * @param {Function} predicate The function invoked per iteration.\n   * @returns {boolean} Returns `true` if any element passes the predicate check,\n   *  else `false`.\n   */\n  function arraySome(array, predicate) {\n    var index = -1,\n        length = array == null ? 0 : array.length;\n\n    while (++index < length) {\n      if (predicate(array[index], index, array)) {\n        return true;\n      }\n    }\n    return false;\n  }\n\n  /**\n   * Gets the size of an ASCII `string`.\n   *\n   * @private\n   * @param {string} string The string inspect.\n   * @returns {number} Returns the string size.\n   */\n  var asciiSize = baseProperty('length');\n\n  /**\n   * Converts an ASCII `string` to an array.\n   *\n   * @private\n   * @param {string} string The string to convert.\n   * @returns {Array} Returns the converted array.\n   */\n  function asciiToArray(string) {\n    return string.split('');\n  }\n\n  /**\n   * Splits an ASCII `string` into an array of its words.\n   *\n   * @private\n   * @param {string} The string to inspect.\n   * @returns {Array} Returns the words of `string`.\n   */\n  function asciiWords(string) {\n    return string.match(reAsciiWord) || [];\n  }\n\n  /**\n   * The base implementation of methods like `_.findKey` and `_.findLastKey`,\n   * without support for iteratee shorthands, which iterates over `collection`\n   * using `eachFunc`.\n   *\n   * @private\n   * @param {Array|Object} collection The collection to inspect.\n   * @param {Function} predicate The function invoked per iteration.\n   * @param {Function} eachFunc The function to iterate over `collection`.\n   * @returns {*} Returns the found element or its key, else `undefined`.\n   */\n  function baseFindKey(collection, predicate, eachFunc) {\n    var result;\n    eachFunc(collection, function(value, key, collection) {\n      if (predicate(value, key, collection)) {\n        result = key;\n        return false;\n      }\n    });\n    return result;\n  }\n\n  /**\n   * The base implementation of `_.findIndex` and `_.findLastIndex` without\n   * support for iteratee shorthands.\n   *\n   * @private\n   * @param {Array} array The array to inspect.\n   * @param {Function} predicate The function invoked per iteration.\n   * @param {number} fromIndex The index to search from.\n   * @param {boolean} [fromRight] Specify iterating from right to left.\n   * @returns {number} Returns the index of the matched value, else `-1`.\n   */\n  function baseFindIndex(array, predicate, fromIndex, fromRight) {\n    var length = array.length,\n        index = fromIndex + (fromRight ? 1 : -1);\n\n    while ((fromRight ? index-- : ++index < length)) {\n      if (predicate(array[index], index, array)) {\n        return index;\n      }\n    }\n    return -1;\n  }\n\n  /**\n   * The base implementation of `_.indexOf` without `fromIndex` bounds checks.\n   *\n   * @private\n   * @param {Array} array The array to inspect.\n   * @param {*} value The value to search for.\n   * @param {number} fromIndex The index to search from.\n   * @returns {number} Returns the index of the matched value, else `-1`.\n   */\n  function baseIndexOf(array, value, fromIndex) {\n    return value === value\n      ? strictIndexOf(array, value, fromIndex)\n      : baseFindIndex(array, baseIsNaN, fromIndex);\n  }\n\n  /**\n   * This function is like `baseIndexOf` except that it accepts a comparator.\n   *\n   * @private\n   * @param {Array} array The array to inspect.\n   * @param {*} value The value to search for.\n   * @param {number} fromIndex The index to search from.\n   * @param {Function} comparator The comparator invoked per element.\n   * @returns {number} Returns the index of the matched value, else `-1`.\n   */\n  function baseIndexOfWith(array, value, fromIndex, comparator) {\n    var index = fromIndex - 1,\n        length = array.length;\n\n    while (++index < length) {\n      if (comparator(array[index], value)) {\n        return index;\n      }\n    }\n    return -1;\n  }\n\n  /**\n   * The base implementation of `_.isNaN` without support for number objects.\n   *\n   * @private\n   * @param {*} value The value to check.\n   * @returns {boolean} Returns `true` if `value` is `NaN`, else `false`.\n   */\n  function baseIsNaN(value) {\n    return value !== value;\n  }\n\n  /**\n   * The base implementation of `_.mean` and `_.meanBy` without support for\n   * iteratee shorthands.\n   *\n   * @private\n   * @param {Array} array The array to iterate over.\n   * @param {Function} iteratee The function invoked per iteration.\n   * @returns {number} Returns the mean.\n   */\n  function baseMean(array, iteratee) {\n    var length = array == null ? 0 : array.length;\n    return length ? (baseSum(array, iteratee) / length) : NAN;\n  }\n\n  /**\n   * The base implementation of `_.property` without support for deep paths.\n   *\n   * @private\n   * @param {string} key The key of the property to get.\n   * @returns {Function} Returns the new accessor function.\n   */\n  function baseProperty(key) {\n    return function(object) {\n      return object == null ? undefined : object[key];\n    };\n  }\n\n  /**\n   * The base implementation of `_.propertyOf` without support for deep paths.\n   *\n   * @private\n   * @param {Object} object The object to query.\n   * @returns {Function} Returns the new accessor function.\n   */\n  function basePropertyOf(object) {\n    return function(key) {\n      return object == null ? undefined : object[key];\n    };\n  }\n\n  /**\n   * The base implementation of `_.reduce` and `_.reduceRight`, without support\n   * for iteratee shorthands, which iterates over `collection` using `eachFunc`.\n   *\n   * @private\n   * @param {Array|Object} collection The collection to iterate over.\n   * @param {Function} iteratee The function invoked per iteration.\n   * @param {*} accumulator The initial value.\n   * @param {boolean} initAccum Specify using the first or last element of\n   *  `collection` as the initial value.\n   * @param {Function} eachFunc The function to iterate over `collection`.\n   * @returns {*} Returns the accumulated value.\n   */\n  function baseReduce(collection, iteratee, accumulator, initAccum, eachFunc) {\n    eachFunc(collection, function(value, index, collection) {\n      accumulator = initAccum\n        ? (initAccum = false, value)\n        : iteratee(accumulator, value, index, collection);\n    });\n    return accumulator;\n  }\n\n  /**\n   * The base implementation of `_.sortBy` which uses `comparer` to define the\n   * sort order of `array` and replaces criteria objects with their corresponding\n   * values.\n   *\n   * @private\n   * @param {Array} array The array to sort.\n   * @param {Function} comparer The function to define sort order.\n   * @returns {Array} Returns `array`.\n   */\n  function baseSortBy(array, comparer) {\n    var length = array.length;\n\n    array.sort(comparer);\n    while (length--) {\n      array[length] = array[length].value;\n    }\n    return array;\n  }\n\n  /**\n   * The base implementation of `_.sum` and `_.sumBy` without support for\n   * iteratee shorthands.\n   *\n   * @private\n   * @param {Array} array The array to iterate over.\n   * @param {Function} iteratee The function invoked per iteration.\n   * @returns {number} Returns the sum.\n   */\n  function baseSum(array, iteratee) {\n    var result,\n        index = -1,\n        length = array.length;\n\n    while (++index < length) {\n      var current = iteratee(array[index]);\n      if (current !== undefined) {\n        result = result === undefined ? current : (result + current);\n      }\n    }\n    return result;\n  }\n\n  /**\n   * The base implementation of `_.times` without support for iteratee shorthands\n   * or max array length checks.\n   *\n   * @private\n   * @param {number} n The number of times to invoke `iteratee`.\n   * @param {Function} iteratee The function invoked per iteration.\n   * @returns {Array} Returns the array of results.\n   */\n  function baseTimes(n, iteratee) {\n    var index = -1,\n        result = Array(n);\n\n    while (++index < n) {\n      result[index] = iteratee(index);\n    }\n    return result;\n  }\n\n  /**\n   * The base implementation of `_.toPairs` and `_.toPairsIn` which creates an array\n   * of key-value pairs for `object` corresponding to the property names of `props`.\n   *\n   * @private\n   * @param {Object} object The object to query.\n   * @param {Array} props The property names to get values for.\n   * @returns {Object} Returns the key-value pairs.\n   */\n  function baseToPairs(object, props) {\n    return arrayMap(props, function(key) {\n      return [key, object[key]];\n    });\n  }\n\n  /**\n   * The base implementation of `_.unary` without support for storing metadata.\n   *\n   * @private\n   * @param {Function} func The function to cap arguments for.\n   * @returns {Function} Returns the new capped function.\n   */\n  function baseUnary(func) {\n    return function(value) {\n      return func(value);\n    };\n  }\n\n  /**\n   * The base implementation of `_.values` and `_.valuesIn` which creates an\n   * array of `object` property values corresponding to the property names\n   * of `props`.\n   *\n   * @private\n   * @param {Object} object The object to query.\n   * @param {Array} props The property names to get values for.\n   * @returns {Object} Returns the array of property values.\n   */\n  function baseValues(object, props) {\n    return arrayMap(props, function(key) {\n      return object[key];\n    });\n  }\n\n  /**\n   * Checks if a `cache` value for `key` exists.\n   *\n   * @private\n   * @param {Object} cache The cache to query.\n   * @param {string} key The key of the entry to check.\n   * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.\n   */\n  function cacheHas(cache, key) {\n    return cache.has(key);\n  }\n\n  /**\n   * Used by `_.trim` and `_.trimStart` to get the index of the first string symbol\n   * that is not found in the character symbols.\n   *\n   * @private\n   * @param {Array} strSymbols The string symbols to inspect.\n   * @param {Array} chrSymbols The character symbols to find.\n   * @returns {number} Returns the index of the first unmatched string symbol.\n   */\n  function charsStartIndex(strSymbols, chrSymbols) {\n    var index = -1,\n        length = strSymbols.length;\n\n    while (++index < length && baseIndexOf(chrSymbols, strSymbols[index], 0) > -1) {}\n    return index;\n  }\n\n  /**\n   * Used by `_.trim` and `_.trimEnd` to get the index of the last string symbol\n   * that is not found in the character symbols.\n   *\n   * @private\n   * @param {Array} strSymbols The string symbols to inspect.\n   * @param {Array} chrSymbols The character symbols to find.\n   * @returns {number} Returns the index of the last unmatched string symbol.\n   */\n  function charsEndIndex(strSymbols, chrSymbols) {\n    var index = strSymbols.length;\n\n    while (index-- && baseIndexOf(chrSymbols, strSymbols[index], 0) > -1) {}\n    return index;\n  }\n\n  /**\n   * Gets the number of `placeholder` occurrences in `array`.\n   *\n   * @private\n   * @param {Array} array The array to inspect.\n   * @param {*} placeholder The placeholder to search for.\n   * @returns {number} Returns the placeholder count.\n   */\n  function countHolders(array, placeholder) {\n    var length = array.length,\n        result = 0;\n\n    while (length--) {\n      if (array[length] === placeholder) {\n        ++result;\n      }\n    }\n    return result;\n  }\n\n  /**\n   * Used by `_.deburr` to convert Latin-1 Supplement and Latin Extended-A\n   * letters to basic Latin letters.\n   *\n   * @private\n   * @param {string} letter The matched letter to deburr.\n   * @returns {string} Returns the deburred letter.\n   */\n  var deburrLetter = basePropertyOf(deburredLetters);\n\n  /**\n   * Used by `_.escape` to convert characters to HTML entities.\n   *\n   * @private\n   * @param {string} chr The matched character to escape.\n   * @returns {string} Returns the escaped character.\n   */\n  var escapeHtmlChar = basePropertyOf(htmlEscapes);\n\n  /**\n   * Used by `_.template` to escape characters for inclusion in compiled string literals.\n   *\n   * @private\n   * @param {string} chr The matched character to escape.\n   * @returns {string} Returns the escaped character.\n   */\n  function escapeStringChar(chr) {\n    return '\\\\' + stringEscapes[chr];\n  }\n\n  /**\n   * Gets the value at `key` of `object`.\n   *\n   * @private\n   * @param {Object} [object] The object to query.\n   * @param {string} key The key of the property to get.\n   * @returns {*} Returns the property value.\n   */\n  function getValue(object, key) {\n    return object == null ? undefined : object[key];\n  }\n\n  /**\n   * Checks if `string` contains Unicode symbols.\n   *\n   * @private\n   * @param {string} string The string to inspect.\n   * @returns {boolean} Returns `true` if a symbol is found, else `false`.\n   */\n  function hasUnicode(string) {\n    return reHasUnicode.test(string);\n  }\n\n  /**\n   * Checks if `string` contains a word composed of Unicode symbols.\n   *\n   * @private\n   * @param {string} string The string to inspect.\n   * @returns {boolean} Returns `true` if a word is found, else `false`.\n   */\n  function hasUnicodeWord(string) {\n    return reHasUnicodeWord.test(string);\n  }\n\n  /**\n   * Converts `iterator` to an array.\n   *\n   * @private\n   * @param {Object} iterator The iterator to convert.\n   * @returns {Array} Returns the converted array.\n   */\n  function iteratorToArray(iterator) {\n    var data,\n        result = [];\n\n    while (!(data = iterator.next()).done) {\n      result.push(data.value);\n    }\n    return result;\n  }\n\n  /**\n   * Converts `map` to its key-value pairs.\n   *\n   * @private\n   * @param {Object} map The map to convert.\n   * @returns {Array} Returns the key-value pairs.\n   */\n  function mapToArray(map) {\n    var index = -1,\n        result = Array(map.size);\n\n    map.forEach(function(value, key) {\n      result[++index] = [key, value];\n    });\n    return result;\n  }\n\n  /**\n   * Creates a unary function that invokes `func` with its argument transformed.\n   *\n   * @private\n   * @param {Function} func The function to wrap.\n   * @param {Function} transform The argument transform.\n   * @returns {Function} Returns the new function.\n   */\n  function overArg(func, transform) {\n    return function(arg) {\n      return func(transform(arg));\n    };\n  }\n\n  /**\n   * Replaces all `placeholder` elements in `array` with an internal placeholder\n   * and returns an array of their indexes.\n   *\n   * @private\n   * @param {Array} array The array to modify.\n   * @param {*} placeholder The placeholder to replace.\n   * @returns {Array} Returns the new array of placeholder indexes.\n   */\n  function replaceHolders(array, placeholder) {\n    var index = -1,\n        length = array.length,\n        resIndex = 0,\n        result = [];\n\n    while (++index < length) {\n      var value = array[index];\n      if (value === placeholder || value === PLACEHOLDER) {\n        array[index] = PLACEHOLDER;\n        result[resIndex++] = index;\n      }\n    }\n    return result;\n  }\n\n  /**\n   * Converts `set` to an array of its values.\n   *\n   * @private\n   * @param {Object} set The set to convert.\n   * @returns {Array} Returns the values.\n   */\n  function setToArray(set) {\n    var index = -1,\n        result = Array(set.size);\n\n    set.forEach(function(value) {\n      result[++index] = value;\n    });\n    return result;\n  }\n\n  /**\n   * Converts `set` to its value-value pairs.\n   *\n   * @private\n   * @param {Object} set The set to convert.\n   * @returns {Array} Returns the value-value pairs.\n   */\n  function setToPairs(set) {\n    var index = -1,\n        result = Array(set.size);\n\n    set.forEach(function(value) {\n      result[++index] = [value, value];\n    });\n    return result;\n  }\n\n  /**\n   * A specialized version of `_.indexOf` which performs strict equality\n   * comparisons of values, i.e. `===`.\n   *\n   * @private\n   * @param {Array} array The array to inspect.\n   * @param {*} value The value to search for.\n   * @param {number} fromIndex The index to search from.\n   * @returns {number} Returns the index of the matched value, else `-1`.\n   */\n  function strictIndexOf(array, value, fromIndex) {\n    var index = fromIndex - 1,\n        length = array.length;\n\n    while (++index < length) {\n      if (array[index] === value) {\n        return index;\n      }\n    }\n    return -1;\n  }\n\n  /**\n   * A specialized version of `_.lastIndexOf` which performs strict equality\n   * comparisons of values, i.e. `===`.\n   *\n   * @private\n   * @param {Array} array The array to inspect.\n   * @param {*} value The value to search for.\n   * @param {number} fromIndex The index to search from.\n   * @returns {number} Returns the index of the matched value, else `-1`.\n   */\n  function strictLastIndexOf(array, value, fromIndex) {\n    var index = fromIndex + 1;\n    while (index--) {\n      if (array[index] === value) {\n        return index;\n      }\n    }\n    return index;\n  }\n\n  /**\n   * Gets the number of symbols in `string`.\n   *\n   * @private\n   * @param {string} string The string to inspect.\n   * @returns {number} Returns the string size.\n   */\n  function stringSize(string) {\n    return hasUnicode(string)\n      ? unicodeSize(string)\n      : asciiSize(string);\n  }\n\n  /**\n   * Converts `string` to an array.\n   *\n   * @private\n   * @param {string} string The string to convert.\n   * @returns {Array} Returns the converted array.\n   */\n  function stringToArray(string) {\n    return hasUnicode(string)\n      ? unicodeToArray(string)\n      : asciiToArray(string);\n  }\n\n  /**\n   * Used by `_.unescape` to convert HTML entities to characters.\n   *\n   * @private\n   * @param {string} chr The matched character to unescape.\n   * @returns {string} Returns the unescaped character.\n   */\n  var unescapeHtmlChar = basePropertyOf(htmlUnescapes);\n\n  /**\n   * Gets the size of a Unicode `string`.\n   *\n   * @private\n   * @param {string} string The string inspect.\n   * @returns {number} Returns the string size.\n   */\n  function unicodeSize(string) {\n    var result = reUnicode.lastIndex = 0;\n    while (reUnicode.test(string)) {\n      ++result;\n    }\n    return result;\n  }\n\n  /**\n   * Converts a Unicode `string` to an array.\n   *\n   * @private\n   * @param {string} string The string to convert.\n   * @returns {Array} Returns the converted array.\n   */\n  function unicodeToArray(string) {\n    return string.match(reUnicode) || [];\n  }\n\n  /**\n   * Splits a Unicode `string` into an array of its words.\n   *\n   * @private\n   * @param {string} The string to inspect.\n   * @returns {Array} Returns the words of `string`.\n   */\n  function unicodeWords(string) {\n    return string.match(reUnicodeWord) || [];\n  }\n\n  /*--------------------------------------------------------------------------*/\n\n  /**\n   * Create a new pristine `lodash` function using the `context` object.\n   *\n   * @static\n   * @memberOf _\n   * @since 1.1.0\n   * @category Util\n   * @param {Object} [context=root] The context object.\n   * @returns {Function} Returns a new `lodash` function.\n   * @example\n   *\n   * _.mixin({ 'foo': _.constant('foo') });\n   *\n   * var lodash = _.runInContext();\n   * lodash.mixin({ 'bar': lodash.constant('bar') });\n   *\n   * _.isFunction(_.foo);\n   * // => true\n   * _.isFunction(_.bar);\n   * // => false\n   *\n   * lodash.isFunction(lodash.foo);\n   * // => false\n   * lodash.isFunction(lodash.bar);\n   * // => true\n   *\n   * // Create a suped-up `defer` in Node.js.\n   * var defer = _.runInContext({ 'setTimeout': setImmediate }).defer;\n   */\n  var runInContext = (function runInContext(context) {\n    context = context == null ? root : _.defaults(root.Object(), context, _.pick(root, contextProps));\n\n    /** Built-in constructor references. */\n    var Array = context.Array,\n        Date = context.Date,\n        Error = context.Error,\n        Function = context.Function,\n        Math = context.Math,\n        Object = context.Object,\n        RegExp = context.RegExp,\n        String = context.String,\n        TypeError = context.TypeError;\n\n    /** Used for built-in method references. */\n    var arrayProto = Array.prototype,\n        funcProto = Function.prototype,\n        objectProto = Object.prototype;\n\n    /** Used to detect overreaching core-js shims. */\n    var coreJsData = context['__core-js_shared__'];\n\n    /** Used to resolve the decompiled source of functions. */\n    var funcToString = funcProto.toString;\n\n    /** Used to check objects for own properties. */\n    var hasOwnProperty = objectProto.hasOwnProperty;\n\n    /** Used to generate unique IDs. */\n    var idCounter = 0;\n\n    /** Used to detect methods masquerading as native. */\n    var maskSrcKey = (function() {\n      var uid = /[^.]+$/.exec(coreJsData && coreJsData.keys && coreJsData.keys.IE_PROTO || '');\n      return uid ? ('Symbol(src)_1.' + uid) : '';\n    }());\n\n    /**\n     * Used to resolve the\n     * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring)\n     * of values.\n     */\n    var nativeObjectToString = objectProto.toString;\n\n    /** Used to infer the `Object` constructor. */\n    var objectCtorString = funcToString.call(Object);\n\n    /** Used to restore the original `_` reference in `_.noConflict`. */\n    var oldDash = root._;\n\n    /** Used to detect if a method is native. */\n    var reIsNative = RegExp('^' +\n      funcToString.call(hasOwnProperty).replace(reRegExpChar, '\\\\$&')\n      .replace(/hasOwnProperty|(function).*?(?=\\\\\\()| for .+?(?=\\\\\\])/g, '$1.*?') + '$'\n    );\n\n    /** Built-in value references. */\n    var Buffer = moduleExports ? context.Buffer : undefined,\n        Symbol = context.Symbol,\n        Uint8Array = context.Uint8Array,\n        allocUnsafe = Buffer ? Buffer.allocUnsafe : undefined,\n        getPrototype = overArg(Object.getPrototypeOf, Object),\n        objectCreate = Object.create,\n        propertyIsEnumerable = objectProto.propertyIsEnumerable,\n        splice = arrayProto.splice,\n        spreadableSymbol = Symbol ? Symbol.isConcatSpreadable : undefined,\n        symIterator = Symbol ? Symbol.iterator : undefined,\n        symToStringTag = Symbol ? Symbol.toStringTag : undefined;\n\n    var defineProperty = (function() {\n      try {\n        var func = getNative(Object, 'defineProperty');\n        func({}, '', {});\n        return func;\n      } catch (e) {}\n    }());\n\n    /** Mocked built-ins. */\n    var ctxClearTimeout = context.clearTimeout !== root.clearTimeout && context.clearTimeout,\n        ctxNow = Date && Date.now !== root.Date.now && Date.now,\n        ctxSetTimeout = context.setTimeout !== root.setTimeout && context.setTimeout;\n\n    /* Built-in method references for those with the same name as other `lodash` methods. */\n    var nativeCeil = Math.ceil,\n        nativeFloor = Math.floor,\n        nativeGetSymbols = Object.getOwnPropertySymbols,\n        nativeIsBuffer = Buffer ? Buffer.isBuffer : undefined,\n        nativeIsFinite = context.isFinite,\n        nativeJoin = arrayProto.join,\n        nativeKeys = overArg(Object.keys, Object),\n        nativeMax = Math.max,\n        nativeMin = Math.min,\n        nativeNow = Date.now,\n        nativeParseInt = context.parseInt,\n        nativeRandom = Math.random,\n        nativeReverse = arrayProto.reverse;\n\n    /* Built-in method references that are verified to be native. */\n    var DataView = getNative(context, 'DataView'),\n        Map = getNative(context, 'Map'),\n        Promise = getNative(context, 'Promise'),\n        Set = getNative(context, 'Set'),\n        WeakMap = getNative(context, 'WeakMap'),\n        nativeCreate = getNative(Object, 'create');\n\n    /** Used to store function metadata. */\n    var metaMap = WeakMap && new WeakMap;\n\n    /** Used to lookup unminified function names. */\n    var realNames = {};\n\n    /** Used to detect maps, sets, and weakmaps. */\n    var dataViewCtorString = toSource(DataView),\n        mapCtorString = toSource(Map),\n        promiseCtorString = toSource(Promise),\n        setCtorString = toSource(Set),\n        weakMapCtorString = toSource(WeakMap);\n\n    /** Used to convert symbols to primitives and strings. */\n    var symbolProto = Symbol ? Symbol.prototype : undefined,\n        symbolValueOf = symbolProto ? symbolProto.valueOf : undefined,\n        symbolToString = symbolProto ? symbolProto.toString : undefined;\n\n    /*------------------------------------------------------------------------*/\n\n    /**\n     * Creates a `lodash` object which wraps `value` to enable implicit method\n     * chain sequences. Methods that operate on and return arrays, collections,\n     * and functions can be chained together. Methods that retrieve a single value\n     * or may return a primitive value will automatically end the chain sequence\n     * and return the unwrapped value. Otherwise, the value must be unwrapped\n     * with `_#value`.\n     *\n     * Explicit chain sequences, which must be unwrapped with `_#value`, may be\n     * enabled using `_.chain`.\n     *\n     * The execution of chained methods is lazy, that is, it's deferred until\n     * `_#value` is implicitly or explicitly called.\n     *\n     * Lazy evaluation allows several methods to support shortcut fusion.\n     * Shortcut fusion is an optimization to merge iteratee calls; this avoids\n     * the creation of intermediate arrays and can greatly reduce the number of\n     * iteratee executions. Sections of a chain sequence qualify for shortcut\n     * fusion if the section is applied to an array and iteratees accept only\n     * one argument. The heuristic for whether a section qualifies for shortcut\n     * fusion is subject to change.\n     *\n     * Chaining is supported in custom builds as long as the `_#value` method is\n     * directly or indirectly included in the build.\n     *\n     * In addition to lodash methods, wrappers have `Array` and `String` methods.\n     *\n     * The wrapper `Array` methods are:\n     * `concat`, `join`, `pop`, `push`, `shift`, `sort`, `splice`, and `unshift`\n     *\n     * The wrapper `String` methods are:\n     * `replace` and `split`\n     *\n     * The wrapper methods that support shortcut fusion are:\n     * `at`, `compact`, `drop`, `dropRight`, `dropWhile`, `filter`, `find`,\n     * `findLast`, `head`, `initial`, `last`, `map`, `reject`, `reverse`, `slice`,\n     * `tail`, `take`, `takeRight`, `takeRightWhile`, `takeWhile`, and `toArray`\n     *\n     * The chainable wrapper methods are:\n     * `after`, `ary`, `assign`, `assignIn`, `assignInWith`, `assignWith`, `at`,\n     * `before`, `bind`, `bindAll`, `bindKey`, `castArray`, `chain`, `chunk`,\n     * `commit`, `compact`, `concat`, `conforms`, `constant`, `countBy`, `create`,\n     * `curry`, `debounce`, `defaults`, `defaultsDeep`, `defer`, `delay`,\n     * `difference`, `differenceBy`, `differenceWith`, `drop`, `dropRight`,\n     * `dropRightWhile`, `dropWhile`, `extend`, `extendWith`, `fill`, `filter`,\n     * `flatMap`, `flatMapDeep`, `flatMapDepth`, `flatten`, `flattenDeep`,\n     * `flattenDepth`, `flip`, `flow`, `flowRight`, `fromPairs`, `functions`,\n     * `functionsIn`, `groupBy`, `initial`, `intersection`, `intersectionBy`,\n     * `intersectionWith`, `invert`, `invertBy`, `invokeMap`, `iteratee`, `keyBy`,\n     * `keys`, `keysIn`, `map`, `mapKeys`, `mapValues`, `matches`, `matchesProperty`,\n     * `memoize`, `merge`, `mergeWith`, `method`, `methodOf`, `mixin`, `negate`,\n     * `nthArg`, `omit`, `omitBy`, `once`, `orderBy`, `over`, `overArgs`,\n     * `overEvery`, `overSome`, `partial`, `partialRight`, `partition`, `pick`,\n     * `pickBy`, `plant`, `property`, `propertyOf`, `pull`, `pullAll`, `pullAllBy`,\n     * `pullAllWith`, `pullAt`, `push`, `range`, `rangeRight`, `rearg`, `reject`,\n     * `remove`, `rest`, `reverse`, `sampleSize`, `set`, `setWith`, `shuffle`,\n     * `slice`, `sort`, `sortBy`, `splice`, `spread`, `tail`, `take`, `takeRight`,\n     * `takeRightWhile`, `takeWhile`, `tap`, `throttle`, `thru`, `toArray`,\n     * `toPairs`, `toPairsIn`, `toPath`, `toPlainObject`, `transform`, `unary`,\n     * `union`, `unionBy`, `unionWith`, `uniq`, `uniqBy`, `uniqWith`, `unset`,\n     * `unshift`, `unzip`, `unzipWith`, `update`, `updateWith`, `values`,\n     * `valuesIn`, `without`, `wrap`, `xor`, `xorBy`, `xorWith`, `zip`,\n     * `zipObject`, `zipObjectDeep`, and `zipWith`\n     *\n     * The wrapper methods that are **not** chainable by default are:\n     * `add`, `attempt`, `camelCase`, `capitalize`, `ceil`, `clamp`, `clone`,\n     * `cloneDeep`, `cloneDeepWith`, `cloneWith`, `conformsTo`, `deburr`,\n     * `defaultTo`, `divide`, `each`, `eachRight`, `endsWith`, `eq`, `escape`,\n     * `escapeRegExp`, `every`, `find`, `findIndex`, `findKey`, `findLast`,\n     * `findLastIndex`, `findLastKey`, `first`, `floor`, `forEach`, `forEachRight`,\n     * `forIn`, `forInRight`, `forOwn`, `forOwnRight`, `get`, `gt`, `gte`, `has`,\n     * `hasIn`, `head`, `identity`, `includes`, `indexOf`, `inRange`, `invoke`,\n     * `isArguments`, `isArray`, `isArrayBuffer`, `isArrayLike`, `isArrayLikeObject`,\n     * `isBoolean`, `isBuffer`, `isDate`, `isElement`, `isEmpty`, `isEqual`,\n     * `isEqualWith`, `isError`, `isFinite`, `isFunction`, `isInteger`, `isLength`,\n     * `isMap`, `isMatch`, `isMatchWith`, `isNaN`, `isNative`, `isNil`, `isNull`,\n     * `isNumber`, `isObject`, `isObjectLike`, `isPlainObject`, `isRegExp`,\n     * `isSafeInteger`, `isSet`, `isString`, `isUndefined`, `isTypedArray`,\n     * `isWeakMap`, `isWeakSet`, `join`, `kebabCase`, `last`, `lastIndexOf`,\n     * `lowerCase`, `lowerFirst`, `lt`, `lte`, `max`, `maxBy`, `mean`, `meanBy`,\n     * `min`, `minBy`, `multiply`, `noConflict`, `noop`, `now`, `nth`, `pad`,\n     * `padEnd`, `padStart`, `parseInt`, `pop`, `random`, `reduce`, `reduceRight`,\n     * `repeat`, `result`, `round`, `runInContext`, `sample`, `shift`, `size`,\n     * `snakeCase`, `some`, `sortedIndex`, `sortedIndexBy`, `sortedLastIndex`,\n     * `sortedLastIndexBy`, `startCase`, `startsWith`, `stubArray`, `stubFalse`,\n     * `stubObject`, `stubString`, `stubTrue`, `subtract`, `sum`, `sumBy`,\n     * `template`, `times`, `toFinite`, `toInteger`, `toJSON`, `toLength`,\n     * `toLower`, `toNumber`, `toSafeInteger`, `toString`, `toUpper`, `trim`,\n     * `trimEnd`, `trimStart`, `truncate`, `unescape`, `uniqueId`, `upperCase`,\n     * `upperFirst`, `value`, and `words`\n     *\n     * @name _\n     * @constructor\n     * @category Seq\n     * @param {*} value The value to wrap in a `lodash` instance.\n     * @returns {Object} Returns the new `lodash` wrapper instance.\n     * @example\n     *\n     * function square(n) {\n     *   return n * n;\n     * }\n     *\n     * var wrapped = _([1, 2, 3]);\n     *\n     * // Returns an unwrapped value.\n     * wrapped.reduce(_.add);\n     * // => 6\n     *\n     * // Returns a wrapped value.\n     * var squares = wrapped.map(square);\n     *\n     * _.isArray(squares);\n     * // => false\n     *\n     * _.isArray(squares.value());\n     * // => true\n     */\n    function lodash(value) {\n      if (isObjectLike(value) && !isArray(value) && !(value instanceof LazyWrapper)) {\n        if (value instanceof LodashWrapper) {\n          return value;\n        }\n        if (hasOwnProperty.call(value, '__wrapped__')) {\n          return wrapperClone(value);\n        }\n      }\n      return new LodashWrapper(value);\n    }\n\n    /**\n     * The base implementation of `_.create` without support for assigning\n     * properties to the created object.\n     *\n     * @private\n     * @param {Object} proto The object to inherit from.\n     * @returns {Object} Returns the new object.\n     */\n    var baseCreate = (function() {\n      function object() {}\n      return function(proto) {\n        if (!isObject(proto)) {\n          return {};\n        }\n        if (objectCreate) {\n          return objectCreate(proto);\n        }\n        object.prototype = proto;\n        var result = new object;\n        object.prototype = undefined;\n        return result;\n      };\n    }());\n\n    /**\n     * The function whose prototype chain sequence wrappers inherit from.\n     *\n     * @private\n     */\n    function baseLodash() {\n      // No operation performed.\n    }\n\n    /**\n     * The base constructor for creating `lodash` wrapper objects.\n     *\n     * @private\n     * @param {*} value The value to wrap.\n     * @param {boolean} [chainAll] Enable explicit method chain sequences.\n     */\n    function LodashWrapper(value, chainAll) {\n      this.__wrapped__ = value;\n      this.__actions__ = [];\n      this.__chain__ = !!chainAll;\n      this.__index__ = 0;\n      this.__values__ = undefined;\n    }\n\n    /**\n     * By default, the template delimiters used by lodash are like those in\n     * embedded Ruby (ERB) as well as ES2015 template strings. Change the\n     * following template settings to use alternative delimiters.\n     *\n     * @static\n     * @memberOf _\n     * @type {Object}\n     */\n    lodash.templateSettings = {\n\n      /**\n       * Used to detect `data` property values to be HTML-escaped.\n       *\n       * @memberOf _.templateSettings\n       * @type {RegExp}\n       */\n      'escape': reEscape,\n\n      /**\n       * Used to detect code to be evaluated.\n       *\n       * @memberOf _.templateSettings\n       * @type {RegExp}\n       */\n      'evaluate': reEvaluate,\n\n      /**\n       * Used to detect `data` property values to inject.\n       *\n       * @memberOf _.templateSettings\n       * @type {RegExp}\n       */\n      'interpolate': reInterpolate,\n\n      /**\n       * Used to reference the data object in the template text.\n       *\n       * @memberOf _.templateSettings\n       * @type {string}\n       */\n      'variable': '',\n\n      /**\n       * Used to import variables into the compiled template.\n       *\n       * @memberOf _.templateSettings\n       * @type {Object}\n       */\n      'imports': {\n\n        /**\n         * A reference to the `lodash` function.\n         *\n         * @memberOf _.templateSettings.imports\n         * @type {Function}\n         */\n        '_': lodash\n      }\n    };\n\n    // Ensure wrappers are instances of `baseLodash`.\n    lodash.prototype = baseLodash.prototype;\n    lodash.prototype.constructor = lodash;\n\n    LodashWrapper.prototype = baseCreate(baseLodash.prototype);\n    LodashWrapper.prototype.constructor = LodashWrapper;\n\n    /*------------------------------------------------------------------------*/\n\n    /**\n     * Creates a lazy wrapper object which wraps `value` to enable lazy evaluation.\n     *\n     * @private\n     * @constructor\n     * @param {*} value The value to wrap.\n     */\n    function LazyWrapper(value) {\n      this.__wrapped__ = value;\n      this.__actions__ = [];\n      this.__dir__ = 1;\n      this.__filtered__ = false;\n      this.__iteratees__ = [];\n      this.__takeCount__ = MAX_ARRAY_LENGTH;\n      this.__views__ = [];\n    }\n\n    /**\n     * Creates a clone of the lazy wrapper object.\n     *\n     * @private\n     * @name clone\n     * @memberOf LazyWrapper\n     * @returns {Object} Returns the cloned `LazyWrapper` object.\n     */\n    function lazyClone() {\n      var result = new LazyWrapper(this.__wrapped__);\n      result.__actions__ = copyArray(this.__actions__);\n      result.__dir__ = this.__dir__;\n      result.__filtered__ = this.__filtered__;\n      result.__iteratees__ = copyArray(this.__iteratees__);\n      result.__takeCount__ = this.__takeCount__;\n      result.__views__ = copyArray(this.__views__);\n      return result;\n    }\n\n    /**\n     * Reverses the direction of lazy iteration.\n     *\n     * @private\n     * @name reverse\n     * @memberOf LazyWrapper\n     * @returns {Object} Returns the new reversed `LazyWrapper` object.\n     */\n    function lazyReverse() {\n      if (this.__filtered__) {\n        var result = new LazyWrapper(this);\n        result.__dir__ = -1;\n        result.__filtered__ = true;\n      } else {\n        result = this.clone();\n        result.__dir__ *= -1;\n      }\n      return result;\n    }\n\n    /**\n     * Extracts the unwrapped value from its lazy wrapper.\n     *\n     * @private\n     * @name value\n     * @memberOf LazyWrapper\n     * @returns {*} Returns the unwrapped value.\n     */\n    function lazyValue() {\n      var array = this.__wrapped__.value(),\n          dir = this.__dir__,\n          isArr = isArray(array),\n          isRight = dir < 0,\n          arrLength = isArr ? array.length : 0,\n          view = getView(0, arrLength, this.__views__),\n          start = view.start,\n          end = view.end,\n          length = end - start,\n          index = isRight ? end : (start - 1),\n          iteratees = this.__iteratees__,\n          iterLength = iteratees.length,\n          resIndex = 0,\n          takeCount = nativeMin(length, this.__takeCount__);\n\n      if (!isArr || (!isRight && arrLength == length && takeCount == length)) {\n        return baseWrapperValue(array, this.__actions__);\n      }\n      var result = [];\n\n      outer:\n      while (length-- && resIndex < takeCount) {\n        index += dir;\n\n        var iterIndex = -1,\n            value = array[index];\n\n        while (++iterIndex < iterLength) {\n          var data = iteratees[iterIndex],\n              iteratee = data.iteratee,\n              type = data.type,\n              computed = iteratee(value);\n\n          if (type == LAZY_MAP_FLAG) {\n            value = computed;\n          } else if (!computed) {\n            if (type == LAZY_FILTER_FLAG) {\n              continue outer;\n            } else {\n              break outer;\n            }\n          }\n        }\n        result[resIndex++] = value;\n      }\n      return result;\n    }\n\n    // Ensure `LazyWrapper` is an instance of `baseLodash`.\n    LazyWrapper.prototype = baseCreate(baseLodash.prototype);\n    LazyWrapper.prototype.constructor = LazyWrapper;\n\n    /*------------------------------------------------------------------------*/\n\n    /**\n     * Creates a hash object.\n     *\n     * @private\n     * @constructor\n     * @param {Array} [entries] The key-value pairs to cache.\n     */\n    function Hash(entries) {\n      var index = -1,\n          length = entries == null ? 0 : entries.length;\n\n      this.clear();\n      while (++index < length) {\n        var entry = entries[index];\n        this.set(entry[0], entry[1]);\n      }\n    }\n\n    /**\n     * Removes all key-value entries from the hash.\n     *\n     * @private\n     * @name clear\n     * @memberOf Hash\n     */\n    function hashClear() {\n      this.__data__ = nativeCreate ? nativeCreate(null) : {};\n      this.size = 0;\n    }\n\n    /**\n     * Removes `key` and its value from the hash.\n     *\n     * @private\n     * @name delete\n     * @memberOf Hash\n     * @param {Object} hash The hash to modify.\n     * @param {string} key The key of the value to remove.\n     * @returns {boolean} Returns `true` if the entry was removed, else `false`.\n     */\n    function hashDelete(key) {\n      var result = this.has(key) && delete this.__data__[key];\n      this.size -= result ? 1 : 0;\n      return result;\n    }\n\n    /**\n     * Gets the hash value for `key`.\n     *\n     * @private\n     * @name get\n     * @memberOf Hash\n     * @param {string} key The key of the value to get.\n     * @returns {*} Returns the entry value.\n     */\n    function hashGet(key) {\n      var data = this.__data__;\n      if (nativeCreate) {\n        var result = data[key];\n        return result === HASH_UNDEFINED ? undefined : result;\n      }\n      return hasOwnProperty.call(data, key) ? data[key] : undefined;\n    }\n\n    /**\n     * Checks if a hash value for `key` exists.\n     *\n     * @private\n     * @name has\n     * @memberOf Hash\n     * @param {string} key The key of the entry to check.\n     * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.\n     */\n    function hashHas(key) {\n      var data = this.__data__;\n      return nativeCreate ? (data[key] !== undefined) : hasOwnProperty.call(data, key);\n    }\n\n    /**\n     * Sets the hash `key` to `value`.\n     *\n     * @private\n     * @name set\n     * @memberOf Hash\n     * @param {string} key The key of the value to set.\n     * @param {*} value The value to set.\n     * @returns {Object} Returns the hash instance.\n     */\n    function hashSet(key, value) {\n      var data = this.__data__;\n      this.size += this.has(key) ? 0 : 1;\n      data[key] = (nativeCreate && value === undefined) ? HASH_UNDEFINED : value;\n      return this;\n    }\n\n    // Add methods to `Hash`.\n    Hash.prototype.clear = hashClear;\n    Hash.prototype['delete'] = hashDelete;\n    Hash.prototype.get = hashGet;\n    Hash.prototype.has = hashHas;\n    Hash.prototype.set = hashSet;\n\n    /*------------------------------------------------------------------------*/\n\n    /**\n     * Creates an list cache object.\n     *\n     * @private\n     * @constructor\n     * @param {Array} [entries] The key-value pairs to cache.\n     */\n    function ListCache(entries) {\n      var index = -1,\n          length = entries == null ? 0 : entries.length;\n\n      this.clear();\n      while (++index < length) {\n        var entry = entries[index];\n        this.set(entry[0], entry[1]);\n      }\n    }\n\n    /**\n     * Removes all key-value entries from the list cache.\n     *\n     * @private\n     * @name clear\n     * @memberOf ListCache\n     */\n    function listCacheClear() {\n      this.__data__ = [];\n      this.size = 0;\n    }\n\n    /**\n     * Removes `key` and its value from the list cache.\n     *\n     * @private\n     * @name delete\n     * @memberOf ListCache\n     * @param {string} key The key of the value to remove.\n     * @returns {boolean} Returns `true` if the entry was removed, else `false`.\n     */\n    function listCacheDelete(key) {\n      var data = this.__data__,\n          index = assocIndexOf(data, key);\n\n      if (index < 0) {\n        return false;\n      }\n      var lastIndex = data.length - 1;\n      if (index == lastIndex) {\n        data.pop();\n      } else {\n        splice.call(data, index, 1);\n      }\n      --this.size;\n      return true;\n    }\n\n    /**\n     * Gets the list cache value for `key`.\n     *\n     * @private\n     * @name get\n     * @memberOf ListCache\n     * @param {string} key The key of the value to get.\n     * @returns {*} Returns the entry value.\n     */\n    function listCacheGet(key) {\n      var data = this.__data__,\n          index = assocIndexOf(data, key);\n\n      return index < 0 ? undefined : data[index][1];\n    }\n\n    /**\n     * Checks if a list cache value for `key` exists.\n     *\n     * @private\n     * @name has\n     * @memberOf ListCache\n     * @param {string} key The key of the entry to check.\n     * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.\n     */\n    function listCacheHas(key) {\n      return assocIndexOf(this.__data__, key) > -1;\n    }\n\n    /**\n     * Sets the list cache `key` to `value`.\n     *\n     * @private\n     * @name set\n     * @memberOf ListCache\n     * @param {string} key The key of the value to set.\n     * @param {*} value The value to set.\n     * @returns {Object} Returns the list cache instance.\n     */\n    function listCacheSet(key, value) {\n      var data = this.__data__,\n          index = assocIndexOf(data, key);\n\n      if (index < 0) {\n        ++this.size;\n        data.push([key, value]);\n      } else {\n        data[index][1] = value;\n      }\n      return this;\n    }\n\n    // Add methods to `ListCache`.\n    ListCache.prototype.clear = listCacheClear;\n    ListCache.prototype['delete'] = listCacheDelete;\n    ListCache.prototype.get = listCacheGet;\n    ListCache.prototype.has = listCacheHas;\n    ListCache.prototype.set = listCacheSet;\n\n    /*------------------------------------------------------------------------*/\n\n    /**\n     * Creates a map cache object to store key-value pairs.\n     *\n     * @private\n     * @constructor\n     * @param {Array} [entries] The key-value pairs to cache.\n     */\n    function MapCache(entries) {\n      var index = -1,\n          length = entries == null ? 0 : entries.length;\n\n      this.clear();\n      while (++index < length) {\n        var entry = entries[index];\n        this.set(entry[0], entry[1]);\n      }\n    }\n\n    /**\n     * Removes all key-value entries from the map.\n     *\n     * @private\n     * @name clear\n     * @memberOf MapCache\n     */\n    function mapCacheClear() {\n      this.size = 0;\n      this.__data__ = {\n        'hash': new Hash,\n        'map': new (Map || ListCache),\n        'string': new Hash\n      };\n    }\n\n    /**\n     * Removes `key` and its value from the map.\n     *\n     * @private\n     * @name delete\n     * @memberOf MapCache\n     * @param {string} key The key of the value to remove.\n     * @returns {boolean} Returns `true` if the entry was removed, else `false`.\n     */\n    function mapCacheDelete(key) {\n      var result = getMapData(this, key)['delete'](key);\n      this.size -= result ? 1 : 0;\n      return result;\n    }\n\n    /**\n     * Gets the map value for `key`.\n     *\n     * @private\n     * @name get\n     * @memberOf MapCache\n     * @param {string} key The key of the value to get.\n     * @returns {*} Returns the entry value.\n     */\n    function mapCacheGet(key) {\n      return getMapData(this, key).get(key);\n    }\n\n    /**\n     * Checks if a map value for `key` exists.\n     *\n     * @private\n     * @name has\n     * @memberOf MapCache\n     * @param {string} key The key of the entry to check.\n     * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.\n     */\n    function mapCacheHas(key) {\n      return getMapData(this, key).has(key);\n    }\n\n    /**\n     * Sets the map `key` to `value`.\n     *\n     * @private\n     * @name set\n     * @memberOf MapCache\n     * @param {string} key The key of the value to set.\n     * @param {*} value The value to set.\n     * @returns {Object} Returns the map cache instance.\n     */\n    function mapCacheSet(key, value) {\n      var data = getMapData(this, key),\n          size = data.size;\n\n      data.set(key, value);\n      this.size += data.size == size ? 0 : 1;\n      return this;\n    }\n\n    // Add methods to `MapCache`.\n    MapCache.prototype.clear = mapCacheClear;\n    MapCache.prototype['delete'] = mapCacheDelete;\n    MapCache.prototype.get = mapCacheGet;\n    MapCache.prototype.has = mapCacheHas;\n    MapCache.prototype.set = mapCacheSet;\n\n    /*------------------------------------------------------------------------*/\n\n    /**\n     *\n     * Creates an array cache object to store unique values.\n     *\n     * @private\n     * @constructor\n     * @param {Array} [values] The values to cache.\n     */\n    function SetCache(values) {\n      var index = -1,\n          length = values == null ? 0 : values.length;\n\n      this.__data__ = new MapCache;\n      while (++index < length) {\n        this.add(values[index]);\n      }\n    }\n\n    /**\n     * Adds `value` to the array cache.\n     *\n     * @private\n     * @name add\n     * @memberOf SetCache\n     * @alias push\n     * @param {*} value The value to cache.\n     * @returns {Object} Returns the cache instance.\n     */\n    function setCacheAdd(value) {\n      this.__data__.set(value, HASH_UNDEFINED);\n      return this;\n    }\n\n    /**\n     * Checks if `value` is in the array cache.\n     *\n     * @private\n     * @name has\n     * @memberOf SetCache\n     * @param {*} value The value to search for.\n     * @returns {number} Returns `true` if `value` is found, else `false`.\n     */\n    function setCacheHas(value) {\n      return this.__data__.has(value);\n    }\n\n    // Add methods to `SetCache`.\n    SetCache.prototype.add = SetCache.prototype.push = setCacheAdd;\n    SetCache.prototype.has = setCacheHas;\n\n    /*------------------------------------------------------------------------*/\n\n    /**\n     * Creates a stack cache object to store key-value pairs.\n     *\n     * @private\n     * @constructor\n     * @param {Array} [entries] The key-value pairs to cache.\n     */\n    function Stack(entries) {\n      var data = this.__data__ = new ListCache(entries);\n      this.size = data.size;\n    }\n\n    /**\n     * Removes all key-value entries from the stack.\n     *\n     * @private\n     * @name clear\n     * @memberOf Stack\n     */\n    function stackClear() {\n      this.__data__ = new ListCache;\n      this.size = 0;\n    }\n\n    /**\n     * Removes `key` and its value from the stack.\n     *\n     * @private\n     * @name delete\n     * @memberOf Stack\n     * @param {string} key The key of the value to remove.\n     * @returns {boolean} Returns `true` if the entry was removed, else `false`.\n     */\n    function stackDelete(key) {\n      var data = this.__data__,\n          result = data['delete'](key);\n\n      this.size = data.size;\n      return result;\n    }\n\n    /**\n     * Gets the stack value for `key`.\n     *\n     * @private\n     * @name get\n     * @memberOf Stack\n     * @param {string} key The key of the value to get.\n     * @returns {*} Returns the entry value.\n     */\n    function stackGet(key) {\n      return this.__data__.get(key);\n    }\n\n    /**\n     * Checks if a stack value for `key` exists.\n     *\n     * @private\n     * @name has\n     * @memberOf Stack\n     * @param {string} key The key of the entry to check.\n     * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.\n     */\n    function stackHas(key) {\n      return this.__data__.has(key);\n    }\n\n    /**\n     * Sets the stack `key` to `value`.\n     *\n     * @private\n     * @name set\n     * @memberOf Stack\n     * @param {string} key The key of the value to set.\n     * @param {*} value The value to set.\n     * @returns {Object} Returns the stack cache instance.\n     */\n    function stackSet(key, value) {\n      var data = this.__data__;\n      if (data instanceof ListCache) {\n        var pairs = data.__data__;\n        if (!Map || (pairs.length < LARGE_ARRAY_SIZE - 1)) {\n          pairs.push([key, value]);\n          this.size = ++data.size;\n          return this;\n        }\n        data = this.__data__ = new MapCache(pairs);\n      }\n      data.set(key, value);\n      this.size = data.size;\n      return this;\n    }\n\n    // Add methods to `Stack`.\n    Stack.prototype.clear = stackClear;\n    Stack.prototype['delete'] = stackDelete;\n    Stack.prototype.get = stackGet;\n    Stack.prototype.has = stackHas;\n    Stack.prototype.set = stackSet;\n\n    /*------------------------------------------------------------------------*/\n\n    /**\n     * Creates an array of the enumerable property names of the array-like `value`.\n     *\n     * @private\n     * @param {*} value The value to query.\n     * @param {boolean} inherited Specify returning inherited property names.\n     * @returns {Array} Returns the array of property names.\n     */\n    function arrayLikeKeys(value, inherited) {\n      var isArr = isArray(value),\n          isArg = !isArr && isArguments(value),\n          isBuff = !isArr && !isArg && isBuffer(value),\n          isType = !isArr && !isArg && !isBuff && isTypedArray(value),\n          skipIndexes = isArr || isArg || isBuff || isType,\n          result = skipIndexes ? baseTimes(value.length, String) : [],\n          length = result.length;\n\n      for (var key in value) {\n        if ((inherited || hasOwnProperty.call(value, key)) &&\n            !(skipIndexes && (\n               // Safari 9 has enumerable `arguments.length` in strict mode.\n               key == 'length' ||\n               // Node.js 0.10 has enumerable non-index properties on buffers.\n               (isBuff && (key == 'offset' || key == 'parent')) ||\n               // PhantomJS 2 has enumerable non-index properties on typed arrays.\n               (isType && (key == 'buffer' || key == 'byteLength' || key == 'byteOffset')) ||\n               // Skip index properties.\n               isIndex(key, length)\n            ))) {\n          result.push(key);\n        }\n      }\n      return result;\n    }\n\n    /**\n     * A specialized version of `_.sample` for arrays.\n     *\n     * @private\n     * @param {Array} array The array to sample.\n     * @returns {*} Returns the random element.\n     */\n    function arraySample(array) {\n      var length = array.length;\n      return length ? array[baseRandom(0, length - 1)] : undefined;\n    }\n\n    /**\n     * A specialized version of `_.sampleSize` for arrays.\n     *\n     * @private\n     * @param {Array} array The array to sample.\n     * @param {number} n The number of elements to sample.\n     * @returns {Array} Returns the random elements.\n     */\n    function arraySampleSize(array, n) {\n      return shuffleSelf(copyArray(array), baseClamp(n, 0, array.length));\n    }\n\n    /**\n     * A specialized version of `_.shuffle` for arrays.\n     *\n     * @private\n     * @param {Array} array The array to shuffle.\n     * @returns {Array} Returns the new shuffled array.\n     */\n    function arrayShuffle(array) {\n      return shuffleSelf(copyArray(array));\n    }\n\n    /**\n     * This function is like `assignValue` except that it doesn't assign\n     * `undefined` values.\n     *\n     * @private\n     * @param {Object} object The object to modify.\n     * @param {string} key The key of the property to assign.\n     * @param {*} value The value to assign.\n     */\n    function assignMergeValue(object, key, value) {\n      if ((value !== undefined && !eq(object[key], value)) ||\n          (value === undefined && !(key in object))) {\n        baseAssignValue(object, key, value);\n      }\n    }\n\n    /**\n     * Assigns `value` to `key` of `object` if the existing value is not equivalent\n     * using [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)\n     * for equality comparisons.\n     *\n     * @private\n     * @param {Object} object The object to modify.\n     * @param {string} key The key of the property to assign.\n     * @param {*} value The value to assign.\n     */\n    function assignValue(object, key, value) {\n      var objValue = object[key];\n      if (!(hasOwnProperty.call(object, key) && eq(objValue, value)) ||\n          (value === undefined && !(key in object))) {\n        baseAssignValue(object, key, value);\n      }\n    }\n\n    /**\n     * Gets the index at which the `key` is found in `array` of key-value pairs.\n     *\n     * @private\n     * @param {Array} array The array to inspect.\n     * @param {*} key The key to search for.\n     * @returns {number} Returns the index of the matched value, else `-1`.\n     */\n    function assocIndexOf(array, key) {\n      var length = array.length;\n      while (length--) {\n        if (eq(array[length][0], key)) {\n          return length;\n        }\n      }\n      return -1;\n    }\n\n    /**\n     * Aggregates elements of `collection` on `accumulator` with keys transformed\n     * by `iteratee` and values set by `setter`.\n     *\n     * @private\n     * @param {Array|Object} collection The collection to iterate over.\n     * @param {Function} setter The function to set `accumulator` values.\n     * @param {Function} iteratee The iteratee to transform keys.\n     * @param {Object} accumulator The initial aggregated object.\n     * @returns {Function} Returns `accumulator`.\n     */\n    function baseAggregator(collection, setter, iteratee, accumulator) {\n      baseEach(collection, function(value, key, collection) {\n        setter(accumulator, value, iteratee(value), collection);\n      });\n      return accumulator;\n    }\n\n    /**\n     * The base implementation of `_.assign` without support for multiple sources\n     * or `customizer` functions.\n     *\n     * @private\n     * @param {Object} object The destination object.\n     * @param {Object} source The source object.\n     * @returns {Object} Returns `object`.\n     */\n    function baseAssign(object, source) {\n      return object && copyObject(source, keys(source), object);\n    }\n\n    /**\n     * The base implementation of `_.assignIn` without support for multiple sources\n     * or `customizer` functions.\n     *\n     * @private\n     * @param {Object} object The destination object.\n     * @param {Object} source The source object.\n     * @returns {Object} Returns `object`.\n     */\n    function baseAssignIn(object, source) {\n      return object && copyObject(source, keysIn(source), object);\n    }\n\n    /**\n     * The base implementation of `assignValue` and `assignMergeValue` without\n     * value checks.\n     *\n     * @private\n     * @param {Object} object The object to modify.\n     * @param {string} key The key of the property to assign.\n     * @param {*} value The value to assign.\n     */\n    function baseAssignValue(object, key, value) {\n      if (key == '__proto__' && defineProperty) {\n        defineProperty(object, key, {\n          'configurable': true,\n          'enumerable': true,\n          'value': value,\n          'writable': true\n        });\n      } else {\n        object[key] = value;\n      }\n    }\n\n    /**\n     * The base implementation of `_.at` without support for individual paths.\n     *\n     * @private\n     * @param {Object} object The object to iterate over.\n     * @param {string[]} paths The property paths to pick.\n     * @returns {Array} Returns the picked elements.\n     */\n    function baseAt(object, paths) {\n      var index = -1,\n          length = paths.length,\n          result = Array(length),\n          skip = object == null;\n\n      while (++index < length) {\n        result[index] = skip ? undefined : get(object, paths[index]);\n      }\n      return result;\n    }\n\n    /**\n     * The base implementation of `_.clamp` which doesn't coerce arguments.\n     *\n     * @private\n     * @param {number} number The number to clamp.\n     * @param {number} [lower] The lower bound.\n     * @param {number} upper The upper bound.\n     * @returns {number} Returns the clamped number.\n     */\n    function baseClamp(number, lower, upper) {\n      if (number === number) {\n        if (upper !== undefined) {\n          number = number <= upper ? number : upper;\n        }\n        if (lower !== undefined) {\n          number = number >= lower ? number : lower;\n        }\n      }\n      return number;\n    }\n\n    /**\n     * The base implementation of `_.clone` and `_.cloneDeep` which tracks\n     * traversed objects.\n     *\n     * @private\n     * @param {*} value The value to clone.\n     * @param {boolean} bitmask The bitmask flags.\n     *  1 - Deep clone\n     *  2 - Flatten inherited properties\n     *  4 - Clone symbols\n     * @param {Function} [customizer] The function to customize cloning.\n     * @param {string} [key] The key of `value`.\n     * @param {Object} [object] The parent object of `value`.\n     * @param {Object} [stack] Tracks traversed objects and their clone counterparts.\n     * @returns {*} Returns the cloned value.\n     */\n    function baseClone(value, bitmask, customizer, key, object, stack) {\n      var result,\n          isDeep = bitmask & CLONE_DEEP_FLAG,\n          isFlat = bitmask & CLONE_FLAT_FLAG,\n          isFull = bitmask & CLONE_SYMBOLS_FLAG;\n\n      if (customizer) {\n        result = object ? customizer(value, key, object, stack) : customizer(value);\n      }\n      if (result !== undefined) {\n        return result;\n      }\n      if (!isObject(value)) {\n        return value;\n      }\n      var isArr = isArray(value);\n      if (isArr) {\n        result = initCloneArray(value);\n        if (!isDeep) {\n          return copyArray(value, result);\n        }\n      } else {\n        var tag = getTag(value),\n            isFunc = tag == funcTag || tag == genTag;\n\n        if (isBuffer(value)) {\n          return cloneBuffer(value, isDeep);\n        }\n        if (tag == objectTag || tag == argsTag || (isFunc && !object)) {\n          result = (isFlat || isFunc) ? {} : initCloneObject(value);\n          if (!isDeep) {\n            return isFlat\n              ? copySymbolsIn(value, baseAssignIn(result, value))\n              : copySymbols(value, baseAssign(result, value));\n          }\n        } else {\n          if (!cloneableTags[tag]) {\n            return object ? value : {};\n          }\n          result = initCloneByTag(value, tag, isDeep);\n        }\n      }\n      // Check for circular references and return its corresponding clone.\n      stack || (stack = new Stack);\n      var stacked = stack.get(value);\n      if (stacked) {\n        return stacked;\n      }\n      stack.set(value, result);\n\n      if (isSet(value)) {\n        value.forEach(function(subValue) {\n          result.add(baseClone(subValue, bitmask, customizer, subValue, value, stack));\n        });\n\n        return result;\n      }\n\n      if (isMap(value)) {\n        value.forEach(function(subValue, key) {\n          result.set(key, baseClone(subValue, bitmask, customizer, key, value, stack));\n        });\n\n        return result;\n      }\n\n      var keysFunc = isFull\n        ? (isFlat ? getAllKeysIn : getAllKeys)\n        : (isFlat ? keysIn : keys);\n\n      var props = isArr ? undefined : keysFunc(value);\n      arrayEach(props || value, function(subValue, key) {\n        if (props) {\n          key = subValue;\n          subValue = value[key];\n        }\n        // Recursively populate clone (susceptible to call stack limits).\n        assignValue(result, key, baseClone(subValue, bitmask, customizer, key, value, stack));\n      });\n      return result;\n    }\n\n    /**\n     * The base implementation of `_.conforms` which doesn't clone `source`.\n     *\n     * @private\n     * @param {Object} source The object of property predicates to conform to.\n     * @returns {Function} Returns the new spec function.\n     */\n    function baseConforms(source) {\n      var props = keys(source);\n      return function(object) {\n        return baseConformsTo(object, source, props);\n      };\n    }\n\n    /**\n     * The base implementation of `_.conformsTo` which accepts `props` to check.\n     *\n     * @private\n     * @param {Object} object The object to inspect.\n     * @param {Object} source The object of property predicates to conform to.\n     * @returns {boolean} Returns `true` if `object` conforms, else `false`.\n     */\n    function baseConformsTo(object, source, props) {\n      var length = props.length;\n      if (object == null) {\n        return !length;\n      }\n      object = Object(object);\n      while (length--) {\n        var key = props[length],\n            predicate = source[key],\n            value = object[key];\n\n        if ((value === undefined && !(key in object)) || !predicate(value)) {\n          return false;\n        }\n      }\n      return true;\n    }\n\n    /**\n     * The base implementation of `_.delay` and `_.defer` which accepts `args`\n     * to provide to `func`.\n     *\n     * @private\n     * @param {Function} func The function to delay.\n     * @param {number} wait The number of milliseconds to delay invocation.\n     * @param {Array} args The arguments to provide to `func`.\n     * @returns {number|Object} Returns the timer id or timeout object.\n     */\n    function baseDelay(func, wait, args) {\n      if (typeof func != 'function') {\n        throw new TypeError(FUNC_ERROR_TEXT);\n      }\n      return setTimeout(function() { func.apply(undefined, args); }, wait);\n    }\n\n    /**\n     * The base implementation of methods like `_.difference` without support\n     * for excluding multiple arrays or iteratee shorthands.\n     *\n     * @private\n     * @param {Array} array The array to inspect.\n     * @param {Array} values The values to exclude.\n     * @param {Function} [iteratee] The iteratee invoked per element.\n     * @param {Function} [comparator] The comparator invoked per element.\n     * @returns {Array} Returns the new array of filtered values.\n     */\n    function baseDifference(array, values, iteratee, comparator) {\n      var index = -1,\n          includes = arrayIncludes,\n          isCommon = true,\n          length = array.length,\n          result = [],\n          valuesLength = values.length;\n\n      if (!length) {\n        return result;\n      }\n      if (iteratee) {\n        values = arrayMap(values, baseUnary(iteratee));\n      }\n      if (comparator) {\n        includes = arrayIncludesWith;\n        isCommon = false;\n      }\n      else if (values.length >= LARGE_ARRAY_SIZE) {\n        includes = cacheHas;\n        isCommon = false;\n        values = new SetCache(values);\n      }\n      outer:\n      while (++index < length) {\n        var value = array[index],\n            computed = iteratee == null ? value : iteratee(value);\n\n        value = (comparator || value !== 0) ? value : 0;\n        if (isCommon && computed === computed) {\n          var valuesIndex = valuesLength;\n          while (valuesIndex--) {\n            if (values[valuesIndex] === computed) {\n              continue outer;\n            }\n          }\n          result.push(value);\n        }\n        else if (!includes(values, computed, comparator)) {\n          result.push(value);\n        }\n      }\n      return result;\n    }\n\n    /**\n     * The base implementation of `_.forEach` without support for iteratee shorthands.\n     *\n     * @private\n     * @param {Array|Object} collection The collection to iterate over.\n     * @param {Function} iteratee The function invoked per iteration.\n     * @returns {Array|Object} Returns `collection`.\n     */\n    var baseEach = createBaseEach(baseForOwn);\n\n    /**\n     * The base implementation of `_.forEachRight` without support for iteratee shorthands.\n     *\n     * @private\n     * @param {Array|Object} collection The collection to iterate over.\n     * @param {Function} iteratee The function invoked per iteration.\n     * @returns {Array|Object} Returns `collection`.\n     */\n    var baseEachRight = createBaseEach(baseForOwnRight, true);\n\n    /**\n     * The base implementation of `_.every` without support for iteratee shorthands.\n     *\n     * @private\n     * @param {Array|Object} collection The collection to iterate over.\n     * @param {Function} predicate The function invoked per iteration.\n     * @returns {boolean} Returns `true` if all elements pass the predicate check,\n     *  else `false`\n     */\n    function baseEvery(collection, predicate) {\n      var result = true;\n      baseEach(collection, function(value, index, collection) {\n        result = !!predicate(value, index, collection);\n        return result;\n      });\n      return result;\n    }\n\n    /**\n     * The base implementation of methods like `_.max` and `_.min` which accepts a\n     * `comparator` to determine the extremum value.\n     *\n     * @private\n     * @param {Array} array The array to iterate over.\n     * @param {Function} iteratee The iteratee invoked per iteration.\n     * @param {Function} comparator The comparator used to compare values.\n     * @returns {*} Returns the extremum value.\n     */\n    function baseExtremum(array, iteratee, comparator) {\n      var index = -1,\n          length = array.length;\n\n      while (++index < length) {\n        var value = array[index],\n            current = iteratee(value);\n\n        if (current != null && (computed === undefined\n              ? (current === current && !isSymbol(current))\n              : comparator(current, computed)\n            )) {\n          var computed = current,\n              result = value;\n        }\n      }\n      return result;\n    }\n\n    /**\n     * The base implementation of `_.fill` without an iteratee call guard.\n     *\n     * @private\n     * @param {Array} array The array to fill.\n     * @param {*} value The value to fill `array` with.\n     * @param {number} [start=0] The start position.\n     * @param {number} [end=array.length] The end position.\n     * @returns {Array} Returns `array`.\n     */\n    function baseFill(array, value, start, end) {\n      var length = array.length;\n\n      start = toInteger(start);\n      if (start < 0) {\n        start = -start > length ? 0 : (length + start);\n      }\n      end = (end === undefined || end > length) ? length : toInteger(end);\n      if (end < 0) {\n        end += length;\n      }\n      end = start > end ? 0 : toLength(end);\n      while (start < end) {\n        array[start++] = value;\n      }\n      return array;\n    }\n\n    /**\n     * The base implementation of `_.filter` without support for iteratee shorthands.\n     *\n     * @private\n     * @param {Array|Object} collection The collection to iterate over.\n     * @param {Function} predicate The function invoked per iteration.\n     * @returns {Array} Returns the new filtered array.\n     */\n    function baseFilter(collection, predicate) {\n      var result = [];\n      baseEach(collection, function(value, index, collection) {\n        if (predicate(value, index, collection)) {\n          result.push(value);\n        }\n      });\n      return result;\n    }\n\n    /**\n     * The base implementation of `_.flatten` with support for restricting flattening.\n     *\n     * @private\n     * @param {Array} array The array to flatten.\n     * @param {number} depth The maximum recursion depth.\n     * @param {boolean} [predicate=isFlattenable] The function invoked per iteration.\n     * @param {boolean} [isStrict] Restrict to values that pass `predicate` checks.\n     * @param {Array} [result=[]] The initial result value.\n     * @returns {Array} Returns the new flattened array.\n     */\n    function baseFlatten(array, depth, predicate, isStrict, result) {\n      var index = -1,\n          length = array.length;\n\n      predicate || (predicate = isFlattenable);\n      result || (result = []);\n\n      while (++index < length) {\n        var value = array[index];\n        if (depth > 0 && predicate(value)) {\n          if (depth > 1) {\n            // Recursively flatten arrays (susceptible to call stack limits).\n            baseFlatten(value, depth - 1, predicate, isStrict, result);\n          } else {\n            arrayPush(result, value);\n          }\n        } else if (!isStrict) {\n          result[result.length] = value;\n        }\n      }\n      return result;\n    }\n\n    /**\n     * The base implementation of `baseForOwn` which iterates over `object`\n     * properties returned by `keysFunc` and invokes `iteratee` for each property.\n     * Iteratee functions may exit iteration early by explicitly returning `false`.\n     *\n     * @private\n     * @param {Object} object The object to iterate over.\n     * @param {Function} iteratee The function invoked per iteration.\n     * @param {Function} keysFunc The function to get the keys of `object`.\n     * @returns {Object} Returns `object`.\n     */\n    var baseFor = createBaseFor();\n\n    /**\n     * This function is like `baseFor` except that it iterates over properties\n     * in the opposite order.\n     *\n     * @private\n     * @param {Object} object The object to iterate over.\n     * @param {Function} iteratee The function invoked per iteration.\n     * @param {Function} keysFunc The function to get the keys of `object`.\n     * @returns {Object} Returns `object`.\n     */\n    var baseForRight = createBaseFor(true);\n\n    /**\n     * The base implementation of `_.forOwn` without support for iteratee shorthands.\n     *\n     * @private\n     * @param {Object} object The object to iterate over.\n     * @param {Function} iteratee The function invoked per iteration.\n     * @returns {Object} Returns `object`.\n     */\n    function baseForOwn(object, iteratee) {\n      return object && baseFor(object, iteratee, keys);\n    }\n\n    /**\n     * The base implementation of `_.forOwnRight` without support for iteratee shorthands.\n     *\n     * @private\n     * @param {Object} object The object to iterate over.\n     * @param {Function} iteratee The function invoked per iteration.\n     * @returns {Object} Returns `object`.\n     */\n    function baseForOwnRight(object, iteratee) {\n      return object && baseForRight(object, iteratee, keys);\n    }\n\n    /**\n     * The base implementation of `_.functions` which creates an array of\n     * `object` function property names filtered from `props`.\n     *\n     * @private\n     * @param {Object} object The object to inspect.\n     * @param {Array} props The property names to filter.\n     * @returns {Array} Returns the function names.\n     */\n    function baseFunctions(object, props) {\n      return arrayFilter(props, function(key) {\n        return isFunction(object[key]);\n      });\n    }\n\n    /**\n     * The base implementation of `_.get` without support for default values.\n     *\n     * @private\n     * @param {Object} object The object to query.\n     * @param {Array|string} path The path of the property to get.\n     * @returns {*} Returns the resolved value.\n     */\n    function baseGet(object, path) {\n      path = castPath(path, object);\n\n      var index = 0,\n          length = path.length;\n\n      while (object != null && index < length) {\n        object = object[toKey(path[index++])];\n      }\n      return (index && index == length) ? object : undefined;\n    }\n\n    /**\n     * The base implementation of `getAllKeys` and `getAllKeysIn` which uses\n     * `keysFunc` and `symbolsFunc` to get the enumerable property names and\n     * symbols of `object`.\n     *\n     * @private\n     * @param {Object} object The object to query.\n     * @param {Function} keysFunc The function to get the keys of `object`.\n     * @param {Function} symbolsFunc The function to get the symbols of `object`.\n     * @returns {Array} Returns the array of property names and symbols.\n     */\n    function baseGetAllKeys(object, keysFunc, symbolsFunc) {\n      var result = keysFunc(object);\n      return isArray(object) ? result : arrayPush(result, symbolsFunc(object));\n    }\n\n    /**\n     * The base implementation of `getTag` without fallbacks for buggy environments.\n     *\n     * @private\n     * @param {*} value The value to query.\n     * @returns {string} Returns the `toStringTag`.\n     */\n    function baseGetTag(value) {\n      if (value == null) {\n        return value === undefined ? undefinedTag : nullTag;\n      }\n      return (symToStringTag && symToStringTag in Object(value))\n        ? getRawTag(value)\n        : objectToString(value);\n    }\n\n    /**\n     * The base implementation of `_.gt` which doesn't coerce arguments.\n     *\n     * @private\n     * @param {*} value The value to compare.\n     * @param {*} other The other value to compare.\n     * @returns {boolean} Returns `true` if `value` is greater than `other`,\n     *  else `false`.\n     */\n    function baseGt(value, other) {\n      return value > other;\n    }\n\n    /**\n     * The base implementation of `_.has` without support for deep paths.\n     *\n     * @private\n     * @param {Object} [object] The object to query.\n     * @param {Array|string} key The key to check.\n     * @returns {boolean} Returns `true` if `key` exists, else `false`.\n     */\n    function baseHas(object, key) {\n      return object != null && hasOwnProperty.call(object, key);\n    }\n\n    /**\n     * The base implementation of `_.hasIn` without support for deep paths.\n     *\n     * @private\n     * @param {Object} [object] The object to query.\n     * @param {Array|string} key The key to check.\n     * @returns {boolean} Returns `true` if `key` exists, else `false`.\n     */\n    function baseHasIn(object, key) {\n      return object != null && key in Object(object);\n    }\n\n    /**\n     * The base implementation of `_.inRange` which doesn't coerce arguments.\n     *\n     * @private\n     * @param {number} number The number to check.\n     * @param {number} start The start of the range.\n     * @param {number} end The end of the range.\n     * @returns {boolean} Returns `true` if `number` is in the range, else `false`.\n     */\n    function baseInRange(number, start, end) {\n      return number >= nativeMin(start, end) && number < nativeMax(start, end);\n    }\n\n    /**\n     * The base implementation of methods like `_.intersection`, without support\n     * for iteratee shorthands, that accepts an array of arrays to inspect.\n     *\n     * @private\n     * @param {Array} arrays The arrays to inspect.\n     * @param {Function} [iteratee] The iteratee invoked per element.\n     * @param {Function} [comparator] The comparator invoked per element.\n     * @returns {Array} Returns the new array of shared values.\n     */\n    function baseIntersection(arrays, iteratee, comparator) {\n      var includes = comparator ? arrayIncludesWith : arrayIncludes,\n          length = arrays[0].length,\n          othLength = arrays.length,\n          othIndex = othLength,\n          caches = Array(othLength),\n          maxLength = Infinity,\n          result = [];\n\n      while (othIndex--) {\n        var array = arrays[othIndex];\n        if (othIndex && iteratee) {\n          array = arrayMap(array, baseUnary(iteratee));\n        }\n        maxLength = nativeMin(array.length, maxLength);\n        caches[othIndex] = !comparator && (iteratee || (length >= 120 && array.length >= 120))\n          ? new SetCache(othIndex && array)\n          : undefined;\n      }\n      array = arrays[0];\n\n      var index = -1,\n          seen = caches[0];\n\n      outer:\n      while (++index < length && result.length < maxLength) {\n        var value = array[index],\n            computed = iteratee ? iteratee(value) : value;\n\n        value = (comparator || value !== 0) ? value : 0;\n        if (!(seen\n              ? cacheHas(seen, computed)\n              : includes(result, computed, comparator)\n            )) {\n          othIndex = othLength;\n          while (--othIndex) {\n            var cache = caches[othIndex];\n            if (!(cache\n                  ? cacheHas(cache, computed)\n                  : includes(arrays[othIndex], computed, comparator))\n                ) {\n              continue outer;\n            }\n          }\n          if (seen) {\n            seen.push(computed);\n          }\n          result.push(value);\n        }\n      }\n      return result;\n    }\n\n    /**\n     * The base implementation of `_.invert` and `_.invertBy` which inverts\n     * `object` with values transformed by `iteratee` and set by `setter`.\n     *\n     * @private\n     * @param {Object} object The object to iterate over.\n     * @param {Function} setter The function to set `accumulator` values.\n     * @param {Function} iteratee The iteratee to transform values.\n     * @param {Object} accumulator The initial inverted object.\n     * @returns {Function} Returns `accumulator`.\n     */\n    function baseInverter(object, setter, iteratee, accumulator) {\n      baseForOwn(object, function(value, key, object) {\n        setter(accumulator, iteratee(value), key, object);\n      });\n      return accumulator;\n    }\n\n    /**\n     * The base implementation of `_.invoke` without support for individual\n     * method arguments.\n     *\n     * @private\n     * @param {Object} object The object to query.\n     * @param {Array|string} path The path of the method to invoke.\n     * @param {Array} args The arguments to invoke the method with.\n     * @returns {*} Returns the result of the invoked method.\n     */\n    function baseInvoke(object, path, args) {\n      path = castPath(path, object);\n      object = parent(object, path);\n      var func = object == null ? object : object[toKey(last(path))];\n      return func == null ? undefined : apply(func, object, args);\n    }\n\n    /**\n     * The base implementation of `_.isArguments`.\n     *\n     * @private\n     * @param {*} value The value to check.\n     * @returns {boolean} Returns `true` if `value` is an `arguments` object,\n     */\n    function baseIsArguments(value) {\n      return isObjectLike(value) && baseGetTag(value) == argsTag;\n    }\n\n    /**\n     * The base implementation of `_.isArrayBuffer` without Node.js optimizations.\n     *\n     * @private\n     * @param {*} value The value to check.\n     * @returns {boolean} Returns `true` if `value` is an array buffer, else `false`.\n     */\n    function baseIsArrayBuffer(value) {\n      return isObjectLike(value) && baseGetTag(value) == arrayBufferTag;\n    }\n\n    /**\n     * The base implementation of `_.isDate` without Node.js optimizations.\n     *\n     * @private\n     * @param {*} value The value to check.\n     * @returns {boolean} Returns `true` if `value` is a date object, else `false`.\n     */\n    function baseIsDate(value) {\n      return isObjectLike(value) && baseGetTag(value) == dateTag;\n    }\n\n    /**\n     * The base implementation of `_.isEqual` which supports partial comparisons\n     * and tracks traversed objects.\n     *\n     * @private\n     * @param {*} value The value to compare.\n     * @param {*} other The other value to compare.\n     * @param {boolean} bitmask The bitmask flags.\n     *  1 - Unordered comparison\n     *  2 - Partial comparison\n     * @param {Function} [customizer] The function to customize comparisons.\n     * @param {Object} [stack] Tracks traversed `value` and `other` objects.\n     * @returns {boolean} Returns `true` if the values are equivalent, else `false`.\n     */\n    function baseIsEqual(value, other, bitmask, customizer, stack) {\n      if (value === other) {\n        return true;\n      }\n      if (value == null || other == null || (!isObjectLike(value) && !isObjectLike(other))) {\n        return value !== value && other !== other;\n      }\n      return baseIsEqualDeep(value, other, bitmask, customizer, baseIsEqual, stack);\n    }\n\n    /**\n     * A specialized version of `baseIsEqual` for arrays and objects which performs\n     * deep comparisons and tracks traversed objects enabling objects with circular\n     * references to be compared.\n     *\n     * @private\n     * @param {Object} object The object to compare.\n     * @param {Object} other The other object to compare.\n     * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details.\n     * @param {Function} customizer The function to customize comparisons.\n     * @param {Function} equalFunc The function to determine equivalents of values.\n     * @param {Object} [stack] Tracks traversed `object` and `other` objects.\n     * @returns {boolean} Returns `true` if the objects are equivalent, else `false`.\n     */\n    function baseIsEqualDeep(object, other, bitmask, customizer, equalFunc, stack) {\n      var objIsArr = isArray(object),\n          othIsArr = isArray(other),\n          objTag = objIsArr ? arrayTag : getTag(object),\n          othTag = othIsArr ? arrayTag : getTag(other);\n\n      objTag = objTag == argsTag ? objectTag : objTag;\n      othTag = othTag == argsTag ? objectTag : othTag;\n\n      var objIsObj = objTag == objectTag,\n          othIsObj = othTag == objectTag,\n          isSameTag = objTag == othTag;\n\n      if (isSameTag && isBuffer(object)) {\n        if (!isBuffer(other)) {\n          return false;\n        }\n        objIsArr = true;\n        objIsObj = false;\n      }\n      if (isSameTag && !objIsObj) {\n        stack || (stack = new Stack);\n        return (objIsArr || isTypedArray(object))\n          ? equalArrays(object, other, bitmask, customizer, equalFunc, stack)\n          : equalByTag(object, other, objTag, bitmask, customizer, equalFunc, stack);\n      }\n      if (!(bitmask & COMPARE_PARTIAL_FLAG)) {\n        var objIsWrapped = objIsObj && hasOwnProperty.call(object, '__wrapped__'),\n            othIsWrapped = othIsObj && hasOwnProperty.call(other, '__wrapped__');\n\n        if (objIsWrapped || othIsWrapped) {\n          var objUnwrapped = objIsWrapped ? object.value() : object,\n              othUnwrapped = othIsWrapped ? other.value() : other;\n\n          stack || (stack = new Stack);\n          return equalFunc(objUnwrapped, othUnwrapped, bitmask, customizer, stack);\n        }\n      }\n      if (!isSameTag) {\n        return false;\n      }\n      stack || (stack = new Stack);\n      return equalObjects(object, other, bitmask, customizer, equalFunc, stack);\n    }\n\n    /**\n     * The base implementation of `_.isMap` without Node.js optimizations.\n     *\n     * @private\n     * @param {*} value The value to check.\n     * @returns {boolean} Returns `true` if `value` is a map, else `false`.\n     */\n    function baseIsMap(value) {\n      return isObjectLike(value) && getTag(value) == mapTag;\n    }\n\n    /**\n     * The base implementation of `_.isMatch` without support for iteratee shorthands.\n     *\n     * @private\n     * @param {Object} object The object to inspect.\n     * @param {Object} source The object of property values to match.\n     * @param {Array} matchData The property names, values, and compare flags to match.\n     * @param {Function} [customizer] The function to customize comparisons.\n     * @returns {boolean} Returns `true` if `object` is a match, else `false`.\n     */\n    function baseIsMatch(object, source, matchData, customizer) {\n      var index = matchData.length,\n          length = index,\n          noCustomizer = !customizer;\n\n      if (object == null) {\n        return !length;\n      }\n      object = Object(object);\n      while (index--) {\n        var data = matchData[index];\n        if ((noCustomizer && data[2])\n              ? data[1] !== object[data[0]]\n              : !(data[0] in object)\n            ) {\n          return false;\n        }\n      }\n      while (++index < length) {\n        data = matchData[index];\n        var key = data[0],\n            objValue = object[key],\n            srcValue = data[1];\n\n        if (noCustomizer && data[2]) {\n          if (objValue === undefined && !(key in object)) {\n            return false;\n          }\n        } else {\n          var stack = new Stack;\n          if (customizer) {\n            var result = customizer(objValue, srcValue, key, object, source, stack);\n          }\n          if (!(result === undefined\n                ? baseIsEqual(srcValue, objValue, COMPARE_PARTIAL_FLAG | COMPARE_UNORDERED_FLAG, customizer, stack)\n                : result\n              )) {\n            return false;\n          }\n        }\n      }\n      return true;\n    }\n\n    /**\n     * The base implementation of `_.isNative` without bad shim checks.\n     *\n     * @private\n     * @param {*} value The value to check.\n     * @returns {boolean} Returns `true` if `value` is a native function,\n     *  else `false`.\n     */\n    function baseIsNative(value) {\n      if (!isObject(value) || isMasked(value)) {\n        return false;\n      }\n      var pattern = isFunction(value) ? reIsNative : reIsHostCtor;\n      return pattern.test(toSource(value));\n    }\n\n    /**\n     * The base implementation of `_.isRegExp` without Node.js optimizations.\n     *\n     * @private\n     * @param {*} value The value to check.\n     * @returns {boolean} Returns `true` if `value` is a regexp, else `false`.\n     */\n    function baseIsRegExp(value) {\n      return isObjectLike(value) && baseGetTag(value) == regexpTag;\n    }\n\n    /**\n     * The base implementation of `_.isSet` without Node.js optimizations.\n     *\n     * @private\n     * @param {*} value The value to check.\n     * @returns {boolean} Returns `true` if `value` is a set, else `false`.\n     */\n    function baseIsSet(value) {\n      return isObjectLike(value) && getTag(value) == setTag;\n    }\n\n    /**\n     * The base implementation of `_.isTypedArray` without Node.js optimizations.\n     *\n     * @private\n     * @param {*} value The value to check.\n     * @returns {boolean} Returns `true` if `value` is a typed array, else `false`.\n     */\n    function baseIsTypedArray(value) {\n      return isObjectLike(value) &&\n        isLength(value.length) && !!typedArrayTags[baseGetTag(value)];\n    }\n\n    /**\n     * The base implementation of `_.iteratee`.\n     *\n     * @private\n     * @param {*} [value=_.identity] The value to convert to an iteratee.\n     * @returns {Function} Returns the iteratee.\n     */\n    function baseIteratee(value) {\n      // Don't store the `typeof` result in a variable to avoid a JIT bug in Safari 9.\n      // See https://bugs.webkit.org/show_bug.cgi?id=156034 for more details.\n      if (typeof value == 'function') {\n        return value;\n      }\n      if (value == null) {\n        return identity;\n      }\n      if (typeof value == 'object') {\n        return isArray(value)\n          ? baseMatchesProperty(value[0], value[1])\n          : baseMatches(value);\n      }\n      return property(value);\n    }\n\n    /**\n     * The base implementation of `_.keys` which doesn't treat sparse arrays as dense.\n     *\n     * @private\n     * @param {Object} object The object to query.\n     * @returns {Array} Returns the array of property names.\n     */\n    function baseKeys(object) {\n      if (!isPrototype(object)) {\n        return nativeKeys(object);\n      }\n      var result = [];\n      for (var key in Object(object)) {\n        if (hasOwnProperty.call(object, key) && key != 'constructor') {\n          result.push(key);\n        }\n      }\n      return result;\n    }\n\n    /**\n     * The base implementation of `_.keysIn` which doesn't treat sparse arrays as dense.\n     *\n     * @private\n     * @param {Object} object The object to query.\n     * @returns {Array} Returns the array of property names.\n     */\n    function baseKeysIn(object) {\n      if (!isObject(object)) {\n        return nativeKeysIn(object);\n      }\n      var isProto = isPrototype(object),\n          result = [];\n\n      for (var key in object) {\n        if (!(key == 'constructor' && (isProto || !hasOwnProperty.call(object, key)))) {\n          result.push(key);\n        }\n      }\n      return result;\n    }\n\n    /**\n     * The base implementation of `_.lt` which doesn't coerce arguments.\n     *\n     * @private\n     * @param {*} value The value to compare.\n     * @param {*} other The other value to compare.\n     * @returns {boolean} Returns `true` if `value` is less than `other`,\n     *  else `false`.\n     */\n    function baseLt(value, other) {\n      return value < other;\n    }\n\n    /**\n     * The base implementation of `_.map` without support for iteratee shorthands.\n     *\n     * @private\n     * @param {Array|Object} collection The collection to iterate over.\n     * @param {Function} iteratee The function invoked per iteration.\n     * @returns {Array} Returns the new mapped array.\n     */\n    function baseMap(collection, iteratee) {\n      var index = -1,\n          result = isArrayLike(collection) ? Array(collection.length) : [];\n\n      baseEach(collection, function(value, key, collection) {\n        result[++index] = iteratee(value, key, collection);\n      });\n      return result;\n    }\n\n    /**\n     * The base implementation of `_.matches` which doesn't clone `source`.\n     *\n     * @private\n     * @param {Object} source The object of property values to match.\n     * @returns {Function} Returns the new spec function.\n     */\n    function baseMatches(source) {\n      var matchData = getMatchData(source);\n      if (matchData.length == 1 && matchData[0][2]) {\n        return matchesStrictComparable(matchData[0][0], matchData[0][1]);\n      }\n      return function(object) {\n        return object === source || baseIsMatch(object, source, matchData);\n      };\n    }\n\n    /**\n     * The base implementation of `_.matchesProperty` which doesn't clone `srcValue`.\n     *\n     * @private\n     * @param {string} path The path of the property to get.\n     * @param {*} srcValue The value to match.\n     * @returns {Function} Returns the new spec function.\n     */\n    function baseMatchesProperty(path, srcValue) {\n      if (isKey(path) && isStrictComparable(srcValue)) {\n        return matchesStrictComparable(toKey(path), srcValue);\n      }\n      return function(object) {\n        var objValue = get(object, path);\n        return (objValue === undefined && objValue === srcValue)\n          ? hasIn(object, path)\n          : baseIsEqual(srcValue, objValue, COMPARE_PARTIAL_FLAG | COMPARE_UNORDERED_FLAG);\n      };\n    }\n\n    /**\n     * The base implementation of `_.merge` without support for multiple sources.\n     *\n     * @private\n     * @param {Object} object The destination object.\n     * @param {Object} source The source object.\n     * @param {number} srcIndex The index of `source`.\n     * @param {Function} [customizer] The function to customize merged values.\n     * @param {Object} [stack] Tracks traversed source values and their merged\n     *  counterparts.\n     */\n    function baseMerge(object, source, srcIndex, customizer, stack) {\n      if (object === source) {\n        return;\n      }\n      baseFor(source, function(srcValue, key) {\n        if (isObject(srcValue)) {\n          stack || (stack = new Stack);\n          baseMergeDeep(object, source, key, srcIndex, baseMerge, customizer, stack);\n        }\n        else {\n          var newValue = customizer\n            ? customizer(safeGet(object, key), srcValue, (key + ''), object, source, stack)\n            : undefined;\n\n          if (newValue === undefined) {\n            newValue = srcValue;\n          }\n          assignMergeValue(object, key, newValue);\n        }\n      }, keysIn);\n    }\n\n    /**\n     * A specialized version of `baseMerge` for arrays and objects which performs\n     * deep merges and tracks traversed objects enabling objects with circular\n     * references to be merged.\n     *\n     * @private\n     * @param {Object} object The destination object.\n     * @param {Object} source The source object.\n     * @param {string} key The key of the value to merge.\n     * @param {number} srcIndex The index of `source`.\n     * @param {Function} mergeFunc The function to merge values.\n     * @param {Function} [customizer] The function to customize assigned values.\n     * @param {Object} [stack] Tracks traversed source values and their merged\n     *  counterparts.\n     */\n    function baseMergeDeep(object, source, key, srcIndex, mergeFunc, customizer, stack) {\n      var objValue = safeGet(object, key),\n          srcValue = safeGet(source, key),\n          stacked = stack.get(srcValue);\n\n      if (stacked) {\n        assignMergeValue(object, key, stacked);\n        return;\n      }\n      var newValue = customizer\n        ? customizer(objValue, srcValue, (key + ''), object, source, stack)\n        : undefined;\n\n      var isCommon = newValue === undefined;\n\n      if (isCommon) {\n        var isArr = isArray(srcValue),\n            isBuff = !isArr && isBuffer(srcValue),\n            isTyped = !isArr && !isBuff && isTypedArray(srcValue);\n\n        newValue = srcValue;\n        if (isArr || isBuff || isTyped) {\n          if (isArray(objValue)) {\n            newValue = objValue;\n          }\n          else if (isArrayLikeObject(objValue)) {\n            newValue = copyArray(objValue);\n          }\n          else if (isBuff) {\n            isCommon = false;\n            newValue = cloneBuffer(srcValue, true);\n          }\n          else if (isTyped) {\n            isCommon = false;\n            newValue = cloneTypedArray(srcValue, true);\n          }\n          else {\n            newValue = [];\n          }\n        }\n        else if (isPlainObject(srcValue) || isArguments(srcValue)) {\n          newValue = objValue;\n          if (isArguments(objValue)) {\n            newValue = toPlainObject(objValue);\n          }\n          else if (!isObject(objValue) || isFunction(objValue)) {\n            newValue = initCloneObject(srcValue);\n          }\n        }\n        else {\n          isCommon = false;\n        }\n      }\n      if (isCommon) {\n        // Recursively merge objects and arrays (susceptible to call stack limits).\n        stack.set(srcValue, newValue);\n        mergeFunc(newValue, srcValue, srcIndex, customizer, stack);\n        stack['delete'](srcValue);\n      }\n      assignMergeValue(object, key, newValue);\n    }\n\n    /**\n     * The base implementation of `_.nth` which doesn't coerce arguments.\n     *\n     * @private\n     * @param {Array} array The array to query.\n     * @param {number} n The index of the element to return.\n     * @returns {*} Returns the nth element of `array`.\n     */\n    function baseNth(array, n) {\n      var length = array.length;\n      if (!length) {\n        return;\n      }\n      n += n < 0 ? length : 0;\n      return isIndex(n, length) ? array[n] : undefined;\n    }\n\n    /**\n     * The base implementation of `_.orderBy` without param guards.\n     *\n     * @private\n     * @param {Array|Object} collection The collection to iterate over.\n     * @param {Function[]|Object[]|string[]} iteratees The iteratees to sort by.\n     * @param {string[]} orders The sort orders of `iteratees`.\n     * @returns {Array} Returns the new sorted array.\n     */\n    function baseOrderBy(collection, iteratees, orders) {\n      var index = -1;\n      iteratees = arrayMap(iteratees.length ? iteratees : [identity], baseUnary(getIteratee()));\n\n      var result = baseMap(collection, function(value, key, collection) {\n        var criteria = arrayMap(iteratees, function(iteratee) {\n          return iteratee(value);\n        });\n        return { 'criteria': criteria, 'index': ++index, 'value': value };\n      });\n\n      return baseSortBy(result, function(object, other) {\n        return compareMultiple(object, other, orders);\n      });\n    }\n\n    /**\n     * The base implementation of `_.pick` without support for individual\n     * property identifiers.\n     *\n     * @private\n     * @param {Object} object The source object.\n     * @param {string[]} paths The property paths to pick.\n     * @returns {Object} Returns the new object.\n     */\n    function basePick(object, paths) {\n      return basePickBy(object, paths, function(value, path) {\n        return hasIn(object, path);\n      });\n    }\n\n    /**\n     * The base implementation of  `_.pickBy` without support for iteratee shorthands.\n     *\n     * @private\n     * @param {Object} object The source object.\n     * @param {string[]} paths The property paths to pick.\n     * @param {Function} predicate The function invoked per property.\n     * @returns {Object} Returns the new object.\n     */\n    function basePickBy(object, paths, predicate) {\n      var index = -1,\n          length = paths.length,\n          result = {};\n\n      while (++index < length) {\n        var path = paths[index],\n            value = baseGet(object, path);\n\n        if (predicate(value, path)) {\n          baseSet(result, castPath(path, object), value);\n        }\n      }\n      return result;\n    }\n\n    /**\n     * A specialized version of `baseProperty` which supports deep paths.\n     *\n     * @private\n     * @param {Array|string} path The path of the property to get.\n     * @returns {Function} Returns the new accessor function.\n     */\n    function basePropertyDeep(path) {\n      return function(object) {\n        return baseGet(object, path);\n      };\n    }\n\n    /**\n     * The base implementation of `_.pullAllBy` without support for iteratee\n     * shorthands.\n     *\n     * @private\n     * @param {Array} array The array to modify.\n     * @param {Array} values The values to remove.\n     * @param {Function} [iteratee] The iteratee invoked per element.\n     * @param {Function} [comparator] The comparator invoked per element.\n     * @returns {Array} Returns `array`.\n     */\n    function basePullAll(array, values, iteratee, comparator) {\n      var indexOf = comparator ? baseIndexOfWith : baseIndexOf,\n          index = -1,\n          length = values.length,\n          seen = array;\n\n      if (array === values) {\n        values = copyArray(values);\n      }\n      if (iteratee) {\n        seen = arrayMap(array, baseUnary(iteratee));\n      }\n      while (++index < length) {\n        var fromIndex = 0,\n            value = values[index],\n            computed = iteratee ? iteratee(value) : value;\n\n        while ((fromIndex = indexOf(seen, computed, fromIndex, comparator)) > -1) {\n          if (seen !== array) {\n            splice.call(seen, fromIndex, 1);\n          }\n          splice.call(array, fromIndex, 1);\n        }\n      }\n      return array;\n    }\n\n    /**\n     * The base implementation of `_.pullAt` without support for individual\n     * indexes or capturing the removed elements.\n     *\n     * @private\n     * @param {Array} array The array to modify.\n     * @param {number[]} indexes The indexes of elements to remove.\n     * @returns {Array} Returns `array`.\n     */\n    function basePullAt(array, indexes) {\n      var length = array ? indexes.length : 0,\n          lastIndex = length - 1;\n\n      while (length--) {\n        var index = indexes[length];\n        if (length == lastIndex || index !== previous) {\n          var previous = index;\n          if (isIndex(index)) {\n            splice.call(array, index, 1);\n          } else {\n            baseUnset(array, index);\n          }\n        }\n      }\n      return array;\n    }\n\n    /**\n     * The base implementation of `_.random` without support for returning\n     * floating-point numbers.\n     *\n     * @private\n     * @param {number} lower The lower bound.\n     * @param {number} upper The upper bound.\n     * @returns {number} Returns the random number.\n     */\n    function baseRandom(lower, upper) {\n      return lower + nativeFloor(nativeRandom() * (upper - lower + 1));\n    }\n\n    /**\n     * The base implementation of `_.range` and `_.rangeRight` which doesn't\n     * coerce arguments.\n     *\n     * @private\n     * @param {number} start The start of the range.\n     * @param {number} end The end of the range.\n     * @param {number} step The value to increment or decrement by.\n     * @param {boolean} [fromRight] Specify iterating from right to left.\n     * @returns {Array} Returns the range of numbers.\n     */\n    function baseRange(start, end, step, fromRight) {\n      var index = -1,\n          length = nativeMax(nativeCeil((end - start) / (step || 1)), 0),\n          result = Array(length);\n\n      while (length--) {\n        result[fromRight ? length : ++index] = start;\n        start += step;\n      }\n      return result;\n    }\n\n    /**\n     * The base implementation of `_.repeat` which doesn't coerce arguments.\n     *\n     * @private\n     * @param {string} string The string to repeat.\n     * @param {number} n The number of times to repeat the string.\n     * @returns {string} Returns the repeated string.\n     */\n    function baseRepeat(string, n) {\n      var result = '';\n      if (!string || n < 1 || n > MAX_SAFE_INTEGER) {\n        return result;\n      }\n      // Leverage the exponentiation by squaring algorithm for a faster repeat.\n      // See https://en.wikipedia.org/wiki/Exponentiation_by_squaring for more details.\n      do {\n        if (n % 2) {\n          result += string;\n        }\n        n = nativeFloor(n / 2);\n        if (n) {\n          string += string;\n        }\n      } while (n);\n\n      return result;\n    }\n\n    /**\n     * The base implementation of `_.rest` which doesn't validate or coerce arguments.\n     *\n     * @private\n     * @param {Function} func The function to apply a rest parameter to.\n     * @param {number} [start=func.length-1] The start position of the rest parameter.\n     * @returns {Function} Returns the new function.\n     */\n    function baseRest(func, start) {\n      return setToString(overRest(func, start, identity), func + '');\n    }\n\n    /**\n     * The base implementation of `_.sample`.\n     *\n     * @private\n     * @param {Array|Object} collection The collection to sample.\n     * @returns {*} Returns the random element.\n     */\n    function baseSample(collection) {\n      return arraySample(values(collection));\n    }\n\n    /**\n     * The base implementation of `_.sampleSize` without param guards.\n     *\n     * @private\n     * @param {Array|Object} collection The collection to sample.\n     * @param {number} n The number of elements to sample.\n     * @returns {Array} Returns the random elements.\n     */\n    function baseSampleSize(collection, n) {\n      var array = values(collection);\n      return shuffleSelf(array, baseClamp(n, 0, array.length));\n    }\n\n    /**\n     * The base implementation of `_.set`.\n     *\n     * @private\n     * @param {Object} object The object to modify.\n     * @param {Array|string} path The path of the property to set.\n     * @param {*} value The value to set.\n     * @param {Function} [customizer] The function to customize path creation.\n     * @returns {Object} Returns `object`.\n     */\n    function baseSet(object, path, value, customizer) {\n      if (!isObject(object)) {\n        return object;\n      }\n      path = castPath(path, object);\n\n      var index = -1,\n          length = path.length,\n          lastIndex = length - 1,\n          nested = object;\n\n      while (nested != null && ++index < length) {\n        var key = toKey(path[index]),\n            newValue = value;\n\n        if (index != lastIndex) {\n          var objValue = nested[key];\n          newValue = customizer ? customizer(objValue, key, nested) : undefined;\n          if (newValue === undefined) {\n            newValue = isObject(objValue)\n              ? objValue\n              : (isIndex(path[index + 1]) ? [] : {});\n          }\n        }\n        assignValue(nested, key, newValue);\n        nested = nested[key];\n      }\n      return object;\n    }\n\n    /**\n     * The base implementation of `setData` without support for hot loop shorting.\n     *\n     * @private\n     * @param {Function} func The function to associate metadata with.\n     * @param {*} data The metadata.\n     * @returns {Function} Returns `func`.\n     */\n    var baseSetData = !metaMap ? identity : function(func, data) {\n      metaMap.set(func, data);\n      return func;\n    };\n\n    /**\n     * The base implementation of `setToString` without support for hot loop shorting.\n     *\n     * @private\n     * @param {Function} func The function to modify.\n     * @param {Function} string The `toString` result.\n     * @returns {Function} Returns `func`.\n     */\n    var baseSetToString = !defineProperty ? identity : function(func, string) {\n      return defineProperty(func, 'toString', {\n        'configurable': true,\n        'enumerable': false,\n        'value': constant(string),\n        'writable': true\n      });\n    };\n\n    /**\n     * The base implementation of `_.shuffle`.\n     *\n     * @private\n     * @param {Array|Object} collection The collection to shuffle.\n     * @returns {Array} Returns the new shuffled array.\n     */\n    function baseShuffle(collection) {\n      return shuffleSelf(values(collection));\n    }\n\n    /**\n     * The base implementation of `_.slice` without an iteratee call guard.\n     *\n     * @private\n     * @param {Array} array The array to slice.\n     * @param {number} [start=0] The start position.\n     * @param {number} [end=array.length] The end position.\n     * @returns {Array} Returns the slice of `array`.\n     */\n    function baseSlice(array, start, end) {\n      var index = -1,\n          length = array.length;\n\n      if (start < 0) {\n        start = -start > length ? 0 : (length + start);\n      }\n      end = end > length ? length : end;\n      if (end < 0) {\n        end += length;\n      }\n      length = start > end ? 0 : ((end - start) >>> 0);\n      start >>>= 0;\n\n      var result = Array(length);\n      while (++index < length) {\n        result[index] = array[index + start];\n      }\n      return result;\n    }\n\n    /**\n     * The base implementation of `_.some` without support for iteratee shorthands.\n     *\n     * @private\n     * @param {Array|Object} collection The collection to iterate over.\n     * @param {Function} predicate The function invoked per iteration.\n     * @returns {boolean} Returns `true` if any element passes the predicate check,\n     *  else `false`.\n     */\n    function baseSome(collection, predicate) {\n      var result;\n\n      baseEach(collection, function(value, index, collection) {\n        result = predicate(value, index, collection);\n        return !result;\n      });\n      return !!result;\n    }\n\n    /**\n     * The base implementation of `_.sortedIndex` and `_.sortedLastIndex` which\n     * performs a binary search of `array` to determine the index at which `value`\n     * should be inserted into `array` in order to maintain its sort order.\n     *\n     * @private\n     * @param {Array} array The sorted array to inspect.\n     * @param {*} value The value to evaluate.\n     * @param {boolean} [retHighest] Specify returning the highest qualified index.\n     * @returns {number} Returns the index at which `value` should be inserted\n     *  into `array`.\n     */\n    function baseSortedIndex(array, value, retHighest) {\n      var low = 0,\n          high = array == null ? low : array.length;\n\n      if (typeof value == 'number' && value === value && high <= HALF_MAX_ARRAY_LENGTH) {\n        while (low < high) {\n          var mid = (low + high) >>> 1,\n              computed = array[mid];\n\n          if (computed !== null && !isSymbol(computed) &&\n              (retHighest ? (computed <= value) : (computed < value))) {\n            low = mid + 1;\n          } else {\n            high = mid;\n          }\n        }\n        return high;\n      }\n      return baseSortedIndexBy(array, value, identity, retHighest);\n    }\n\n    /**\n     * The base implementation of `_.sortedIndexBy` and `_.sortedLastIndexBy`\n     * which invokes `iteratee` for `value` and each element of `array` to compute\n     * their sort ranking. The iteratee is invoked with one argument; (value).\n     *\n     * @private\n     * @param {Array} array The sorted array to inspect.\n     * @param {*} value The value to evaluate.\n     * @param {Function} iteratee The iteratee invoked per element.\n     * @param {boolean} [retHighest] Specify returning the highest qualified index.\n     * @returns {number} Returns the index at which `value` should be inserted\n     *  into `array`.\n     */\n    function baseSortedIndexBy(array, value, iteratee, retHighest) {\n      value = iteratee(value);\n\n      var low = 0,\n          high = array == null ? 0 : array.length,\n          valIsNaN = value !== value,\n          valIsNull = value === null,\n          valIsSymbol = isSymbol(value),\n          valIsUndefined = value === undefined;\n\n      while (low < high) {\n        var mid = nativeFloor((low + high) / 2),\n            computed = iteratee(array[mid]),\n            othIsDefined = computed !== undefined,\n            othIsNull = computed === null,\n            othIsReflexive = computed === computed,\n            othIsSymbol = isSymbol(computed);\n\n        if (valIsNaN) {\n          var setLow = retHighest || othIsReflexive;\n        } else if (valIsUndefined) {\n          setLow = othIsReflexive && (retHighest || othIsDefined);\n        } else if (valIsNull) {\n          setLow = othIsReflexive && othIsDefined && (retHighest || !othIsNull);\n        } else if (valIsSymbol) {\n          setLow = othIsReflexive && othIsDefined && !othIsNull && (retHighest || !othIsSymbol);\n        } else if (othIsNull || othIsSymbol) {\n          setLow = false;\n        } else {\n          setLow = retHighest ? (computed <= value) : (computed < value);\n        }\n        if (setLow) {\n          low = mid + 1;\n        } else {\n          high = mid;\n        }\n      }\n      return nativeMin(high, MAX_ARRAY_INDEX);\n    }\n\n    /**\n     * The base implementation of `_.sortedUniq` and `_.sortedUniqBy` without\n     * support for iteratee shorthands.\n     *\n     * @private\n     * @param {Array} array The array to inspect.\n     * @param {Function} [iteratee] The iteratee invoked per element.\n     * @returns {Array} Returns the new duplicate free array.\n     */\n    function baseSortedUniq(array, iteratee) {\n      var index = -1,\n          length = array.length,\n          resIndex = 0,\n          result = [];\n\n      while (++index < length) {\n        var value = array[index],\n            computed = iteratee ? iteratee(value) : value;\n\n        if (!index || !eq(computed, seen)) {\n          var seen = computed;\n          result[resIndex++] = value === 0 ? 0 : value;\n        }\n      }\n      return result;\n    }\n\n    /**\n     * The base implementation of `_.toNumber` which doesn't ensure correct\n     * conversions of binary, hexadecimal, or octal string values.\n     *\n     * @private\n     * @param {*} value The value to process.\n     * @returns {number} Returns the number.\n     */\n    function baseToNumber(value) {\n      if (typeof value == 'number') {\n        return value;\n      }\n      if (isSymbol(value)) {\n        return NAN;\n      }\n      return +value;\n    }\n\n    /**\n     * The base implementation of `_.toString` which doesn't convert nullish\n     * values to empty strings.\n     *\n     * @private\n     * @param {*} value The value to process.\n     * @returns {string} Returns the string.\n     */\n    function baseToString(value) {\n      // Exit early for strings to avoid a performance hit in some environments.\n      if (typeof value == 'string') {\n        return value;\n      }\n      if (isArray(value)) {\n        // Recursively convert values (susceptible to call stack limits).\n        return arrayMap(value, baseToString) + '';\n      }\n      if (isSymbol(value)) {\n        return symbolToString ? symbolToString.call(value) : '';\n      }\n      var result = (value + '');\n      return (result == '0' && (1 / value) == -INFINITY) ? '-0' : result;\n    }\n\n    /**\n     * The base implementation of `_.uniqBy` without support for iteratee shorthands.\n     *\n     * @private\n     * @param {Array} array The array to inspect.\n     * @param {Function} [iteratee] The iteratee invoked per element.\n     * @param {Function} [comparator] The comparator invoked per element.\n     * @returns {Array} Returns the new duplicate free array.\n     */\n    function baseUniq(array, iteratee, comparator) {\n      var index = -1,\n          includes = arrayIncludes,\n          length = array.length,\n          isCommon = true,\n          result = [],\n          seen = result;\n\n      if (comparator) {\n        isCommon = false;\n        includes = arrayIncludesWith;\n      }\n      else if (length >= LARGE_ARRAY_SIZE) {\n        var set = iteratee ? null : createSet(array);\n        if (set) {\n          return setToArray(set);\n        }\n        isCommon = false;\n        includes = cacheHas;\n        seen = new SetCache;\n      }\n      else {\n        seen = iteratee ? [] : result;\n      }\n      outer:\n      while (++index < length) {\n        var value = array[index],\n            computed = iteratee ? iteratee(value) : value;\n\n        value = (comparator || value !== 0) ? value : 0;\n        if (isCommon && computed === computed) {\n          var seenIndex = seen.length;\n          while (seenIndex--) {\n            if (seen[seenIndex] === computed) {\n              continue outer;\n            }\n          }\n          if (iteratee) {\n            seen.push(computed);\n          }\n          result.push(value);\n        }\n        else if (!includes(seen, computed, comparator)) {\n          if (seen !== result) {\n            seen.push(computed);\n          }\n          result.push(value);\n        }\n      }\n      return result;\n    }\n\n    /**\n     * The base implementation of `_.unset`.\n     *\n     * @private\n     * @param {Object} object The object to modify.\n     * @param {Array|string} path The property path to unset.\n     * @returns {boolean} Returns `true` if the property is deleted, else `false`.\n     */\n    function baseUnset(object, path) {\n      path = castPath(path, object);\n      object = parent(object, path);\n      return object == null || delete object[toKey(last(path))];\n    }\n\n    /**\n     * The base implementation of `_.update`.\n     *\n     * @private\n     * @param {Object} object The object to modify.\n     * @param {Array|string} path The path of the property to update.\n     * @param {Function} updater The function to produce the updated value.\n     * @param {Function} [customizer] The function to customize path creation.\n     * @returns {Object} Returns `object`.\n     */\n    function baseUpdate(object, path, updater, customizer) {\n      return baseSet(object, path, updater(baseGet(object, path)), customizer);\n    }\n\n    /**\n     * The base implementation of methods like `_.dropWhile` and `_.takeWhile`\n     * without support for iteratee shorthands.\n     *\n     * @private\n     * @param {Array} array The array to query.\n     * @param {Function} predicate The function invoked per iteration.\n     * @param {boolean} [isDrop] Specify dropping elements instead of taking them.\n     * @param {boolean} [fromRight] Specify iterating from right to left.\n     * @returns {Array} Returns the slice of `array`.\n     */\n    function baseWhile(array, predicate, isDrop, fromRight) {\n      var length = array.length,\n          index = fromRight ? length : -1;\n\n      while ((fromRight ? index-- : ++index < length) &&\n        predicate(array[index], index, array)) {}\n\n      return isDrop\n        ? baseSlice(array, (fromRight ? 0 : index), (fromRight ? index + 1 : length))\n        : baseSlice(array, (fromRight ? index + 1 : 0), (fromRight ? length : index));\n    }\n\n    /**\n     * The base implementation of `wrapperValue` which returns the result of\n     * performing a sequence of actions on the unwrapped `value`, where each\n     * successive action is supplied the return value of the previous.\n     *\n     * @private\n     * @param {*} value The unwrapped value.\n     * @param {Array} actions Actions to perform to resolve the unwrapped value.\n     * @returns {*} Returns the resolved value.\n     */\n    function baseWrapperValue(value, actions) {\n      var result = value;\n      if (result instanceof LazyWrapper) {\n        result = result.value();\n      }\n      return arrayReduce(actions, function(result, action) {\n        return action.func.apply(action.thisArg, arrayPush([result], action.args));\n      }, result);\n    }\n\n    /**\n     * The base implementation of methods like `_.xor`, without support for\n     * iteratee shorthands, that accepts an array of arrays to inspect.\n     *\n     * @private\n     * @param {Array} arrays The arrays to inspect.\n     * @param {Function} [iteratee] The iteratee invoked per element.\n     * @param {Function} [comparator] The comparator invoked per element.\n     * @returns {Array} Returns the new array of values.\n     */\n    function baseXor(arrays, iteratee, comparator) {\n      var length = arrays.length;\n      if (length < 2) {\n        return length ? baseUniq(arrays[0]) : [];\n      }\n      var index = -1,\n          result = Array(length);\n\n      while (++index < length) {\n        var array = arrays[index],\n            othIndex = -1;\n\n        while (++othIndex < length) {\n          if (othIndex != index) {\n            result[index] = baseDifference(result[index] || array, arrays[othIndex], iteratee, comparator);\n          }\n        }\n      }\n      return baseUniq(baseFlatten(result, 1), iteratee, comparator);\n    }\n\n    /**\n     * This base implementation of `_.zipObject` which assigns values using `assignFunc`.\n     *\n     * @private\n     * @param {Array} props The property identifiers.\n     * @param {Array} values The property values.\n     * @param {Function} assignFunc The function to assign values.\n     * @returns {Object} Returns the new object.\n     */\n    function baseZipObject(props, values, assignFunc) {\n      var index = -1,\n          length = props.length,\n          valsLength = values.length,\n          result = {};\n\n      while (++index < length) {\n        var value = index < valsLength ? values[index] : undefined;\n        assignFunc(result, props[index], value);\n      }\n      return result;\n    }\n\n    /**\n     * Casts `value` to an empty array if it's not an array like object.\n     *\n     * @private\n     * @param {*} value The value to inspect.\n     * @returns {Array|Object} Returns the cast array-like object.\n     */\n    function castArrayLikeObject(value) {\n      return isArrayLikeObject(value) ? value : [];\n    }\n\n    /**\n     * Casts `value` to `identity` if it's not a function.\n     *\n     * @private\n     * @param {*} value The value to inspect.\n     * @returns {Function} Returns cast function.\n     */\n    function castFunction(value) {\n      return typeof value == 'function' ? value : identity;\n    }\n\n    /**\n     * Casts `value` to a path array if it's not one.\n     *\n     * @private\n     * @param {*} value The value to inspect.\n     * @param {Object} [object] The object to query keys on.\n     * @returns {Array} Returns the cast property path array.\n     */\n    function castPath(value, object) {\n      if (isArray(value)) {\n        return value;\n      }\n      return isKey(value, object) ? [value] : stringToPath(toString(value));\n    }\n\n    /**\n     * A `baseRest` alias which can be replaced with `identity` by module\n     * replacement plugins.\n     *\n     * @private\n     * @type {Function}\n     * @param {Function} func The function to apply a rest parameter to.\n     * @returns {Function} Returns the new function.\n     */\n    var castRest = baseRest;\n\n    /**\n     * Casts `array` to a slice if it's needed.\n     *\n     * @private\n     * @param {Array} array The array to inspect.\n     * @param {number} start The start position.\n     * @param {number} [end=array.length] The end position.\n     * @returns {Array} Returns the cast slice.\n     */\n    function castSlice(array, start, end) {\n      var length = array.length;\n      end = end === undefined ? length : end;\n      return (!start && end >= length) ? array : baseSlice(array, start, end);\n    }\n\n    /**\n     * A simple wrapper around the global [`clearTimeout`](https://mdn.io/clearTimeout).\n     *\n     * @private\n     * @param {number|Object} id The timer id or timeout object of the timer to clear.\n     */\n    var clearTimeout = ctxClearTimeout || function(id) {\n      return root.clearTimeout(id);\n    };\n\n    /**\n     * Creates a clone of  `buffer`.\n     *\n     * @private\n     * @param {Buffer} buffer The buffer to clone.\n     * @param {boolean} [isDeep] Specify a deep clone.\n     * @returns {Buffer} Returns the cloned buffer.\n     */\n    function cloneBuffer(buffer, isDeep) {\n      if (isDeep) {\n        return buffer.slice();\n      }\n      var length = buffer.length,\n          result = allocUnsafe ? allocUnsafe(length) : new buffer.constructor(length);\n\n      buffer.copy(result);\n      return result;\n    }\n\n    /**\n     * Creates a clone of `arrayBuffer`.\n     *\n     * @private\n     * @param {ArrayBuffer} arrayBuffer The array buffer to clone.\n     * @returns {ArrayBuffer} Returns the cloned array buffer.\n     */\n    function cloneArrayBuffer(arrayBuffer) {\n      var result = new arrayBuffer.constructor(arrayBuffer.byteLength);\n      new Uint8Array(result).set(new Uint8Array(arrayBuffer));\n      return result;\n    }\n\n    /**\n     * Creates a clone of `dataView`.\n     *\n     * @private\n     * @param {Object} dataView The data view to clone.\n     * @param {boolean} [isDeep] Specify a deep clone.\n     * @returns {Object} Returns the cloned data view.\n     */\n    function cloneDataView(dataView, isDeep) {\n      var buffer = isDeep ? cloneArrayBuffer(dataView.buffer) : dataView.buffer;\n      return new dataView.constructor(buffer, dataView.byteOffset, dataView.byteLength);\n    }\n\n    /**\n     * Creates a clone of `regexp`.\n     *\n     * @private\n     * @param {Object} regexp The regexp to clone.\n     * @returns {Object} Returns the cloned regexp.\n     */\n    function cloneRegExp(regexp) {\n      var result = new regexp.constructor(regexp.source, reFlags.exec(regexp));\n      result.lastIndex = regexp.lastIndex;\n      return result;\n    }\n\n    /**\n     * Creates a clone of the `symbol` object.\n     *\n     * @private\n     * @param {Object} symbol The symbol object to clone.\n     * @returns {Object} Returns the cloned symbol object.\n     */\n    function cloneSymbol(symbol) {\n      return symbolValueOf ? Object(symbolValueOf.call(symbol)) : {};\n    }\n\n    /**\n     * Creates a clone of `typedArray`.\n     *\n     * @private\n     * @param {Object} typedArray The typed array to clone.\n     * @param {boolean} [isDeep] Specify a deep clone.\n     * @returns {Object} Returns the cloned typed array.\n     */\n    function cloneTypedArray(typedArray, isDeep) {\n      var buffer = isDeep ? cloneArrayBuffer(typedArray.buffer) : typedArray.buffer;\n      return new typedArray.constructor(buffer, typedArray.byteOffset, typedArray.length);\n    }\n\n    /**\n     * Compares values to sort them in ascending order.\n     *\n     * @private\n     * @param {*} value The value to compare.\n     * @param {*} other The other value to compare.\n     * @returns {number} Returns the sort order indicator for `value`.\n     */\n    function compareAscending(value, other) {\n      if (value !== other) {\n        var valIsDefined = value !== undefined,\n            valIsNull = value === null,\n            valIsReflexive = value === value,\n            valIsSymbol = isSymbol(value);\n\n        var othIsDefined = other !== undefined,\n            othIsNull = other === null,\n            othIsReflexive = other === other,\n            othIsSymbol = isSymbol(other);\n\n        if ((!othIsNull && !othIsSymbol && !valIsSymbol && value > other) ||\n            (valIsSymbol && othIsDefined && othIsReflexive && !othIsNull && !othIsSymbol) ||\n            (valIsNull && othIsDefined && othIsReflexive) ||\n            (!valIsDefined && othIsReflexive) ||\n            !valIsReflexive) {\n          return 1;\n        }\n        if ((!valIsNull && !valIsSymbol && !othIsSymbol && value < other) ||\n            (othIsSymbol && valIsDefined && valIsReflexive && !valIsNull && !valIsSymbol) ||\n            (othIsNull && valIsDefined && valIsReflexive) ||\n            (!othIsDefined && valIsReflexive) ||\n            !othIsReflexive) {\n          return -1;\n        }\n      }\n      return 0;\n    }\n\n    /**\n     * Used by `_.orderBy` to compare multiple properties of a value to another\n     * and stable sort them.\n     *\n     * If `orders` is unspecified, all values are sorted in ascending order. Otherwise,\n     * specify an order of \"desc\" for descending or \"asc\" for ascending sort order\n     * of corresponding values.\n     *\n     * @private\n     * @param {Object} object The object to compare.\n     * @param {Object} other The other object to compare.\n     * @param {boolean[]|string[]} orders The order to sort by for each property.\n     * @returns {number} Returns the sort order indicator for `object`.\n     */\n    function compareMultiple(object, other, orders) {\n      var index = -1,\n          objCriteria = object.criteria,\n          othCriteria = other.criteria,\n          length = objCriteria.length,\n          ordersLength = orders.length;\n\n      while (++index < length) {\n        var result = compareAscending(objCriteria[index], othCriteria[index]);\n        if (result) {\n          if (index >= ordersLength) {\n            return result;\n          }\n          var order = orders[index];\n          return result * (order == 'desc' ? -1 : 1);\n        }\n      }\n      // Fixes an `Array#sort` bug in the JS engine embedded in Adobe applications\n      // that causes it, under certain circumstances, to provide the same value for\n      // `object` and `other`. See https://github.com/jashkenas/underscore/pull/1247\n      // for more details.\n      //\n      // This also ensures a stable sort in V8 and other engines.\n      // See https://bugs.chromium.org/p/v8/issues/detail?id=90 for more details.\n      return object.index - other.index;\n    }\n\n    /**\n     * Creates an array that is the composition of partially applied arguments,\n     * placeholders, and provided arguments into a single array of arguments.\n     *\n     * @private\n     * @param {Array} args The provided arguments.\n     * @param {Array} partials The arguments to prepend to those provided.\n     * @param {Array} holders The `partials` placeholder indexes.\n     * @params {boolean} [isCurried] Specify composing for a curried function.\n     * @returns {Array} Returns the new array of composed arguments.\n     */\n    function composeArgs(args, partials, holders, isCurried) {\n      var argsIndex = -1,\n          argsLength = args.length,\n          holdersLength = holders.length,\n          leftIndex = -1,\n          leftLength = partials.length,\n          rangeLength = nativeMax(argsLength - holdersLength, 0),\n          result = Array(leftLength + rangeLength),\n          isUncurried = !isCurried;\n\n      while (++leftIndex < leftLength) {\n        result[leftIndex] = partials[leftIndex];\n      }\n      while (++argsIndex < holdersLength) {\n        if (isUncurried || argsIndex < argsLength) {\n          result[holders[argsIndex]] = args[argsIndex];\n        }\n      }\n      while (rangeLength--) {\n        result[leftIndex++] = args[argsIndex++];\n      }\n      return result;\n    }\n\n    /**\n     * This function is like `composeArgs` except that the arguments composition\n     * is tailored for `_.partialRight`.\n     *\n     * @private\n     * @param {Array} args The provided arguments.\n     * @param {Array} partials The arguments to append to those provided.\n     * @param {Array} holders The `partials` placeholder indexes.\n     * @params {boolean} [isCurried] Specify composing for a curried function.\n     * @returns {Array} Returns the new array of composed arguments.\n     */\n    function composeArgsRight(args, partials, holders, isCurried) {\n      var argsIndex = -1,\n          argsLength = args.length,\n          holdersIndex = -1,\n          holdersLength = holders.length,\n          rightIndex = -1,\n          rightLength = partials.length,\n          rangeLength = nativeMax(argsLength - holdersLength, 0),\n          result = Array(rangeLength + rightLength),\n          isUncurried = !isCurried;\n\n      while (++argsIndex < rangeLength) {\n        result[argsIndex] = args[argsIndex];\n      }\n      var offset = argsIndex;\n      while (++rightIndex < rightLength) {\n        result[offset + rightIndex] = partials[rightIndex];\n      }\n      while (++holdersIndex < holdersLength) {\n        if (isUncurried || argsIndex < argsLength) {\n          result[offset + holders[holdersIndex]] = args[argsIndex++];\n        }\n      }\n      return result;\n    }\n\n    /**\n     * Copies the values of `source` to `array`.\n     *\n     * @private\n     * @param {Array} source The array to copy values from.\n     * @param {Array} [array=[]] The array to copy values to.\n     * @returns {Array} Returns `array`.\n     */\n    function copyArray(source, array) {\n      var index = -1,\n          length = source.length;\n\n      array || (array = Array(length));\n      while (++index < length) {\n        array[index] = source[index];\n      }\n      return array;\n    }\n\n    /**\n     * Copies properties of `source` to `object`.\n     *\n     * @private\n     * @param {Object} source The object to copy properties from.\n     * @param {Array} props The property identifiers to copy.\n     * @param {Object} [object={}] The object to copy properties to.\n     * @param {Function} [customizer] The function to customize copied values.\n     * @returns {Object} Returns `object`.\n     */\n    function copyObject(source, props, object, customizer) {\n      var isNew = !object;\n      object || (object = {});\n\n      var index = -1,\n          length = props.length;\n\n      while (++index < length) {\n        var key = props[index];\n\n        var newValue = customizer\n          ? customizer(object[key], source[key], key, object, source)\n          : undefined;\n\n        if (newValue === undefined) {\n          newValue = source[key];\n        }\n        if (isNew) {\n          baseAssignValue(object, key, newValue);\n        } else {\n          assignValue(object, key, newValue);\n        }\n      }\n      return object;\n    }\n\n    /**\n     * Copies own symbols of `source` to `object`.\n     *\n     * @private\n     * @param {Object} source The object to copy symbols from.\n     * @param {Object} [object={}] The object to copy symbols to.\n     * @returns {Object} Returns `object`.\n     */\n    function copySymbols(source, object) {\n      return copyObject(source, getSymbols(source), object);\n    }\n\n    /**\n     * Copies own and inherited symbols of `source` to `object`.\n     *\n     * @private\n     * @param {Object} source The object to copy symbols from.\n     * @param {Object} [object={}] The object to copy symbols to.\n     * @returns {Object} Returns `object`.\n     */\n    function copySymbolsIn(source, object) {\n      return copyObject(source, getSymbolsIn(source), object);\n    }\n\n    /**\n     * Creates a function like `_.groupBy`.\n     *\n     * @private\n     * @param {Function} setter The function to set accumulator values.\n     * @param {Function} [initializer] The accumulator object initializer.\n     * @returns {Function} Returns the new aggregator function.\n     */\n    function createAggregator(setter, initializer) {\n      return function(collection, iteratee) {\n        var func = isArray(collection) ? arrayAggregator : baseAggregator,\n            accumulator = initializer ? initializer() : {};\n\n        return func(collection, setter, getIteratee(iteratee, 2), accumulator);\n      };\n    }\n\n    /**\n     * Creates a function like `_.assign`.\n     *\n     * @private\n     * @param {Function} assigner The function to assign values.\n     * @returns {Function} Returns the new assigner function.\n     */\n    function createAssigner(assigner) {\n      return baseRest(function(object, sources) {\n        var index = -1,\n            length = sources.length,\n            customizer = length > 1 ? sources[length - 1] : undefined,\n            guard = length > 2 ? sources[2] : undefined;\n\n        customizer = (assigner.length > 3 && typeof customizer == 'function')\n          ? (length--, customizer)\n          : undefined;\n\n        if (guard && isIterateeCall(sources[0], sources[1], guard)) {\n          customizer = length < 3 ? undefined : customizer;\n          length = 1;\n        }\n        object = Object(object);\n        while (++index < length) {\n          var source = sources[index];\n          if (source) {\n            assigner(object, source, index, customizer);\n          }\n        }\n        return object;\n      });\n    }\n\n    /**\n     * Creates a `baseEach` or `baseEachRight` function.\n     *\n     * @private\n     * @param {Function} eachFunc The function to iterate over a collection.\n     * @param {boolean} [fromRight] Specify iterating from right to left.\n     * @returns {Function} Returns the new base function.\n     */\n    function createBaseEach(eachFunc, fromRight) {\n      return function(collection, iteratee) {\n        if (collection == null) {\n          return collection;\n        }\n        if (!isArrayLike(collection)) {\n          return eachFunc(collection, iteratee);\n        }\n        var length = collection.length,\n            index = fromRight ? length : -1,\n            iterable = Object(collection);\n\n        while ((fromRight ? index-- : ++index < length)) {\n          if (iteratee(iterable[index], index, iterable) === false) {\n            break;\n          }\n        }\n        return collection;\n      };\n    }\n\n    /**\n     * Creates a base function for methods like `_.forIn` and `_.forOwn`.\n     *\n     * @private\n     * @param {boolean} [fromRight] Specify iterating from right to left.\n     * @returns {Function} Returns the new base function.\n     */\n    function createBaseFor(fromRight) {\n      return function(object, iteratee, keysFunc) {\n        var index = -1,\n            iterable = Object(object),\n            props = keysFunc(object),\n            length = props.length;\n\n        while (length--) {\n          var key = props[fromRight ? length : ++index];\n          if (iteratee(iterable[key], key, iterable) === false) {\n            break;\n          }\n        }\n        return object;\n      };\n    }\n\n    /**\n     * Creates a function that wraps `func` to invoke it with the optional `this`\n     * binding of `thisArg`.\n     *\n     * @private\n     * @param {Function} func The function to wrap.\n     * @param {number} bitmask The bitmask flags. See `createWrap` for more details.\n     * @param {*} [thisArg] The `this` binding of `func`.\n     * @returns {Function} Returns the new wrapped function.\n     */\n    function createBind(func, bitmask, thisArg) {\n      var isBind = bitmask & WRAP_BIND_FLAG,\n          Ctor = createCtor(func);\n\n      function wrapper() {\n        var fn = (this && this !== root && this instanceof wrapper) ? Ctor : func;\n        return fn.apply(isBind ? thisArg : this, arguments);\n      }\n      return wrapper;\n    }\n\n    /**\n     * Creates a function like `_.lowerFirst`.\n     *\n     * @private\n     * @param {string} methodName The name of the `String` case method to use.\n     * @returns {Function} Returns the new case function.\n     */\n    function createCaseFirst(methodName) {\n      return function(string) {\n        string = toString(string);\n\n        var strSymbols = hasUnicode(string)\n          ? stringToArray(string)\n          : undefined;\n\n        var chr = strSymbols\n          ? strSymbols[0]\n          : string.charAt(0);\n\n        var trailing = strSymbols\n          ? castSlice(strSymbols, 1).join('')\n          : string.slice(1);\n\n        return chr[methodName]() + trailing;\n      };\n    }\n\n    /**\n     * Creates a function like `_.camelCase`.\n     *\n     * @private\n     * @param {Function} callback The function to combine each word.\n     * @returns {Function} Returns the new compounder function.\n     */\n    function createCompounder(callback) {\n      return function(string) {\n        return arrayReduce(words(deburr(string).replace(reApos, '')), callback, '');\n      };\n    }\n\n    /**\n     * Creates a function that produces an instance of `Ctor` regardless of\n     * whether it was invoked as part of a `new` expression or by `call` or `apply`.\n     *\n     * @private\n     * @param {Function} Ctor The constructor to wrap.\n     * @returns {Function} Returns the new wrapped function.\n     */\n    function createCtor(Ctor) {\n      return function() {\n        // Use a `switch` statement to work with class constructors. See\n        // http://ecma-international.org/ecma-262/7.0/#sec-ecmascript-function-objects-call-thisargument-argumentslist\n        // for more details.\n        var args = arguments;\n        switch (args.length) {\n          case 0: return new Ctor;\n          case 1: return new Ctor(args[0]);\n          case 2: return new Ctor(args[0], args[1]);\n          case 3: return new Ctor(args[0], args[1], args[2]);\n          case 4: return new Ctor(args[0], args[1], args[2], args[3]);\n          case 5: return new Ctor(args[0], args[1], args[2], args[3], args[4]);\n          case 6: return new Ctor(args[0], args[1], args[2], args[3], args[4], args[5]);\n          case 7: return new Ctor(args[0], args[1], args[2], args[3], args[4], args[5], args[6]);\n        }\n        var thisBinding = baseCreate(Ctor.prototype),\n            result = Ctor.apply(thisBinding, args);\n\n        // Mimic the constructor's `return` behavior.\n        // See https://es5.github.io/#x13.2.2 for more details.\n        return isObject(result) ? result : thisBinding;\n      };\n    }\n\n    /**\n     * Creates a function that wraps `func` to enable currying.\n     *\n     * @private\n     * @param {Function} func The function to wrap.\n     * @param {number} bitmask The bitmask flags. See `createWrap` for more details.\n     * @param {number} arity The arity of `func`.\n     * @returns {Function} Returns the new wrapped function.\n     */\n    function createCurry(func, bitmask, arity) {\n      var Ctor = createCtor(func);\n\n      function wrapper() {\n        var length = arguments.length,\n            args = Array(length),\n            index = length,\n            placeholder = getHolder(wrapper);\n\n        while (index--) {\n          args[index] = arguments[index];\n        }\n        var holders = (length < 3 && args[0] !== placeholder && args[length - 1] !== placeholder)\n          ? []\n          : replaceHolders(args, placeholder);\n\n        length -= holders.length;\n        if (length < arity) {\n          return createRecurry(\n            func, bitmask, createHybrid, wrapper.placeholder, undefined,\n            args, holders, undefined, undefined, arity - length);\n        }\n        var fn = (this && this !== root && this instanceof wrapper) ? Ctor : func;\n        return apply(fn, this, args);\n      }\n      return wrapper;\n    }\n\n    /**\n     * Creates a `_.find` or `_.findLast` function.\n     *\n     * @private\n     * @param {Function} findIndexFunc The function to find the collection index.\n     * @returns {Function} Returns the new find function.\n     */\n    function createFind(findIndexFunc) {\n      return function(collection, predicate, fromIndex) {\n        var iterable = Object(collection);\n        if (!isArrayLike(collection)) {\n          var iteratee = getIteratee(predicate, 3);\n          collection = keys(collection);\n          predicate = function(key) { return iteratee(iterable[key], key, iterable); };\n        }\n        var index = findIndexFunc(collection, predicate, fromIndex);\n        return index > -1 ? iterable[iteratee ? collection[index] : index] : undefined;\n      };\n    }\n\n    /**\n     * Creates a `_.flow` or `_.flowRight` function.\n     *\n     * @private\n     * @param {boolean} [fromRight] Specify iterating from right to left.\n     * @returns {Function} Returns the new flow function.\n     */\n    function createFlow(fromRight) {\n      return flatRest(function(funcs) {\n        var length = funcs.length,\n            index = length,\n            prereq = LodashWrapper.prototype.thru;\n\n        if (fromRight) {\n          funcs.reverse();\n        }\n        while (index--) {\n          var func = funcs[index];\n          if (typeof func != 'function') {\n            throw new TypeError(FUNC_ERROR_TEXT);\n          }\n          if (prereq && !wrapper && getFuncName(func) == 'wrapper') {\n            var wrapper = new LodashWrapper([], true);\n          }\n        }\n        index = wrapper ? index : length;\n        while (++index < length) {\n          func = funcs[index];\n\n          var funcName = getFuncName(func),\n              data = funcName == 'wrapper' ? getData(func) : undefined;\n\n          if (data && isLaziable(data[0]) &&\n                data[1] == (WRAP_ARY_FLAG | WRAP_CURRY_FLAG | WRAP_PARTIAL_FLAG | WRAP_REARG_FLAG) &&\n                !data[4].length && data[9] == 1\n              ) {\n            wrapper = wrapper[getFuncName(data[0])].apply(wrapper, data[3]);\n          } else {\n            wrapper = (func.length == 1 && isLaziable(func))\n              ? wrapper[funcName]()\n              : wrapper.thru(func);\n          }\n        }\n        return function() {\n          var args = arguments,\n              value = args[0];\n\n          if (wrapper && args.length == 1 && isArray(value)) {\n            return wrapper.plant(value).value();\n          }\n          var index = 0,\n              result = length ? funcs[index].apply(this, args) : value;\n\n          while (++index < length) {\n            result = funcs[index].call(this, result);\n          }\n          return result;\n        };\n      });\n    }\n\n    /**\n     * Creates a function that wraps `func` to invoke it with optional `this`\n     * binding of `thisArg`, partial application, and currying.\n     *\n     * @private\n     * @param {Function|string} func The function or method name to wrap.\n     * @param {number} bitmask The bitmask flags. See `createWrap` for more details.\n     * @param {*} [thisArg] The `this` binding of `func`.\n     * @param {Array} [partials] The arguments to prepend to those provided to\n     *  the new function.\n     * @param {Array} [holders] The `partials` placeholder indexes.\n     * @param {Array} [partialsRight] The arguments to append to those provided\n     *  to the new function.\n     * @param {Array} [holdersRight] The `partialsRight` placeholder indexes.\n     * @param {Array} [argPos] The argument positions of the new function.\n     * @param {number} [ary] The arity cap of `func`.\n     * @param {number} [arity] The arity of `func`.\n     * @returns {Function} Returns the new wrapped function.\n     */\n    function createHybrid(func, bitmask, thisArg, partials, holders, partialsRight, holdersRight, argPos, ary, arity) {\n      var isAry = bitmask & WRAP_ARY_FLAG,\n          isBind = bitmask & WRAP_BIND_FLAG,\n          isBindKey = bitmask & WRAP_BIND_KEY_FLAG,\n          isCurried = bitmask & (WRAP_CURRY_FLAG | WRAP_CURRY_RIGHT_FLAG),\n          isFlip = bitmask & WRAP_FLIP_FLAG,\n          Ctor = isBindKey ? undefined : createCtor(func);\n\n      function wrapper() {\n        var length = arguments.length,\n            args = Array(length),\n            index = length;\n\n        while (index--) {\n          args[index] = arguments[index];\n        }\n        if (isCurried) {\n          var placeholder = getHolder(wrapper),\n              holdersCount = countHolders(args, placeholder);\n        }\n        if (partials) {\n          args = composeArgs(args, partials, holders, isCurried);\n        }\n        if (partialsRight) {\n          args = composeArgsRight(args, partialsRight, holdersRight, isCurried);\n        }\n        length -= holdersCount;\n        if (isCurried && length < arity) {\n          var newHolders = replaceHolders(args, placeholder);\n          return createRecurry(\n            func, bitmask, createHybrid, wrapper.placeholder, thisArg,\n            args, newHolders, argPos, ary, arity - length\n          );\n        }\n        var thisBinding = isBind ? thisArg : this,\n            fn = isBindKey ? thisBinding[func] : func;\n\n        length = args.length;\n        if (argPos) {\n          args = reorder(args, argPos);\n        } else if (isFlip && length > 1) {\n          args.reverse();\n        }\n        if (isAry && ary < length) {\n          args.length = ary;\n        }\n        if (this && this !== root && this instanceof wrapper) {\n          fn = Ctor || createCtor(fn);\n        }\n        return fn.apply(thisBinding, args);\n      }\n      return wrapper;\n    }\n\n    /**\n     * Creates a function like `_.invertBy`.\n     *\n     * @private\n     * @param {Function} setter The function to set accumulator values.\n     * @param {Function} toIteratee The function to resolve iteratees.\n     * @returns {Function} Returns the new inverter function.\n     */\n    function createInverter(setter, toIteratee) {\n      return function(object, iteratee) {\n        return baseInverter(object, setter, toIteratee(iteratee), {});\n      };\n    }\n\n    /**\n     * Creates a function that performs a mathematical operation on two values.\n     *\n     * @private\n     * @param {Function} operator The function to perform the operation.\n     * @param {number} [defaultValue] The value used for `undefined` arguments.\n     * @returns {Function} Returns the new mathematical operation function.\n     */\n    function createMathOperation(operator, defaultValue) {\n      return function(value, other) {\n        var result;\n        if (value === undefined && other === undefined) {\n          return defaultValue;\n        }\n        if (value !== undefined) {\n          result = value;\n        }\n        if (other !== undefined) {\n          if (result === undefined) {\n            return other;\n          }\n          if (typeof value == 'string' || typeof other == 'string') {\n            value = baseToString(value);\n            other = baseToString(other);\n          } else {\n            value = baseToNumber(value);\n            other = baseToNumber(other);\n          }\n          result = operator(value, other);\n        }\n        return result;\n      };\n    }\n\n    /**\n     * Creates a function like `_.over`.\n     *\n     * @private\n     * @param {Function} arrayFunc The function to iterate over iteratees.\n     * @returns {Function} Returns the new over function.\n     */\n    function createOver(arrayFunc) {\n      return flatRest(function(iteratees) {\n        iteratees = arrayMap(iteratees, baseUnary(getIteratee()));\n        return baseRest(function(args) {\n          var thisArg = this;\n          return arrayFunc(iteratees, function(iteratee) {\n            return apply(iteratee, thisArg, args);\n          });\n        });\n      });\n    }\n\n    /**\n     * Creates the padding for `string` based on `length`. The `chars` string\n     * is truncated if the number of characters exceeds `length`.\n     *\n     * @private\n     * @param {number} length The padding length.\n     * @param {string} [chars=' '] The string used as padding.\n     * @returns {string} Returns the padding for `string`.\n     */\n    function createPadding(length, chars) {\n      chars = chars === undefined ? ' ' : baseToString(chars);\n\n      var charsLength = chars.length;\n      if (charsLength < 2) {\n        return charsLength ? baseRepeat(chars, length) : chars;\n      }\n      var result = baseRepeat(chars, nativeCeil(length / stringSize(chars)));\n      return hasUnicode(chars)\n        ? castSlice(stringToArray(result), 0, length).join('')\n        : result.slice(0, length);\n    }\n\n    /**\n     * Creates a function that wraps `func` to invoke it with the `this` binding\n     * of `thisArg` and `partials` prepended to the arguments it receives.\n     *\n     * @private\n     * @param {Function} func The function to wrap.\n     * @param {number} bitmask The bitmask flags. See `createWrap` for more details.\n     * @param {*} thisArg The `this` binding of `func`.\n     * @param {Array} partials The arguments to prepend to those provided to\n     *  the new function.\n     * @returns {Function} Returns the new wrapped function.\n     */\n    function createPartial(func, bitmask, thisArg, partials) {\n      var isBind = bitmask & WRAP_BIND_FLAG,\n          Ctor = createCtor(func);\n\n      function wrapper() {\n        var argsIndex = -1,\n            argsLength = arguments.length,\n            leftIndex = -1,\n            leftLength = partials.length,\n            args = Array(leftLength + argsLength),\n            fn = (this && this !== root && this instanceof wrapper) ? Ctor : func;\n\n        while (++leftIndex < leftLength) {\n          args[leftIndex] = partials[leftIndex];\n        }\n        while (argsLength--) {\n          args[leftIndex++] = arguments[++argsIndex];\n        }\n        return apply(fn, isBind ? thisArg : this, args);\n      }\n      return wrapper;\n    }\n\n    /**\n     * Creates a `_.range` or `_.rangeRight` function.\n     *\n     * @private\n     * @param {boolean} [fromRight] Specify iterating from right to left.\n     * @returns {Function} Returns the new range function.\n     */\n    function createRange(fromRight) {\n      return function(start, end, step) {\n        if (step && typeof step != 'number' && isIterateeCall(start, end, step)) {\n          end = step = undefined;\n        }\n        // Ensure the sign of `-0` is preserved.\n        start = toFinite(start);\n        if (end === undefined) {\n          end = start;\n          start = 0;\n        } else {\n          end = toFinite(end);\n        }\n        step = step === undefined ? (start < end ? 1 : -1) : toFinite(step);\n        return baseRange(start, end, step, fromRight);\n      };\n    }\n\n    /**\n     * Creates a function that performs a relational operation on two values.\n     *\n     * @private\n     * @param {Function} operator The function to perform the operation.\n     * @returns {Function} Returns the new relational operation function.\n     */\n    function createRelationalOperation(operator) {\n      return function(value, other) {\n        if (!(typeof value == 'string' && typeof other == 'string')) {\n          value = toNumber(value);\n          other = toNumber(other);\n        }\n        return operator(value, other);\n      };\n    }\n\n    /**\n     * Creates a function that wraps `func` to continue currying.\n     *\n     * @private\n     * @param {Function} func The function to wrap.\n     * @param {number} bitmask The bitmask flags. See `createWrap` for more details.\n     * @param {Function} wrapFunc The function to create the `func` wrapper.\n     * @param {*} placeholder The placeholder value.\n     * @param {*} [thisArg] The `this` binding of `func`.\n     * @param {Array} [partials] The arguments to prepend to those provided to\n     *  the new function.\n     * @param {Array} [holders] The `partials` placeholder indexes.\n     * @param {Array} [argPos] The argument positions of the new function.\n     * @param {number} [ary] The arity cap of `func`.\n     * @param {number} [arity] The arity of `func`.\n     * @returns {Function} Returns the new wrapped function.\n     */\n    function createRecurry(func, bitmask, wrapFunc, placeholder, thisArg, partials, holders, argPos, ary, arity) {\n      var isCurry = bitmask & WRAP_CURRY_FLAG,\n          newHolders = isCurry ? holders : undefined,\n          newHoldersRight = isCurry ? undefined : holders,\n          newPartials = isCurry ? partials : undefined,\n          newPartialsRight = isCurry ? undefined : partials;\n\n      bitmask |= (isCurry ? WRAP_PARTIAL_FLAG : WRAP_PARTIAL_RIGHT_FLAG);\n      bitmask &= ~(isCurry ? WRAP_PARTIAL_RIGHT_FLAG : WRAP_PARTIAL_FLAG);\n\n      if (!(bitmask & WRAP_CURRY_BOUND_FLAG)) {\n        bitmask &= ~(WRAP_BIND_FLAG | WRAP_BIND_KEY_FLAG);\n      }\n      var newData = [\n        func, bitmask, thisArg, newPartials, newHolders, newPartialsRight,\n        newHoldersRight, argPos, ary, arity\n      ];\n\n      var result = wrapFunc.apply(undefined, newData);\n      if (isLaziable(func)) {\n        setData(result, newData);\n      }\n      result.placeholder = placeholder;\n      return setWrapToString(result, func, bitmask);\n    }\n\n    /**\n     * Creates a function like `_.round`.\n     *\n     * @private\n     * @param {string} methodName The name of the `Math` method to use when rounding.\n     * @returns {Function} Returns the new round function.\n     */\n    function createRound(methodName) {\n      var func = Math[methodName];\n      return function(number, precision) {\n        number = toNumber(number);\n        precision = precision == null ? 0 : nativeMin(toInteger(precision), 292);\n        if (precision) {\n          // Shift with exponential notation to avoid floating-point issues.\n          // See [MDN](https://mdn.io/round#Examples) for more details.\n          var pair = (toString(number) + 'e').split('e'),\n              value = func(pair[0] + 'e' + (+pair[1] + precision));\n\n          pair = (toString(value) + 'e').split('e');\n          return +(pair[0] + 'e' + (+pair[1] - precision));\n        }\n        return func(number);\n      };\n    }\n\n    /**\n     * Creates a set object of `values`.\n     *\n     * @private\n     * @param {Array} values The values to add to the set.\n     * @returns {Object} Returns the new set.\n     */\n    var createSet = !(Set && (1 / setToArray(new Set([,-0]))[1]) == INFINITY) ? noop : function(values) {\n      return new Set(values);\n    };\n\n    /**\n     * Creates a `_.toPairs` or `_.toPairsIn` function.\n     *\n     * @private\n     * @param {Function} keysFunc The function to get the keys of a given object.\n     * @returns {Function} Returns the new pairs function.\n     */\n    function createToPairs(keysFunc) {\n      return function(object) {\n        var tag = getTag(object);\n        if (tag == mapTag) {\n          return mapToArray(object);\n        }\n        if (tag == setTag) {\n          return setToPairs(object);\n        }\n        return baseToPairs(object, keysFunc(object));\n      };\n    }\n\n    /**\n     * Creates a function that either curries or invokes `func` with optional\n     * `this` binding and partially applied arguments.\n     *\n     * @private\n     * @param {Function|string} func The function or method name to wrap.\n     * @param {number} bitmask The bitmask flags.\n     *    1 - `_.bind`\n     *    2 - `_.bindKey`\n     *    4 - `_.curry` or `_.curryRight` of a bound function\n     *    8 - `_.curry`\n     *   16 - `_.curryRight`\n     *   32 - `_.partial`\n     *   64 - `_.partialRight`\n     *  128 - `_.rearg`\n     *  256 - `_.ary`\n     *  512 - `_.flip`\n     * @param {*} [thisArg] The `this` binding of `func`.\n     * @param {Array} [partials] The arguments to be partially applied.\n     * @param {Array} [holders] The `partials` placeholder indexes.\n     * @param {Array} [argPos] The argument positions of the new function.\n     * @param {number} [ary] The arity cap of `func`.\n     * @param {number} [arity] The arity of `func`.\n     * @returns {Function} Returns the new wrapped function.\n     */\n    function createWrap(func, bitmask, thisArg, partials, holders, argPos, ary, arity) {\n      var isBindKey = bitmask & WRAP_BIND_KEY_FLAG;\n      if (!isBindKey && typeof func != 'function') {\n        throw new TypeError(FUNC_ERROR_TEXT);\n      }\n      var length = partials ? partials.length : 0;\n      if (!length) {\n        bitmask &= ~(WRAP_PARTIAL_FLAG | WRAP_PARTIAL_RIGHT_FLAG);\n        partials = holders = undefined;\n      }\n      ary = ary === undefined ? ary : nativeMax(toInteger(ary), 0);\n      arity = arity === undefined ? arity : toInteger(arity);\n      length -= holders ? holders.length : 0;\n\n      if (bitmask & WRAP_PARTIAL_RIGHT_FLAG) {\n        var partialsRight = partials,\n            holdersRight = holders;\n\n        partials = holders = undefined;\n      }\n      var data = isBindKey ? undefined : getData(func);\n\n      var newData = [\n        func, bitmask, thisArg, partials, holders, partialsRight, holdersRight,\n        argPos, ary, arity\n      ];\n\n      if (data) {\n        mergeData(newData, data);\n      }\n      func = newData[0];\n      bitmask = newData[1];\n      thisArg = newData[2];\n      partials = newData[3];\n      holders = newData[4];\n      arity = newData[9] = newData[9] === undefined\n        ? (isBindKey ? 0 : func.length)\n        : nativeMax(newData[9] - length, 0);\n\n      if (!arity && bitmask & (WRAP_CURRY_FLAG | WRAP_CURRY_RIGHT_FLAG)) {\n        bitmask &= ~(WRAP_CURRY_FLAG | WRAP_CURRY_RIGHT_FLAG);\n      }\n      if (!bitmask || bitmask == WRAP_BIND_FLAG) {\n        var result = createBind(func, bitmask, thisArg);\n      } else if (bitmask == WRAP_CURRY_FLAG || bitmask == WRAP_CURRY_RIGHT_FLAG) {\n        result = createCurry(func, bitmask, arity);\n      } else if ((bitmask == WRAP_PARTIAL_FLAG || bitmask == (WRAP_BIND_FLAG | WRAP_PARTIAL_FLAG)) && !holders.length) {\n        result = createPartial(func, bitmask, thisArg, partials);\n      } else {\n        result = createHybrid.apply(undefined, newData);\n      }\n      var setter = data ? baseSetData : setData;\n      return setWrapToString(setter(result, newData), func, bitmask);\n    }\n\n    /**\n     * Used by `_.defaults` to customize its `_.assignIn` use to assign properties\n     * of source objects to the destination object for all destination properties\n     * that resolve to `undefined`.\n     *\n     * @private\n     * @param {*} objValue The destination value.\n     * @param {*} srcValue The source value.\n     * @param {string} key The key of the property to assign.\n     * @param {Object} object The parent object of `objValue`.\n     * @returns {*} Returns the value to assign.\n     */\n    function customDefaultsAssignIn(objValue, srcValue, key, object) {\n      if (objValue === undefined ||\n          (eq(objValue, objectProto[key]) && !hasOwnProperty.call(object, key))) {\n        return srcValue;\n      }\n      return objValue;\n    }\n\n    /**\n     * Used by `_.defaultsDeep` to customize its `_.merge` use to merge source\n     * objects into destination objects that are passed thru.\n     *\n     * @private\n     * @param {*} objValue The destination value.\n     * @param {*} srcValue The source value.\n     * @param {string} key The key of the property to merge.\n     * @param {Object} object The parent object of `objValue`.\n     * @param {Object} source The parent object of `srcValue`.\n     * @param {Object} [stack] Tracks traversed source values and their merged\n     *  counterparts.\n     * @returns {*} Returns the value to assign.\n     */\n    function customDefaultsMerge(objValue, srcValue, key, object, source, stack) {\n      if (isObject(objValue) && isObject(srcValue)) {\n        // Recursively merge objects and arrays (susceptible to call stack limits).\n        stack.set(srcValue, objValue);\n        baseMerge(objValue, srcValue, undefined, customDefaultsMerge, stack);\n        stack['delete'](srcValue);\n      }\n      return objValue;\n    }\n\n    /**\n     * Used by `_.omit` to customize its `_.cloneDeep` use to only clone plain\n     * objects.\n     *\n     * @private\n     * @param {*} value The value to inspect.\n     * @param {string} key The key of the property to inspect.\n     * @returns {*} Returns the uncloned value or `undefined` to defer cloning to `_.cloneDeep`.\n     */\n    function customOmitClone(value) {\n      return isPlainObject(value) ? undefined : value;\n    }\n\n    /**\n     * A specialized version of `baseIsEqualDeep` for arrays with support for\n     * partial deep comparisons.\n     *\n     * @private\n     * @param {Array} array The array to compare.\n     * @param {Array} other The other array to compare.\n     * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details.\n     * @param {Function} customizer The function to customize comparisons.\n     * @param {Function} equalFunc The function to determine equivalents of values.\n     * @param {Object} stack Tracks traversed `array` and `other` objects.\n     * @returns {boolean} Returns `true` if the arrays are equivalent, else `false`.\n     */\n    function equalArrays(array, other, bitmask, customizer, equalFunc, stack) {\n      var isPartial = bitmask & COMPARE_PARTIAL_FLAG,\n          arrLength = array.length,\n          othLength = other.length;\n\n      if (arrLength != othLength && !(isPartial && othLength > arrLength)) {\n        return false;\n      }\n      // Assume cyclic values are equal.\n      var stacked = stack.get(array);\n      if (stacked && stack.get(other)) {\n        return stacked == other;\n      }\n      var index = -1,\n          result = true,\n          seen = (bitmask & COMPARE_UNORDERED_FLAG) ? new SetCache : undefined;\n\n      stack.set(array, other);\n      stack.set(other, array);\n\n      // Ignore non-index properties.\n      while (++index < arrLength) {\n        var arrValue = array[index],\n            othValue = other[index];\n\n        if (customizer) {\n          var compared = isPartial\n            ? customizer(othValue, arrValue, index, other, array, stack)\n            : customizer(arrValue, othValue, index, array, other, stack);\n        }\n        if (compared !== undefined) {\n          if (compared) {\n            continue;\n          }\n          result = false;\n          break;\n        }\n        // Recursively compare arrays (susceptible to call stack limits).\n        if (seen) {\n          if (!arraySome(other, function(othValue, othIndex) {\n                if (!cacheHas(seen, othIndex) &&\n                    (arrValue === othValue || equalFunc(arrValue, othValue, bitmask, customizer, stack))) {\n                  return seen.push(othIndex);\n                }\n              })) {\n            result = false;\n            break;\n          }\n        } else if (!(\n              arrValue === othValue ||\n                equalFunc(arrValue, othValue, bitmask, customizer, stack)\n            )) {\n          result = false;\n          break;\n        }\n      }\n      stack['delete'](array);\n      stack['delete'](other);\n      return result;\n    }\n\n    /**\n     * A specialized version of `baseIsEqualDeep` for comparing objects of\n     * the same `toStringTag`.\n     *\n     * **Note:** This function only supports comparing values with tags of\n     * `Boolean`, `Date`, `Error`, `Number`, `RegExp`, or `String`.\n     *\n     * @private\n     * @param {Object} object The object to compare.\n     * @param {Object} other The other object to compare.\n     * @param {string} tag The `toStringTag` of the objects to compare.\n     * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details.\n     * @param {Function} customizer The function to customize comparisons.\n     * @param {Function} equalFunc The function to determine equivalents of values.\n     * @param {Object} stack Tracks traversed `object` and `other` objects.\n     * @returns {boolean} Returns `true` if the objects are equivalent, else `false`.\n     */\n    function equalByTag(object, other, tag, bitmask, customizer, equalFunc, stack) {\n      switch (tag) {\n        case dataViewTag:\n          if ((object.byteLength != other.byteLength) ||\n              (object.byteOffset != other.byteOffset)) {\n            return false;\n          }\n          object = object.buffer;\n          other = other.buffer;\n\n        case arrayBufferTag:\n          if ((object.byteLength != other.byteLength) ||\n              !equalFunc(new Uint8Array(object), new Uint8Array(other))) {\n            return false;\n          }\n          return true;\n\n        case boolTag:\n        case dateTag:\n        case numberTag:\n          // Coerce booleans to `1` or `0` and dates to milliseconds.\n          // Invalid dates are coerced to `NaN`.\n          return eq(+object, +other);\n\n        case errorTag:\n          return object.name == other.name && object.message == other.message;\n\n        case regexpTag:\n        case stringTag:\n          // Coerce regexes to strings and treat strings, primitives and objects,\n          // as equal. See http://www.ecma-international.org/ecma-262/7.0/#sec-regexp.prototype.tostring\n          // for more details.\n          return object == (other + '');\n\n        case mapTag:\n          var convert = mapToArray;\n\n        case setTag:\n          var isPartial = bitmask & COMPARE_PARTIAL_FLAG;\n          convert || (convert = setToArray);\n\n          if (object.size != other.size && !isPartial) {\n            return false;\n          }\n          // Assume cyclic values are equal.\n          var stacked = stack.get(object);\n          if (stacked) {\n            return stacked == other;\n          }\n          bitmask |= COMPARE_UNORDERED_FLAG;\n\n          // Recursively compare objects (susceptible to call stack limits).\n          stack.set(object, other);\n          var result = equalArrays(convert(object), convert(other), bitmask, customizer, equalFunc, stack);\n          stack['delete'](object);\n          return result;\n\n        case symbolTag:\n          if (symbolValueOf) {\n            return symbolValueOf.call(object) == symbolValueOf.call(other);\n          }\n      }\n      return false;\n    }\n\n    /**\n     * A specialized version of `baseIsEqualDeep` for objects with support for\n     * partial deep comparisons.\n     *\n     * @private\n     * @param {Object} object The object to compare.\n     * @param {Object} other The other object to compare.\n     * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details.\n     * @param {Function} customizer The function to customize comparisons.\n     * @param {Function} equalFunc The function to determine equivalents of values.\n     * @param {Object} stack Tracks traversed `object` and `other` objects.\n     * @returns {boolean} Returns `true` if the objects are equivalent, else `false`.\n     */\n    function equalObjects(object, other, bitmask, customizer, equalFunc, stack) {\n      var isPartial = bitmask & COMPARE_PARTIAL_FLAG,\n          objProps = getAllKeys(object),\n          objLength = objProps.length,\n          othProps = getAllKeys(other),\n          othLength = othProps.length;\n\n      if (objLength != othLength && !isPartial) {\n        return false;\n      }\n      var index = objLength;\n      while (index--) {\n        var key = objProps[index];\n        if (!(isPartial ? key in other : hasOwnProperty.call(other, key))) {\n          return false;\n        }\n      }\n      // Assume cyclic values are equal.\n      var stacked = stack.get(object);\n      if (stacked && stack.get(other)) {\n        return stacked == other;\n      }\n      var result = true;\n      stack.set(object, other);\n      stack.set(other, object);\n\n      var skipCtor = isPartial;\n      while (++index < objLength) {\n        key = objProps[index];\n        var objValue = object[key],\n            othValue = other[key];\n\n        if (customizer) {\n          var compared = isPartial\n            ? customizer(othValue, objValue, key, other, object, stack)\n            : customizer(objValue, othValue, key, object, other, stack);\n        }\n        // Recursively compare objects (susceptible to call stack limits).\n        if (!(compared === undefined\n              ? (objValue === othValue || equalFunc(objValue, othValue, bitmask, customizer, stack))\n              : compared\n            )) {\n          result = false;\n          break;\n        }\n        skipCtor || (skipCtor = key == 'constructor');\n      }\n      if (result && !skipCtor) {\n        var objCtor = object.constructor,\n            othCtor = other.constructor;\n\n        // Non `Object` object instances with different constructors are not equal.\n        if (objCtor != othCtor &&\n            ('constructor' in object && 'constructor' in other) &&\n            !(typeof objCtor == 'function' && objCtor instanceof objCtor &&\n              typeof othCtor == 'function' && othCtor instanceof othCtor)) {\n          result = false;\n        }\n      }\n      stack['delete'](object);\n      stack['delete'](other);\n      return result;\n    }\n\n    /**\n     * A specialized version of `baseRest` which flattens the rest array.\n     *\n     * @private\n     * @param {Function} func The function to apply a rest parameter to.\n     * @returns {Function} Returns the new function.\n     */\n    function flatRest(func) {\n      return setToString(overRest(func, undefined, flatten), func + '');\n    }\n\n    /**\n     * Creates an array of own enumerable property names and symbols of `object`.\n     *\n     * @private\n     * @param {Object} object The object to query.\n     * @returns {Array} Returns the array of property names and symbols.\n     */\n    function getAllKeys(object) {\n      return baseGetAllKeys(object, keys, getSymbols);\n    }\n\n    /**\n     * Creates an array of own and inherited enumerable property names and\n     * symbols of `object`.\n     *\n     * @private\n     * @param {Object} object The object to query.\n     * @returns {Array} Returns the array of property names and symbols.\n     */\n    function getAllKeysIn(object) {\n      return baseGetAllKeys(object, keysIn, getSymbolsIn);\n    }\n\n    /**\n     * Gets metadata for `func`.\n     *\n     * @private\n     * @param {Function} func The function to query.\n     * @returns {*} Returns the metadata for `func`.\n     */\n    var getData = !metaMap ? noop : function(func) {\n      return metaMap.get(func);\n    };\n\n    /**\n     * Gets the name of `func`.\n     *\n     * @private\n     * @param {Function} func The function to query.\n     * @returns {string} Returns the function name.\n     */\n    function getFuncName(func) {\n      var result = (func.name + ''),\n          array = realNames[result],\n          length = hasOwnProperty.call(realNames, result) ? array.length : 0;\n\n      while (length--) {\n        var data = array[length],\n            otherFunc = data.func;\n        if (otherFunc == null || otherFunc == func) {\n          return data.name;\n        }\n      }\n      return result;\n    }\n\n    /**\n     * Gets the argument placeholder value for `func`.\n     *\n     * @private\n     * @param {Function} func The function to inspect.\n     * @returns {*} Returns the placeholder value.\n     */\n    function getHolder(func) {\n      var object = hasOwnProperty.call(lodash, 'placeholder') ? lodash : func;\n      return object.placeholder;\n    }\n\n    /**\n     * Gets the appropriate \"iteratee\" function. If `_.iteratee` is customized,\n     * this function returns the custom method, otherwise it returns `baseIteratee`.\n     * If arguments are provided, the chosen function is invoked with them and\n     * its result is returned.\n     *\n     * @private\n     * @param {*} [value] The value to convert to an iteratee.\n     * @param {number} [arity] The arity of the created iteratee.\n     * @returns {Function} Returns the chosen function or its result.\n     */\n    function getIteratee() {\n      var result = lodash.iteratee || iteratee;\n      result = result === iteratee ? baseIteratee : result;\n      return arguments.length ? result(arguments[0], arguments[1]) : result;\n    }\n\n    /**\n     * Gets the data for `map`.\n     *\n     * @private\n     * @param {Object} map The map to query.\n     * @param {string} key The reference key.\n     * @returns {*} Returns the map data.\n     */\n    function getMapData(map, key) {\n      var data = map.__data__;\n      return isKeyable(key)\n        ? data[typeof key == 'string' ? 'string' : 'hash']\n        : data.map;\n    }\n\n    /**\n     * Gets the property names, values, and compare flags of `object`.\n     *\n     * @private\n     * @param {Object} object The object to query.\n     * @returns {Array} Returns the match data of `object`.\n     */\n    function getMatchData(object) {\n      var result = keys(object),\n          length = result.length;\n\n      while (length--) {\n        var key = result[length],\n            value = object[key];\n\n        result[length] = [key, value, isStrictComparable(value)];\n      }\n      return result;\n    }\n\n    /**\n     * Gets the native function at `key` of `object`.\n     *\n     * @private\n     * @param {Object} object The object to query.\n     * @param {string} key The key of the method to get.\n     * @returns {*} Returns the function if it's native, else `undefined`.\n     */\n    function getNative(object, key) {\n      var value = getValue(object, key);\n      return baseIsNative(value) ? value : undefined;\n    }\n\n    /**\n     * A specialized version of `baseGetTag` which ignores `Symbol.toStringTag` values.\n     *\n     * @private\n     * @param {*} value The value to query.\n     * @returns {string} Returns the raw `toStringTag`.\n     */\n    function getRawTag(value) {\n      var isOwn = hasOwnProperty.call(value, symToStringTag),\n          tag = value[symToStringTag];\n\n      try {\n        value[symToStringTag] = undefined;\n        var unmasked = true;\n      } catch (e) {}\n\n      var result = nativeObjectToString.call(value);\n      if (unmasked) {\n        if (isOwn) {\n          value[symToStringTag] = tag;\n        } else {\n          delete value[symToStringTag];\n        }\n      }\n      return result;\n    }\n\n    /**\n     * Creates an array of the own enumerable symbols of `object`.\n     *\n     * @private\n     * @param {Object} object The object to query.\n     * @returns {Array} Returns the array of symbols.\n     */\n    var getSymbols = !nativeGetSymbols ? stubArray : function(object) {\n      if (object == null) {\n        return [];\n      }\n      object = Object(object);\n      return arrayFilter(nativeGetSymbols(object), function(symbol) {\n        return propertyIsEnumerable.call(object, symbol);\n      });\n    };\n\n    /**\n     * Creates an array of the own and inherited enumerable symbols of `object`.\n     *\n     * @private\n     * @param {Object} object The object to query.\n     * @returns {Array} Returns the array of symbols.\n     */\n    var getSymbolsIn = !nativeGetSymbols ? stubArray : function(object) {\n      var result = [];\n      while (object) {\n        arrayPush(result, getSymbols(object));\n        object = getPrototype(object);\n      }\n      return result;\n    };\n\n    /**\n     * Gets the `toStringTag` of `value`.\n     *\n     * @private\n     * @param {*} value The value to query.\n     * @returns {string} Returns the `toStringTag`.\n     */\n    var getTag = baseGetTag;\n\n    // Fallback for data views, maps, sets, and weak maps in IE 11 and promises in Node.js < 6.\n    if ((DataView && getTag(new DataView(new ArrayBuffer(1))) != dataViewTag) ||\n        (Map && getTag(new Map) != mapTag) ||\n        (Promise && getTag(Promise.resolve()) != promiseTag) ||\n        (Set && getTag(new Set) != setTag) ||\n        (WeakMap && getTag(new WeakMap) != weakMapTag)) {\n      getTag = function(value) {\n        var result = baseGetTag(value),\n            Ctor = result == objectTag ? value.constructor : undefined,\n            ctorString = Ctor ? toSource(Ctor) : '';\n\n        if (ctorString) {\n          switch (ctorString) {\n            case dataViewCtorString: return dataViewTag;\n            case mapCtorString: return mapTag;\n            case promiseCtorString: return promiseTag;\n            case setCtorString: return setTag;\n            case weakMapCtorString: return weakMapTag;\n          }\n        }\n        return result;\n      };\n    }\n\n    /**\n     * Gets the view, applying any `transforms` to the `start` and `end` positions.\n     *\n     * @private\n     * @param {number} start The start of the view.\n     * @param {number} end The end of the view.\n     * @param {Array} transforms The transformations to apply to the view.\n     * @returns {Object} Returns an object containing the `start` and `end`\n     *  positions of the view.\n     */\n    function getView(start, end, transforms) {\n      var index = -1,\n          length = transforms.length;\n\n      while (++index < length) {\n        var data = transforms[index],\n            size = data.size;\n\n        switch (data.type) {\n          case 'drop':      start += size; break;\n          case 'dropRight': end -= size; break;\n          case 'take':      end = nativeMin(end, start + size); break;\n          case 'takeRight': start = nativeMax(start, end - size); break;\n        }\n      }\n      return { 'start': start, 'end': end };\n    }\n\n    /**\n     * Extracts wrapper details from the `source` body comment.\n     *\n     * @private\n     * @param {string} source The source to inspect.\n     * @returns {Array} Returns the wrapper details.\n     */\n    function getWrapDetails(source) {\n      var match = source.match(reWrapDetails);\n      return match ? match[1].split(reSplitDetails) : [];\n    }\n\n    /**\n     * Checks if `path` exists on `object`.\n     *\n     * @private\n     * @param {Object} object The object to query.\n     * @param {Array|string} path The path to check.\n     * @param {Function} hasFunc The function to check properties.\n     * @returns {boolean} Returns `true` if `path` exists, else `false`.\n     */\n    function hasPath(object, path, hasFunc) {\n      path = castPath(path, object);\n\n      var index = -1,\n          length = path.length,\n          result = false;\n\n      while (++index < length) {\n        var key = toKey(path[index]);\n        if (!(result = object != null && hasFunc(object, key))) {\n          break;\n        }\n        object = object[key];\n      }\n      if (result || ++index != length) {\n        return result;\n      }\n      length = object == null ? 0 : object.length;\n      return !!length && isLength(length) && isIndex(key, length) &&\n        (isArray(object) || isArguments(object));\n    }\n\n    /**\n     * Initializes an array clone.\n     *\n     * @private\n     * @param {Array} array The array to clone.\n     * @returns {Array} Returns the initialized clone.\n     */\n    function initCloneArray(array) {\n      var length = array.length,\n          result = new array.constructor(length);\n\n      // Add properties assigned by `RegExp#exec`.\n      if (length && typeof array[0] == 'string' && hasOwnProperty.call(array, 'index')) {\n        result.index = array.index;\n        result.input = array.input;\n      }\n      return result;\n    }\n\n    /**\n     * Initializes an object clone.\n     *\n     * @private\n     * @param {Object} object The object to clone.\n     * @returns {Object} Returns the initialized clone.\n     */\n    function initCloneObject(object) {\n      return (typeof object.constructor == 'function' && !isPrototype(object))\n        ? baseCreate(getPrototype(object))\n        : {};\n    }\n\n    /**\n     * Initializes an object clone based on its `toStringTag`.\n     *\n     * **Note:** This function only supports cloning values with tags of\n     * `Boolean`, `Date`, `Error`, `Map`, `Number`, `RegExp`, `Set`, or `String`.\n     *\n     * @private\n     * @param {Object} object The object to clone.\n     * @param {string} tag The `toStringTag` of the object to clone.\n     * @param {boolean} [isDeep] Specify a deep clone.\n     * @returns {Object} Returns the initialized clone.\n     */\n    function initCloneByTag(object, tag, isDeep) {\n      var Ctor = object.constructor;\n      switch (tag) {\n        case arrayBufferTag:\n          return cloneArrayBuffer(object);\n\n        case boolTag:\n        case dateTag:\n          return new Ctor(+object);\n\n        case dataViewTag:\n          return cloneDataView(object, isDeep);\n\n        case float32Tag: case float64Tag:\n        case int8Tag: case int16Tag: case int32Tag:\n        case uint8Tag: case uint8ClampedTag: case uint16Tag: case uint32Tag:\n          return cloneTypedArray(object, isDeep);\n\n        case mapTag:\n          return new Ctor;\n\n        case numberTag:\n        case stringTag:\n          return new Ctor(object);\n\n        case regexpTag:\n          return cloneRegExp(object);\n\n        case setTag:\n          return new Ctor;\n\n        case symbolTag:\n          return cloneSymbol(object);\n      }\n    }\n\n    /**\n     * Inserts wrapper `details` in a comment at the top of the `source` body.\n     *\n     * @private\n     * @param {string} source The source to modify.\n     * @returns {Array} details The details to insert.\n     * @returns {string} Returns the modified source.\n     */\n    function insertWrapDetails(source, details) {\n      var length = details.length;\n      if (!length) {\n        return source;\n      }\n      var lastIndex = length - 1;\n      details[lastIndex] = (length > 1 ? '& ' : '') + details[lastIndex];\n      details = details.join(length > 2 ? ', ' : ' ');\n      return source.replace(reWrapComment, '{\\n/* [wrapped with ' + details + '] */\\n');\n    }\n\n    /**\n     * Checks if `value` is a flattenable `arguments` object or array.\n     *\n     * @private\n     * @param {*} value The value to check.\n     * @returns {boolean} Returns `true` if `value` is flattenable, else `false`.\n     */\n    function isFlattenable(value) {\n      return isArray(value) || isArguments(value) ||\n        !!(spreadableSymbol && value && value[spreadableSymbol]);\n    }\n\n    /**\n     * Checks if `value` is a valid array-like index.\n     *\n     * @private\n     * @param {*} value The value to check.\n     * @param {number} [length=MAX_SAFE_INTEGER] The upper bounds of a valid index.\n     * @returns {boolean} Returns `true` if `value` is a valid index, else `false`.\n     */\n    function isIndex(value, length) {\n      var type = typeof value;\n      length = length == null ? MAX_SAFE_INTEGER : length;\n\n      return !!length &&\n        (type == 'number' ||\n          (type != 'symbol' && reIsUint.test(value))) &&\n            (value > -1 && value % 1 == 0 && value < length);\n    }\n\n    /**\n     * Checks if the given arguments are from an iteratee call.\n     *\n     * @private\n     * @param {*} value The potential iteratee value argument.\n     * @param {*} index The potential iteratee index or key argument.\n     * @param {*} object The potential iteratee object argument.\n     * @returns {boolean} Returns `true` if the arguments are from an iteratee call,\n     *  else `false`.\n     */\n    function isIterateeCall(value, index, object) {\n      if (!isObject(object)) {\n        return false;\n      }\n      var type = typeof index;\n      if (type == 'number'\n            ? (isArrayLike(object) && isIndex(index, object.length))\n            : (type == 'string' && index in object)\n          ) {\n        return eq(object[index], value);\n      }\n      return false;\n    }\n\n    /**\n     * Checks if `value` is a property name and not a property path.\n     *\n     * @private\n     * @param {*} value The value to check.\n     * @param {Object} [object] The object to query keys on.\n     * @returns {boolean} Returns `true` if `value` is a property name, else `false`.\n     */\n    function isKey(value, object) {\n      if (isArray(value)) {\n        return false;\n      }\n      var type = typeof value;\n      if (type == 'number' || type == 'symbol' || type == 'boolean' ||\n          value == null || isSymbol(value)) {\n        return true;\n      }\n      return reIsPlainProp.test(value) || !reIsDeepProp.test(value) ||\n        (object != null && value in Object(object));\n    }\n\n    /**\n     * Checks if `value` is suitable for use as unique object key.\n     *\n     * @private\n     * @param {*} value The value to check.\n     * @returns {boolean} Returns `true` if `value` is suitable, else `false`.\n     */\n    function isKeyable(value) {\n      var type = typeof value;\n      return (type == 'string' || type == 'number' || type == 'symbol' || type == 'boolean')\n        ? (value !== '__proto__')\n        : (value === null);\n    }\n\n    /**\n     * Checks if `func` has a lazy counterpart.\n     *\n     * @private\n     * @param {Function} func The function to check.\n     * @returns {boolean} Returns `true` if `func` has a lazy counterpart,\n     *  else `false`.\n     */\n    function isLaziable(func) {\n      var funcName = getFuncName(func),\n          other = lodash[funcName];\n\n      if (typeof other != 'function' || !(funcName in LazyWrapper.prototype)) {\n        return false;\n      }\n      if (func === other) {\n        return true;\n      }\n      var data = getData(other);\n      return !!data && func === data[0];\n    }\n\n    /**\n     * Checks if `func` has its source masked.\n     *\n     * @private\n     * @param {Function} func The function to check.\n     * @returns {boolean} Returns `true` if `func` is masked, else `false`.\n     */\n    function isMasked(func) {\n      return !!maskSrcKey && (maskSrcKey in func);\n    }\n\n    /**\n     * Checks if `func` is capable of being masked.\n     *\n     * @private\n     * @param {*} value The value to check.\n     * @returns {boolean} Returns `true` if `func` is maskable, else `false`.\n     */\n    var isMaskable = coreJsData ? isFunction : stubFalse;\n\n    /**\n     * Checks if `value` is likely a prototype object.\n     *\n     * @private\n     * @param {*} value The value to check.\n     * @returns {boolean} Returns `true` if `value` is a prototype, else `false`.\n     */\n    function isPrototype(value) {\n      var Ctor = value && value.constructor,\n          proto = (typeof Ctor == 'function' && Ctor.prototype) || objectProto;\n\n      return value === proto;\n    }\n\n    /**\n     * Checks if `value` is suitable for strict equality comparisons, i.e. `===`.\n     *\n     * @private\n     * @param {*} value The value to check.\n     * @returns {boolean} Returns `true` if `value` if suitable for strict\n     *  equality comparisons, else `false`.\n     */\n    function isStrictComparable(value) {\n      return value === value && !isObject(value);\n    }\n\n    /**\n     * A specialized version of `matchesProperty` for source values suitable\n     * for strict equality comparisons, i.e. `===`.\n     *\n     * @private\n     * @param {string} key The key of the property to get.\n     * @param {*} srcValue The value to match.\n     * @returns {Function} Returns the new spec function.\n     */\n    function matchesStrictComparable(key, srcValue) {\n      return function(object) {\n        if (object == null) {\n          return false;\n        }\n        return object[key] === srcValue &&\n          (srcValue !== undefined || (key in Object(object)));\n      };\n    }\n\n    /**\n     * A specialized version of `_.memoize` which clears the memoized function's\n     * cache when it exceeds `MAX_MEMOIZE_SIZE`.\n     *\n     * @private\n     * @param {Function} func The function to have its output memoized.\n     * @returns {Function} Returns the new memoized function.\n     */\n    function memoizeCapped(func) {\n      var result = memoize(func, function(key) {\n        if (cache.size === MAX_MEMOIZE_SIZE) {\n          cache.clear();\n        }\n        return key;\n      });\n\n      var cache = result.cache;\n      return result;\n    }\n\n    /**\n     * Merges the function metadata of `source` into `data`.\n     *\n     * Merging metadata reduces the number of wrappers used to invoke a function.\n     * This is possible because methods like `_.bind`, `_.curry`, and `_.partial`\n     * may be applied regardless of execution order. Methods like `_.ary` and\n     * `_.rearg` modify function arguments, making the order in which they are\n     * executed important, preventing the merging of metadata. However, we make\n     * an exception for a safe combined case where curried functions have `_.ary`\n     * and or `_.rearg` applied.\n     *\n     * @private\n     * @param {Array} data The destination metadata.\n     * @param {Array} source The source metadata.\n     * @returns {Array} Returns `data`.\n     */\n    function mergeData(data, source) {\n      var bitmask = data[1],\n          srcBitmask = source[1],\n          newBitmask = bitmask | srcBitmask,\n          isCommon = newBitmask < (WRAP_BIND_FLAG | WRAP_BIND_KEY_FLAG | WRAP_ARY_FLAG);\n\n      var isCombo =\n        ((srcBitmask == WRAP_ARY_FLAG) && (bitmask == WRAP_CURRY_FLAG)) ||\n        ((srcBitmask == WRAP_ARY_FLAG) && (bitmask == WRAP_REARG_FLAG) && (data[7].length <= source[8])) ||\n        ((srcBitmask == (WRAP_ARY_FLAG | WRAP_REARG_FLAG)) && (source[7].length <= source[8]) && (bitmask == WRAP_CURRY_FLAG));\n\n      // Exit early if metadata can't be merged.\n      if (!(isCommon || isCombo)) {\n        return data;\n      }\n      // Use source `thisArg` if available.\n      if (srcBitmask & WRAP_BIND_FLAG) {\n        data[2] = source[2];\n        // Set when currying a bound function.\n        newBitmask |= bitmask & WRAP_BIND_FLAG ? 0 : WRAP_CURRY_BOUND_FLAG;\n      }\n      // Compose partial arguments.\n      var value = source[3];\n      if (value) {\n        var partials = data[3];\n        data[3] = partials ? composeArgs(partials, value, source[4]) : value;\n        data[4] = partials ? replaceHolders(data[3], PLACEHOLDER) : source[4];\n      }\n      // Compose partial right arguments.\n      value = source[5];\n      if (value) {\n        partials = data[5];\n        data[5] = partials ? composeArgsRight(partials, value, source[6]) : value;\n        data[6] = partials ? replaceHolders(data[5], PLACEHOLDER) : source[6];\n      }\n      // Use source `argPos` if available.\n      value = source[7];\n      if (value) {\n        data[7] = value;\n      }\n      // Use source `ary` if it's smaller.\n      if (srcBitmask & WRAP_ARY_FLAG) {\n        data[8] = data[8] == null ? source[8] : nativeMin(data[8], source[8]);\n      }\n      // Use source `arity` if one is not provided.\n      if (data[9] == null) {\n        data[9] = source[9];\n      }\n      // Use source `func` and merge bitmasks.\n      data[0] = source[0];\n      data[1] = newBitmask;\n\n      return data;\n    }\n\n    /**\n     * This function is like\n     * [`Object.keys`](http://ecma-international.org/ecma-262/7.0/#sec-object.keys)\n     * except that it includes inherited enumerable properties.\n     *\n     * @private\n     * @param {Object} object The object to query.\n     * @returns {Array} Returns the array of property names.\n     */\n    function nativeKeysIn(object) {\n      var result = [];\n      if (object != null) {\n        for (var key in Object(object)) {\n          result.push(key);\n        }\n      }\n      return result;\n    }\n\n    /**\n     * Converts `value` to a string using `Object.prototype.toString`.\n     *\n     * @private\n     * @param {*} value The value to convert.\n     * @returns {string} Returns the converted string.\n     */\n    function objectToString(value) {\n      return nativeObjectToString.call(value);\n    }\n\n    /**\n     * A specialized version of `baseRest` which transforms the rest array.\n     *\n     * @private\n     * @param {Function} func The function to apply a rest parameter to.\n     * @param {number} [start=func.length-1] The start position of the rest parameter.\n     * @param {Function} transform The rest array transform.\n     * @returns {Function} Returns the new function.\n     */\n    function overRest(func, start, transform) {\n      start = nativeMax(start === undefined ? (func.length - 1) : start, 0);\n      return function() {\n        var args = arguments,\n            index = -1,\n            length = nativeMax(args.length - start, 0),\n            array = Array(length);\n\n        while (++index < length) {\n          array[index] = args[start + index];\n        }\n        index = -1;\n        var otherArgs = Array(start + 1);\n        while (++index < start) {\n          otherArgs[index] = args[index];\n        }\n        otherArgs[start] = transform(array);\n        return apply(func, this, otherArgs);\n      };\n    }\n\n    /**\n     * Gets the parent value at `path` of `object`.\n     *\n     * @private\n     * @param {Object} object The object to query.\n     * @param {Array} path The path to get the parent value of.\n     * @returns {*} Returns the parent value.\n     */\n    function parent(object, path) {\n      return path.length < 2 ? object : baseGet(object, baseSlice(path, 0, -1));\n    }\n\n    /**\n     * Reorder `array` according to the specified indexes where the element at\n     * the first index is assigned as the first element, the element at\n     * the second index is assigned as the second element, and so on.\n     *\n     * @private\n     * @param {Array} array The array to reorder.\n     * @param {Array} indexes The arranged array indexes.\n     * @returns {Array} Returns `array`.\n     */\n    function reorder(array, indexes) {\n      var arrLength = array.length,\n          length = nativeMin(indexes.length, arrLength),\n          oldArray = copyArray(array);\n\n      while (length--) {\n        var index = indexes[length];\n        array[length] = isIndex(index, arrLength) ? oldArray[index] : undefined;\n      }\n      return array;\n    }\n\n    /**\n     * Gets the value at `key`, unless `key` is \"__proto__\".\n     *\n     * @private\n     * @param {Object} object The object to query.\n     * @param {string} key The key of the property to get.\n     * @returns {*} Returns the property value.\n     */\n    function safeGet(object, key) {\n      if (key == '__proto__') {\n        return;\n      }\n\n      return object[key];\n    }\n\n    /**\n     * Sets metadata for `func`.\n     *\n     * **Note:** If this function becomes hot, i.e. is invoked a lot in a short\n     * period of time, it will trip its breaker and transition to an identity\n     * function to avoid garbage collection pauses in V8. See\n     * [V8 issue 2070](https://bugs.chromium.org/p/v8/issues/detail?id=2070)\n     * for more details.\n     *\n     * @private\n     * @param {Function} func The function to associate metadata with.\n     * @param {*} data The metadata.\n     * @returns {Function} Returns `func`.\n     */\n    var setData = shortOut(baseSetData);\n\n    /**\n     * A simple wrapper around the global [`setTimeout`](https://mdn.io/setTimeout).\n     *\n     * @private\n     * @param {Function} func The function to delay.\n     * @param {number} wait The number of milliseconds to delay invocation.\n     * @returns {number|Object} Returns the timer id or timeout object.\n     */\n    var setTimeout = ctxSetTimeout || function(func, wait) {\n      return root.setTimeout(func, wait);\n    };\n\n    /**\n     * Sets the `toString` method of `func` to return `string`.\n     *\n     * @private\n     * @param {Function} func The function to modify.\n     * @param {Function} string The `toString` result.\n     * @returns {Function} Returns `func`.\n     */\n    var setToString = shortOut(baseSetToString);\n\n    /**\n     * Sets the `toString` method of `wrapper` to mimic the source of `reference`\n     * with wrapper details in a comment at the top of the source body.\n     *\n     * @private\n     * @param {Function} wrapper The function to modify.\n     * @param {Function} reference The reference function.\n     * @param {number} bitmask The bitmask flags. See `createWrap` for more details.\n     * @returns {Function} Returns `wrapper`.\n     */\n    function setWrapToString(wrapper, reference, bitmask) {\n      var source = (reference + '');\n      return setToString(wrapper, insertWrapDetails(source, updateWrapDetails(getWrapDetails(source), bitmask)));\n    }\n\n    /**\n     * Creates a function that'll short out and invoke `identity` instead\n     * of `func` when it's called `HOT_COUNT` or more times in `HOT_SPAN`\n     * milliseconds.\n     *\n     * @private\n     * @param {Function} func The function to restrict.\n     * @returns {Function} Returns the new shortable function.\n     */\n    function shortOut(func) {\n      var count = 0,\n          lastCalled = 0;\n\n      return function() {\n        var stamp = nativeNow(),\n            remaining = HOT_SPAN - (stamp - lastCalled);\n\n        lastCalled = stamp;\n        if (remaining > 0) {\n          if (++count >= HOT_COUNT) {\n            return arguments[0];\n          }\n        } else {\n          count = 0;\n        }\n        return func.apply(undefined, arguments);\n      };\n    }\n\n    /**\n     * A specialized version of `_.shuffle` which mutates and sets the size of `array`.\n     *\n     * @private\n     * @param {Array} array The array to shuffle.\n     * @param {number} [size=array.length] The size of `array`.\n     * @returns {Array} Returns `array`.\n     */\n    function shuffleSelf(array, size) {\n      var index = -1,\n          length = array.length,\n          lastIndex = length - 1;\n\n      size = size === undefined ? length : size;\n      while (++index < size) {\n        var rand = baseRandom(index, lastIndex),\n            value = array[rand];\n\n        array[rand] = array[index];\n        array[index] = value;\n      }\n      array.length = size;\n      return array;\n    }\n\n    /**\n     * Converts `string` to a property path array.\n     *\n     * @private\n     * @param {string} string The string to convert.\n     * @returns {Array} Returns the property path array.\n     */\n    var stringToPath = memoizeCapped(function(string) {\n      var result = [];\n      if (string.charCodeAt(0) === 46 /* . */) {\n        result.push('');\n      }\n      string.replace(rePropName, function(match, number, quote, subString) {\n        result.push(quote ? subString.replace(reEscapeChar, '$1') : (number || match));\n      });\n      return result;\n    });\n\n    /**\n     * Converts `value` to a string key if it's not a string or symbol.\n     *\n     * @private\n     * @param {*} value The value to inspect.\n     * @returns {string|symbol} Returns the key.\n     */\n    function toKey(value) {\n      if (typeof value == 'string' || isSymbol(value)) {\n        return value;\n      }\n      var result = (value + '');\n      return (result == '0' && (1 / value) == -INFINITY) ? '-0' : result;\n    }\n\n    /**\n     * Converts `func` to its source code.\n     *\n     * @private\n     * @param {Function} func The function to convert.\n     * @returns {string} Returns the source code.\n     */\n    function toSource(func) {\n      if (func != null) {\n        try {\n          return funcToString.call(func);\n        } catch (e) {}\n        try {\n          return (func + '');\n        } catch (e) {}\n      }\n      return '';\n    }\n\n    /**\n     * Updates wrapper `details` based on `bitmask` flags.\n     *\n     * @private\n     * @returns {Array} details The details to modify.\n     * @param {number} bitmask The bitmask flags. See `createWrap` for more details.\n     * @returns {Array} Returns `details`.\n     */\n    function updateWrapDetails(details, bitmask) {\n      arrayEach(wrapFlags, function(pair) {\n        var value = '_.' + pair[0];\n        if ((bitmask & pair[1]) && !arrayIncludes(details, value)) {\n          details.push(value);\n        }\n      });\n      return details.sort();\n    }\n\n    /**\n     * Creates a clone of `wrapper`.\n     *\n     * @private\n     * @param {Object} wrapper The wrapper to clone.\n     * @returns {Object} Returns the cloned wrapper.\n     */\n    function wrapperClone(wrapper) {\n      if (wrapper instanceof LazyWrapper) {\n        return wrapper.clone();\n      }\n      var result = new LodashWrapper(wrapper.__wrapped__, wrapper.__chain__);\n      result.__actions__ = copyArray(wrapper.__actions__);\n      result.__index__  = wrapper.__index__;\n      result.__values__ = wrapper.__values__;\n      return result;\n    }\n\n    /*------------------------------------------------------------------------*/\n\n    /**\n     * Creates an array of elements split into groups the length of `size`.\n     * If `array` can't be split evenly, the final chunk will be the remaining\n     * elements.\n     *\n     * @static\n     * @memberOf _\n     * @since 3.0.0\n     * @category Array\n     * @param {Array} array The array to process.\n     * @param {number} [size=1] The length of each chunk\n     * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.\n     * @returns {Array} Returns the new array of chunks.\n     * @example\n     *\n     * _.chunk(['a', 'b', 'c', 'd'], 2);\n     * // => [['a', 'b'], ['c', 'd']]\n     *\n     * _.chunk(['a', 'b', 'c', 'd'], 3);\n     * // => [['a', 'b', 'c'], ['d']]\n     */\n    function chunk(array, size, guard) {\n      if ((guard ? isIterateeCall(array, size, guard) : size === undefined)) {\n        size = 1;\n      } else {\n        size = nativeMax(toInteger(size), 0);\n      }\n      var length = array == null ? 0 : array.length;\n      if (!length || size < 1) {\n        return [];\n      }\n      var index = 0,\n          resIndex = 0,\n          result = Array(nativeCeil(length / size));\n\n      while (index < length) {\n        result[resIndex++] = baseSlice(array, index, (index += size));\n      }\n      return result;\n    }\n\n    /**\n     * Creates an array with all falsey values removed. The values `false`, `null`,\n     * `0`, `\"\"`, `undefined`, and `NaN` are falsey.\n     *\n     * @static\n     * @memberOf _\n     * @since 0.1.0\n     * @category Array\n     * @param {Array} array The array to compact.\n     * @returns {Array} Returns the new array of filtered values.\n     * @example\n     *\n     * _.compact([0, 1, false, 2, '', 3]);\n     * // => [1, 2, 3]\n     */\n    function compact(array) {\n      var index = -1,\n          length = array == null ? 0 : array.length,\n          resIndex = 0,\n          result = [];\n\n      while (++index < length) {\n        var value = array[index];\n        if (value) {\n          result[resIndex++] = value;\n        }\n      }\n      return result;\n    }\n\n    /**\n     * Creates a new array concatenating `array` with any additional arrays\n     * and/or values.\n     *\n     * @static\n     * @memberOf _\n     * @since 4.0.0\n     * @category Array\n     * @param {Array} array The array to concatenate.\n     * @param {...*} [values] The values to concatenate.\n     * @returns {Array} Returns the new concatenated array.\n     * @example\n     *\n     * var array = [1];\n     * var other = _.concat(array, 2, [3], [[4]]);\n     *\n     * console.log(other);\n     * // => [1, 2, 3, [4]]\n     *\n     * console.log(array);\n     * // => [1]\n     */\n    function concat() {\n      var length = arguments.length;\n      if (!length) {\n        return [];\n      }\n      var args = Array(length - 1),\n          array = arguments[0],\n          index = length;\n\n      while (index--) {\n        args[index - 1] = arguments[index];\n      }\n      return arrayPush(isArray(array) ? copyArray(array) : [array], baseFlatten(args, 1));\n    }\n\n    /**\n     * Creates an array of `array` values not included in the other given arrays\n     * using [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)\n     * for equality comparisons. The order and references of result values are\n     * determined by the first array.\n     *\n     * **Note:** Unlike `_.pullAll`, this method returns a new array.\n     *\n     * @static\n     * @memberOf _\n     * @since 0.1.0\n     * @category Array\n     * @param {Array} array The array to inspect.\n     * @param {...Array} [values] The values to exclude.\n     * @returns {Array} Returns the new array of filtered values.\n     * @see _.without, _.xor\n     * @example\n     *\n     * _.difference([2, 1], [2, 3]);\n     * // => [1]\n     */\n    var difference = baseRest(function(array, values) {\n      return isArrayLikeObject(array)\n        ? baseDifference(array, baseFlatten(values, 1, isArrayLikeObject, true))\n        : [];\n    });\n\n    /**\n     * This method is like `_.difference` except that it accepts `iteratee` which\n     * is invoked for each element of `array` and `values` to generate the criterion\n     * by which they're compared. The order and references of result values are\n     * determined by the first array. The iteratee is invoked with one argument:\n     * (value).\n     *\n     * **Note:** Unlike `_.pullAllBy`, this method returns a new array.\n     *\n     * @static\n     * @memberOf _\n     * @since 4.0.0\n     * @category Array\n     * @param {Array} array The array to inspect.\n     * @param {...Array} [values] The values to exclude.\n     * @param {Function} [iteratee=_.identity] The iteratee invoked per element.\n     * @returns {Array} Returns the new array of filtered values.\n     * @example\n     *\n     * _.differenceBy([2.1, 1.2], [2.3, 3.4], Math.floor);\n     * // => [1.2]\n     *\n     * // The `_.property` iteratee shorthand.\n     * _.differenceBy([{ 'x': 2 }, { 'x': 1 }], [{ 'x': 1 }], 'x');\n     * // => [{ 'x': 2 }]\n     */\n    var differenceBy = baseRest(function(array, values) {\n      var iteratee = last(values);\n      if (isArrayLikeObject(iteratee)) {\n        iteratee = undefined;\n      }\n      return isArrayLikeObject(array)\n        ? baseDifference(array, baseFlatten(values, 1, isArrayLikeObject, true), getIteratee(iteratee, 2))\n        : [];\n    });\n\n    /**\n     * This method is like `_.difference` except that it accepts `comparator`\n     * which is invoked to compare elements of `array` to `values`. The order and\n     * references of result values are determined by the first array. The comparator\n     * is invoked with two arguments: (arrVal, othVal).\n     *\n     * **Note:** Unlike `_.pullAllWith`, this method returns a new array.\n     *\n     * @static\n     * @memberOf _\n     * @since 4.0.0\n     * @category Array\n     * @param {Array} array The array to inspect.\n     * @param {...Array} [values] The values to exclude.\n     * @param {Function} [comparator] The comparator invoked per element.\n     * @returns {Array} Returns the new array of filtered values.\n     * @example\n     *\n     * var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }];\n     *\n     * _.differenceWith(objects, [{ 'x': 1, 'y': 2 }], _.isEqual);\n     * // => [{ 'x': 2, 'y': 1 }]\n     */\n    var differenceWith = baseRest(function(array, values) {\n      var comparator = last(values);\n      if (isArrayLikeObject(comparator)) {\n        comparator = undefined;\n      }\n      return isArrayLikeObject(array)\n        ? baseDifference(array, baseFlatten(values, 1, isArrayLikeObject, true), undefined, comparator)\n        : [];\n    });\n\n    /**\n     * Creates a slice of `array` with `n` elements dropped from the beginning.\n     *\n     * @static\n     * @memberOf _\n     * @since 0.5.0\n     * @category Array\n     * @param {Array} array The array to query.\n     * @param {number} [n=1] The number of elements to drop.\n     * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.\n     * @returns {Array} Returns the slice of `array`.\n     * @example\n     *\n     * _.drop([1, 2, 3]);\n     * // => [2, 3]\n     *\n     * _.drop([1, 2, 3], 2);\n     * // => [3]\n     *\n     * _.drop([1, 2, 3], 5);\n     * // => []\n     *\n     * _.drop([1, 2, 3], 0);\n     * // => [1, 2, 3]\n     */\n    function drop(array, n, guard) {\n      var length = array == null ? 0 : array.length;\n      if (!length) {\n        return [];\n      }\n      n = (guard || n === undefined) ? 1 : toInteger(n);\n      return baseSlice(array, n < 0 ? 0 : n, length);\n    }\n\n    /**\n     * Creates a slice of `array` with `n` elements dropped from the end.\n     *\n     * @static\n     * @memberOf _\n     * @since 3.0.0\n     * @category Array\n     * @param {Array} array The array to query.\n     * @param {number} [n=1] The number of elements to drop.\n     * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.\n     * @returns {Array} Returns the slice of `array`.\n     * @example\n     *\n     * _.dropRight([1, 2, 3]);\n     * // => [1, 2]\n     *\n     * _.dropRight([1, 2, 3], 2);\n     * // => [1]\n     *\n     * _.dropRight([1, 2, 3], 5);\n     * // => []\n     *\n     * _.dropRight([1, 2, 3], 0);\n     * // => [1, 2, 3]\n     */\n    function dropRight(array, n, guard) {\n      var length = array == null ? 0 : array.length;\n      if (!length) {\n        return [];\n      }\n      n = (guard || n === undefined) ? 1 : toInteger(n);\n      n = length - n;\n      return baseSlice(array, 0, n < 0 ? 0 : n);\n    }\n\n    /**\n     * Creates a slice of `array` excluding elements dropped from the end.\n     * Elements are dropped until `predicate` returns falsey. The predicate is\n     * invoked with three arguments: (value, index, array).\n     *\n     * @static\n     * @memberOf _\n     * @since 3.0.0\n     * @category Array\n     * @param {Array} array The array to query.\n     * @param {Function} [predicate=_.identity] The function invoked per iteration.\n     * @returns {Array} Returns the slice of `array`.\n     * @example\n     *\n     * var users = [\n     *   { 'user': 'barney',  'active': true },\n     *   { 'user': 'fred',    'active': false },\n     *   { 'user': 'pebbles', 'active': false }\n     * ];\n     *\n     * _.dropRightWhile(users, function(o) { return !o.active; });\n     * // => objects for ['barney']\n     *\n     * // The `_.matches` iteratee shorthand.\n     * _.dropRightWhile(users, { 'user': 'pebbles', 'active': false });\n     * // => objects for ['barney', 'fred']\n     *\n     * // The `_.matchesProperty` iteratee shorthand.\n     * _.dropRightWhile(users, ['active', false]);\n     * // => objects for ['barney']\n     *\n     * // The `_.property` iteratee shorthand.\n     * _.dropRightWhile(users, 'active');\n     * // => objects for ['barney', 'fred', 'pebbles']\n     */\n    function dropRightWhile(array, predicate) {\n      return (array && array.length)\n        ? baseWhile(array, getIteratee(predicate, 3), true, true)\n        : [];\n    }\n\n    /**\n     * Creates a slice of `array` excluding elements dropped from the beginning.\n     * Elements are dropped until `predicate` returns falsey. The predicate is\n     * invoked with three arguments: (value, index, array).\n     *\n     * @static\n     * @memberOf _\n     * @since 3.0.0\n     * @category Array\n     * @param {Array} array The array to query.\n     * @param {Function} [predicate=_.identity] The function invoked per iteration.\n     * @returns {Array} Returns the slice of `array`.\n     * @example\n     *\n     * var users = [\n     *   { 'user': 'barney',  'active': false },\n     *   { 'user': 'fred',    'active': false },\n     *   { 'user': 'pebbles', 'active': true }\n     * ];\n     *\n     * _.dropWhile(users, function(o) { return !o.active; });\n     * // => objects for ['pebbles']\n     *\n     * // The `_.matches` iteratee shorthand.\n     * _.dropWhile(users, { 'user': 'barney', 'active': false });\n     * // => objects for ['fred', 'pebbles']\n     *\n     * // The `_.matchesProperty` iteratee shorthand.\n     * _.dropWhile(users, ['active', false]);\n     * // => objects for ['pebbles']\n     *\n     * // The `_.property` iteratee shorthand.\n     * _.dropWhile(users, 'active');\n     * // => objects for ['barney', 'fred', 'pebbles']\n     */\n    function dropWhile(array, predicate) {\n      return (array && array.length)\n        ? baseWhile(array, getIteratee(predicate, 3), true)\n        : [];\n    }\n\n    /**\n     * Fills elements of `array` with `value` from `start` up to, but not\n     * including, `end`.\n     *\n     * **Note:** This method mutates `array`.\n     *\n     * @static\n     * @memberOf _\n     * @since 3.2.0\n     * @category Array\n     * @param {Array} array The array to fill.\n     * @param {*} value The value to fill `array` with.\n     * @param {number} [start=0] The start position.\n     * @param {number} [end=array.length] The end position.\n     * @returns {Array} Returns `array`.\n     * @example\n     *\n     * var array = [1, 2, 3];\n     *\n     * _.fill(array, 'a');\n     * console.log(array);\n     * // => ['a', 'a', 'a']\n     *\n     * _.fill(Array(3), 2);\n     * // => [2, 2, 2]\n     *\n     * _.fill([4, 6, 8, 10], '*', 1, 3);\n     * // => [4, '*', '*', 10]\n     */\n    function fill(array, value, start, end) {\n      var length = array == null ? 0 : array.length;\n      if (!length) {\n        return [];\n      }\n      if (start && typeof start != 'number' && isIterateeCall(array, value, start)) {\n        start = 0;\n        end = length;\n      }\n      return baseFill(array, value, start, end);\n    }\n\n    /**\n     * This method is like `_.find` except that it returns the index of the first\n     * element `predicate` returns truthy for instead of the element itself.\n     *\n     * @static\n     * @memberOf _\n     * @since 1.1.0\n     * @category Array\n     * @param {Array} array The array to inspect.\n     * @param {Function} [predicate=_.identity] The function invoked per iteration.\n     * @param {number} [fromIndex=0] The index to search from.\n     * @returns {number} Returns the index of the found element, else `-1`.\n     * @example\n     *\n     * var users = [\n     *   { 'user': 'barney',  'active': false },\n     *   { 'user': 'fred',    'active': false },\n     *   { 'user': 'pebbles', 'active': true }\n     * ];\n     *\n     * _.findIndex(users, function(o) { return o.user == 'barney'; });\n     * // => 0\n     *\n     * // The `_.matches` iteratee shorthand.\n     * _.findIndex(users, { 'user': 'fred', 'active': false });\n     * // => 1\n     *\n     * // The `_.matchesProperty` iteratee shorthand.\n     * _.findIndex(users, ['active', false]);\n     * // => 0\n     *\n     * // The `_.property` iteratee shorthand.\n     * _.findIndex(users, 'active');\n     * // => 2\n     */\n    function findIndex(array, predicate, fromIndex) {\n      var length = array == null ? 0 : array.length;\n      if (!length) {\n        return -1;\n      }\n      var index = fromIndex == null ? 0 : toInteger(fromIndex);\n      if (index < 0) {\n        index = nativeMax(length + index, 0);\n      }\n      return baseFindIndex(array, getIteratee(predicate, 3), index);\n    }\n\n    /**\n     * This method is like `_.findIndex` except that it iterates over elements\n     * of `collection` from right to left.\n     *\n     * @static\n     * @memberOf _\n     * @since 2.0.0\n     * @category Array\n     * @param {Array} array The array to inspect.\n     * @param {Function} [predicate=_.identity] The function invoked per iteration.\n     * @param {number} [fromIndex=array.length-1] The index to search from.\n     * @returns {number} Returns the index of the found element, else `-1`.\n     * @example\n     *\n     * var users = [\n     *   { 'user': 'barney',  'active': true },\n     *   { 'user': 'fred',    'active': false },\n     *   { 'user': 'pebbles', 'active': false }\n     * ];\n     *\n     * _.findLastIndex(users, function(o) { return o.user == 'pebbles'; });\n     * // => 2\n     *\n     * // The `_.matches` iteratee shorthand.\n     * _.findLastIndex(users, { 'user': 'barney', 'active': true });\n     * // => 0\n     *\n     * // The `_.matchesProperty` iteratee shorthand.\n     * _.findLastIndex(users, ['active', false]);\n     * // => 2\n     *\n     * // The `_.property` iteratee shorthand.\n     * _.findLastIndex(users, 'active');\n     * // => 0\n     */\n    function findLastIndex(array, predicate, fromIndex) {\n      var length = array == null ? 0 : array.length;\n      if (!length) {\n        return -1;\n      }\n      var index = length - 1;\n      if (fromIndex !== undefined) {\n        index = toInteger(fromIndex);\n        index = fromIndex < 0\n          ? nativeMax(length + index, 0)\n          : nativeMin(index, length - 1);\n      }\n      return baseFindIndex(array, getIteratee(predicate, 3), index, true);\n    }\n\n    /**\n     * Flattens `array` a single level deep.\n     *\n     * @static\n     * @memberOf _\n     * @since 0.1.0\n     * @category Array\n     * @param {Array} array The array to flatten.\n     * @returns {Array} Returns the new flattened array.\n     * @example\n     *\n     * _.flatten([1, [2, [3, [4]], 5]]);\n     * // => [1, 2, [3, [4]], 5]\n     */\n    function flatten(array) {\n      var length = array == null ? 0 : array.length;\n      return length ? baseFlatten(array, 1) : [];\n    }\n\n    /**\n     * Recursively flattens `array`.\n     *\n     * @static\n     * @memberOf _\n     * @since 3.0.0\n     * @category Array\n     * @param {Array} array The array to flatten.\n     * @returns {Array} Returns the new flattened array.\n     * @example\n     *\n     * _.flattenDeep([1, [2, [3, [4]], 5]]);\n     * // => [1, 2, 3, 4, 5]\n     */\n    function flattenDeep(array) {\n      var length = array == null ? 0 : array.length;\n      return length ? baseFlatten(array, INFINITY) : [];\n    }\n\n    /**\n     * Recursively flatten `array` up to `depth` times.\n     *\n     * @static\n     * @memberOf _\n     * @since 4.4.0\n     * @category Array\n     * @param {Array} array The array to flatten.\n     * @param {number} [depth=1] The maximum recursion depth.\n     * @returns {Array} Returns the new flattened array.\n     * @example\n     *\n     * var array = [1, [2, [3, [4]], 5]];\n     *\n     * _.flattenDepth(array, 1);\n     * // => [1, 2, [3, [4]], 5]\n     *\n     * _.flattenDepth(array, 2);\n     * // => [1, 2, 3, [4], 5]\n     */\n    function flattenDepth(array, depth) {\n      var length = array == null ? 0 : array.length;\n      if (!length) {\n        return [];\n      }\n      depth = depth === undefined ? 1 : toInteger(depth);\n      return baseFlatten(array, depth);\n    }\n\n    /**\n     * The inverse of `_.toPairs`; this method returns an object composed\n     * from key-value `pairs`.\n     *\n     * @static\n     * @memberOf _\n     * @since 4.0.0\n     * @category Array\n     * @param {Array} pairs The key-value pairs.\n     * @returns {Object} Returns the new object.\n     * @example\n     *\n     * _.fromPairs([['a', 1], ['b', 2]]);\n     * // => { 'a': 1, 'b': 2 }\n     */\n    function fromPairs(pairs) {\n      var index = -1,\n          length = pairs == null ? 0 : pairs.length,\n          result = {};\n\n      while (++index < length) {\n        var pair = pairs[index];\n        result[pair[0]] = pair[1];\n      }\n      return result;\n    }\n\n    /**\n     * Gets the first element of `array`.\n     *\n     * @static\n     * @memberOf _\n     * @since 0.1.0\n     * @alias first\n     * @category Array\n     * @param {Array} array The array to query.\n     * @returns {*} Returns the first element of `array`.\n     * @example\n     *\n     * _.head([1, 2, 3]);\n     * // => 1\n     *\n     * _.head([]);\n     * // => undefined\n     */\n    function head(array) {\n      return (array && array.length) ? array[0] : undefined;\n    }\n\n    /**\n     * Gets the index at which the first occurrence of `value` is found in `array`\n     * using [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)\n     * for equality comparisons. If `fromIndex` is negative, it's used as the\n     * offset from the end of `array`.\n     *\n     * @static\n     * @memberOf _\n     * @since 0.1.0\n     * @category Array\n     * @param {Array} array The array to inspect.\n     * @param {*} value The value to search for.\n     * @param {number} [fromIndex=0] The index to search from.\n     * @returns {number} Returns the index of the matched value, else `-1`.\n     * @example\n     *\n     * _.indexOf([1, 2, 1, 2], 2);\n     * // => 1\n     *\n     * // Search from the `fromIndex`.\n     * _.indexOf([1, 2, 1, 2], 2, 2);\n     * // => 3\n     */\n    function indexOf(array, value, fromIndex) {\n      var length = array == null ? 0 : array.length;\n      if (!length) {\n        return -1;\n      }\n      var index = fromIndex == null ? 0 : toInteger(fromIndex);\n      if (index < 0) {\n        index = nativeMax(length + index, 0);\n      }\n      return baseIndexOf(array, value, index);\n    }\n\n    /**\n     * Gets all but the last element of `array`.\n     *\n     * @static\n     * @memberOf _\n     * @since 0.1.0\n     * @category Array\n     * @param {Array} array The array to query.\n     * @returns {Array} Returns the slice of `array`.\n     * @example\n     *\n     * _.initial([1, 2, 3]);\n     * // => [1, 2]\n     */\n    function initial(array) {\n      var length = array == null ? 0 : array.length;\n      return length ? baseSlice(array, 0, -1) : [];\n    }\n\n    /**\n     * Creates an array of unique values that are included in all given arrays\n     * using [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)\n     * for equality comparisons. The order and references of result values are\n     * determined by the first array.\n     *\n     * @static\n     * @memberOf _\n     * @since 0.1.0\n     * @category Array\n     * @param {...Array} [arrays] The arrays to inspect.\n     * @returns {Array} Returns the new array of intersecting values.\n     * @example\n     *\n     * _.intersection([2, 1], [2, 3]);\n     * // => [2]\n     */\n    var intersection = baseRest(function(arrays) {\n      var mapped = arrayMap(arrays, castArrayLikeObject);\n      return (mapped.length && mapped[0] === arrays[0])\n        ? baseIntersection(mapped)\n        : [];\n    });\n\n    /**\n     * This method is like `_.intersection` except that it accepts `iteratee`\n     * which is invoked for each element of each `arrays` to generate the criterion\n     * by which they're compared. The order and references of result values are\n     * determined by the first array. The iteratee is invoked with one argument:\n     * (value).\n     *\n     * @static\n     * @memberOf _\n     * @since 4.0.0\n     * @category Array\n     * @param {...Array} [arrays] The arrays to inspect.\n     * @param {Function} [iteratee=_.identity] The iteratee invoked per element.\n     * @returns {Array} Returns the new array of intersecting values.\n     * @example\n     *\n     * _.intersectionBy([2.1, 1.2], [2.3, 3.4], Math.floor);\n     * // => [2.1]\n     *\n     * // The `_.property` iteratee shorthand.\n     * _.intersectionBy([{ 'x': 1 }], [{ 'x': 2 }, { 'x': 1 }], 'x');\n     * // => [{ 'x': 1 }]\n     */\n    var intersectionBy = baseRest(function(arrays) {\n      var iteratee = last(arrays),\n          mapped = arrayMap(arrays, castArrayLikeObject);\n\n      if (iteratee === last(mapped)) {\n        iteratee = undefined;\n      } else {\n        mapped.pop();\n      }\n      return (mapped.length && mapped[0] === arrays[0])\n        ? baseIntersection(mapped, getIteratee(iteratee, 2))\n        : [];\n    });\n\n    /**\n     * This method is like `_.intersection` except that it accepts `comparator`\n     * which is invoked to compare elements of `arrays`. The order and references\n     * of result values are determined by the first array. The comparator is\n     * invoked with two arguments: (arrVal, othVal).\n     *\n     * @static\n     * @memberOf _\n     * @since 4.0.0\n     * @category Array\n     * @param {...Array} [arrays] The arrays to inspect.\n     * @param {Function} [comparator] The comparator invoked per element.\n     * @returns {Array} Returns the new array of intersecting values.\n     * @example\n     *\n     * var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }];\n     * var others = [{ 'x': 1, 'y': 1 }, { 'x': 1, 'y': 2 }];\n     *\n     * _.intersectionWith(objects, others, _.isEqual);\n     * // => [{ 'x': 1, 'y': 2 }]\n     */\n    var intersectionWith = baseRest(function(arrays) {\n      var comparator = last(arrays),\n          mapped = arrayMap(arrays, castArrayLikeObject);\n\n      comparator = typeof comparator == 'function' ? comparator : undefined;\n      if (comparator) {\n        mapped.pop();\n      }\n      return (mapped.length && mapped[0] === arrays[0])\n        ? baseIntersection(mapped, undefined, comparator)\n        : [];\n    });\n\n    /**\n     * Converts all elements in `array` into a string separated by `separator`.\n     *\n     * @static\n     * @memberOf _\n     * @since 4.0.0\n     * @category Array\n     * @param {Array} array The array to convert.\n     * @param {string} [separator=','] The element separator.\n     * @returns {string} Returns the joined string.\n     * @example\n     *\n     * _.join(['a', 'b', 'c'], '~');\n     * // => 'a~b~c'\n     */\n    function join(array, separator) {\n      return array == null ? '' : nativeJoin.call(array, separator);\n    }\n\n    /**\n     * Gets the last element of `array`.\n     *\n     * @static\n     * @memberOf _\n     * @since 0.1.0\n     * @category Array\n     * @param {Array} array The array to query.\n     * @returns {*} Returns the last element of `array`.\n     * @example\n     *\n     * _.last([1, 2, 3]);\n     * // => 3\n     */\n    function last(array) {\n      var length = array == null ? 0 : array.length;\n      return length ? array[length - 1] : undefined;\n    }\n\n    /**\n     * This method is like `_.indexOf` except that it iterates over elements of\n     * `array` from right to left.\n     *\n     * @static\n     * @memberOf _\n     * @since 0.1.0\n     * @category Array\n     * @param {Array} array The array to inspect.\n     * @param {*} value The value to search for.\n     * @param {number} [fromIndex=array.length-1] The index to search from.\n     * @returns {number} Returns the index of the matched value, else `-1`.\n     * @example\n     *\n     * _.lastIndexOf([1, 2, 1, 2], 2);\n     * // => 3\n     *\n     * // Search from the `fromIndex`.\n     * _.lastIndexOf([1, 2, 1, 2], 2, 2);\n     * // => 1\n     */\n    function lastIndexOf(array, value, fromIndex) {\n      var length = array == null ? 0 : array.length;\n      if (!length) {\n        return -1;\n      }\n      var index = length;\n      if (fromIndex !== undefined) {\n        index = toInteger(fromIndex);\n        index = index < 0 ? nativeMax(length + index, 0) : nativeMin(index, length - 1);\n      }\n      return value === value\n        ? strictLastIndexOf(array, value, index)\n        : baseFindIndex(array, baseIsNaN, index, true);\n    }\n\n    /**\n     * Gets the element at index `n` of `array`. If `n` is negative, the nth\n     * element from the end is returned.\n     *\n     * @static\n     * @memberOf _\n     * @since 4.11.0\n     * @category Array\n     * @param {Array} array The array to query.\n     * @param {number} [n=0] The index of the element to return.\n     * @returns {*} Returns the nth element of `array`.\n     * @example\n     *\n     * var array = ['a', 'b', 'c', 'd'];\n     *\n     * _.nth(array, 1);\n     * // => 'b'\n     *\n     * _.nth(array, -2);\n     * // => 'c';\n     */\n    function nth(array, n) {\n      return (array && array.length) ? baseNth(array, toInteger(n)) : undefined;\n    }\n\n    /**\n     * Removes all given values from `array` using\n     * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)\n     * for equality comparisons.\n     *\n     * **Note:** Unlike `_.without`, this method mutates `array`. Use `_.remove`\n     * to remove elements from an array by predicate.\n     *\n     * @static\n     * @memberOf _\n     * @since 2.0.0\n     * @category Array\n     * @param {Array} array The array to modify.\n     * @param {...*} [values] The values to remove.\n     * @returns {Array} Returns `array`.\n     * @example\n     *\n     * var array = ['a', 'b', 'c', 'a', 'b', 'c'];\n     *\n     * _.pull(array, 'a', 'c');\n     * console.log(array);\n     * // => ['b', 'b']\n     */\n    var pull = baseRest(pullAll);\n\n    /**\n     * This method is like `_.pull` except that it accepts an array of values to remove.\n     *\n     * **Note:** Unlike `_.difference`, this method mutates `array`.\n     *\n     * @static\n     * @memberOf _\n     * @since 4.0.0\n     * @category Array\n     * @param {Array} array The array to modify.\n     * @param {Array} values The values to remove.\n     * @returns {Array} Returns `array`.\n     * @example\n     *\n     * var array = ['a', 'b', 'c', 'a', 'b', 'c'];\n     *\n     * _.pullAll(array, ['a', 'c']);\n     * console.log(array);\n     * // => ['b', 'b']\n     */\n    function pullAll(array, values) {\n      return (array && array.length && values && values.length)\n        ? basePullAll(array, values)\n        : array;\n    }\n\n    /**\n     * This method is like `_.pullAll` except that it accepts `iteratee` which is\n     * invoked for each element of `array` and `values` to generate the criterion\n     * by which they're compared. The iteratee is invoked with one argument: (value).\n     *\n     * **Note:** Unlike `_.differenceBy`, this method mutates `array`.\n     *\n     * @static\n     * @memberOf _\n     * @since 4.0.0\n     * @category Array\n     * @param {Array} array The array to modify.\n     * @param {Array} values The values to remove.\n     * @param {Function} [iteratee=_.identity] The iteratee invoked per element.\n     * @returns {Array} Returns `array`.\n     * @example\n     *\n     * var array = [{ 'x': 1 }, { 'x': 2 }, { 'x': 3 }, { 'x': 1 }];\n     *\n     * _.pullAllBy(array, [{ 'x': 1 }, { 'x': 3 }], 'x');\n     * console.log(array);\n     * // => [{ 'x': 2 }]\n     */\n    function pullAllBy(array, values, iteratee) {\n      return (array && array.length && values && values.length)\n        ? basePullAll(array, values, getIteratee(iteratee, 2))\n        : array;\n    }\n\n    /**\n     * This method is like `_.pullAll` except that it accepts `comparator` which\n     * is invoked to compare elements of `array` to `values`. The comparator is\n     * invoked with two arguments: (arrVal, othVal).\n     *\n     * **Note:** Unlike `_.differenceWith`, this method mutates `array`.\n     *\n     * @static\n     * @memberOf _\n     * @since 4.6.0\n     * @category Array\n     * @param {Array} array The array to modify.\n     * @param {Array} values The values to remove.\n     * @param {Function} [comparator] The comparator invoked per element.\n     * @returns {Array} Returns `array`.\n     * @example\n     *\n     * var array = [{ 'x': 1, 'y': 2 }, { 'x': 3, 'y': 4 }, { 'x': 5, 'y': 6 }];\n     *\n     * _.pullAllWith(array, [{ 'x': 3, 'y': 4 }], _.isEqual);\n     * console.log(array);\n     * // => [{ 'x': 1, 'y': 2 }, { 'x': 5, 'y': 6 }]\n     */\n    function pullAllWith(array, values, comparator) {\n      return (array && array.length && values && values.length)\n        ? basePullAll(array, values, undefined, comparator)\n        : array;\n    }\n\n    /**\n     * Removes elements from `array` corresponding to `indexes` and returns an\n     * array of removed elements.\n     *\n     * **Note:** Unlike `_.at`, this method mutates `array`.\n     *\n     * @static\n     * @memberOf _\n     * @since 3.0.0\n     * @category Array\n     * @param {Array} array The array to modify.\n     * @param {...(number|number[])} [indexes] The indexes of elements to remove.\n     * @returns {Array} Returns the new array of removed elements.\n     * @example\n     *\n     * var array = ['a', 'b', 'c', 'd'];\n     * var pulled = _.pullAt(array, [1, 3]);\n     *\n     * console.log(array);\n     * // => ['a', 'c']\n     *\n     * console.log(pulled);\n     * // => ['b', 'd']\n     */\n    var pullAt = flatRest(function(array, indexes) {\n      var length = array == null ? 0 : array.length,\n          result = baseAt(array, indexes);\n\n      basePullAt(array, arrayMap(indexes, function(index) {\n        return isIndex(index, length) ? +index : index;\n      }).sort(compareAscending));\n\n      return result;\n    });\n\n    /**\n     * Removes all elements from `array` that `predicate` returns truthy for\n     * and returns an array of the removed elements. The predicate is invoked\n     * with three arguments: (value, index, array).\n     *\n     * **Note:** Unlike `_.filter`, this method mutates `array`. Use `_.pull`\n     * to pull elements from an array by value.\n     *\n     * @static\n     * @memberOf _\n     * @since 2.0.0\n     * @category Array\n     * @param {Array} array The array to modify.\n     * @param {Function} [predicate=_.identity] The function invoked per iteration.\n     * @returns {Array} Returns the new array of removed elements.\n     * @example\n     *\n     * var array = [1, 2, 3, 4];\n     * var evens = _.remove(array, function(n) {\n     *   return n % 2 == 0;\n     * });\n     *\n     * console.log(array);\n     * // => [1, 3]\n     *\n     * console.log(evens);\n     * // => [2, 4]\n     */\n    function remove(array, predicate) {\n      var result = [];\n      if (!(array && array.length)) {\n        return result;\n      }\n      var index = -1,\n          indexes = [],\n          length = array.length;\n\n      predicate = getIteratee(predicate, 3);\n      while (++index < length) {\n        var value = array[index];\n        if (predicate(value, index, array)) {\n          result.push(value);\n          indexes.push(index);\n        }\n      }\n      basePullAt(array, indexes);\n      return result;\n    }\n\n    /**\n     * Reverses `array` so that the first element becomes the last, the second\n     * element becomes the second to last, and so on.\n     *\n     * **Note:** This method mutates `array` and is based on\n     * [`Array#reverse`](https://mdn.io/Array/reverse).\n     *\n     * @static\n     * @memberOf _\n     * @since 4.0.0\n     * @category Array\n     * @param {Array} array The array to modify.\n     * @returns {Array} Returns `array`.\n     * @example\n     *\n     * var array = [1, 2, 3];\n     *\n     * _.reverse(array);\n     * // => [3, 2, 1]\n     *\n     * console.log(array);\n     * // => [3, 2, 1]\n     */\n    function reverse(array) {\n      return array == null ? array : nativeReverse.call(array);\n    }\n\n    /**\n     * Creates a slice of `array` from `start` up to, but not including, `end`.\n     *\n     * **Note:** This method is used instead of\n     * [`Array#slice`](https://mdn.io/Array/slice) to ensure dense arrays are\n     * returned.\n     *\n     * @static\n     * @memberOf _\n     * @since 3.0.0\n     * @category Array\n     * @param {Array} array The array to slice.\n     * @param {number} [start=0] The start position.\n     * @param {number} [end=array.length] The end position.\n     * @returns {Array} Returns the slice of `array`.\n     */\n    function slice(array, start, end) {\n      var length = array == null ? 0 : array.length;\n      if (!length) {\n        return [];\n      }\n      if (end && typeof end != 'number' && isIterateeCall(array, start, end)) {\n        start = 0;\n        end = length;\n      }\n      else {\n        start = start == null ? 0 : toInteger(start);\n        end = end === undefined ? length : toInteger(end);\n      }\n      return baseSlice(array, start, end);\n    }\n\n    /**\n     * Uses a binary search to determine the lowest index at which `value`\n     * should be inserted into `array` in order to maintain its sort order.\n     *\n     * @static\n     * @memberOf _\n     * @since 0.1.0\n     * @category Array\n     * @param {Array} array The sorted array to inspect.\n     * @param {*} value The value to evaluate.\n     * @returns {number} Returns the index at which `value` should be inserted\n     *  into `array`.\n     * @example\n     *\n     * _.sortedIndex([30, 50], 40);\n     * // => 1\n     */\n    function sortedIndex(array, value) {\n      return baseSortedIndex(array, value);\n    }\n\n    /**\n     * This method is like `_.sortedIndex` except that it accepts `iteratee`\n     * which is invoked for `value` and each element of `array` to compute their\n     * sort ranking. The iteratee is invoked with one argument: (value).\n     *\n     * @static\n     * @memberOf _\n     * @since 4.0.0\n     * @category Array\n     * @param {Array} array The sorted array to inspect.\n     * @param {*} value The value to evaluate.\n     * @param {Function} [iteratee=_.identity] The iteratee invoked per element.\n     * @returns {number} Returns the index at which `value` should be inserted\n     *  into `array`.\n     * @example\n     *\n     * var objects = [{ 'x': 4 }, { 'x': 5 }];\n     *\n     * _.sortedIndexBy(objects, { 'x': 4 }, function(o) { return o.x; });\n     * // => 0\n     *\n     * // The `_.property` iteratee shorthand.\n     * _.sortedIndexBy(objects, { 'x': 4 }, 'x');\n     * // => 0\n     */\n    function sortedIndexBy(array, value, iteratee) {\n      return baseSortedIndexBy(array, value, getIteratee(iteratee, 2));\n    }\n\n    /**\n     * This method is like `_.indexOf` except that it performs a binary\n     * search on a sorted `array`.\n     *\n     * @static\n     * @memberOf _\n     * @since 4.0.0\n     * @category Array\n     * @param {Array} array The array to inspect.\n     * @param {*} value The value to search for.\n     * @returns {number} Returns the index of the matched value, else `-1`.\n     * @example\n     *\n     * _.sortedIndexOf([4, 5, 5, 5, 6], 5);\n     * // => 1\n     */\n    function sortedIndexOf(array, value) {\n      var length = array == null ? 0 : array.length;\n      if (length) {\n        var index = baseSortedIndex(array, value);\n        if (index < length && eq(array[index], value)) {\n          return index;\n        }\n      }\n      return -1;\n    }\n\n    /**\n     * This method is like `_.sortedIndex` except that it returns the highest\n     * index at which `value` should be inserted into `array` in order to\n     * maintain its sort order.\n     *\n     * @static\n     * @memberOf _\n     * @since 3.0.0\n     * @category Array\n     * @param {Array} array The sorted array to inspect.\n     * @param {*} value The value to evaluate.\n     * @returns {number} Returns the index at which `value` should be inserted\n     *  into `array`.\n     * @example\n     *\n     * _.sortedLastIndex([4, 5, 5, 5, 6], 5);\n     * // => 4\n     */\n    function sortedLastIndex(array, value) {\n      return baseSortedIndex(array, value, true);\n    }\n\n    /**\n     * This method is like `_.sortedLastIndex` except that it accepts `iteratee`\n     * which is invoked for `value` and each element of `array` to compute their\n     * sort ranking. The iteratee is invoked with one argument: (value).\n     *\n     * @static\n     * @memberOf _\n     * @since 4.0.0\n     * @category Array\n     * @param {Array} array The sorted array to inspect.\n     * @param {*} value The value to evaluate.\n     * @param {Function} [iteratee=_.identity] The iteratee invoked per element.\n     * @returns {number} Returns the index at which `value` should be inserted\n     *  into `array`.\n     * @example\n     *\n     * var objects = [{ 'x': 4 }, { 'x': 5 }];\n     *\n     * _.sortedLastIndexBy(objects, { 'x': 4 }, function(o) { return o.x; });\n     * // => 1\n     *\n     * // The `_.property` iteratee shorthand.\n     * _.sortedLastIndexBy(objects, { 'x': 4 }, 'x');\n     * // => 1\n     */\n    function sortedLastIndexBy(array, value, iteratee) {\n      return baseSortedIndexBy(array, value, getIteratee(iteratee, 2), true);\n    }\n\n    /**\n     * This method is like `_.lastIndexOf` except that it performs a binary\n     * search on a sorted `array`.\n     *\n     * @static\n     * @memberOf _\n     * @since 4.0.0\n     * @category Array\n     * @param {Array} array The array to inspect.\n     * @param {*} value The value to search for.\n     * @returns {number} Returns the index of the matched value, else `-1`.\n     * @example\n     *\n     * _.sortedLastIndexOf([4, 5, 5, 5, 6], 5);\n     * // => 3\n     */\n    function sortedLastIndexOf(array, value) {\n      var length = array == null ? 0 : array.length;\n      if (length) {\n        var index = baseSortedIndex(array, value, true) - 1;\n        if (eq(array[index], value)) {\n          return index;\n        }\n      }\n      return -1;\n    }\n\n    /**\n     * This method is like `_.uniq` except that it's designed and optimized\n     * for sorted arrays.\n     *\n     * @static\n     * @memberOf _\n     * @since 4.0.0\n     * @category Array\n     * @param {Array} array The array to inspect.\n     * @returns {Array} Returns the new duplicate free array.\n     * @example\n     *\n     * _.sortedUniq([1, 1, 2]);\n     * // => [1, 2]\n     */\n    function sortedUniq(array) {\n      return (array && array.length)\n        ? baseSortedUniq(array)\n        : [];\n    }\n\n    /**\n     * This method is like `_.uniqBy` except that it's designed and optimized\n     * for sorted arrays.\n     *\n     * @static\n     * @memberOf _\n     * @since 4.0.0\n     * @category Array\n     * @param {Array} array The array to inspect.\n     * @param {Function} [iteratee] The iteratee invoked per element.\n     * @returns {Array} Returns the new duplicate free array.\n     * @example\n     *\n     * _.sortedUniqBy([1.1, 1.2, 2.3, 2.4], Math.floor);\n     * // => [1.1, 2.3]\n     */\n    function sortedUniqBy(array, iteratee) {\n      return (array && array.length)\n        ? baseSortedUniq(array, getIteratee(iteratee, 2))\n        : [];\n    }\n\n    /**\n     * Gets all but the first element of `array`.\n     *\n     * @static\n     * @memberOf _\n     * @since 4.0.0\n     * @category Array\n     * @param {Array} array The array to query.\n     * @returns {Array} Returns the slice of `array`.\n     * @example\n     *\n     * _.tail([1, 2, 3]);\n     * // => [2, 3]\n     */\n    function tail(array) {\n      var length = array == null ? 0 : array.length;\n      return length ? baseSlice(array, 1, length) : [];\n    }\n\n    /**\n     * Creates a slice of `array` with `n` elements taken from the beginning.\n     *\n     * @static\n     * @memberOf _\n     * @since 0.1.0\n     * @category Array\n     * @param {Array} array The array to query.\n     * @param {number} [n=1] The number of elements to take.\n     * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.\n     * @returns {Array} Returns the slice of `array`.\n     * @example\n     *\n     * _.take([1, 2, 3]);\n     * // => [1]\n     *\n     * _.take([1, 2, 3], 2);\n     * // => [1, 2]\n     *\n     * _.take([1, 2, 3], 5);\n     * // => [1, 2, 3]\n     *\n     * _.take([1, 2, 3], 0);\n     * // => []\n     */\n    function take(array, n, guard) {\n      if (!(array && array.length)) {\n        return [];\n      }\n      n = (guard || n === undefined) ? 1 : toInteger(n);\n      return baseSlice(array, 0, n < 0 ? 0 : n);\n    }\n\n    /**\n     * Creates a slice of `array` with `n` elements taken from the end.\n     *\n     * @static\n     * @memberOf _\n     * @since 3.0.0\n     * @category Array\n     * @param {Array} array The array to query.\n     * @param {number} [n=1] The number of elements to take.\n     * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.\n     * @returns {Array} Returns the slice of `array`.\n     * @example\n     *\n     * _.takeRight([1, 2, 3]);\n     * // => [3]\n     *\n     * _.takeRight([1, 2, 3], 2);\n     * // => [2, 3]\n     *\n     * _.takeRight([1, 2, 3], 5);\n     * // => [1, 2, 3]\n     *\n     * _.takeRight([1, 2, 3], 0);\n     * // => []\n     */\n    function takeRight(array, n, guard) {\n      var length = array == null ? 0 : array.length;\n      if (!length) {\n        return [];\n      }\n      n = (guard || n === undefined) ? 1 : toInteger(n);\n      n = length - n;\n      return baseSlice(array, n < 0 ? 0 : n, length);\n    }\n\n    /**\n     * Creates a slice of `array` with elements taken from the end. Elements are\n     * taken until `predicate` returns falsey. The predicate is invoked with\n     * three arguments: (value, index, array).\n     *\n     * @static\n     * @memberOf _\n     * @since 3.0.0\n     * @category Array\n     * @param {Array} array The array to query.\n     * @param {Function} [predicate=_.identity] The function invoked per iteration.\n     * @returns {Array} Returns the slice of `array`.\n     * @example\n     *\n     * var users = [\n     *   { 'user': 'barney',  'active': true },\n     *   { 'user': 'fred',    'active': false },\n     *   { 'user': 'pebbles', 'active': false }\n     * ];\n     *\n     * _.takeRightWhile(users, function(o) { return !o.active; });\n     * // => objects for ['fred', 'pebbles']\n     *\n     * // The `_.matches` iteratee shorthand.\n     * _.takeRightWhile(users, { 'user': 'pebbles', 'active': false });\n     * // => objects for ['pebbles']\n     *\n     * // The `_.matchesProperty` iteratee shorthand.\n     * _.takeRightWhile(users, ['active', false]);\n     * // => objects for ['fred', 'pebbles']\n     *\n     * // The `_.property` iteratee shorthand.\n     * _.takeRightWhile(users, 'active');\n     * // => []\n     */\n    function takeRightWhile(array, predicate) {\n      return (array && array.length)\n        ? baseWhile(array, getIteratee(predicate, 3), false, true)\n        : [];\n    }\n\n    /**\n     * Creates a slice of `array` with elements taken from the beginning. Elements\n     * are taken until `predicate` returns falsey. The predicate is invoked with\n     * three arguments: (value, index, array).\n     *\n     * @static\n     * @memberOf _\n     * @since 3.0.0\n     * @category Array\n     * @param {Array} array The array to query.\n     * @param {Function} [predicate=_.identity] The function invoked per iteration.\n     * @returns {Array} Returns the slice of `array`.\n     * @example\n     *\n     * var users = [\n     *   { 'user': 'barney',  'active': false },\n     *   { 'user': 'fred',    'active': false },\n     *   { 'user': 'pebbles', 'active': true }\n     * ];\n     *\n     * _.takeWhile(users, function(o) { return !o.active; });\n     * // => objects for ['barney', 'fred']\n     *\n     * // The `_.matches` iteratee shorthand.\n     * _.takeWhile(users, { 'user': 'barney', 'active': false });\n     * // => objects for ['barney']\n     *\n     * // The `_.matchesProperty` iteratee shorthand.\n     * _.takeWhile(users, ['active', false]);\n     * // => objects for ['barney', 'fred']\n     *\n     * // The `_.property` iteratee shorthand.\n     * _.takeWhile(users, 'active');\n     * // => []\n     */\n    function takeWhile(array, predicate) {\n      return (array && array.length)\n        ? baseWhile(array, getIteratee(predicate, 3))\n        : [];\n    }\n\n    /**\n     * Creates an array of unique values, in order, from all given arrays using\n     * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)\n     * for equality comparisons.\n     *\n     * @static\n     * @memberOf _\n     * @since 0.1.0\n     * @category Array\n     * @param {...Array} [arrays] The arrays to inspect.\n     * @returns {Array} Returns the new array of combined values.\n     * @example\n     *\n     * _.union([2], [1, 2]);\n     * // => [2, 1]\n     */\n    var union = baseRest(function(arrays) {\n      return baseUniq(baseFlatten(arrays, 1, isArrayLikeObject, true));\n    });\n\n    /**\n     * This method is like `_.union` except that it accepts `iteratee` which is\n     * invoked for each element of each `arrays` to generate the criterion by\n     * which uniqueness is computed. Result values are chosen from the first\n     * array in which the value occurs. The iteratee is invoked with one argument:\n     * (value).\n     *\n     * @static\n     * @memberOf _\n     * @since 4.0.0\n     * @category Array\n     * @param {...Array} [arrays] The arrays to inspect.\n     * @param {Function} [iteratee=_.identity] The iteratee invoked per element.\n     * @returns {Array} Returns the new array of combined values.\n     * @example\n     *\n     * _.unionBy([2.1], [1.2, 2.3], Math.floor);\n     * // => [2.1, 1.2]\n     *\n     * // The `_.property` iteratee shorthand.\n     * _.unionBy([{ 'x': 1 }], [{ 'x': 2 }, { 'x': 1 }], 'x');\n     * // => [{ 'x': 1 }, { 'x': 2 }]\n     */\n    var unionBy = baseRest(function(arrays) {\n      var iteratee = last(arrays);\n      if (isArrayLikeObject(iteratee)) {\n        iteratee = undefined;\n      }\n      return baseUniq(baseFlatten(arrays, 1, isArrayLikeObject, true), getIteratee(iteratee, 2));\n    });\n\n    /**\n     * This method is like `_.union` except that it accepts `comparator` which\n     * is invoked to compare elements of `arrays`. Result values are chosen from\n     * the first array in which the value occurs. The comparator is invoked\n     * with two arguments: (arrVal, othVal).\n     *\n     * @static\n     * @memberOf _\n     * @since 4.0.0\n     * @category Array\n     * @param {...Array} [arrays] The arrays to inspect.\n     * @param {Function} [comparator] The comparator invoked per element.\n     * @returns {Array} Returns the new array of combined values.\n     * @example\n     *\n     * var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }];\n     * var others = [{ 'x': 1, 'y': 1 }, { 'x': 1, 'y': 2 }];\n     *\n     * _.unionWith(objects, others, _.isEqual);\n     * // => [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }, { 'x': 1, 'y': 1 }]\n     */\n    var unionWith = baseRest(function(arrays) {\n      var comparator = last(arrays);\n      comparator = typeof comparator == 'function' ? comparator : undefined;\n      return baseUniq(baseFlatten(arrays, 1, isArrayLikeObject, true), undefined, comparator);\n    });\n\n    /**\n     * Creates a duplicate-free version of an array, using\n     * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)\n     * for equality comparisons, in which only the first occurrence of each element\n     * is kept. The order of result values is determined by the order they occur\n     * in the array.\n     *\n     * @static\n     * @memberOf _\n     * @since 0.1.0\n     * @category Array\n     * @param {Array} array The array to inspect.\n     * @returns {Array} Returns the new duplicate free array.\n     * @example\n     *\n     * _.uniq([2, 1, 2]);\n     * // => [2, 1]\n     */\n    function uniq(array) {\n      return (array && array.length) ? baseUniq(array) : [];\n    }\n\n    /**\n     * This method is like `_.uniq` except that it accepts `iteratee` which is\n     * invoked for each element in `array` to generate the criterion by which\n     * uniqueness is computed. The order of result values is determined by the\n     * order they occur in the array. The iteratee is invoked with one argument:\n     * (value).\n     *\n     * @static\n     * @memberOf _\n     * @since 4.0.0\n     * @category Array\n     * @param {Array} array The array to inspect.\n     * @param {Function} [iteratee=_.identity] The iteratee invoked per element.\n     * @returns {Array} Returns the new duplicate free array.\n     * @example\n     *\n     * _.uniqBy([2.1, 1.2, 2.3], Math.floor);\n     * // => [2.1, 1.2]\n     *\n     * // The `_.property` iteratee shorthand.\n     * _.uniqBy([{ 'x': 1 }, { 'x': 2 }, { 'x': 1 }], 'x');\n     * // => [{ 'x': 1 }, { 'x': 2 }]\n     */\n    function uniqBy(array, iteratee) {\n      return (array && array.length) ? baseUniq(array, getIteratee(iteratee, 2)) : [];\n    }\n\n    /**\n     * This method is like `_.uniq` except that it accepts `comparator` which\n     * is invoked to compare elements of `array`. The order of result values is\n     * determined by the order they occur in the array.The comparator is invoked\n     * with two arguments: (arrVal, othVal).\n     *\n     * @static\n     * @memberOf _\n     * @since 4.0.0\n     * @category Array\n     * @param {Array} array The array to inspect.\n     * @param {Function} [comparator] The comparator invoked per element.\n     * @returns {Array} Returns the new duplicate free array.\n     * @example\n     *\n     * var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }, { 'x': 1, 'y': 2 }];\n     *\n     * _.uniqWith(objects, _.isEqual);\n     * // => [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }]\n     */\n    function uniqWith(array, comparator) {\n      comparator = typeof comparator == 'function' ? comparator : undefined;\n      return (array && array.length) ? baseUniq(array, undefined, comparator) : [];\n    }\n\n    /**\n     * This method is like `_.zip` except that it accepts an array of grouped\n     * elements and creates an array regrouping the elements to their pre-zip\n     * configuration.\n     *\n     * @static\n     * @memberOf _\n     * @since 1.2.0\n     * @category Array\n     * @param {Array} array The array of grouped elements to process.\n     * @returns {Array} Returns the new array of regrouped elements.\n     * @example\n     *\n     * var zipped = _.zip(['a', 'b'], [1, 2], [true, false]);\n     * // => [['a', 1, true], ['b', 2, false]]\n     *\n     * _.unzip(zipped);\n     * // => [['a', 'b'], [1, 2], [true, false]]\n     */\n    function unzip(array) {\n      if (!(array && array.length)) {\n        return [];\n      }\n      var length = 0;\n      array = arrayFilter(array, function(group) {\n        if (isArrayLikeObject(group)) {\n          length = nativeMax(group.length, length);\n          return true;\n        }\n      });\n      return baseTimes(length, function(index) {\n        return arrayMap(array, baseProperty(index));\n      });\n    }\n\n    /**\n     * This method is like `_.unzip` except that it accepts `iteratee` to specify\n     * how regrouped values should be combined. The iteratee is invoked with the\n     * elements of each group: (...group).\n     *\n     * @static\n     * @memberOf _\n     * @since 3.8.0\n     * @category Array\n     * @param {Array} array The array of grouped elements to process.\n     * @param {Function} [iteratee=_.identity] The function to combine\n     *  regrouped values.\n     * @returns {Array} Returns the new array of regrouped elements.\n     * @example\n     *\n     * var zipped = _.zip([1, 2], [10, 20], [100, 200]);\n     * // => [[1, 10, 100], [2, 20, 200]]\n     *\n     * _.unzipWith(zipped, _.add);\n     * // => [3, 30, 300]\n     */\n    function unzipWith(array, iteratee) {\n      if (!(array && array.length)) {\n        return [];\n      }\n      var result = unzip(array);\n      if (iteratee == null) {\n        return result;\n      }\n      return arrayMap(result, function(group) {\n        return apply(iteratee, undefined, group);\n      });\n    }\n\n    /**\n     * Creates an array excluding all given values using\n     * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)\n     * for equality comparisons.\n     *\n     * **Note:** Unlike `_.pull`, this method returns a new array.\n     *\n     * @static\n     * @memberOf _\n     * @since 0.1.0\n     * @category Array\n     * @param {Array} array The array to inspect.\n     * @param {...*} [values] The values to exclude.\n     * @returns {Array} Returns the new array of filtered values.\n     * @see _.difference, _.xor\n     * @example\n     *\n     * _.without([2, 1, 2, 3], 1, 2);\n     * // => [3]\n     */\n    var without = baseRest(function(array, values) {\n      return isArrayLikeObject(array)\n        ? baseDifference(array, values)\n        : [];\n    });\n\n    /**\n     * Creates an array of unique values that is the\n     * [symmetric difference](https://en.wikipedia.org/wiki/Symmetric_difference)\n     * of the given arrays. The order of result values is determined by the order\n     * they occur in the arrays.\n     *\n     * @static\n     * @memberOf _\n     * @since 2.4.0\n     * @category Array\n     * @param {...Array} [arrays] The arrays to inspect.\n     * @returns {Array} Returns the new array of filtered values.\n     * @see _.difference, _.without\n     * @example\n     *\n     * _.xor([2, 1], [2, 3]);\n     * // => [1, 3]\n     */\n    var xor = baseRest(function(arrays) {\n      return baseXor(arrayFilter(arrays, isArrayLikeObject));\n    });\n\n    /**\n     * This method is like `_.xor` except that it accepts `iteratee` which is\n     * invoked for each element of each `arrays` to generate the criterion by\n     * which by which they're compared. The order of result values is determined\n     * by the order they occur in the arrays. The iteratee is invoked with one\n     * argument: (value).\n     *\n     * @static\n     * @memberOf _\n     * @since 4.0.0\n     * @category Array\n     * @param {...Array} [arrays] The arrays to inspect.\n     * @param {Function} [iteratee=_.identity] The iteratee invoked per element.\n     * @returns {Array} Returns the new array of filtered values.\n     * @example\n     *\n     * _.xorBy([2.1, 1.2], [2.3, 3.4], Math.floor);\n     * // => [1.2, 3.4]\n     *\n     * // The `_.property` iteratee shorthand.\n     * _.xorBy([{ 'x': 1 }], [{ 'x': 2 }, { 'x': 1 }], 'x');\n     * // => [{ 'x': 2 }]\n     */\n    var xorBy = baseRest(function(arrays) {\n      var iteratee = last(arrays);\n      if (isArrayLikeObject(iteratee)) {\n        iteratee = undefined;\n      }\n      return baseXor(arrayFilter(arrays, isArrayLikeObject), getIteratee(iteratee, 2));\n    });\n\n    /**\n     * This method is like `_.xor` except that it accepts `comparator` which is\n     * invoked to compare elements of `arrays`. The order of result values is\n     * determined by the order they occur in the arrays. The comparator is invoked\n     * with two arguments: (arrVal, othVal).\n     *\n     * @static\n     * @memberOf _\n     * @since 4.0.0\n     * @category Array\n     * @param {...Array} [arrays] The arrays to inspect.\n     * @param {Function} [comparator] The comparator invoked per element.\n     * @returns {Array} Returns the new array of filtered values.\n     * @example\n     *\n     * var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }];\n     * var others = [{ 'x': 1, 'y': 1 }, { 'x': 1, 'y': 2 }];\n     *\n     * _.xorWith(objects, others, _.isEqual);\n     * // => [{ 'x': 2, 'y': 1 }, { 'x': 1, 'y': 1 }]\n     */\n    var xorWith = baseRest(function(arrays) {\n      var comparator = last(arrays);\n      comparator = typeof comparator == 'function' ? comparator : undefined;\n      return baseXor(arrayFilter(arrays, isArrayLikeObject), undefined, comparator);\n    });\n\n    /**\n     * Creates an array of grouped elements, the first of which contains the\n     * first elements of the given arrays, the second of which contains the\n     * second elements of the given arrays, and so on.\n     *\n     * @static\n     * @memberOf _\n     * @since 0.1.0\n     * @category Array\n     * @param {...Array} [arrays] The arrays to process.\n     * @returns {Array} Returns the new array of grouped elements.\n     * @example\n     *\n     * _.zip(['a', 'b'], [1, 2], [true, false]);\n     * // => [['a', 1, true], ['b', 2, false]]\n     */\n    var zip = baseRest(unzip);\n\n    /**\n     * This method is like `_.fromPairs` except that it accepts two arrays,\n     * one of property identifiers and one of corresponding values.\n     *\n     * @static\n     * @memberOf _\n     * @since 0.4.0\n     * @category Array\n     * @param {Array} [props=[]] The property identifiers.\n     * @param {Array} [values=[]] The property values.\n     * @returns {Object} Returns the new object.\n     * @example\n     *\n     * _.zipObject(['a', 'b'], [1, 2]);\n     * // => { 'a': 1, 'b': 2 }\n     */\n    function zipObject(props, values) {\n      return baseZipObject(props || [], values || [], assignValue);\n    }\n\n    /**\n     * This method is like `_.zipObject` except that it supports property paths.\n     *\n     * @static\n     * @memberOf _\n     * @since 4.1.0\n     * @category Array\n     * @param {Array} [props=[]] The property identifiers.\n     * @param {Array} [values=[]] The property values.\n     * @returns {Object} Returns the new object.\n     * @example\n     *\n     * _.zipObjectDeep(['a.b[0].c', 'a.b[1].d'], [1, 2]);\n     * // => { 'a': { 'b': [{ 'c': 1 }, { 'd': 2 }] } }\n     */\n    function zipObjectDeep(props, values) {\n      return baseZipObject(props || [], values || [], baseSet);\n    }\n\n    /**\n     * This method is like `_.zip` except that it accepts `iteratee` to specify\n     * how grouped values should be combined. The iteratee is invoked with the\n     * elements of each group: (...group).\n     *\n     * @static\n     * @memberOf _\n     * @since 3.8.0\n     * @category Array\n     * @param {...Array} [arrays] The arrays to process.\n     * @param {Function} [iteratee=_.identity] The function to combine\n     *  grouped values.\n     * @returns {Array} Returns the new array of grouped elements.\n     * @example\n     *\n     * _.zipWith([1, 2], [10, 20], [100, 200], function(a, b, c) {\n     *   return a + b + c;\n     * });\n     * // => [111, 222]\n     */\n    var zipWith = baseRest(function(arrays) {\n      var length = arrays.length,\n          iteratee = length > 1 ? arrays[length - 1] : undefined;\n\n      iteratee = typeof iteratee == 'function' ? (arrays.pop(), iteratee) : undefined;\n      return unzipWith(arrays, iteratee);\n    });\n\n    /*------------------------------------------------------------------------*/\n\n    /**\n     * Creates a `lodash` wrapper instance that wraps `value` with explicit method\n     * chain sequences enabled. The result of such sequences must be unwrapped\n     * with `_#value`.\n     *\n     * @static\n     * @memberOf _\n     * @since 1.3.0\n     * @category Seq\n     * @param {*} value The value to wrap.\n     * @returns {Object} Returns the new `lodash` wrapper instance.\n     * @example\n     *\n     * var users = [\n     *   { 'user': 'barney',  'age': 36 },\n     *   { 'user': 'fred',    'age': 40 },\n     *   { 'user': 'pebbles', 'age': 1 }\n     * ];\n     *\n     * var youngest = _\n     *   .chain(users)\n     *   .sortBy('age')\n     *   .map(function(o) {\n     *     return o.user + ' is ' + o.age;\n     *   })\n     *   .head()\n     *   .value();\n     * // => 'pebbles is 1'\n     */\n    function chain(value) {\n      var result = lodash(value);\n      result.__chain__ = true;\n      return result;\n    }\n\n    /**\n     * This method invokes `interceptor` and returns `value`. The interceptor\n     * is invoked with one argument; (value). The purpose of this method is to\n     * \"tap into\" a method chain sequence in order to modify intermediate results.\n     *\n     * @static\n     * @memberOf _\n     * @since 0.1.0\n     * @category Seq\n     * @param {*} value The value to provide to `interceptor`.\n     * @param {Function} interceptor The function to invoke.\n     * @returns {*} Returns `value`.\n     * @example\n     *\n     * _([1, 2, 3])\n     *  .tap(function(array) {\n     *    // Mutate input array.\n     *    array.pop();\n     *  })\n     *  .reverse()\n     *  .value();\n     * // => [2, 1]\n     */\n    function tap(value, interceptor) {\n      interceptor(value);\n      return value;\n    }\n\n    /**\n     * This method is like `_.tap` except that it returns the result of `interceptor`.\n     * The purpose of this method is to \"pass thru\" values replacing intermediate\n     * results in a method chain sequence.\n     *\n     * @static\n     * @memberOf _\n     * @since 3.0.0\n     * @category Seq\n     * @param {*} value The value to provide to `interceptor`.\n     * @param {Function} interceptor The function to invoke.\n     * @returns {*} Returns the result of `interceptor`.\n     * @example\n     *\n     * _('  abc  ')\n     *  .chain()\n     *  .trim()\n     *  .thru(function(value) {\n     *    return [value];\n     *  })\n     *  .value();\n     * // => ['abc']\n     */\n    function thru(value, interceptor) {\n      return interceptor(value);\n    }\n\n    /**\n     * This method is the wrapper version of `_.at`.\n     *\n     * @name at\n     * @memberOf _\n     * @since 1.0.0\n     * @category Seq\n     * @param {...(string|string[])} [paths] The property paths to pick.\n     * @returns {Object} Returns the new `lodash` wrapper instance.\n     * @example\n     *\n     * var object = { 'a': [{ 'b': { 'c': 3 } }, 4] };\n     *\n     * _(object).at(['a[0].b.c', 'a[1]']).value();\n     * // => [3, 4]\n     */\n    var wrapperAt = flatRest(function(paths) {\n      var length = paths.length,\n          start = length ? paths[0] : 0,\n          value = this.__wrapped__,\n          interceptor = function(object) { return baseAt(object, paths); };\n\n      if (length > 1 || this.__actions__.length ||\n          !(value instanceof LazyWrapper) || !isIndex(start)) {\n        return this.thru(interceptor);\n      }\n      value = value.slice(start, +start + (length ? 1 : 0));\n      value.__actions__.push({\n        'func': thru,\n        'args': [interceptor],\n        'thisArg': undefined\n      });\n      return new LodashWrapper(value, this.__chain__).thru(function(array) {\n        if (length && !array.length) {\n          array.push(undefined);\n        }\n        return array;\n      });\n    });\n\n    /**\n     * Creates a `lodash` wrapper instance with explicit method chain sequences enabled.\n     *\n     * @name chain\n     * @memberOf _\n     * @since 0.1.0\n     * @category Seq\n     * @returns {Object} Returns the new `lodash` wrapper instance.\n     * @example\n     *\n     * var users = [\n     *   { 'user': 'barney', 'age': 36 },\n     *   { 'user': 'fred',   'age': 40 }\n     * ];\n     *\n     * // A sequence without explicit chaining.\n     * _(users).head();\n     * // => { 'user': 'barney', 'age': 36 }\n     *\n     * // A sequence with explicit chaining.\n     * _(users)\n     *   .chain()\n     *   .head()\n     *   .pick('user')\n     *   .value();\n     * // => { 'user': 'barney' }\n     */\n    function wrapperChain() {\n      return chain(this);\n    }\n\n    /**\n     * Executes the chain sequence and returns the wrapped result.\n     *\n     * @name commit\n     * @memberOf _\n     * @since 3.2.0\n     * @category Seq\n     * @returns {Object} Returns the new `lodash` wrapper instance.\n     * @example\n     *\n     * var array = [1, 2];\n     * var wrapped = _(array).push(3);\n     *\n     * console.log(array);\n     * // => [1, 2]\n     *\n     * wrapped = wrapped.commit();\n     * console.log(array);\n     * // => [1, 2, 3]\n     *\n     * wrapped.last();\n     * // => 3\n     *\n     * console.log(array);\n     * // => [1, 2, 3]\n     */\n    function wrapperCommit() {\n      return new LodashWrapper(this.value(), this.__chain__);\n    }\n\n    /**\n     * Gets the next value on a wrapped object following the\n     * [iterator protocol](https://mdn.io/iteration_protocols#iterator).\n     *\n     * @name next\n     * @memberOf _\n     * @since 4.0.0\n     * @category Seq\n     * @returns {Object} Returns the next iterator value.\n     * @example\n     *\n     * var wrapped = _([1, 2]);\n     *\n     * wrapped.next();\n     * // => { 'done': false, 'value': 1 }\n     *\n     * wrapped.next();\n     * // => { 'done': false, 'value': 2 }\n     *\n     * wrapped.next();\n     * // => { 'done': true, 'value': undefined }\n     */\n    function wrapperNext() {\n      if (this.__values__ === undefined) {\n        this.__values__ = toArray(this.value());\n      }\n      var done = this.__index__ >= this.__values__.length,\n          value = done ? undefined : this.__values__[this.__index__++];\n\n      return { 'done': done, 'value': value };\n    }\n\n    /**\n     * Enables the wrapper to be iterable.\n     *\n     * @name Symbol.iterator\n     * @memberOf _\n     * @since 4.0.0\n     * @category Seq\n     * @returns {Object} Returns the wrapper object.\n     * @example\n     *\n     * var wrapped = _([1, 2]);\n     *\n     * wrapped[Symbol.iterator]() === wrapped;\n     * // => true\n     *\n     * Array.from(wrapped);\n     * // => [1, 2]\n     */\n    function wrapperToIterator() {\n      return this;\n    }\n\n    /**\n     * Creates a clone of the chain sequence planting `value` as the wrapped value.\n     *\n     * @name plant\n     * @memberOf _\n     * @since 3.2.0\n     * @category Seq\n     * @param {*} value The value to plant.\n     * @returns {Object} Returns the new `lodash` wrapper instance.\n     * @example\n     *\n     * function square(n) {\n     *   return n * n;\n     * }\n     *\n     * var wrapped = _([1, 2]).map(square);\n     * var other = wrapped.plant([3, 4]);\n     *\n     * other.value();\n     * // => [9, 16]\n     *\n     * wrapped.value();\n     * // => [1, 4]\n     */\n    function wrapperPlant(value) {\n      var result,\n          parent = this;\n\n      while (parent instanceof baseLodash) {\n        var clone = wrapperClone(parent);\n        clone.__index__ = 0;\n        clone.__values__ = undefined;\n        if (result) {\n          previous.__wrapped__ = clone;\n        } else {\n          result = clone;\n        }\n        var previous = clone;\n        parent = parent.__wrapped__;\n      }\n      previous.__wrapped__ = value;\n      return result;\n    }\n\n    /**\n     * This method is the wrapper version of `_.reverse`.\n     *\n     * **Note:** This method mutates the wrapped array.\n     *\n     * @name reverse\n     * @memberOf _\n     * @since 0.1.0\n     * @category Seq\n     * @returns {Object} Returns the new `lodash` wrapper instance.\n     * @example\n     *\n     * var array = [1, 2, 3];\n     *\n     * _(array).reverse().value()\n     * // => [3, 2, 1]\n     *\n     * console.log(array);\n     * // => [3, 2, 1]\n     */\n    function wrapperReverse() {\n      var value = this.__wrapped__;\n      if (value instanceof LazyWrapper) {\n        var wrapped = value;\n        if (this.__actions__.length) {\n          wrapped = new LazyWrapper(this);\n        }\n        wrapped = wrapped.reverse();\n        wrapped.__actions__.push({\n          'func': thru,\n          'args': [reverse],\n          'thisArg': undefined\n        });\n        return new LodashWrapper(wrapped, this.__chain__);\n      }\n      return this.thru(reverse);\n    }\n\n    /**\n     * Executes the chain sequence to resolve the unwrapped value.\n     *\n     * @name value\n     * @memberOf _\n     * @since 0.1.0\n     * @alias toJSON, valueOf\n     * @category Seq\n     * @returns {*} Returns the resolved unwrapped value.\n     * @example\n     *\n     * _([1, 2, 3]).value();\n     * // => [1, 2, 3]\n     */\n    function wrapperValue() {\n      return baseWrapperValue(this.__wrapped__, this.__actions__);\n    }\n\n    /*------------------------------------------------------------------------*/\n\n    /**\n     * Creates an object composed of keys generated from the results of running\n     * each element of `collection` thru `iteratee`. The corresponding value of\n     * each key is the number of times the key was returned by `iteratee`. The\n     * iteratee is invoked with one argument: (value).\n     *\n     * @static\n     * @memberOf _\n     * @since 0.5.0\n     * @category Collection\n     * @param {Array|Object} collection The collection to iterate over.\n     * @param {Function} [iteratee=_.identity] The iteratee to transform keys.\n     * @returns {Object} Returns the composed aggregate object.\n     * @example\n     *\n     * _.countBy([6.1, 4.2, 6.3], Math.floor);\n     * // => { '4': 1, '6': 2 }\n     *\n     * // The `_.property` iteratee shorthand.\n     * _.countBy(['one', 'two', 'three'], 'length');\n     * // => { '3': 2, '5': 1 }\n     */\n    var countBy = createAggregator(function(result, value, key) {\n      if (hasOwnProperty.call(result, key)) {\n        ++result[key];\n      } else {\n        baseAssignValue(result, key, 1);\n      }\n    });\n\n    /**\n     * Checks if `predicate` returns truthy for **all** elements of `collection`.\n     * Iteration is stopped once `predicate` returns falsey. The predicate is\n     * invoked with three arguments: (value, index|key, collection).\n     *\n     * **Note:** This method returns `true` for\n     * [empty collections](https://en.wikipedia.org/wiki/Empty_set) because\n     * [everything is true](https://en.wikipedia.org/wiki/Vacuous_truth) of\n     * elements of empty collections.\n     *\n     * @static\n     * @memberOf _\n     * @since 0.1.0\n     * @category Collection\n     * @param {Array|Object} collection The collection to iterate over.\n     * @param {Function} [predicate=_.identity] The function invoked per iteration.\n     * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.\n     * @returns {boolean} Returns `true` if all elements pass the predicate check,\n     *  else `false`.\n     * @example\n     *\n     * _.every([true, 1, null, 'yes'], Boolean);\n     * // => false\n     *\n     * var users = [\n     *   { 'user': 'barney', 'age': 36, 'active': false },\n     *   { 'user': 'fred',   'age': 40, 'active': false }\n     * ];\n     *\n     * // The `_.matches` iteratee shorthand.\n     * _.every(users, { 'user': 'barney', 'active': false });\n     * // => false\n     *\n     * // The `_.matchesProperty` iteratee shorthand.\n     * _.every(users, ['active', false]);\n     * // => true\n     *\n     * // The `_.property` iteratee shorthand.\n     * _.every(users, 'active');\n     * // => false\n     */\n    function every(collection, predicate, guard) {\n      var func = isArray(collection) ? arrayEvery : baseEvery;\n      if (guard && isIterateeCall(collection, predicate, guard)) {\n        predicate = undefined;\n      }\n      return func(collection, getIteratee(predicate, 3));\n    }\n\n    /**\n     * Iterates over elements of `collection`, returning an array of all elements\n     * `predicate` returns truthy for. The predicate is invoked with three\n     * arguments: (value, index|key, collection).\n     *\n     * **Note:** Unlike `_.remove`, this method returns a new array.\n     *\n     * @static\n     * @memberOf _\n     * @since 0.1.0\n     * @category Collection\n     * @param {Array|Object} collection The collection to iterate over.\n     * @param {Function} [predicate=_.identity] The function invoked per iteration.\n     * @returns {Array} Returns the new filtered array.\n     * @see _.reject\n     * @example\n     *\n     * var users = [\n     *   { 'user': 'barney', 'age': 36, 'active': true },\n     *   { 'user': 'fred',   'age': 40, 'active': false }\n     * ];\n     *\n     * _.filter(users, function(o) { return !o.active; });\n     * // => objects for ['fred']\n     *\n     * // The `_.matches` iteratee shorthand.\n     * _.filter(users, { 'age': 36, 'active': true });\n     * // => objects for ['barney']\n     *\n     * // The `_.matchesProperty` iteratee shorthand.\n     * _.filter(users, ['active', false]);\n     * // => objects for ['fred']\n     *\n     * // The `_.property` iteratee shorthand.\n     * _.filter(users, 'active');\n     * // => objects for ['barney']\n     */\n    function filter(collection, predicate) {\n      var func = isArray(collection) ? arrayFilter : baseFilter;\n      return func(collection, getIteratee(predicate, 3));\n    }\n\n    /**\n     * Iterates over elements of `collection`, returning the first element\n     * `predicate` returns truthy for. The predicate is invoked with three\n     * arguments: (value, index|key, collection).\n     *\n     * @static\n     * @memberOf _\n     * @since 0.1.0\n     * @category Collection\n     * @param {Array|Object} collection The collection to inspect.\n     * @param {Function} [predicate=_.identity] The function invoked per iteration.\n     * @param {number} [fromIndex=0] The index to search from.\n     * @returns {*} Returns the matched element, else `undefined`.\n     * @example\n     *\n     * var users = [\n     *   { 'user': 'barney',  'age': 36, 'active': true },\n     *   { 'user': 'fred',    'age': 40, 'active': false },\n     *   { 'user': 'pebbles', 'age': 1,  'active': true }\n     * ];\n     *\n     * _.find(users, function(o) { return o.age < 40; });\n     * // => object for 'barney'\n     *\n     * // The `_.matches` iteratee shorthand.\n     * _.find(users, { 'age': 1, 'active': true });\n     * // => object for 'pebbles'\n     *\n     * // The `_.matchesProperty` iteratee shorthand.\n     * _.find(users, ['active', false]);\n     * // => object for 'fred'\n     *\n     * // The `_.property` iteratee shorthand.\n     * _.find(users, 'active');\n     * // => object for 'barney'\n     */\n    var find = createFind(findIndex);\n\n    /**\n     * This method is like `_.find` except that it iterates over elements of\n     * `collection` from right to left.\n     *\n     * @static\n     * @memberOf _\n     * @since 2.0.0\n     * @category Collection\n     * @param {Array|Object} collection The collection to inspect.\n     * @param {Function} [predicate=_.identity] The function invoked per iteration.\n     * @param {number} [fromIndex=collection.length-1] The index to search from.\n     * @returns {*} Returns the matched element, else `undefined`.\n     * @example\n     *\n     * _.findLast([1, 2, 3, 4], function(n) {\n     *   return n % 2 == 1;\n     * });\n     * // => 3\n     */\n    var findLast = createFind(findLastIndex);\n\n    /**\n     * Creates a flattened array of values by running each element in `collection`\n     * thru `iteratee` and flattening the mapped results. The iteratee is invoked\n     * with three arguments: (value, index|key, collection).\n     *\n     * @static\n     * @memberOf _\n     * @since 4.0.0\n     * @category Collection\n     * @param {Array|Object} collection The collection to iterate over.\n     * @param {Function} [iteratee=_.identity] The function invoked per iteration.\n     * @returns {Array} Returns the new flattened array.\n     * @example\n     *\n     * function duplicate(n) {\n     *   return [n, n];\n     * }\n     *\n     * _.flatMap([1, 2], duplicate);\n     * // => [1, 1, 2, 2]\n     */\n    function flatMap(collection, iteratee) {\n      return baseFlatten(map(collection, iteratee), 1);\n    }\n\n    /**\n     * This method is like `_.flatMap` except that it recursively flattens the\n     * mapped results.\n     *\n     * @static\n     * @memberOf _\n     * @since 4.7.0\n     * @category Collection\n     * @param {Array|Object} collection The collection to iterate over.\n     * @param {Function} [iteratee=_.identity] The function invoked per iteration.\n     * @returns {Array} Returns the new flattened array.\n     * @example\n     *\n     * function duplicate(n) {\n     *   return [[[n, n]]];\n     * }\n     *\n     * _.flatMapDeep([1, 2], duplicate);\n     * // => [1, 1, 2, 2]\n     */\n    function flatMapDeep(collection, iteratee) {\n      return baseFlatten(map(collection, iteratee), INFINITY);\n    }\n\n    /**\n     * This method is like `_.flatMap` except that it recursively flattens the\n     * mapped results up to `depth` times.\n     *\n     * @static\n     * @memberOf _\n     * @since 4.7.0\n     * @category Collection\n     * @param {Array|Object} collection The collection to iterate over.\n     * @param {Function} [iteratee=_.identity] The function invoked per iteration.\n     * @param {number} [depth=1] The maximum recursion depth.\n     * @returns {Array} Returns the new flattened array.\n     * @example\n     *\n     * function duplicate(n) {\n     *   return [[[n, n]]];\n     * }\n     *\n     * _.flatMapDepth([1, 2], duplicate, 2);\n     * // => [[1, 1], [2, 2]]\n     */\n    function flatMapDepth(collection, iteratee, depth) {\n      depth = depth === undefined ? 1 : toInteger(depth);\n      return baseFlatten(map(collection, iteratee), depth);\n    }\n\n    /**\n     * Iterates over elements of `collection` and invokes `iteratee` for each element.\n     * The iteratee is invoked with three arguments: (value, index|key, collection).\n     * Iteratee functions may exit iteration early by explicitly returning `false`.\n     *\n     * **Note:** As with other \"Collections\" methods, objects with a \"length\"\n     * property are iterated like arrays. To avoid this behavior use `_.forIn`\n     * or `_.forOwn` for object iteration.\n     *\n     * @static\n     * @memberOf _\n     * @since 0.1.0\n     * @alias each\n     * @category Collection\n     * @param {Array|Object} collection The collection to iterate over.\n     * @param {Function} [iteratee=_.identity] The function invoked per iteration.\n     * @returns {Array|Object} Returns `collection`.\n     * @see _.forEachRight\n     * @example\n     *\n     * _.forEach([1, 2], function(value) {\n     *   console.log(value);\n     * });\n     * // => Logs `1` then `2`.\n     *\n     * _.forEach({ 'a': 1, 'b': 2 }, function(value, key) {\n     *   console.log(key);\n     * });\n     * // => Logs 'a' then 'b' (iteration order is not guaranteed).\n     */\n    function forEach(collection, iteratee) {\n      var func = isArray(collection) ? arrayEach : baseEach;\n      return func(collection, getIteratee(iteratee, 3));\n    }\n\n    /**\n     * This method is like `_.forEach` except that it iterates over elements of\n     * `collection` from right to left.\n     *\n     * @static\n     * @memberOf _\n     * @since 2.0.0\n     * @alias eachRight\n     * @category Collection\n     * @param {Array|Object} collection The collection to iterate over.\n     * @param {Function} [iteratee=_.identity] The function invoked per iteration.\n     * @returns {Array|Object} Returns `collection`.\n     * @see _.forEach\n     * @example\n     *\n     * _.forEachRight([1, 2], function(value) {\n     *   console.log(value);\n     * });\n     * // => Logs `2` then `1`.\n     */\n    function forEachRight(collection, iteratee) {\n      var func = isArray(collection) ? arrayEachRight : baseEachRight;\n      return func(collection, getIteratee(iteratee, 3));\n    }\n\n    /**\n     * Creates an object composed of keys generated from the results of running\n     * each element of `collection` thru `iteratee`. The order of grouped values\n     * is determined by the order they occur in `collection`. The corresponding\n     * value of each key is an array of elements responsible for generating the\n     * key. The iteratee is invoked with one argument: (value).\n     *\n     * @static\n     * @memberOf _\n     * @since 0.1.0\n     * @category Collection\n     * @param {Array|Object} collection The collection to iterate over.\n     * @param {Function} [iteratee=_.identity] The iteratee to transform keys.\n     * @returns {Object} Returns the composed aggregate object.\n     * @example\n     *\n     * _.groupBy([6.1, 4.2, 6.3], Math.floor);\n     * // => { '4': [4.2], '6': [6.1, 6.3] }\n     *\n     * // The `_.property` iteratee shorthand.\n     * _.groupBy(['one', 'two', 'three'], 'length');\n     * // => { '3': ['one', 'two'], '5': ['three'] }\n     */\n    var groupBy = createAggregator(function(result, value, key) {\n      if (hasOwnProperty.call(result, key)) {\n        result[key].push(value);\n      } else {\n        baseAssignValue(result, key, [value]);\n      }\n    });\n\n    /**\n     * Checks if `value` is in `collection`. If `collection` is a string, it's\n     * checked for a substring of `value`, otherwise\n     * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)\n     * is used for equality comparisons. If `fromIndex` is negative, it's used as\n     * the offset from the end of `collection`.\n     *\n     * @static\n     * @memberOf _\n     * @since 0.1.0\n     * @category Collection\n     * @param {Array|Object|string} collection The collection to inspect.\n     * @param {*} value The value to search for.\n     * @param {number} [fromIndex=0] The index to search from.\n     * @param- {Object} [guard] Enables use as an iteratee for methods like `_.reduce`.\n     * @returns {boolean} Returns `true` if `value` is found, else `false`.\n     * @example\n     *\n     * _.includes([1, 2, 3], 1);\n     * // => true\n     *\n     * _.includes([1, 2, 3], 1, 2);\n     * // => false\n     *\n     * _.includes({ 'a': 1, 'b': 2 }, 1);\n     * // => true\n     *\n     * _.includes('abcd', 'bc');\n     * // => true\n     */\n    function includes(collection, value, fromIndex, guard) {\n      collection = isArrayLike(collection) ? collection : values(collection);\n      fromIndex = (fromIndex && !guard) ? toInteger(fromIndex) : 0;\n\n      var length = collection.length;\n      if (fromIndex < 0) {\n        fromIndex = nativeMax(length + fromIndex, 0);\n      }\n      return isString(collection)\n        ? (fromIndex <= length && collection.indexOf(value, fromIndex) > -1)\n        : (!!length && baseIndexOf(collection, value, fromIndex) > -1);\n    }\n\n    /**\n     * Invokes the method at `path` of each element in `collection`, returning\n     * an array of the results of each invoked method. Any additional arguments\n     * are provided to each invoked method. If `path` is a function, it's invoked\n     * for, and `this` bound to, each element in `collection`.\n     *\n     * @static\n     * @memberOf _\n     * @since 4.0.0\n     * @category Collection\n     * @param {Array|Object} collection The collection to iterate over.\n     * @param {Array|Function|string} path The path of the method to invoke or\n     *  the function invoked per iteration.\n     * @param {...*} [args] The arguments to invoke each method with.\n     * @returns {Array} Returns the array of results.\n     * @example\n     *\n     * _.invokeMap([[5, 1, 7], [3, 2, 1]], 'sort');\n     * // => [[1, 5, 7], [1, 2, 3]]\n     *\n     * _.invokeMap([123, 456], String.prototype.split, '');\n     * // => [['1', '2', '3'], ['4', '5', '6']]\n     */\n    var invokeMap = baseRest(function(collection, path, args) {\n      var index = -1,\n          isFunc = typeof path == 'function',\n          result = isArrayLike(collection) ? Array(collection.length) : [];\n\n      baseEach(collection, function(value) {\n        result[++index] = isFunc ? apply(path, value, args) : baseInvoke(value, path, args);\n      });\n      return result;\n    });\n\n    /**\n     * Creates an object composed of keys generated from the results of running\n     * each element of `collection` thru `iteratee`. The corresponding value of\n     * each key is the last element responsible for generating the key. The\n     * iteratee is invoked with one argument: (value).\n     *\n     * @static\n     * @memberOf _\n     * @since 4.0.0\n     * @category Collection\n     * @param {Array|Object} collection The collection to iterate over.\n     * @param {Function} [iteratee=_.identity] The iteratee to transform keys.\n     * @returns {Object} Returns the composed aggregate object.\n     * @example\n     *\n     * var array = [\n     *   { 'dir': 'left', 'code': 97 },\n     *   { 'dir': 'right', 'code': 100 }\n     * ];\n     *\n     * _.keyBy(array, function(o) {\n     *   return String.fromCharCode(o.code);\n     * });\n     * // => { 'a': { 'dir': 'left', 'code': 97 }, 'd': { 'dir': 'right', 'code': 100 } }\n     *\n     * _.keyBy(array, 'dir');\n     * // => { 'left': { 'dir': 'left', 'code': 97 }, 'right': { 'dir': 'right', 'code': 100 } }\n     */\n    var keyBy = createAggregator(function(result, value, key) {\n      baseAssignValue(result, key, value);\n    });\n\n    /**\n     * Creates an array of values by running each element in `collection` thru\n     * `iteratee`. The iteratee is invoked with three arguments:\n     * (value, index|key, collection).\n     *\n     * Many lodash methods are guarded to work as iteratees for methods like\n     * `_.every`, `_.filter`, `_.map`, `_.mapValues`, `_.reject`, and `_.some`.\n     *\n     * The guarded methods are:\n     * `ary`, `chunk`, `curry`, `curryRight`, `drop`, `dropRight`, `every`,\n     * `fill`, `invert`, `parseInt`, `random`, `range`, `rangeRight`, `repeat`,\n     * `sampleSize`, `slice`, `some`, `sortBy`, `split`, `take`, `takeRight`,\n     * `template`, `trim`, `trimEnd`, `trimStart`, and `words`\n     *\n     * @static\n     * @memberOf _\n     * @since 0.1.0\n     * @category Collection\n     * @param {Array|Object} collection The collection to iterate over.\n     * @param {Function} [iteratee=_.identity] The function invoked per iteration.\n     * @returns {Array} Returns the new mapped array.\n     * @example\n     *\n     * function square(n) {\n     *   return n * n;\n     * }\n     *\n     * _.map([4, 8], square);\n     * // => [16, 64]\n     *\n     * _.map({ 'a': 4, 'b': 8 }, square);\n     * // => [16, 64] (iteration order is not guaranteed)\n     *\n     * var users = [\n     *   { 'user': 'barney' },\n     *   { 'user': 'fred' }\n     * ];\n     *\n     * // The `_.property` iteratee shorthand.\n     * _.map(users, 'user');\n     * // => ['barney', 'fred']\n     */\n    function map(collection, iteratee) {\n      var func = isArray(collection) ? arrayMap : baseMap;\n      return func(collection, getIteratee(iteratee, 3));\n    }\n\n    /**\n     * This method is like `_.sortBy` except that it allows specifying the sort\n     * orders of the iteratees to sort by. If `orders` is unspecified, all values\n     * are sorted in ascending order. Otherwise, specify an order of \"desc\" for\n     * descending or \"asc\" for ascending sort order of corresponding values.\n     *\n     * @static\n     * @memberOf _\n     * @since 4.0.0\n     * @category Collection\n     * @param {Array|Object} collection The collection to iterate over.\n     * @param {Array[]|Function[]|Object[]|string[]} [iteratees=[_.identity]]\n     *  The iteratees to sort by.\n     * @param {string[]} [orders] The sort orders of `iteratees`.\n     * @param- {Object} [guard] Enables use as an iteratee for methods like `_.reduce`.\n     * @returns {Array} Returns the new sorted array.\n     * @example\n     *\n     * var users = [\n     *   { 'user': 'fred',   'age': 48 },\n     *   { 'user': 'barney', 'age': 34 },\n     *   { 'user': 'fred',   'age': 40 },\n     *   { 'user': 'barney', 'age': 36 }\n     * ];\n     *\n     * // Sort by `user` in ascending order and by `age` in descending order.\n     * _.orderBy(users, ['user', 'age'], ['asc', 'desc']);\n     * // => objects for [['barney', 36], ['barney', 34], ['fred', 48], ['fred', 40]]\n     */\n    function orderBy(collection, iteratees, orders, guard) {\n      if (collection == null) {\n        return [];\n      }\n      if (!isArray(iteratees)) {\n        iteratees = iteratees == null ? [] : [iteratees];\n      }\n      orders = guard ? undefined : orders;\n      if (!isArray(orders)) {\n        orders = orders == null ? [] : [orders];\n      }\n      return baseOrderBy(collection, iteratees, orders);\n    }\n\n    /**\n     * Creates an array of elements split into two groups, the first of which\n     * contains elements `predicate` returns truthy for, the second of which\n     * contains elements `predicate` returns falsey for. The predicate is\n     * invoked with one argument: (value).\n     *\n     * @static\n     * @memberOf _\n     * @since 3.0.0\n     * @category Collection\n     * @param {Array|Object} collection The collection to iterate over.\n     * @param {Function} [predicate=_.identity] The function invoked per iteration.\n     * @returns {Array} Returns the array of grouped elements.\n     * @example\n     *\n     * var users = [\n     *   { 'user': 'barney',  'age': 36, 'active': false },\n     *   { 'user': 'fred',    'age': 40, 'active': true },\n     *   { 'user': 'pebbles', 'age': 1,  'active': false }\n     * ];\n     *\n     * _.partition(users, function(o) { return o.active; });\n     * // => objects for [['fred'], ['barney', 'pebbles']]\n     *\n     * // The `_.matches` iteratee shorthand.\n     * _.partition(users, { 'age': 1, 'active': false });\n     * // => objects for [['pebbles'], ['barney', 'fred']]\n     *\n     * // The `_.matchesProperty` iteratee shorthand.\n     * _.partition(users, ['active', false]);\n     * // => objects for [['barney', 'pebbles'], ['fred']]\n     *\n     * // The `_.property` iteratee shorthand.\n     * _.partition(users, 'active');\n     * // => objects for [['fred'], ['barney', 'pebbles']]\n     */\n    var partition = createAggregator(function(result, value, key) {\n      result[key ? 0 : 1].push(value);\n    }, function() { return [[], []]; });\n\n    /**\n     * Reduces `collection` to a value which is the accumulated result of running\n     * each element in `collection` thru `iteratee`, where each successive\n     * invocation is supplied the return value of the previous. If `accumulator`\n     * is not given, the first element of `collection` is used as the initial\n     * value. The iteratee is invoked with four arguments:\n     * (accumulator, value, index|key, collection).\n     *\n     * Many lodash methods are guarded to work as iteratees for methods like\n     * `_.reduce`, `_.reduceRight`, and `_.transform`.\n     *\n     * The guarded methods are:\n     * `assign`, `defaults`, `defaultsDeep`, `includes`, `merge`, `orderBy`,\n     * and `sortBy`\n     *\n     * @static\n     * @memberOf _\n     * @since 0.1.0\n     * @category Collection\n     * @param {Array|Object} collection The collection to iterate over.\n     * @param {Function} [iteratee=_.identity] The function invoked per iteration.\n     * @param {*} [accumulator] The initial value.\n     * @returns {*} Returns the accumulated value.\n     * @see _.reduceRight\n     * @example\n     *\n     * _.reduce([1, 2], function(sum, n) {\n     *   return sum + n;\n     * }, 0);\n     * // => 3\n     *\n     * _.reduce({ 'a': 1, 'b': 2, 'c': 1 }, function(result, value, key) {\n     *   (result[value] || (result[value] = [])).push(key);\n     *   return result;\n     * }, {});\n     * // => { '1': ['a', 'c'], '2': ['b'] } (iteration order is not guaranteed)\n     */\n    function reduce(collection, iteratee, accumulator) {\n      var func = isArray(collection) ? arrayReduce : baseReduce,\n          initAccum = arguments.length < 3;\n\n      return func(collection, getIteratee(iteratee, 4), accumulator, initAccum, baseEach);\n    }\n\n    /**\n     * This method is like `_.reduce` except that it iterates over elements of\n     * `collection` from right to left.\n     *\n     * @static\n     * @memberOf _\n     * @since 0.1.0\n     * @category Collection\n     * @param {Array|Object} collection The collection to iterate over.\n     * @param {Function} [iteratee=_.identity] The function invoked per iteration.\n     * @param {*} [accumulator] The initial value.\n     * @returns {*} Returns the accumulated value.\n     * @see _.reduce\n     * @example\n     *\n     * var array = [[0, 1], [2, 3], [4, 5]];\n     *\n     * _.reduceRight(array, function(flattened, other) {\n     *   return flattened.concat(other);\n     * }, []);\n     * // => [4, 5, 2, 3, 0, 1]\n     */\n    function reduceRight(collection, iteratee, accumulator) {\n      var func = isArray(collection) ? arrayReduceRight : baseReduce,\n          initAccum = arguments.length < 3;\n\n      return func(collection, getIteratee(iteratee, 4), accumulator, initAccum, baseEachRight);\n    }\n\n    /**\n     * The opposite of `_.filter`; this method returns the elements of `collection`\n     * that `predicate` does **not** return truthy for.\n     *\n     * @static\n     * @memberOf _\n     * @since 0.1.0\n     * @category Collection\n     * @param {Array|Object} collection The collection to iterate over.\n     * @param {Function} [predicate=_.identity] The function invoked per iteration.\n     * @returns {Array} Returns the new filtered array.\n     * @see _.filter\n     * @example\n     *\n     * var users = [\n     *   { 'user': 'barney', 'age': 36, 'active': false },\n     *   { 'user': 'fred',   'age': 40, 'active': true }\n     * ];\n     *\n     * _.reject(users, function(o) { return !o.active; });\n     * // => objects for ['fred']\n     *\n     * // The `_.matches` iteratee shorthand.\n     * _.reject(users, { 'age': 40, 'active': true });\n     * // => objects for ['barney']\n     *\n     * // The `_.matchesProperty` iteratee shorthand.\n     * _.reject(users, ['active', false]);\n     * // => objects for ['fred']\n     *\n     * // The `_.property` iteratee shorthand.\n     * _.reject(users, 'active');\n     * // => objects for ['barney']\n     */\n    function reject(collection, predicate) {\n      var func = isArray(collection) ? arrayFilter : baseFilter;\n      return func(collection, negate(getIteratee(predicate, 3)));\n    }\n\n    /**\n     * Gets a random element from `collection`.\n     *\n     * @static\n     * @memberOf _\n     * @since 2.0.0\n     * @category Collection\n     * @param {Array|Object} collection The collection to sample.\n     * @returns {*} Returns the random element.\n     * @example\n     *\n     * _.sample([1, 2, 3, 4]);\n     * // => 2\n     */\n    function sample(collection) {\n      var func = isArray(collection) ? arraySample : baseSample;\n      return func(collection);\n    }\n\n    /**\n     * Gets `n` random elements at unique keys from `collection` up to the\n     * size of `collection`.\n     *\n     * @static\n     * @memberOf _\n     * @since 4.0.0\n     * @category Collection\n     * @param {Array|Object} collection The collection to sample.\n     * @param {number} [n=1] The number of elements to sample.\n     * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.\n     * @returns {Array} Returns the random elements.\n     * @example\n     *\n     * _.sampleSize([1, 2, 3], 2);\n     * // => [3, 1]\n     *\n     * _.sampleSize([1, 2, 3], 4);\n     * // => [2, 3, 1]\n     */\n    function sampleSize(collection, n, guard) {\n      if ((guard ? isIterateeCall(collection, n, guard) : n === undefined)) {\n        n = 1;\n      } else {\n        n = toInteger(n);\n      }\n      var func = isArray(collection) ? arraySampleSize : baseSampleSize;\n      return func(collection, n);\n    }\n\n    /**\n     * Creates an array of shuffled values, using a version of the\n     * [Fisher-Yates shuffle](https://en.wikipedia.org/wiki/Fisher-Yates_shuffle).\n     *\n     * @static\n     * @memberOf _\n     * @since 0.1.0\n     * @category Collection\n     * @param {Array|Object} collection The collection to shuffle.\n     * @returns {Array} Returns the new shuffled array.\n     * @example\n     *\n     * _.shuffle([1, 2, 3, 4]);\n     * // => [4, 1, 3, 2]\n     */\n    function shuffle(collection) {\n      var func = isArray(collection) ? arrayShuffle : baseShuffle;\n      return func(collection);\n    }\n\n    /**\n     * Gets the size of `collection` by returning its length for array-like\n     * values or the number of own enumerable string keyed properties for objects.\n     *\n     * @static\n     * @memberOf _\n     * @since 0.1.0\n     * @category Collection\n     * @param {Array|Object|string} collection The collection to inspect.\n     * @returns {number} Returns the collection size.\n     * @example\n     *\n     * _.size([1, 2, 3]);\n     * // => 3\n     *\n     * _.size({ 'a': 1, 'b': 2 });\n     * // => 2\n     *\n     * _.size('pebbles');\n     * // => 7\n     */\n    function size(collection) {\n      if (collection == null) {\n        return 0;\n      }\n      if (isArrayLike(collection)) {\n        return isString(collection) ? stringSize(collection) : collection.length;\n      }\n      var tag = getTag(collection);\n      if (tag == mapTag || tag == setTag) {\n        return collection.size;\n      }\n      return baseKeys(collection).length;\n    }\n\n    /**\n     * Checks if `predicate` returns truthy for **any** element of `collection`.\n     * Iteration is stopped once `predicate` returns truthy. The predicate is\n     * invoked with three arguments: (value, index|key, collection).\n     *\n     * @static\n     * @memberOf _\n     * @since 0.1.0\n     * @category Collection\n     * @param {Array|Object} collection The collection to iterate over.\n     * @param {Function} [predicate=_.identity] The function invoked per iteration.\n     * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.\n     * @returns {boolean} Returns `true` if any element passes the predicate check,\n     *  else `false`.\n     * @example\n     *\n     * _.some([null, 0, 'yes', false], Boolean);\n     * // => true\n     *\n     * var users = [\n     *   { 'user': 'barney', 'active': true },\n     *   { 'user': 'fred',   'active': false }\n     * ];\n     *\n     * // The `_.matches` iteratee shorthand.\n     * _.some(users, { 'user': 'barney', 'active': false });\n     * // => false\n     *\n     * // The `_.matchesProperty` iteratee shorthand.\n     * _.some(users, ['active', false]);\n     * // => true\n     *\n     * // The `_.property` iteratee shorthand.\n     * _.some(users, 'active');\n     * // => true\n     */\n    function some(collection, predicate, guard) {\n      var func = isArray(collection) ? arraySome : baseSome;\n      if (guard && isIterateeCall(collection, predicate, guard)) {\n        predicate = undefined;\n      }\n      return func(collection, getIteratee(predicate, 3));\n    }\n\n    /**\n     * Creates an array of elements, sorted in ascending order by the results of\n     * running each element in a collection thru each iteratee. This method\n     * performs a stable sort, that is, it preserves the original sort order of\n     * equal elements. The iteratees are invoked with one argument: (value).\n     *\n     * @static\n     * @memberOf _\n     * @since 0.1.0\n     * @category Collection\n     * @param {Array|Object} collection The collection to iterate over.\n     * @param {...(Function|Function[])} [iteratees=[_.identity]]\n     *  The iteratees to sort by.\n     * @returns {Array} Returns the new sorted array.\n     * @example\n     *\n     * var users = [\n     *   { 'user': 'fred',   'age': 48 },\n     *   { 'user': 'barney', 'age': 36 },\n     *   { 'user': 'fred',   'age': 40 },\n     *   { 'user': 'barney', 'age': 34 }\n     * ];\n     *\n     * _.sortBy(users, [function(o) { return o.user; }]);\n     * // => objects for [['barney', 36], ['barney', 34], ['fred', 48], ['fred', 40]]\n     *\n     * _.sortBy(users, ['user', 'age']);\n     * // => objects for [['barney', 34], ['barney', 36], ['fred', 40], ['fred', 48]]\n     */\n    var sortBy = baseRest(function(collection, iteratees) {\n      if (collection == null) {\n        return [];\n      }\n      var length = iteratees.length;\n      if (length > 1 && isIterateeCall(collection, iteratees[0], iteratees[1])) {\n        iteratees = [];\n      } else if (length > 2 && isIterateeCall(iteratees[0], iteratees[1], iteratees[2])) {\n        iteratees = [iteratees[0]];\n      }\n      return baseOrderBy(collection, baseFlatten(iteratees, 1), []);\n    });\n\n    /*------------------------------------------------------------------------*/\n\n    /**\n     * Gets the timestamp of the number of milliseconds that have elapsed since\n     * the Unix epoch (1 January 1970 00:00:00 UTC).\n     *\n     * @static\n     * @memberOf _\n     * @since 2.4.0\n     * @category Date\n     * @returns {number} Returns the timestamp.\n     * @example\n     *\n     * _.defer(function(stamp) {\n     *   console.log(_.now() - stamp);\n     * }, _.now());\n     * // => Logs the number of milliseconds it took for the deferred invocation.\n     */\n    var now = ctxNow || function() {\n      return root.Date.now();\n    };\n\n    /*------------------------------------------------------------------------*/\n\n    /**\n     * The opposite of `_.before`; this method creates a function that invokes\n     * `func` once it's called `n` or more times.\n     *\n     * @static\n     * @memberOf _\n     * @since 0.1.0\n     * @category Function\n     * @param {number} n The number of calls before `func` is invoked.\n     * @param {Function} func The function to restrict.\n     * @returns {Function} Returns the new restricted function.\n     * @example\n     *\n     * var saves = ['profile', 'settings'];\n     *\n     * var done = _.after(saves.length, function() {\n     *   console.log('done saving!');\n     * });\n     *\n     * _.forEach(saves, function(type) {\n     *   asyncSave({ 'type': type, 'complete': done });\n     * });\n     * // => Logs 'done saving!' after the two async saves have completed.\n     */\n    function after(n, func) {\n      if (typeof func != 'function') {\n        throw new TypeError(FUNC_ERROR_TEXT);\n      }\n      n = toInteger(n);\n      return function() {\n        if (--n < 1) {\n          return func.apply(this, arguments);\n        }\n      };\n    }\n\n    /**\n     * Creates a function that invokes `func`, with up to `n` arguments,\n     * ignoring any additional arguments.\n     *\n     * @static\n     * @memberOf _\n     * @since 3.0.0\n     * @category Function\n     * @param {Function} func The function to cap arguments for.\n     * @param {number} [n=func.length] The arity cap.\n     * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.\n     * @returns {Function} Returns the new capped function.\n     * @example\n     *\n     * _.map(['6', '8', '10'], _.ary(parseInt, 1));\n     * // => [6, 8, 10]\n     */\n    function ary(func, n, guard) {\n      n = guard ? undefined : n;\n      n = (func && n == null) ? func.length : n;\n      return createWrap(func, WRAP_ARY_FLAG, undefined, undefined, undefined, undefined, n);\n    }\n\n    /**\n     * Creates a function that invokes `func`, with the `this` binding and arguments\n     * of the created function, while it's called less than `n` times. Subsequent\n     * calls to the created function return the result of the last `func` invocation.\n     *\n     * @static\n     * @memberOf _\n     * @since 3.0.0\n     * @category Function\n     * @param {number} n The number of calls at which `func` is no longer invoked.\n     * @param {Function} func The function to restrict.\n     * @returns {Function} Returns the new restricted function.\n     * @example\n     *\n     * jQuery(element).on('click', _.before(5, addContactToList));\n     * // => Allows adding up to 4 contacts to the list.\n     */\n    function before(n, func) {\n      var result;\n      if (typeof func != 'function') {\n        throw new TypeError(FUNC_ERROR_TEXT);\n      }\n      n = toInteger(n);\n      return function() {\n        if (--n > 0) {\n          result = func.apply(this, arguments);\n        }\n        if (n <= 1) {\n          func = undefined;\n        }\n        return result;\n      };\n    }\n\n    /**\n     * Creates a function that invokes `func` with the `this` binding of `thisArg`\n     * and `partials` prepended to the arguments it receives.\n     *\n     * The `_.bind.placeholder` value, which defaults to `_` in monolithic builds,\n     * may be used as a placeholder for partially applied arguments.\n     *\n     * **Note:** Unlike native `Function#bind`, this method doesn't set the \"length\"\n     * property of bound functions.\n     *\n     * @static\n     * @memberOf _\n     * @since 0.1.0\n     * @category Function\n     * @param {Function} func The function to bind.\n     * @param {*} thisArg The `this` binding of `func`.\n     * @param {...*} [partials] The arguments to be partially applied.\n     * @returns {Function} Returns the new bound function.\n     * @example\n     *\n     * function greet(greeting, punctuation) {\n     *   return greeting + ' ' + this.user + punctuation;\n     * }\n     *\n     * var object = { 'user': 'fred' };\n     *\n     * var bound = _.bind(greet, object, 'hi');\n     * bound('!');\n     * // => 'hi fred!'\n     *\n     * // Bound with placeholders.\n     * var bound = _.bind(greet, object, _, '!');\n     * bound('hi');\n     * // => 'hi fred!'\n     */\n    var bind = baseRest(function(func, thisArg, partials) {\n      var bitmask = WRAP_BIND_FLAG;\n      if (partials.length) {\n        var holders = replaceHolders(partials, getHolder(bind));\n        bitmask |= WRAP_PARTIAL_FLAG;\n      }\n      return createWrap(func, bitmask, thisArg, partials, holders);\n    });\n\n    /**\n     * Creates a function that invokes the method at `object[key]` with `partials`\n     * prepended to the arguments it receives.\n     *\n     * This method differs from `_.bind` by allowing bound functions to reference\n     * methods that may be redefined or don't yet exist. See\n     * [Peter Michaux's article](http://peter.michaux.ca/articles/lazy-function-definition-pattern)\n     * for more details.\n     *\n     * The `_.bindKey.placeholder` value, which defaults to `_` in monolithic\n     * builds, may be used as a placeholder for partially applied arguments.\n     *\n     * @static\n     * @memberOf _\n     * @since 0.10.0\n     * @category Function\n     * @param {Object} object The object to invoke the method on.\n     * @param {string} key The key of the method.\n     * @param {...*} [partials] The arguments to be partially applied.\n     * @returns {Function} Returns the new bound function.\n     * @example\n     *\n     * var object = {\n     *   'user': 'fred',\n     *   'greet': function(greeting, punctuation) {\n     *     return greeting + ' ' + this.user + punctuation;\n     *   }\n     * };\n     *\n     * var bound = _.bindKey(object, 'greet', 'hi');\n     * bound('!');\n     * // => 'hi fred!'\n     *\n     * object.greet = function(greeting, punctuation) {\n     *   return greeting + 'ya ' + this.user + punctuation;\n     * };\n     *\n     * bound('!');\n     * // => 'hiya fred!'\n     *\n     * // Bound with placeholders.\n     * var bound = _.bindKey(object, 'greet', _, '!');\n     * bound('hi');\n     * // => 'hiya fred!'\n     */\n    var bindKey = baseRest(function(object, key, partials) {\n      var bitmask = WRAP_BIND_FLAG | WRAP_BIND_KEY_FLAG;\n      if (partials.length) {\n        var holders = replaceHolders(partials, getHolder(bindKey));\n        bitmask |= WRAP_PARTIAL_FLAG;\n      }\n      return createWrap(key, bitmask, object, partials, holders);\n    });\n\n    /**\n     * Creates a function that accepts arguments of `func` and either invokes\n     * `func` returning its result, if at least `arity` number of arguments have\n     * been provided, or returns a function that accepts the remaining `func`\n     * arguments, and so on. The arity of `func` may be specified if `func.length`\n     * is not sufficient.\n     *\n     * The `_.curry.placeholder` value, which defaults to `_` in monolithic builds,\n     * may be used as a placeholder for provided arguments.\n     *\n     * **Note:** This method doesn't set the \"length\" property of curried functions.\n     *\n     * @static\n     * @memberOf _\n     * @since 2.0.0\n     * @category Function\n     * @param {Function} func The function to curry.\n     * @param {number} [arity=func.length] The arity of `func`.\n     * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.\n     * @returns {Function} Returns the new curried function.\n     * @example\n     *\n     * var abc = function(a, b, c) {\n     *   return [a, b, c];\n     * };\n     *\n     * var curried = _.curry(abc);\n     *\n     * curried(1)(2)(3);\n     * // => [1, 2, 3]\n     *\n     * curried(1, 2)(3);\n     * // => [1, 2, 3]\n     *\n     * curried(1, 2, 3);\n     * // => [1, 2, 3]\n     *\n     * // Curried with placeholders.\n     * curried(1)(_, 3)(2);\n     * // => [1, 2, 3]\n     */\n    function curry(func, arity, guard) {\n      arity = guard ? undefined : arity;\n      var result = createWrap(func, WRAP_CURRY_FLAG, undefined, undefined, undefined, undefined, undefined, arity);\n      result.placeholder = curry.placeholder;\n      return result;\n    }\n\n    /**\n     * This method is like `_.curry` except that arguments are applied to `func`\n     * in the manner of `_.partialRight` instead of `_.partial`.\n     *\n     * The `_.curryRight.placeholder` value, which defaults to `_` in monolithic\n     * builds, may be used as a placeholder for provided arguments.\n     *\n     * **Note:** This method doesn't set the \"length\" property of curried functions.\n     *\n     * @static\n     * @memberOf _\n     * @since 3.0.0\n     * @category Function\n     * @param {Function} func The function to curry.\n     * @param {number} [arity=func.length] The arity of `func`.\n     * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.\n     * @returns {Function} Returns the new curried function.\n     * @example\n     *\n     * var abc = function(a, b, c) {\n     *   return [a, b, c];\n     * };\n     *\n     * var curried = _.curryRight(abc);\n     *\n     * curried(3)(2)(1);\n     * // => [1, 2, 3]\n     *\n     * curried(2, 3)(1);\n     * // => [1, 2, 3]\n     *\n     * curried(1, 2, 3);\n     * // => [1, 2, 3]\n     *\n     * // Curried with placeholders.\n     * curried(3)(1, _)(2);\n     * // => [1, 2, 3]\n     */\n    function curryRight(func, arity, guard) {\n      arity = guard ? undefined : arity;\n      var result = createWrap(func, WRAP_CURRY_RIGHT_FLAG, undefined, undefined, undefined, undefined, undefined, arity);\n      result.placeholder = curryRight.placeholder;\n      return result;\n    }\n\n    /**\n     * Creates a debounced function that delays invoking `func` until after `wait`\n     * milliseconds have elapsed since the last time the debounced function was\n     * invoked. The debounced function comes with a `cancel` method to cancel\n     * delayed `func` invocations and a `flush` method to immediately invoke them.\n     * Provide `options` to indicate whether `func` should be invoked on the\n     * leading and/or trailing edge of the `wait` timeout. The `func` is invoked\n     * with the last arguments provided to the debounced function. Subsequent\n     * calls to the debounced function return the result of the last `func`\n     * invocation.\n     *\n     * **Note:** If `leading` and `trailing` options are `true`, `func` is\n     * invoked on the trailing edge of the timeout only if the debounced function\n     * is invoked more than once during the `wait` timeout.\n     *\n     * If `wait` is `0` and `leading` is `false`, `func` invocation is deferred\n     * until to the next tick, similar to `setTimeout` with a timeout of `0`.\n     *\n     * See [David Corbacho's article](https://css-tricks.com/debouncing-throttling-explained-examples/)\n     * for details over the differences between `_.debounce` and `_.throttle`.\n     *\n     * @static\n     * @memberOf _\n     * @since 0.1.0\n     * @category Function\n     * @param {Function} func The function to debounce.\n     * @param {number} [wait=0] The number of milliseconds to delay.\n     * @param {Object} [options={}] The options object.\n     * @param {boolean} [options.leading=false]\n     *  Specify invoking on the leading edge of the timeout.\n     * @param {number} [options.maxWait]\n     *  The maximum time `func` is allowed to be delayed before it's invoked.\n     * @param {boolean} [options.trailing=true]\n     *  Specify invoking on the trailing edge of the timeout.\n     * @returns {Function} Returns the new debounced function.\n     * @example\n     *\n     * // Avoid costly calculations while the window size is in flux.\n     * jQuery(window).on('resize', _.debounce(calculateLayout, 150));\n     *\n     * // Invoke `sendMail` when clicked, debouncing subsequent calls.\n     * jQuery(element).on('click', _.debounce(sendMail, 300, {\n     *   'leading': true,\n     *   'trailing': false\n     * }));\n     *\n     * // Ensure `batchLog` is invoked once after 1 second of debounced calls.\n     * var debounced = _.debounce(batchLog, 250, { 'maxWait': 1000 });\n     * var source = new EventSource('/stream');\n     * jQuery(source).on('message', debounced);\n     *\n     * // Cancel the trailing debounced invocation.\n     * jQuery(window).on('popstate', debounced.cancel);\n     */\n    function debounce(func, wait, options) {\n      var lastArgs,\n          lastThis,\n          maxWait,\n          result,\n          timerId,\n          lastCallTime,\n          lastInvokeTime = 0,\n          leading = false,\n          maxing = false,\n          trailing = true;\n\n      if (typeof func != 'function') {\n        throw new TypeError(FUNC_ERROR_TEXT);\n      }\n      wait = toNumber(wait) || 0;\n      if (isObject(options)) {\n        leading = !!options.leading;\n        maxing = 'maxWait' in options;\n        maxWait = maxing ? nativeMax(toNumber(options.maxWait) || 0, wait) : maxWait;\n        trailing = 'trailing' in options ? !!options.trailing : trailing;\n      }\n\n      function invokeFunc(time) {\n        var args = lastArgs,\n            thisArg = lastThis;\n\n        lastArgs = lastThis = undefined;\n        lastInvokeTime = time;\n        result = func.apply(thisArg, args);\n        return result;\n      }\n\n      function leadingEdge(time) {\n        // Reset any `maxWait` timer.\n        lastInvokeTime = time;\n        // Start the timer for the trailing edge.\n        timerId = setTimeout(timerExpired, wait);\n        // Invoke the leading edge.\n        return leading ? invokeFunc(time) : result;\n      }\n\n      function remainingWait(time) {\n        var timeSinceLastCall = time - lastCallTime,\n            timeSinceLastInvoke = time - lastInvokeTime,\n            timeWaiting = wait - timeSinceLastCall;\n\n        return maxing\n          ? nativeMin(timeWaiting, maxWait - timeSinceLastInvoke)\n          : timeWaiting;\n      }\n\n      function shouldInvoke(time) {\n        var timeSinceLastCall = time - lastCallTime,\n            timeSinceLastInvoke = time - lastInvokeTime;\n\n        // Either this is the first call, activity has stopped and we're at the\n        // trailing edge, the system time has gone backwards and we're treating\n        // it as the trailing edge, or we've hit the `maxWait` limit.\n        return (lastCallTime === undefined || (timeSinceLastCall >= wait) ||\n          (timeSinceLastCall < 0) || (maxing && timeSinceLastInvoke >= maxWait));\n      }\n\n      function timerExpired() {\n        var time = now();\n        if (shouldInvoke(time)) {\n          return trailingEdge(time);\n        }\n        // Restart the timer.\n        timerId = setTimeout(timerExpired, remainingWait(time));\n      }\n\n      function trailingEdge(time) {\n        timerId = undefined;\n\n        // Only invoke if we have `lastArgs` which means `func` has been\n        // debounced at least once.\n        if (trailing && lastArgs) {\n          return invokeFunc(time);\n        }\n        lastArgs = lastThis = undefined;\n        return result;\n      }\n\n      function cancel() {\n        if (timerId !== undefined) {\n          clearTimeout(timerId);\n        }\n        lastInvokeTime = 0;\n        lastArgs = lastCallTime = lastThis = timerId = undefined;\n      }\n\n      function flush() {\n        return timerId === undefined ? result : trailingEdge(now());\n      }\n\n      function debounced() {\n        var time = now(),\n            isInvoking = shouldInvoke(time);\n\n        lastArgs = arguments;\n        lastThis = this;\n        lastCallTime = time;\n\n        if (isInvoking) {\n          if (timerId === undefined) {\n            return leadingEdge(lastCallTime);\n          }\n          if (maxing) {\n            // Handle invocations in a tight loop.\n            timerId = setTimeout(timerExpired, wait);\n            return invokeFunc(lastCallTime);\n          }\n        }\n        if (timerId === undefined) {\n          timerId = setTimeout(timerExpired, wait);\n        }\n        return result;\n      }\n      debounced.cancel = cancel;\n      debounced.flush = flush;\n      return debounced;\n    }\n\n    /**\n     * Defers invoking the `func` until the current call stack has cleared. Any\n     * additional arguments are provided to `func` when it's invoked.\n     *\n     * @static\n     * @memberOf _\n     * @since 0.1.0\n     * @category Function\n     * @param {Function} func The function to defer.\n     * @param {...*} [args] The arguments to invoke `func` with.\n     * @returns {number} Returns the timer id.\n     * @example\n     *\n     * _.defer(function(text) {\n     *   console.log(text);\n     * }, 'deferred');\n     * // => Logs 'deferred' after one millisecond.\n     */\n    var defer = baseRest(function(func, args) {\n      return baseDelay(func, 1, args);\n    });\n\n    /**\n     * Invokes `func` after `wait` milliseconds. Any additional arguments are\n     * provided to `func` when it's invoked.\n     *\n     * @static\n     * @memberOf _\n     * @since 0.1.0\n     * @category Function\n     * @param {Function} func The function to delay.\n     * @param {number} wait The number of milliseconds to delay invocation.\n     * @param {...*} [args] The arguments to invoke `func` with.\n     * @returns {number} Returns the timer id.\n     * @example\n     *\n     * _.delay(function(text) {\n     *   console.log(text);\n     * }, 1000, 'later');\n     * // => Logs 'later' after one second.\n     */\n    var delay = baseRest(function(func, wait, args) {\n      return baseDelay(func, toNumber(wait) || 0, args);\n    });\n\n    /**\n     * Creates a function that invokes `func` with arguments reversed.\n     *\n     * @static\n     * @memberOf _\n     * @since 4.0.0\n     * @category Function\n     * @param {Function} func The function to flip arguments for.\n     * @returns {Function} Returns the new flipped function.\n     * @example\n     *\n     * var flipped = _.flip(function() {\n     *   return _.toArray(arguments);\n     * });\n     *\n     * flipped('a', 'b', 'c', 'd');\n     * // => ['d', 'c', 'b', 'a']\n     */\n    function flip(func) {\n      return createWrap(func, WRAP_FLIP_FLAG);\n    }\n\n    /**\n     * Creates a function that memoizes the result of `func`. If `resolver` is\n     * provided, it determines the cache key for storing the result based on the\n     * arguments provided to the memoized function. By default, the first argument\n     * provided to the memoized function is used as the map cache key. The `func`\n     * is invoked with the `this` binding of the memoized function.\n     *\n     * **Note:** The cache is exposed as the `cache` property on the memoized\n     * function. Its creation may be customized by replacing the `_.memoize.Cache`\n     * constructor with one whose instances implement the\n     * [`Map`](http://ecma-international.org/ecma-262/7.0/#sec-properties-of-the-map-prototype-object)\n     * method interface of `clear`, `delete`, `get`, `has`, and `set`.\n     *\n     * @static\n     * @memberOf _\n     * @since 0.1.0\n     * @category Function\n     * @param {Function} func The function to have its output memoized.\n     * @param {Function} [resolver] The function to resolve the cache key.\n     * @returns {Function} Returns the new memoized function.\n     * @example\n     *\n     * var object = { 'a': 1, 'b': 2 };\n     * var other = { 'c': 3, 'd': 4 };\n     *\n     * var values = _.memoize(_.values);\n     * values(object);\n     * // => [1, 2]\n     *\n     * values(other);\n     * // => [3, 4]\n     *\n     * object.a = 2;\n     * values(object);\n     * // => [1, 2]\n     *\n     * // Modify the result cache.\n     * values.cache.set(object, ['a', 'b']);\n     * values(object);\n     * // => ['a', 'b']\n     *\n     * // Replace `_.memoize.Cache`.\n     * _.memoize.Cache = WeakMap;\n     */\n    function memoize(func, resolver) {\n      if (typeof func != 'function' || (resolver != null && typeof resolver != 'function')) {\n        throw new TypeError(FUNC_ERROR_TEXT);\n      }\n      var memoized = function() {\n        var args = arguments,\n            key = resolver ? resolver.apply(this, args) : args[0],\n            cache = memoized.cache;\n\n        if (cache.has(key)) {\n          return cache.get(key);\n        }\n        var result = func.apply(this, args);\n        memoized.cache = cache.set(key, result) || cache;\n        return result;\n      };\n      memoized.cache = new (memoize.Cache || MapCache);\n      return memoized;\n    }\n\n    // Expose `MapCache`.\n    memoize.Cache = MapCache;\n\n    /**\n     * Creates a function that negates the result of the predicate `func`. The\n     * `func` predicate is invoked with the `this` binding and arguments of the\n     * created function.\n     *\n     * @static\n     * @memberOf _\n     * @since 3.0.0\n     * @category Function\n     * @param {Function} predicate The predicate to negate.\n     * @returns {Function} Returns the new negated function.\n     * @example\n     *\n     * function isEven(n) {\n     *   return n % 2 == 0;\n     * }\n     *\n     * _.filter([1, 2, 3, 4, 5, 6], _.negate(isEven));\n     * // => [1, 3, 5]\n     */\n    function negate(predicate) {\n      if (typeof predicate != 'function') {\n        throw new TypeError(FUNC_ERROR_TEXT);\n      }\n      return function() {\n        var args = arguments;\n        switch (args.length) {\n          case 0: return !predicate.call(this);\n          case 1: return !predicate.call(this, args[0]);\n          case 2: return !predicate.call(this, args[0], args[1]);\n          case 3: return !predicate.call(this, args[0], args[1], args[2]);\n        }\n        return !predicate.apply(this, args);\n      };\n    }\n\n    /**\n     * Creates a function that is restricted to invoking `func` once. Repeat calls\n     * to the function return the value of the first invocation. The `func` is\n     * invoked with the `this` binding and arguments of the created function.\n     *\n     * @static\n     * @memberOf _\n     * @since 0.1.0\n     * @category Function\n     * @param {Function} func The function to restrict.\n     * @returns {Function} Returns the new restricted function.\n     * @example\n     *\n     * var initialize = _.once(createApplication);\n     * initialize();\n     * initialize();\n     * // => `createApplication` is invoked once\n     */\n    function once(func) {\n      return before(2, func);\n    }\n\n    /**\n     * Creates a function that invokes `func` with its arguments transformed.\n     *\n     * @static\n     * @since 4.0.0\n     * @memberOf _\n     * @category Function\n     * @param {Function} func The function to wrap.\n     * @param {...(Function|Function[])} [transforms=[_.identity]]\n     *  The argument transforms.\n     * @returns {Function} Returns the new function.\n     * @example\n     *\n     * function doubled(n) {\n     *   return n * 2;\n     * }\n     *\n     * function square(n) {\n     *   return n * n;\n     * }\n     *\n     * var func = _.overArgs(function(x, y) {\n     *   return [x, y];\n     * }, [square, doubled]);\n     *\n     * func(9, 3);\n     * // => [81, 6]\n     *\n     * func(10, 5);\n     * // => [100, 10]\n     */\n    var overArgs = castRest(function(func, transforms) {\n      transforms = (transforms.length == 1 && isArray(transforms[0]))\n        ? arrayMap(transforms[0], baseUnary(getIteratee()))\n        : arrayMap(baseFlatten(transforms, 1), baseUnary(getIteratee()));\n\n      var funcsLength = transforms.length;\n      return baseRest(function(args) {\n        var index = -1,\n            length = nativeMin(args.length, funcsLength);\n\n        while (++index < length) {\n          args[index] = transforms[index].call(this, args[index]);\n        }\n        return apply(func, this, args);\n      });\n    });\n\n    /**\n     * Creates a function that invokes `func` with `partials` prepended to the\n     * arguments it receives. This method is like `_.bind` except it does **not**\n     * alter the `this` binding.\n     *\n     * The `_.partial.placeholder` value, which defaults to `_` in monolithic\n     * builds, may be used as a placeholder for partially applied arguments.\n     *\n     * **Note:** This method doesn't set the \"length\" property of partially\n     * applied functions.\n     *\n     * @static\n     * @memberOf _\n     * @since 0.2.0\n     * @category Function\n     * @param {Function} func The function to partially apply arguments to.\n     * @param {...*} [partials] The arguments to be partially applied.\n     * @returns {Function} Returns the new partially applied function.\n     * @example\n     *\n     * function greet(greeting, name) {\n     *   return greeting + ' ' + name;\n     * }\n     *\n     * var sayHelloTo = _.partial(greet, 'hello');\n     * sayHelloTo('fred');\n     * // => 'hello fred'\n     *\n     * // Partially applied with placeholders.\n     * var greetFred = _.partial(greet, _, 'fred');\n     * greetFred('hi');\n     * // => 'hi fred'\n     */\n    var partial = baseRest(function(func, partials) {\n      var holders = replaceHolders(partials, getHolder(partial));\n      return createWrap(func, WRAP_PARTIAL_FLAG, undefined, partials, holders);\n    });\n\n    /**\n     * This method is like `_.partial` except that partially applied arguments\n     * are appended to the arguments it receives.\n     *\n     * The `_.partialRight.placeholder` value, which defaults to `_` in monolithic\n     * builds, may be used as a placeholder for partially applied arguments.\n     *\n     * **Note:** This method doesn't set the \"length\" property of partially\n     * applied functions.\n     *\n     * @static\n     * @memberOf _\n     * @since 1.0.0\n     * @category Function\n     * @param {Function} func The function to partially apply arguments to.\n     * @param {...*} [partials] The arguments to be partially applied.\n     * @returns {Function} Returns the new partially applied function.\n     * @example\n     *\n     * function greet(greeting, name) {\n     *   return greeting + ' ' + name;\n     * }\n     *\n     * var greetFred = _.partialRight(greet, 'fred');\n     * greetFred('hi');\n     * // => 'hi fred'\n     *\n     * // Partially applied with placeholders.\n     * var sayHelloTo = _.partialRight(greet, 'hello', _);\n     * sayHelloTo('fred');\n     * // => 'hello fred'\n     */\n    var partialRight = baseRest(function(func, partials) {\n      var holders = replaceHolders(partials, getHolder(partialRight));\n      return createWrap(func, WRAP_PARTIAL_RIGHT_FLAG, undefined, partials, holders);\n    });\n\n    /**\n     * Creates a function that invokes `func` with arguments arranged according\n     * to the specified `indexes` where the argument value at the first index is\n     * provided as the first argument, the argument value at the second index is\n     * provided as the second argument, and so on.\n     *\n     * @static\n     * @memberOf _\n     * @since 3.0.0\n     * @category Function\n     * @param {Function} func The function to rearrange arguments for.\n     * @param {...(number|number[])} indexes The arranged argument indexes.\n     * @returns {Function} Returns the new function.\n     * @example\n     *\n     * var rearged = _.rearg(function(a, b, c) {\n     *   return [a, b, c];\n     * }, [2, 0, 1]);\n     *\n     * rearged('b', 'c', 'a')\n     * // => ['a', 'b', 'c']\n     */\n    var rearg = flatRest(function(func, indexes) {\n      return createWrap(func, WRAP_REARG_FLAG, undefined, undefined, undefined, indexes);\n    });\n\n    /**\n     * Creates a function that invokes `func` with the `this` binding of the\n     * created function and arguments from `start` and beyond provided as\n     * an array.\n     *\n     * **Note:** This method is based on the\n     * [rest parameter](https://mdn.io/rest_parameters).\n     *\n     * @static\n     * @memberOf _\n     * @since 4.0.0\n     * @category Function\n     * @param {Function} func The function to apply a rest parameter to.\n     * @param {number} [start=func.length-1] The start position of the rest parameter.\n     * @returns {Function} Returns the new function.\n     * @example\n     *\n     * var say = _.rest(function(what, names) {\n     *   return what + ' ' + _.initial(names).join(', ') +\n     *     (_.size(names) > 1 ? ', & ' : '') + _.last(names);\n     * });\n     *\n     * say('hello', 'fred', 'barney', 'pebbles');\n     * // => 'hello fred, barney, & pebbles'\n     */\n    function rest(func, start) {\n      if (typeof func != 'function') {\n        throw new TypeError(FUNC_ERROR_TEXT);\n      }\n      start = start === undefined ? start : toInteger(start);\n      return baseRest(func, start);\n    }\n\n    /**\n     * Creates a function that invokes `func` with the `this` binding of the\n     * create function and an array of arguments much like\n     * [`Function#apply`](http://www.ecma-international.org/ecma-262/7.0/#sec-function.prototype.apply).\n     *\n     * **Note:** This method is based on the\n     * [spread operator](https://mdn.io/spread_operator).\n     *\n     * @static\n     * @memberOf _\n     * @since 3.2.0\n     * @category Function\n     * @param {Function} func The function to spread arguments over.\n     * @param {number} [start=0] The start position of the spread.\n     * @returns {Function} Returns the new function.\n     * @example\n     *\n     * var say = _.spread(function(who, what) {\n     *   return who + ' says ' + what;\n     * });\n     *\n     * say(['fred', 'hello']);\n     * // => 'fred says hello'\n     *\n     * var numbers = Promise.all([\n     *   Promise.resolve(40),\n     *   Promise.resolve(36)\n     * ]);\n     *\n     * numbers.then(_.spread(function(x, y) {\n     *   return x + y;\n     * }));\n     * // => a Promise of 76\n     */\n    function spread(func, start) {\n      if (typeof func != 'function') {\n        throw new TypeError(FUNC_ERROR_TEXT);\n      }\n      start = start == null ? 0 : nativeMax(toInteger(start), 0);\n      return baseRest(function(args) {\n        var array = args[start],\n            otherArgs = castSlice(args, 0, start);\n\n        if (array) {\n          arrayPush(otherArgs, array);\n        }\n        return apply(func, this, otherArgs);\n      });\n    }\n\n    /**\n     * Creates a throttled function that only invokes `func` at most once per\n     * every `wait` milliseconds. The throttled function comes with a `cancel`\n     * method to cancel delayed `func` invocations and a `flush` method to\n     * immediately invoke them. Provide `options` to indicate whether `func`\n     * should be invoked on the leading and/or trailing edge of the `wait`\n     * timeout. The `func` is invoked with the last arguments provided to the\n     * throttled function. Subsequent calls to the throttled function return the\n     * result of the last `func` invocation.\n     *\n     * **Note:** If `leading` and `trailing` options are `true`, `func` is\n     * invoked on the trailing edge of the timeout only if the throttled function\n     * is invoked more than once during the `wait` timeout.\n     *\n     * If `wait` is `0` and `leading` is `false`, `func` invocation is deferred\n     * until to the next tick, similar to `setTimeout` with a timeout of `0`.\n     *\n     * See [David Corbacho's article](https://css-tricks.com/debouncing-throttling-explained-examples/)\n     * for details over the differences between `_.throttle` and `_.debounce`.\n     *\n     * @static\n     * @memberOf _\n     * @since 0.1.0\n     * @category Function\n     * @param {Function} func The function to throttle.\n     * @param {number} [wait=0] The number of milliseconds to throttle invocations to.\n     * @param {Object} [options={}] The options object.\n     * @param {boolean} [options.leading=true]\n     *  Specify invoking on the leading edge of the timeout.\n     * @param {boolean} [options.trailing=true]\n     *  Specify invoking on the trailing edge of the timeout.\n     * @returns {Function} Returns the new throttled function.\n     * @example\n     *\n     * // Avoid excessively updating the position while scrolling.\n     * jQuery(window).on('scroll', _.throttle(updatePosition, 100));\n     *\n     * // Invoke `renewToken` when the click event is fired, but not more than once every 5 minutes.\n     * var throttled = _.throttle(renewToken, 300000, { 'trailing': false });\n     * jQuery(element).on('click', throttled);\n     *\n     * // Cancel the trailing throttled invocation.\n     * jQuery(window).on('popstate', throttled.cancel);\n     */\n    function throttle(func, wait, options) {\n      var leading = true,\n          trailing = true;\n\n      if (typeof func != 'function') {\n        throw new TypeError(FUNC_ERROR_TEXT);\n      }\n      if (isObject(options)) {\n        leading = 'leading' in options ? !!options.leading : leading;\n        trailing = 'trailing' in options ? !!options.trailing : trailing;\n      }\n      return debounce(func, wait, {\n        'leading': leading,\n        'maxWait': wait,\n        'trailing': trailing\n      });\n    }\n\n    /**\n     * Creates a function that accepts up to one argument, ignoring any\n     * additional arguments.\n     *\n     * @static\n     * @memberOf _\n     * @since 4.0.0\n     * @category Function\n     * @param {Function} func The function to cap arguments for.\n     * @returns {Function} Returns the new capped function.\n     * @example\n     *\n     * _.map(['6', '8', '10'], _.unary(parseInt));\n     * // => [6, 8, 10]\n     */\n    function unary(func) {\n      return ary(func, 1);\n    }\n\n    /**\n     * Creates a function that provides `value` to `wrapper` as its first\n     * argument. Any additional arguments provided to the function are appended\n     * to those provided to the `wrapper`. The wrapper is invoked with the `this`\n     * binding of the created function.\n     *\n     * @static\n     * @memberOf _\n     * @since 0.1.0\n     * @category Function\n     * @param {*} value The value to wrap.\n     * @param {Function} [wrapper=identity] The wrapper function.\n     * @returns {Function} Returns the new function.\n     * @example\n     *\n     * var p = _.wrap(_.escape, function(func, text) {\n     *   return '<p>' + func(text) + '</p>';\n     * });\n     *\n     * p('fred, barney, & pebbles');\n     * // => '<p>fred, barney, &amp; pebbles</p>'\n     */\n    function wrap(value, wrapper) {\n      return partial(castFunction(wrapper), value);\n    }\n\n    /*------------------------------------------------------------------------*/\n\n    /**\n     * Casts `value` as an array if it's not one.\n     *\n     * @static\n     * @memberOf _\n     * @since 4.4.0\n     * @category Lang\n     * @param {*} value The value to inspect.\n     * @returns {Array} Returns the cast array.\n     * @example\n     *\n     * _.castArray(1);\n     * // => [1]\n     *\n     * _.castArray({ 'a': 1 });\n     * // => [{ 'a': 1 }]\n     *\n     * _.castArray('abc');\n     * // => ['abc']\n     *\n     * _.castArray(null);\n     * // => [null]\n     *\n     * _.castArray(undefined);\n     * // => [undefined]\n     *\n     * _.castArray();\n     * // => []\n     *\n     * var array = [1, 2, 3];\n     * console.log(_.castArray(array) === array);\n     * // => true\n     */\n    function castArray() {\n      if (!arguments.length) {\n        return [];\n      }\n      var value = arguments[0];\n      return isArray(value) ? value : [value];\n    }\n\n    /**\n     * Creates a shallow clone of `value`.\n     *\n     * **Note:** This method is loosely based on the\n     * [structured clone algorithm](https://mdn.io/Structured_clone_algorithm)\n     * and supports cloning arrays, array buffers, booleans, date objects, maps,\n     * numbers, `Object` objects, regexes, sets, strings, symbols, and typed\n     * arrays. The own enumerable properties of `arguments` objects are cloned\n     * as plain objects. An empty object is returned for uncloneable values such\n     * as error objects, functions, DOM nodes, and WeakMaps.\n     *\n     * @static\n     * @memberOf _\n     * @since 0.1.0\n     * @category Lang\n     * @param {*} value The value to clone.\n     * @returns {*} Returns the cloned value.\n     * @see _.cloneDeep\n     * @example\n     *\n     * var objects = [{ 'a': 1 }, { 'b': 2 }];\n     *\n     * var shallow = _.clone(objects);\n     * console.log(shallow[0] === objects[0]);\n     * // => true\n     */\n    function clone(value) {\n      return baseClone(value, CLONE_SYMBOLS_FLAG);\n    }\n\n    /**\n     * This method is like `_.clone` except that it accepts `customizer` which\n     * is invoked to produce the cloned value. If `customizer` returns `undefined`,\n     * cloning is handled by the method instead. The `customizer` is invoked with\n     * up to four arguments; (value [, index|key, object, stack]).\n     *\n     * @static\n     * @memberOf _\n     * @since 4.0.0\n     * @category Lang\n     * @param {*} value The value to clone.\n     * @param {Function} [customizer] The function to customize cloning.\n     * @returns {*} Returns the cloned value.\n     * @see _.cloneDeepWith\n     * @example\n     *\n     * function customizer(value) {\n     *   if (_.isElement(value)) {\n     *     return value.cloneNode(false);\n     *   }\n     * }\n     *\n     * var el = _.cloneWith(document.body, customizer);\n     *\n     * console.log(el === document.body);\n     * // => false\n     * console.log(el.nodeName);\n     * // => 'BODY'\n     * console.log(el.childNodes.length);\n     * // => 0\n     */\n    function cloneWith(value, customizer) {\n      customizer = typeof customizer == 'function' ? customizer : undefined;\n      return baseClone(value, CLONE_SYMBOLS_FLAG, customizer);\n    }\n\n    /**\n     * This method is like `_.clone` except that it recursively clones `value`.\n     *\n     * @static\n     * @memberOf _\n     * @since 1.0.0\n     * @category Lang\n     * @param {*} value The value to recursively clone.\n     * @returns {*} Returns the deep cloned value.\n     * @see _.clone\n     * @example\n     *\n     * var objects = [{ 'a': 1 }, { 'b': 2 }];\n     *\n     * var deep = _.cloneDeep(objects);\n     * console.log(deep[0] === objects[0]);\n     * // => false\n     */\n    function cloneDeep(value) {\n      return baseClone(value, CLONE_DEEP_FLAG | CLONE_SYMBOLS_FLAG);\n    }\n\n    /**\n     * This method is like `_.cloneWith` except that it recursively clones `value`.\n     *\n     * @static\n     * @memberOf _\n     * @since 4.0.0\n     * @category Lang\n     * @param {*} value The value to recursively clone.\n     * @param {Function} [customizer] The function to customize cloning.\n     * @returns {*} Returns the deep cloned value.\n     * @see _.cloneWith\n     * @example\n     *\n     * function customizer(value) {\n     *   if (_.isElement(value)) {\n     *     return value.cloneNode(true);\n     *   }\n     * }\n     *\n     * var el = _.cloneDeepWith(document.body, customizer);\n     *\n     * console.log(el === document.body);\n     * // => false\n     * console.log(el.nodeName);\n     * // => 'BODY'\n     * console.log(el.childNodes.length);\n     * // => 20\n     */\n    function cloneDeepWith(value, customizer) {\n      customizer = typeof customizer == 'function' ? customizer : undefined;\n      return baseClone(value, CLONE_DEEP_FLAG | CLONE_SYMBOLS_FLAG, customizer);\n    }\n\n    /**\n     * Checks if `object` conforms to `source` by invoking the predicate\n     * properties of `source` with the corresponding property values of `object`.\n     *\n     * **Note:** This method is equivalent to `_.conforms` when `source` is\n     * partially applied.\n     *\n     * @static\n     * @memberOf _\n     * @since 4.14.0\n     * @category Lang\n     * @param {Object} object The object to inspect.\n     * @param {Object} source The object of property predicates to conform to.\n     * @returns {boolean} Returns `true` if `object` conforms, else `false`.\n     * @example\n     *\n     * var object = { 'a': 1, 'b': 2 };\n     *\n     * _.conformsTo(object, { 'b': function(n) { return n > 1; } });\n     * // => true\n     *\n     * _.conformsTo(object, { 'b': function(n) { return n > 2; } });\n     * // => false\n     */\n    function conformsTo(object, source) {\n      return source == null || baseConformsTo(object, source, keys(source));\n    }\n\n    /**\n     * Performs a\n     * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)\n     * comparison between two values to determine if they are equivalent.\n     *\n     * @static\n     * @memberOf _\n     * @since 4.0.0\n     * @category Lang\n     * @param {*} value The value to compare.\n     * @param {*} other The other value to compare.\n     * @returns {boolean} Returns `true` if the values are equivalent, else `false`.\n     * @example\n     *\n     * var object = { 'a': 1 };\n     * var other = { 'a': 1 };\n     *\n     * _.eq(object, object);\n     * // => true\n     *\n     * _.eq(object, other);\n     * // => false\n     *\n     * _.eq('a', 'a');\n     * // => true\n     *\n     * _.eq('a', Object('a'));\n     * // => false\n     *\n     * _.eq(NaN, NaN);\n     * // => true\n     */\n    function eq(value, other) {\n      return value === other || (value !== value && other !== other);\n    }\n\n    /**\n     * Checks if `value` is greater than `other`.\n     *\n     * @static\n     * @memberOf _\n     * @since 3.9.0\n     * @category Lang\n     * @param {*} value The value to compare.\n     * @param {*} other The other value to compare.\n     * @returns {boolean} Returns `true` if `value` is greater than `other`,\n     *  else `false`.\n     * @see _.lt\n     * @example\n     *\n     * _.gt(3, 1);\n     * // => true\n     *\n     * _.gt(3, 3);\n     * // => false\n     *\n     * _.gt(1, 3);\n     * // => false\n     */\n    var gt = createRelationalOperation(baseGt);\n\n    /**\n     * Checks if `value` is greater than or equal to `other`.\n     *\n     * @static\n     * @memberOf _\n     * @since 3.9.0\n     * @category Lang\n     * @param {*} value The value to compare.\n     * @param {*} other The other value to compare.\n     * @returns {boolean} Returns `true` if `value` is greater than or equal to\n     *  `other`, else `false`.\n     * @see _.lte\n     * @example\n     *\n     * _.gte(3, 1);\n     * // => true\n     *\n     * _.gte(3, 3);\n     * // => true\n     *\n     * _.gte(1, 3);\n     * // => false\n     */\n    var gte = createRelationalOperation(function(value, other) {\n      return value >= other;\n    });\n\n    /**\n     * Checks if `value` is likely an `arguments` object.\n     *\n     * @static\n     * @memberOf _\n     * @since 0.1.0\n     * @category Lang\n     * @param {*} value The value to check.\n     * @returns {boolean} Returns `true` if `value` is an `arguments` object,\n     *  else `false`.\n     * @example\n     *\n     * _.isArguments(function() { return arguments; }());\n     * // => true\n     *\n     * _.isArguments([1, 2, 3]);\n     * // => false\n     */\n    var isArguments = baseIsArguments(function() { return arguments; }()) ? baseIsArguments : function(value) {\n      return isObjectLike(value) && hasOwnProperty.call(value, 'callee') &&\n        !propertyIsEnumerable.call(value, 'callee');\n    };\n\n    /**\n     * Checks if `value` is classified as an `Array` object.\n     *\n     * @static\n     * @memberOf _\n     * @since 0.1.0\n     * @category Lang\n     * @param {*} value The value to check.\n     * @returns {boolean} Returns `true` if `value` is an array, else `false`.\n     * @example\n     *\n     * _.isArray([1, 2, 3]);\n     * // => true\n     *\n     * _.isArray(document.body.children);\n     * // => false\n     *\n     * _.isArray('abc');\n     * // => false\n     *\n     * _.isArray(_.noop);\n     * // => false\n     */\n    var isArray = Array.isArray;\n\n    /**\n     * Checks if `value` is classified as an `ArrayBuffer` object.\n     *\n     * @static\n     * @memberOf _\n     * @since 4.3.0\n     * @category Lang\n     * @param {*} value The value to check.\n     * @returns {boolean} Returns `true` if `value` is an array buffer, else `false`.\n     * @example\n     *\n     * _.isArrayBuffer(new ArrayBuffer(2));\n     * // => true\n     *\n     * _.isArrayBuffer(new Array(2));\n     * // => false\n     */\n    var isArrayBuffer = nodeIsArrayBuffer ? baseUnary(nodeIsArrayBuffer) : baseIsArrayBuffer;\n\n    /**\n     * Checks if `value` is array-like. A value is considered array-like if it's\n     * not a function and has a `value.length` that's an integer greater than or\n     * equal to `0` and less than or equal to `Number.MAX_SAFE_INTEGER`.\n     *\n     * @static\n     * @memberOf _\n     * @since 4.0.0\n     * @category Lang\n     * @param {*} value The value to check.\n     * @returns {boolean} Returns `true` if `value` is array-like, else `false`.\n     * @example\n     *\n     * _.isArrayLike([1, 2, 3]);\n     * // => true\n     *\n     * _.isArrayLike(document.body.children);\n     * // => true\n     *\n     * _.isArrayLike('abc');\n     * // => true\n     *\n     * _.isArrayLike(_.noop);\n     * // => false\n     */\n    function isArrayLike(value) {\n      return value != null && isLength(value.length) && !isFunction(value);\n    }\n\n    /**\n     * This method is like `_.isArrayLike` except that it also checks if `value`\n     * is an object.\n     *\n     * @static\n     * @memberOf _\n     * @since 4.0.0\n     * @category Lang\n     * @param {*} value The value to check.\n     * @returns {boolean} Returns `true` if `value` is an array-like object,\n     *  else `false`.\n     * @example\n     *\n     * _.isArrayLikeObject([1, 2, 3]);\n     * // => true\n     *\n     * _.isArrayLikeObject(document.body.children);\n     * // => true\n     *\n     * _.isArrayLikeObject('abc');\n     * // => false\n     *\n     * _.isArrayLikeObject(_.noop);\n     * // => false\n     */\n    function isArrayLikeObject(value) {\n      return isObjectLike(value) && isArrayLike(value);\n    }\n\n    /**\n     * Checks if `value` is classified as a boolean primitive or object.\n     *\n     * @static\n     * @memberOf _\n     * @since 0.1.0\n     * @category Lang\n     * @param {*} value The value to check.\n     * @returns {boolean} Returns `true` if `value` is a boolean, else `false`.\n     * @example\n     *\n     * _.isBoolean(false);\n     * // => true\n     *\n     * _.isBoolean(null);\n     * // => false\n     */\n    function isBoolean(value) {\n      return value === true || value === false ||\n        (isObjectLike(value) && baseGetTag(value) == boolTag);\n    }\n\n    /**\n     * Checks if `value` is a buffer.\n     *\n     * @static\n     * @memberOf _\n     * @since 4.3.0\n     * @category Lang\n     * @param {*} value The value to check.\n     * @returns {boolean} Returns `true` if `value` is a buffer, else `false`.\n     * @example\n     *\n     * _.isBuffer(new Buffer(2));\n     * // => true\n     *\n     * _.isBuffer(new Uint8Array(2));\n     * // => false\n     */\n    var isBuffer = nativeIsBuffer || stubFalse;\n\n    /**\n     * Checks if `value` is classified as a `Date` object.\n     *\n     * @static\n     * @memberOf _\n     * @since 0.1.0\n     * @category Lang\n     * @param {*} value The value to check.\n     * @returns {boolean} Returns `true` if `value` is a date object, else `false`.\n     * @example\n     *\n     * _.isDate(new Date);\n     * // => true\n     *\n     * _.isDate('Mon April 23 2012');\n     * // => false\n     */\n    var isDate = nodeIsDate ? baseUnary(nodeIsDate) : baseIsDate;\n\n    /**\n     * Checks if `value` is likely a DOM element.\n     *\n     * @static\n     * @memberOf _\n     * @since 0.1.0\n     * @category Lang\n     * @param {*} value The value to check.\n     * @returns {boolean} Returns `true` if `value` is a DOM element, else `false`.\n     * @example\n     *\n     * _.isElement(document.body);\n     * // => true\n     *\n     * _.isElement('<body>');\n     * // => false\n     */\n    function isElement(value) {\n      return isObjectLike(value) && value.nodeType === 1 && !isPlainObject(value);\n    }\n\n    /**\n     * Checks if `value` is an empty object, collection, map, or set.\n     *\n     * Objects are considered empty if they have no own enumerable string keyed\n     * properties.\n     *\n     * Array-like values such as `arguments` objects, arrays, buffers, strings, or\n     * jQuery-like collections are considered empty if they have a `length` of `0`.\n     * Similarly, maps and sets are considered empty if they have a `size` of `0`.\n     *\n     * @static\n     * @memberOf _\n     * @since 0.1.0\n     * @category Lang\n     * @param {*} value The value to check.\n     * @returns {boolean} Returns `true` if `value` is empty, else `false`.\n     * @example\n     *\n     * _.isEmpty(null);\n     * // => true\n     *\n     * _.isEmpty(true);\n     * // => true\n     *\n     * _.isEmpty(1);\n     * // => true\n     *\n     * _.isEmpty([1, 2, 3]);\n     * // => false\n     *\n     * _.isEmpty({ 'a': 1 });\n     * // => false\n     */\n    function isEmpty(value) {\n      if (value == null) {\n        return true;\n      }\n      if (isArrayLike(value) &&\n          (isArray(value) || typeof value == 'string' || typeof value.splice == 'function' ||\n            isBuffer(value) || isTypedArray(value) || isArguments(value))) {\n        return !value.length;\n      }\n      var tag = getTag(value);\n      if (tag == mapTag || tag == setTag) {\n        return !value.size;\n      }\n      if (isPrototype(value)) {\n        return !baseKeys(value).length;\n      }\n      for (var key in value) {\n        if (hasOwnProperty.call(value, key)) {\n          return false;\n        }\n      }\n      return true;\n    }\n\n    /**\n     * Performs a deep comparison between two values to determine if they are\n     * equivalent.\n     *\n     * **Note:** This method supports comparing arrays, array buffers, booleans,\n     * date objects, error objects, maps, numbers, `Object` objects, regexes,\n     * sets, strings, symbols, and typed arrays. `Object` objects are compared\n     * by their own, not inherited, enumerable properties. Functions and DOM\n     * nodes are compared by strict equality, i.e. `===`.\n     *\n     * @static\n     * @memberOf _\n     * @since 0.1.0\n     * @category Lang\n     * @param {*} value The value to compare.\n     * @param {*} other The other value to compare.\n     * @returns {boolean} Returns `true` if the values are equivalent, else `false`.\n     * @example\n     *\n     * var object = { 'a': 1 };\n     * var other = { 'a': 1 };\n     *\n     * _.isEqual(object, other);\n     * // => true\n     *\n     * object === other;\n     * // => false\n     */\n    function isEqual(value, other) {\n      return baseIsEqual(value, other);\n    }\n\n    /**\n     * This method is like `_.isEqual` except that it accepts `customizer` which\n     * is invoked to compare values. If `customizer` returns `undefined`, comparisons\n     * are handled by the method instead. The `customizer` is invoked with up to\n     * six arguments: (objValue, othValue [, index|key, object, other, stack]).\n     *\n     * @static\n     * @memberOf _\n     * @since 4.0.0\n     * @category Lang\n     * @param {*} value The value to compare.\n     * @param {*} other The other value to compare.\n     * @param {Function} [customizer] The function to customize comparisons.\n     * @returns {boolean} Returns `true` if the values are equivalent, else `false`.\n     * @example\n     *\n     * function isGreeting(value) {\n     *   return /^h(?:i|ello)$/.test(value);\n     * }\n     *\n     * function customizer(objValue, othValue) {\n     *   if (isGreeting(objValue) && isGreeting(othValue)) {\n     *     return true;\n     *   }\n     * }\n     *\n     * var array = ['hello', 'goodbye'];\n     * var other = ['hi', 'goodbye'];\n     *\n     * _.isEqualWith(array, other, customizer);\n     * // => true\n     */\n    function isEqualWith(value, other, customizer) {\n      customizer = typeof customizer == 'function' ? customizer : undefined;\n      var result = customizer ? customizer(value, other) : undefined;\n      return result === undefined ? baseIsEqual(value, other, undefined, customizer) : !!result;\n    }\n\n    /**\n     * Checks if `value` is an `Error`, `EvalError`, `RangeError`, `ReferenceError`,\n     * `SyntaxError`, `TypeError`, or `URIError` object.\n     *\n     * @static\n     * @memberOf _\n     * @since 3.0.0\n     * @category Lang\n     * @param {*} value The value to check.\n     * @returns {boolean} Returns `true` if `value` is an error object, else `false`.\n     * @example\n     *\n     * _.isError(new Error);\n     * // => true\n     *\n     * _.isError(Error);\n     * // => false\n     */\n    function isError(value) {\n      if (!isObjectLike(value)) {\n        return false;\n      }\n      var tag = baseGetTag(value);\n      return tag == errorTag || tag == domExcTag ||\n        (typeof value.message == 'string' && typeof value.name == 'string' && !isPlainObject(value));\n    }\n\n    /**\n     * Checks if `value` is a finite primitive number.\n     *\n     * **Note:** This method is based on\n     * [`Number.isFinite`](https://mdn.io/Number/isFinite).\n     *\n     * @static\n     * @memberOf _\n     * @since 0.1.0\n     * @category Lang\n     * @param {*} value The value to check.\n     * @returns {boolean} Returns `true` if `value` is a finite number, else `false`.\n     * @example\n     *\n     * _.isFinite(3);\n     * // => true\n     *\n     * _.isFinite(Number.MIN_VALUE);\n     * // => true\n     *\n     * _.isFinite(Infinity);\n     * // => false\n     *\n     * _.isFinite('3');\n     * // => false\n     */\n    function isFinite(value) {\n      return typeof value == 'number' && nativeIsFinite(value);\n    }\n\n    /**\n     * Checks if `value` is classified as a `Function` object.\n     *\n     * @static\n     * @memberOf _\n     * @since 0.1.0\n     * @category Lang\n     * @param {*} value The value to check.\n     * @returns {boolean} Returns `true` if `value` is a function, else `false`.\n     * @example\n     *\n     * _.isFunction(_);\n     * // => true\n     *\n     * _.isFunction(/abc/);\n     * // => false\n     */\n    function isFunction(value) {\n      if (!isObject(value)) {\n        return false;\n      }\n      // The use of `Object#toString` avoids issues with the `typeof` operator\n      // in Safari 9 which returns 'object' for typed arrays and other constructors.\n      var tag = baseGetTag(value);\n      return tag == funcTag || tag == genTag || tag == asyncTag || tag == proxyTag;\n    }\n\n    /**\n     * Checks if `value` is an integer.\n     *\n     * **Note:** This method is based on\n     * [`Number.isInteger`](https://mdn.io/Number/isInteger).\n     *\n     * @static\n     * @memberOf _\n     * @since 4.0.0\n     * @category Lang\n     * @param {*} value The value to check.\n     * @returns {boolean} Returns `true` if `value` is an integer, else `false`.\n     * @example\n     *\n     * _.isInteger(3);\n     * // => true\n     *\n     * _.isInteger(Number.MIN_VALUE);\n     * // => false\n     *\n     * _.isInteger(Infinity);\n     * // => false\n     *\n     * _.isInteger('3');\n     * // => false\n     */\n    function isInteger(value) {\n      return typeof value == 'number' && value == toInteger(value);\n    }\n\n    /**\n     * Checks if `value` is a valid array-like length.\n     *\n     * **Note:** This method is loosely based on\n     * [`ToLength`](http://ecma-international.org/ecma-262/7.0/#sec-tolength).\n     *\n     * @static\n     * @memberOf _\n     * @since 4.0.0\n     * @category Lang\n     * @param {*} value The value to check.\n     * @returns {boolean} Returns `true` if `value` is a valid length, else `false`.\n     * @example\n     *\n     * _.isLength(3);\n     * // => true\n     *\n     * _.isLength(Number.MIN_VALUE);\n     * // => false\n     *\n     * _.isLength(Infinity);\n     * // => false\n     *\n     * _.isLength('3');\n     * // => false\n     */\n    function isLength(value) {\n      return typeof value == 'number' &&\n        value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER;\n    }\n\n    /**\n     * Checks if `value` is the\n     * [language type](http://www.ecma-international.org/ecma-262/7.0/#sec-ecmascript-language-types)\n     * of `Object`. (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`)\n     *\n     * @static\n     * @memberOf _\n     * @since 0.1.0\n     * @category Lang\n     * @param {*} value The value to check.\n     * @returns {boolean} Returns `true` if `value` is an object, else `false`.\n     * @example\n     *\n     * _.isObject({});\n     * // => true\n     *\n     * _.isObject([1, 2, 3]);\n     * // => true\n     *\n     * _.isObject(_.noop);\n     * // => true\n     *\n     * _.isObject(null);\n     * // => false\n     */\n    function isObject(value) {\n      var type = typeof value;\n      return value != null && (type == 'object' || type == 'function');\n    }\n\n    /**\n     * Checks if `value` is object-like. A value is object-like if it's not `null`\n     * and has a `typeof` result of \"object\".\n     *\n     * @static\n     * @memberOf _\n     * @since 4.0.0\n     * @category Lang\n     * @param {*} value The value to check.\n     * @returns {boolean} Returns `true` if `value` is object-like, else `false`.\n     * @example\n     *\n     * _.isObjectLike({});\n     * // => true\n     *\n     * _.isObjectLike([1, 2, 3]);\n     * // => true\n     *\n     * _.isObjectLike(_.noop);\n     * // => false\n     *\n     * _.isObjectLike(null);\n     * // => false\n     */\n    function isObjectLike(value) {\n      return value != null && typeof value == 'object';\n    }\n\n    /**\n     * Checks if `value` is classified as a `Map` object.\n     *\n     * @static\n     * @memberOf _\n     * @since 4.3.0\n     * @category Lang\n     * @param {*} value The value to check.\n     * @returns {boolean} Returns `true` if `value` is a map, else `false`.\n     * @example\n     *\n     * _.isMap(new Map);\n     * // => true\n     *\n     * _.isMap(new WeakMap);\n     * // => false\n     */\n    var isMap = nodeIsMap ? baseUnary(nodeIsMap) : baseIsMap;\n\n    /**\n     * Performs a partial deep comparison between `object` and `source` to\n     * determine if `object` contains equivalent property values.\n     *\n     * **Note:** This method is equivalent to `_.matches` when `source` is\n     * partially applied.\n     *\n     * Partial comparisons will match empty array and empty object `source`\n     * values against any array or object value, respectively. See `_.isEqual`\n     * for a list of supported value comparisons.\n     *\n     * @static\n     * @memberOf _\n     * @since 3.0.0\n     * @category Lang\n     * @param {Object} object The object to inspect.\n     * @param {Object} source The object of property values to match.\n     * @returns {boolean} Returns `true` if `object` is a match, else `false`.\n     * @example\n     *\n     * var object = { 'a': 1, 'b': 2 };\n     *\n     * _.isMatch(object, { 'b': 2 });\n     * // => true\n     *\n     * _.isMatch(object, { 'b': 1 });\n     * // => false\n     */\n    function isMatch(object, source) {\n      return object === source || baseIsMatch(object, source, getMatchData(source));\n    }\n\n    /**\n     * This method is like `_.isMatch` except that it accepts `customizer` which\n     * is invoked to compare values. If `customizer` returns `undefined`, comparisons\n     * are handled by the method instead. The `customizer` is invoked with five\n     * arguments: (objValue, srcValue, index|key, object, source).\n     *\n     * @static\n     * @memberOf _\n     * @since 4.0.0\n     * @category Lang\n     * @param {Object} object The object to inspect.\n     * @param {Object} source The object of property values to match.\n     * @param {Function} [customizer] The function to customize comparisons.\n     * @returns {boolean} Returns `true` if `object` is a match, else `false`.\n     * @example\n     *\n     * function isGreeting(value) {\n     *   return /^h(?:i|ello)$/.test(value);\n     * }\n     *\n     * function customizer(objValue, srcValue) {\n     *   if (isGreeting(objValue) && isGreeting(srcValue)) {\n     *     return true;\n     *   }\n     * }\n     *\n     * var object = { 'greeting': 'hello' };\n     * var source = { 'greeting': 'hi' };\n     *\n     * _.isMatchWith(object, source, customizer);\n     * // => true\n     */\n    function isMatchWith(object, source, customizer) {\n      customizer = typeof customizer == 'function' ? customizer : undefined;\n      return baseIsMatch(object, source, getMatchData(source), customizer);\n    }\n\n    /**\n     * Checks if `value` is `NaN`.\n     *\n     * **Note:** This method is based on\n     * [`Number.isNaN`](https://mdn.io/Number/isNaN) and is not the same as\n     * global [`isNaN`](https://mdn.io/isNaN) which returns `true` for\n     * `undefined` and other non-number values.\n     *\n     * @static\n     * @memberOf _\n     * @since 0.1.0\n     * @category Lang\n     * @param {*} value The value to check.\n     * @returns {boolean} Returns `true` if `value` is `NaN`, else `false`.\n     * @example\n     *\n     * _.isNaN(NaN);\n     * // => true\n     *\n     * _.isNaN(new Number(NaN));\n     * // => true\n     *\n     * isNaN(undefined);\n     * // => true\n     *\n     * _.isNaN(undefined);\n     * // => false\n     */\n    function isNaN(value) {\n      // An `NaN` primitive is the only value that is not equal to itself.\n      // Perform the `toStringTag` check first to avoid errors with some\n      // ActiveX objects in IE.\n      return isNumber(value) && value != +value;\n    }\n\n    /**\n     * Checks if `value` is a pristine native function.\n     *\n     * **Note:** This method can't reliably detect native functions in the presence\n     * of the core-js package because core-js circumvents this kind of detection.\n     * Despite multiple requests, the core-js maintainer has made it clear: any\n     * attempt to fix the detection will be obstructed. As a result, we're left\n     * with little choice but to throw an error. Unfortunately, this also affects\n     * packages, like [babel-polyfill](https://www.npmjs.com/package/babel-polyfill),\n     * which rely on core-js.\n     *\n     * @static\n     * @memberOf _\n     * @since 3.0.0\n     * @category Lang\n     * @param {*} value The value to check.\n     * @returns {boolean} Returns `true` if `value` is a native function,\n     *  else `false`.\n     * @example\n     *\n     * _.isNative(Array.prototype.push);\n     * // => true\n     *\n     * _.isNative(_);\n     * // => false\n     */\n    function isNative(value) {\n      if (isMaskable(value)) {\n        throw new Error(CORE_ERROR_TEXT);\n      }\n      return baseIsNative(value);\n    }\n\n    /**\n     * Checks if `value` is `null`.\n     *\n     * @static\n     * @memberOf _\n     * @since 0.1.0\n     * @category Lang\n     * @param {*} value The value to check.\n     * @returns {boolean} Returns `true` if `value` is `null`, else `false`.\n     * @example\n     *\n     * _.isNull(null);\n     * // => true\n     *\n     * _.isNull(void 0);\n     * // => false\n     */\n    function isNull(value) {\n      return value === null;\n    }\n\n    /**\n     * Checks if `value` is `null` or `undefined`.\n     *\n     * @static\n     * @memberOf _\n     * @since 4.0.0\n     * @category Lang\n     * @param {*} value The value to check.\n     * @returns {boolean} Returns `true` if `value` is nullish, else `false`.\n     * @example\n     *\n     * _.isNil(null);\n     * // => true\n     *\n     * _.isNil(void 0);\n     * // => true\n     *\n     * _.isNil(NaN);\n     * // => false\n     */\n    function isNil(value) {\n      return value == null;\n    }\n\n    /**\n     * Checks if `value` is classified as a `Number` primitive or object.\n     *\n     * **Note:** To exclude `Infinity`, `-Infinity`, and `NaN`, which are\n     * classified as numbers, use the `_.isFinite` method.\n     *\n     * @static\n     * @memberOf _\n     * @since 0.1.0\n     * @category Lang\n     * @param {*} value The value to check.\n     * @returns {boolean} Returns `true` if `value` is a number, else `false`.\n     * @example\n     *\n     * _.isNumber(3);\n     * // => true\n     *\n     * _.isNumber(Number.MIN_VALUE);\n     * // => true\n     *\n     * _.isNumber(Infinity);\n     * // => true\n     *\n     * _.isNumber('3');\n     * // => false\n     */\n    function isNumber(value) {\n      return typeof value == 'number' ||\n        (isObjectLike(value) && baseGetTag(value) == numberTag);\n    }\n\n    /**\n     * Checks if `value` is a plain object, that is, an object created by the\n     * `Object` constructor or one with a `[[Prototype]]` of `null`.\n     *\n     * @static\n     * @memberOf _\n     * @since 0.8.0\n     * @category Lang\n     * @param {*} value The value to check.\n     * @returns {boolean} Returns `true` if `value` is a plain object, else `false`.\n     * @example\n     *\n     * function Foo() {\n     *   this.a = 1;\n     * }\n     *\n     * _.isPlainObject(new Foo);\n     * // => false\n     *\n     * _.isPlainObject([1, 2, 3]);\n     * // => false\n     *\n     * _.isPlainObject({ 'x': 0, 'y': 0 });\n     * // => true\n     *\n     * _.isPlainObject(Object.create(null));\n     * // => true\n     */\n    function isPlainObject(value) {\n      if (!isObjectLike(value) || baseGetTag(value) != objectTag) {\n        return false;\n      }\n      var proto = getPrototype(value);\n      if (proto === null) {\n        return true;\n      }\n      var Ctor = hasOwnProperty.call(proto, 'constructor') && proto.constructor;\n      return typeof Ctor == 'function' && Ctor instanceof Ctor &&\n        funcToString.call(Ctor) == objectCtorString;\n    }\n\n    /**\n     * Checks if `value` is classified as a `RegExp` object.\n     *\n     * @static\n     * @memberOf _\n     * @since 0.1.0\n     * @category Lang\n     * @param {*} value The value to check.\n     * @returns {boolean} Returns `true` if `value` is a regexp, else `false`.\n     * @example\n     *\n     * _.isRegExp(/abc/);\n     * // => true\n     *\n     * _.isRegExp('/abc/');\n     * // => false\n     */\n    var isRegExp = nodeIsRegExp ? baseUnary(nodeIsRegExp) : baseIsRegExp;\n\n    /**\n     * Checks if `value` is a safe integer. An integer is safe if it's an IEEE-754\n     * double precision number which isn't the result of a rounded unsafe integer.\n     *\n     * **Note:** This method is based on\n     * [`Number.isSafeInteger`](https://mdn.io/Number/isSafeInteger).\n     *\n     * @static\n     * @memberOf _\n     * @since 4.0.0\n     * @category Lang\n     * @param {*} value The value to check.\n     * @returns {boolean} Returns `true` if `value` is a safe integer, else `false`.\n     * @example\n     *\n     * _.isSafeInteger(3);\n     * // => true\n     *\n     * _.isSafeInteger(Number.MIN_VALUE);\n     * // => false\n     *\n     * _.isSafeInteger(Infinity);\n     * // => false\n     *\n     * _.isSafeInteger('3');\n     * // => false\n     */\n    function isSafeInteger(value) {\n      return isInteger(value) && value >= -MAX_SAFE_INTEGER && value <= MAX_SAFE_INTEGER;\n    }\n\n    /**\n     * Checks if `value` is classified as a `Set` object.\n     *\n     * @static\n     * @memberOf _\n     * @since 4.3.0\n     * @category Lang\n     * @param {*} value The value to check.\n     * @returns {boolean} Returns `true` if `value` is a set, else `false`.\n     * @example\n     *\n     * _.isSet(new Set);\n     * // => true\n     *\n     * _.isSet(new WeakSet);\n     * // => false\n     */\n    var isSet = nodeIsSet ? baseUnary(nodeIsSet) : baseIsSet;\n\n    /**\n     * Checks if `value` is classified as a `String` primitive or object.\n     *\n     * @static\n     * @since 0.1.0\n     * @memberOf _\n     * @category Lang\n     * @param {*} value The value to check.\n     * @returns {boolean} Returns `true` if `value` is a string, else `false`.\n     * @example\n     *\n     * _.isString('abc');\n     * // => true\n     *\n     * _.isString(1);\n     * // => false\n     */\n    function isString(value) {\n      return typeof value == 'string' ||\n        (!isArray(value) && isObjectLike(value) && baseGetTag(value) == stringTag);\n    }\n\n    /**\n     * Checks if `value` is classified as a `Symbol` primitive or object.\n     *\n     * @static\n     * @memberOf _\n     * @since 4.0.0\n     * @category Lang\n     * @param {*} value The value to check.\n     * @returns {boolean} Returns `true` if `value` is a symbol, else `false`.\n     * @example\n     *\n     * _.isSymbol(Symbol.iterator);\n     * // => true\n     *\n     * _.isSymbol('abc');\n     * // => false\n     */\n    function isSymbol(value) {\n      return typeof value == 'symbol' ||\n        (isObjectLike(value) && baseGetTag(value) == symbolTag);\n    }\n\n    /**\n     * Checks if `value` is classified as a typed array.\n     *\n     * @static\n     * @memberOf _\n     * @since 3.0.0\n     * @category Lang\n     * @param {*} value The value to check.\n     * @returns {boolean} Returns `true` if `value` is a typed array, else `false`.\n     * @example\n     *\n     * _.isTypedArray(new Uint8Array);\n     * // => true\n     *\n     * _.isTypedArray([]);\n     * // => false\n     */\n    var isTypedArray = nodeIsTypedArray ? baseUnary(nodeIsTypedArray) : baseIsTypedArray;\n\n    /**\n     * Checks if `value` is `undefined`.\n     *\n     * @static\n     * @since 0.1.0\n     * @memberOf _\n     * @category Lang\n     * @param {*} value The value to check.\n     * @returns {boolean} Returns `true` if `value` is `undefined`, else `false`.\n     * @example\n     *\n     * _.isUndefined(void 0);\n     * // => true\n     *\n     * _.isUndefined(null);\n     * // => false\n     */\n    function isUndefined(value) {\n      return value === undefined;\n    }\n\n    /**\n     * Checks if `value` is classified as a `WeakMap` object.\n     *\n     * @static\n     * @memberOf _\n     * @since 4.3.0\n     * @category Lang\n     * @param {*} value The value to check.\n     * @returns {boolean} Returns `true` if `value` is a weak map, else `false`.\n     * @example\n     *\n     * _.isWeakMap(new WeakMap);\n     * // => true\n     *\n     * _.isWeakMap(new Map);\n     * // => false\n     */\n    function isWeakMap(value) {\n      return isObjectLike(value) && getTag(value) == weakMapTag;\n    }\n\n    /**\n     * Checks if `value` is classified as a `WeakSet` object.\n     *\n     * @static\n     * @memberOf _\n     * @since 4.3.0\n     * @category Lang\n     * @param {*} value The value to check.\n     * @returns {boolean} Returns `true` if `value` is a weak set, else `false`.\n     * @example\n     *\n     * _.isWeakSet(new WeakSet);\n     * // => true\n     *\n     * _.isWeakSet(new Set);\n     * // => false\n     */\n    function isWeakSet(value) {\n      return isObjectLike(value) && baseGetTag(value) == weakSetTag;\n    }\n\n    /**\n     * Checks if `value` is less than `other`.\n     *\n     * @static\n     * @memberOf _\n     * @since 3.9.0\n     * @category Lang\n     * @param {*} value The value to compare.\n     * @param {*} other The other value to compare.\n     * @returns {boolean} Returns `true` if `value` is less than `other`,\n     *  else `false`.\n     * @see _.gt\n     * @example\n     *\n     * _.lt(1, 3);\n     * // => true\n     *\n     * _.lt(3, 3);\n     * // => false\n     *\n     * _.lt(3, 1);\n     * // => false\n     */\n    var lt = createRelationalOperation(baseLt);\n\n    /**\n     * Checks if `value` is less than or equal to `other`.\n     *\n     * @static\n     * @memberOf _\n     * @since 3.9.0\n     * @category Lang\n     * @param {*} value The value to compare.\n     * @param {*} other The other value to compare.\n     * @returns {boolean} Returns `true` if `value` is less than or equal to\n     *  `other`, else `false`.\n     * @see _.gte\n     * @example\n     *\n     * _.lte(1, 3);\n     * // => true\n     *\n     * _.lte(3, 3);\n     * // => true\n     *\n     * _.lte(3, 1);\n     * // => false\n     */\n    var lte = createRelationalOperation(function(value, other) {\n      return value <= other;\n    });\n\n    /**\n     * Converts `value` to an array.\n     *\n     * @static\n     * @since 0.1.0\n     * @memberOf _\n     * @category Lang\n     * @param {*} value The value to convert.\n     * @returns {Array} Returns the converted array.\n     * @example\n     *\n     * _.toArray({ 'a': 1, 'b': 2 });\n     * // => [1, 2]\n     *\n     * _.toArray('abc');\n     * // => ['a', 'b', 'c']\n     *\n     * _.toArray(1);\n     * // => []\n     *\n     * _.toArray(null);\n     * // => []\n     */\n    function toArray(value) {\n      if (!value) {\n        return [];\n      }\n      if (isArrayLike(value)) {\n        return isString(value) ? stringToArray(value) : copyArray(value);\n      }\n      if (symIterator && value[symIterator]) {\n        return iteratorToArray(value[symIterator]());\n      }\n      var tag = getTag(value),\n          func = tag == mapTag ? mapToArray : (tag == setTag ? setToArray : values);\n\n      return func(value);\n    }\n\n    /**\n     * Converts `value` to a finite number.\n     *\n     * @static\n     * @memberOf _\n     * @since 4.12.0\n     * @category Lang\n     * @param {*} value The value to convert.\n     * @returns {number} Returns the converted number.\n     * @example\n     *\n     * _.toFinite(3.2);\n     * // => 3.2\n     *\n     * _.toFinite(Number.MIN_VALUE);\n     * // => 5e-324\n     *\n     * _.toFinite(Infinity);\n     * // => 1.7976931348623157e+308\n     *\n     * _.toFinite('3.2');\n     * // => 3.2\n     */\n    function toFinite(value) {\n      if (!value) {\n        return value === 0 ? value : 0;\n      }\n      value = toNumber(value);\n      if (value === INFINITY || value === -INFINITY) {\n        var sign = (value < 0 ? -1 : 1);\n        return sign * MAX_INTEGER;\n      }\n      return value === value ? value : 0;\n    }\n\n    /**\n     * Converts `value` to an integer.\n     *\n     * **Note:** This method is loosely based on\n     * [`ToInteger`](http://www.ecma-international.org/ecma-262/7.0/#sec-tointeger).\n     *\n     * @static\n     * @memberOf _\n     * @since 4.0.0\n     * @category Lang\n     * @param {*} value The value to convert.\n     * @returns {number} Returns the converted integer.\n     * @example\n     *\n     * _.toInteger(3.2);\n     * // => 3\n     *\n     * _.toInteger(Number.MIN_VALUE);\n     * // => 0\n     *\n     * _.toInteger(Infinity);\n     * // => 1.7976931348623157e+308\n     *\n     * _.toInteger('3.2');\n     * // => 3\n     */\n    function toInteger(value) {\n      var result = toFinite(value),\n          remainder = result % 1;\n\n      return result === result ? (remainder ? result - remainder : result) : 0;\n    }\n\n    /**\n     * Converts `value` to an integer suitable for use as the length of an\n     * array-like object.\n     *\n     * **Note:** This method is based on\n     * [`ToLength`](http://ecma-international.org/ecma-262/7.0/#sec-tolength).\n     *\n     * @static\n     * @memberOf _\n     * @since 4.0.0\n     * @category Lang\n     * @param {*} value The value to convert.\n     * @returns {number} Returns the converted integer.\n     * @example\n     *\n     * _.toLength(3.2);\n     * // => 3\n     *\n     * _.toLength(Number.MIN_VALUE);\n     * // => 0\n     *\n     * _.toLength(Infinity);\n     * // => 4294967295\n     *\n     * _.toLength('3.2');\n     * // => 3\n     */\n    function toLength(value) {\n      return value ? baseClamp(toInteger(value), 0, MAX_ARRAY_LENGTH) : 0;\n    }\n\n    /**\n     * Converts `value` to a number.\n     *\n     * @static\n     * @memberOf _\n     * @since 4.0.0\n     * @category Lang\n     * @param {*} value The value to process.\n     * @returns {number} Returns the number.\n     * @example\n     *\n     * _.toNumber(3.2);\n     * // => 3.2\n     *\n     * _.toNumber(Number.MIN_VALUE);\n     * // => 5e-324\n     *\n     * _.toNumber(Infinity);\n     * // => Infinity\n     *\n     * _.toNumber('3.2');\n     * // => 3.2\n     */\n    function toNumber(value) {\n      if (typeof value == 'number') {\n        return value;\n      }\n      if (isSymbol(value)) {\n        return NAN;\n      }\n      if (isObject(value)) {\n        var other = typeof value.valueOf == 'function' ? value.valueOf() : value;\n        value = isObject(other) ? (other + '') : other;\n      }\n      if (typeof value != 'string') {\n        return value === 0 ? value : +value;\n      }\n      value = value.replace(reTrim, '');\n      var isBinary = reIsBinary.test(value);\n      return (isBinary || reIsOctal.test(value))\n        ? freeParseInt(value.slice(2), isBinary ? 2 : 8)\n        : (reIsBadHex.test(value) ? NAN : +value);\n    }\n\n    /**\n     * Converts `value` to a plain object flattening inherited enumerable string\n     * keyed properties of `value` to own properties of the plain object.\n     *\n     * @static\n     * @memberOf _\n     * @since 3.0.0\n     * @category Lang\n     * @param {*} value The value to convert.\n     * @returns {Object} Returns the converted plain object.\n     * @example\n     *\n     * function Foo() {\n     *   this.b = 2;\n     * }\n     *\n     * Foo.prototype.c = 3;\n     *\n     * _.assign({ 'a': 1 }, new Foo);\n     * // => { 'a': 1, 'b': 2 }\n     *\n     * _.assign({ 'a': 1 }, _.toPlainObject(new Foo));\n     * // => { 'a': 1, 'b': 2, 'c': 3 }\n     */\n    function toPlainObject(value) {\n      return copyObject(value, keysIn(value));\n    }\n\n    /**\n     * Converts `value` to a safe integer. A safe integer can be compared and\n     * represented correctly.\n     *\n     * @static\n     * @memberOf _\n     * @since 4.0.0\n     * @category Lang\n     * @param {*} value The value to convert.\n     * @returns {number} Returns the converted integer.\n     * @example\n     *\n     * _.toSafeInteger(3.2);\n     * // => 3\n     *\n     * _.toSafeInteger(Number.MIN_VALUE);\n     * // => 0\n     *\n     * _.toSafeInteger(Infinity);\n     * // => 9007199254740991\n     *\n     * _.toSafeInteger('3.2');\n     * // => 3\n     */\n    function toSafeInteger(value) {\n      return value\n        ? baseClamp(toInteger(value), -MAX_SAFE_INTEGER, MAX_SAFE_INTEGER)\n        : (value === 0 ? value : 0);\n    }\n\n    /**\n     * Converts `value` to a string. An empty string is returned for `null`\n     * and `undefined` values. The sign of `-0` is preserved.\n     *\n     * @static\n     * @memberOf _\n     * @since 4.0.0\n     * @category Lang\n     * @param {*} value The value to convert.\n     * @returns {string} Returns the converted string.\n     * @example\n     *\n     * _.toString(null);\n     * // => ''\n     *\n     * _.toString(-0);\n     * // => '-0'\n     *\n     * _.toString([1, 2, 3]);\n     * // => '1,2,3'\n     */\n    function toString(value) {\n      return value == null ? '' : baseToString(value);\n    }\n\n    /*------------------------------------------------------------------------*/\n\n    /**\n     * Assigns own enumerable string keyed properties of source objects to the\n     * destination object. Source objects are applied from left to right.\n     * Subsequent sources overwrite property assignments of previous sources.\n     *\n     * **Note:** This method mutates `object` and is loosely based on\n     * [`Object.assign`](https://mdn.io/Object/assign).\n     *\n     * @static\n     * @memberOf _\n     * @since 0.10.0\n     * @category Object\n     * @param {Object} object The destination object.\n     * @param {...Object} [sources] The source objects.\n     * @returns {Object} Returns `object`.\n     * @see _.assignIn\n     * @example\n     *\n     * function Foo() {\n     *   this.a = 1;\n     * }\n     *\n     * function Bar() {\n     *   this.c = 3;\n     * }\n     *\n     * Foo.prototype.b = 2;\n     * Bar.prototype.d = 4;\n     *\n     * _.assign({ 'a': 0 }, new Foo, new Bar);\n     * // => { 'a': 1, 'c': 3 }\n     */\n    var assign = createAssigner(function(object, source) {\n      if (isPrototype(source) || isArrayLike(source)) {\n        copyObject(source, keys(source), object);\n        return;\n      }\n      for (var key in source) {\n        if (hasOwnProperty.call(source, key)) {\n          assignValue(object, key, source[key]);\n        }\n      }\n    });\n\n    /**\n     * This method is like `_.assign` except that it iterates over own and\n     * inherited source properties.\n     *\n     * **Note:** This method mutates `object`.\n     *\n     * @static\n     * @memberOf _\n     * @since 4.0.0\n     * @alias extend\n     * @category Object\n     * @param {Object} object The destination object.\n     * @param {...Object} [sources] The source objects.\n     * @returns {Object} Returns `object`.\n     * @see _.assign\n     * @example\n     *\n     * function Foo() {\n     *   this.a = 1;\n     * }\n     *\n     * function Bar() {\n     *   this.c = 3;\n     * }\n     *\n     * Foo.prototype.b = 2;\n     * Bar.prototype.d = 4;\n     *\n     * _.assignIn({ 'a': 0 }, new Foo, new Bar);\n     * // => { 'a': 1, 'b': 2, 'c': 3, 'd': 4 }\n     */\n    var assignIn = createAssigner(function(object, source) {\n      copyObject(source, keysIn(source), object);\n    });\n\n    /**\n     * This method is like `_.assignIn` except that it accepts `customizer`\n     * which is invoked to produce the assigned values. If `customizer` returns\n     * `undefined`, assignment is handled by the method instead. The `customizer`\n     * is invoked with five arguments: (objValue, srcValue, key, object, source).\n     *\n     * **Note:** This method mutates `object`.\n     *\n     * @static\n     * @memberOf _\n     * @since 4.0.0\n     * @alias extendWith\n     * @category Object\n     * @param {Object} object The destination object.\n     * @param {...Object} sources The source objects.\n     * @param {Function} [customizer] The function to customize assigned values.\n     * @returns {Object} Returns `object`.\n     * @see _.assignWith\n     * @example\n     *\n     * function customizer(objValue, srcValue) {\n     *   return _.isUndefined(objValue) ? srcValue : objValue;\n     * }\n     *\n     * var defaults = _.partialRight(_.assignInWith, customizer);\n     *\n     * defaults({ 'a': 1 }, { 'b': 2 }, { 'a': 3 });\n     * // => { 'a': 1, 'b': 2 }\n     */\n    var assignInWith = createAssigner(function(object, source, srcIndex, customizer) {\n      copyObject(source, keysIn(source), object, customizer);\n    });\n\n    /**\n     * This method is like `_.assign` except that it accepts `customizer`\n     * which is invoked to produce the assigned values. If `customizer` returns\n     * `undefined`, assignment is handled by the method instead. The `customizer`\n     * is invoked with five arguments: (objValue, srcValue, key, object, source).\n     *\n     * **Note:** This method mutates `object`.\n     *\n     * @static\n     * @memberOf _\n     * @since 4.0.0\n     * @category Object\n     * @param {Object} object The destination object.\n     * @param {...Object} sources The source objects.\n     * @param {Function} [customizer] The function to customize assigned values.\n     * @returns {Object} Returns `object`.\n     * @see _.assignInWith\n     * @example\n     *\n     * function customizer(objValue, srcValue) {\n     *   return _.isUndefined(objValue) ? srcValue : objValue;\n     * }\n     *\n     * var defaults = _.partialRight(_.assignWith, customizer);\n     *\n     * defaults({ 'a': 1 }, { 'b': 2 }, { 'a': 3 });\n     * // => { 'a': 1, 'b': 2 }\n     */\n    var assignWith = createAssigner(function(object, source, srcIndex, customizer) {\n      copyObject(source, keys(source), object, customizer);\n    });\n\n    /**\n     * Creates an array of values corresponding to `paths` of `object`.\n     *\n     * @static\n     * @memberOf _\n     * @since 1.0.0\n     * @category Object\n     * @param {Object} object The object to iterate over.\n     * @param {...(string|string[])} [paths] The property paths to pick.\n     * @returns {Array} Returns the picked values.\n     * @example\n     *\n     * var object = { 'a': [{ 'b': { 'c': 3 } }, 4] };\n     *\n     * _.at(object, ['a[0].b.c', 'a[1]']);\n     * // => [3, 4]\n     */\n    var at = flatRest(baseAt);\n\n    /**\n     * Creates an object that inherits from the `prototype` object. If a\n     * `properties` object is given, its own enumerable string keyed properties\n     * are assigned to the created object.\n     *\n     * @static\n     * @memberOf _\n     * @since 2.3.0\n     * @category Object\n     * @param {Object} prototype The object to inherit from.\n     * @param {Object} [properties] The properties to assign to the object.\n     * @returns {Object} Returns the new object.\n     * @example\n     *\n     * function Shape() {\n     *   this.x = 0;\n     *   this.y = 0;\n     * }\n     *\n     * function Circle() {\n     *   Shape.call(this);\n     * }\n     *\n     * Circle.prototype = _.create(Shape.prototype, {\n     *   'constructor': Circle\n     * });\n     *\n     * var circle = new Circle;\n     * circle instanceof Circle;\n     * // => true\n     *\n     * circle instanceof Shape;\n     * // => true\n     */\n    function create(prototype, properties) {\n      var result = baseCreate(prototype);\n      return properties == null ? result : baseAssign(result, properties);\n    }\n\n    /**\n     * Assigns own and inherited enumerable string keyed properties of source\n     * objects to the destination object for all destination properties that\n     * resolve to `undefined`. Source objects are applied from left to right.\n     * Once a property is set, additional values of the same property are ignored.\n     *\n     * **Note:** This method mutates `object`.\n     *\n     * @static\n     * @since 0.1.0\n     * @memberOf _\n     * @category Object\n     * @param {Object} object The destination object.\n     * @param {...Object} [sources] The source objects.\n     * @returns {Object} Returns `object`.\n     * @see _.defaultsDeep\n     * @example\n     *\n     * _.defaults({ 'a': 1 }, { 'b': 2 }, { 'a': 3 });\n     * // => { 'a': 1, 'b': 2 }\n     */\n    var defaults = baseRest(function(object, sources) {\n      object = Object(object);\n\n      var index = -1;\n      var length = sources.length;\n      var guard = length > 2 ? sources[2] : undefined;\n\n      if (guard && isIterateeCall(sources[0], sources[1], guard)) {\n        length = 1;\n      }\n\n      while (++index < length) {\n        var source = sources[index];\n        var props = keysIn(source);\n        var propsIndex = -1;\n        var propsLength = props.length;\n\n        while (++propsIndex < propsLength) {\n          var key = props[propsIndex];\n          var value = object[key];\n\n          if (value === undefined ||\n              (eq(value, objectProto[key]) && !hasOwnProperty.call(object, key))) {\n            object[key] = source[key];\n          }\n        }\n      }\n\n      return object;\n    });\n\n    /**\n     * This method is like `_.defaults` except that it recursively assigns\n     * default properties.\n     *\n     * **Note:** This method mutates `object`.\n     *\n     * @static\n     * @memberOf _\n     * @since 3.10.0\n     * @category Object\n     * @param {Object} object The destination object.\n     * @param {...Object} [sources] The source objects.\n     * @returns {Object} Returns `object`.\n     * @see _.defaults\n     * @example\n     *\n     * _.defaultsDeep({ 'a': { 'b': 2 } }, { 'a': { 'b': 1, 'c': 3 } });\n     * // => { 'a': { 'b': 2, 'c': 3 } }\n     */\n    var defaultsDeep = baseRest(function(args) {\n      args.push(undefined, customDefaultsMerge);\n      return apply(mergeWith, undefined, args);\n    });\n\n    /**\n     * This method is like `_.find` except that it returns the key of the first\n     * element `predicate` returns truthy for instead of the element itself.\n     *\n     * @static\n     * @memberOf _\n     * @since 1.1.0\n     * @category Object\n     * @param {Object} object The object to inspect.\n     * @param {Function} [predicate=_.identity] The function invoked per iteration.\n     * @returns {string|undefined} Returns the key of the matched element,\n     *  else `undefined`.\n     * @example\n     *\n     * var users = {\n     *   'barney':  { 'age': 36, 'active': true },\n     *   'fred':    { 'age': 40, 'active': false },\n     *   'pebbles': { 'age': 1,  'active': true }\n     * };\n     *\n     * _.findKey(users, function(o) { return o.age < 40; });\n     * // => 'barney' (iteration order is not guaranteed)\n     *\n     * // The `_.matches` iteratee shorthand.\n     * _.findKey(users, { 'age': 1, 'active': true });\n     * // => 'pebbles'\n     *\n     * // The `_.matchesProperty` iteratee shorthand.\n     * _.findKey(users, ['active', false]);\n     * // => 'fred'\n     *\n     * // The `_.property` iteratee shorthand.\n     * _.findKey(users, 'active');\n     * // => 'barney'\n     */\n    function findKey(object, predicate) {\n      return baseFindKey(object, getIteratee(predicate, 3), baseForOwn);\n    }\n\n    /**\n     * This method is like `_.findKey` except that it iterates over elements of\n     * a collection in the opposite order.\n     *\n     * @static\n     * @memberOf _\n     * @since 2.0.0\n     * @category Object\n     * @param {Object} object The object to inspect.\n     * @param {Function} [predicate=_.identity] The function invoked per iteration.\n     * @returns {string|undefined} Returns the key of the matched element,\n     *  else `undefined`.\n     * @example\n     *\n     * var users = {\n     *   'barney':  { 'age': 36, 'active': true },\n     *   'fred':    { 'age': 40, 'active': false },\n     *   'pebbles': { 'age': 1,  'active': true }\n     * };\n     *\n     * _.findLastKey(users, function(o) { return o.age < 40; });\n     * // => returns 'pebbles' assuming `_.findKey` returns 'barney'\n     *\n     * // The `_.matches` iteratee shorthand.\n     * _.findLastKey(users, { 'age': 36, 'active': true });\n     * // => 'barney'\n     *\n     * // The `_.matchesProperty` iteratee shorthand.\n     * _.findLastKey(users, ['active', false]);\n     * // => 'fred'\n     *\n     * // The `_.property` iteratee shorthand.\n     * _.findLastKey(users, 'active');\n     * // => 'pebbles'\n     */\n    function findLastKey(object, predicate) {\n      return baseFindKey(object, getIteratee(predicate, 3), baseForOwnRight);\n    }\n\n    /**\n     * Iterates over own and inherited enumerable string keyed properties of an\n     * object and invokes `iteratee` for each property. The iteratee is invoked\n     * with three arguments: (value, key, object). Iteratee functions may exit\n     * iteration early by explicitly returning `false`.\n     *\n     * @static\n     * @memberOf _\n     * @since 0.3.0\n     * @category Object\n     * @param {Object} object The object to iterate over.\n     * @param {Function} [iteratee=_.identity] The function invoked per iteration.\n     * @returns {Object} Returns `object`.\n     * @see _.forInRight\n     * @example\n     *\n     * function Foo() {\n     *   this.a = 1;\n     *   this.b = 2;\n     * }\n     *\n     * Foo.prototype.c = 3;\n     *\n     * _.forIn(new Foo, function(value, key) {\n     *   console.log(key);\n     * });\n     * // => Logs 'a', 'b', then 'c' (iteration order is not guaranteed).\n     */\n    function forIn(object, iteratee) {\n      return object == null\n        ? object\n        : baseFor(object, getIteratee(iteratee, 3), keysIn);\n    }\n\n    /**\n     * This method is like `_.forIn` except that it iterates over properties of\n     * `object` in the opposite order.\n     *\n     * @static\n     * @memberOf _\n     * @since 2.0.0\n     * @category Object\n     * @param {Object} object The object to iterate over.\n     * @param {Function} [iteratee=_.identity] The function invoked per iteration.\n     * @returns {Object} Returns `object`.\n     * @see _.forIn\n     * @example\n     *\n     * function Foo() {\n     *   this.a = 1;\n     *   this.b = 2;\n     * }\n     *\n     * Foo.prototype.c = 3;\n     *\n     * _.forInRight(new Foo, function(value, key) {\n     *   console.log(key);\n     * });\n     * // => Logs 'c', 'b', then 'a' assuming `_.forIn` logs 'a', 'b', then 'c'.\n     */\n    function forInRight(object, iteratee) {\n      return object == null\n        ? object\n        : baseForRight(object, getIteratee(iteratee, 3), keysIn);\n    }\n\n    /**\n     * Iterates over own enumerable string keyed properties of an object and\n     * invokes `iteratee` for each property. The iteratee is invoked with three\n     * arguments: (value, key, object). Iteratee functions may exit iteration\n     * early by explicitly returning `false`.\n     *\n     * @static\n     * @memberOf _\n     * @since 0.3.0\n     * @category Object\n     * @param {Object} object The object to iterate over.\n     * @param {Function} [iteratee=_.identity] The function invoked per iteration.\n     * @returns {Object} Returns `object`.\n     * @see _.forOwnRight\n     * @example\n     *\n     * function Foo() {\n     *   this.a = 1;\n     *   this.b = 2;\n     * }\n     *\n     * Foo.prototype.c = 3;\n     *\n     * _.forOwn(new Foo, function(value, key) {\n     *   console.log(key);\n     * });\n     * // => Logs 'a' then 'b' (iteration order is not guaranteed).\n     */\n    function forOwn(object, iteratee) {\n      return object && baseForOwn(object, getIteratee(iteratee, 3));\n    }\n\n    /**\n     * This method is like `_.forOwn` except that it iterates over properties of\n     * `object` in the opposite order.\n     *\n     * @static\n     * @memberOf _\n     * @since 2.0.0\n     * @category Object\n     * @param {Object} object The object to iterate over.\n     * @param {Function} [iteratee=_.identity] The function invoked per iteration.\n     * @returns {Object} Returns `object`.\n     * @see _.forOwn\n     * @example\n     *\n     * function Foo() {\n     *   this.a = 1;\n     *   this.b = 2;\n     * }\n     *\n     * Foo.prototype.c = 3;\n     *\n     * _.forOwnRight(new Foo, function(value, key) {\n     *   console.log(key);\n     * });\n     * // => Logs 'b' then 'a' assuming `_.forOwn` logs 'a' then 'b'.\n     */\n    function forOwnRight(object, iteratee) {\n      return object && baseForOwnRight(object, getIteratee(iteratee, 3));\n    }\n\n    /**\n     * Creates an array of function property names from own enumerable properties\n     * of `object`.\n     *\n     * @static\n     * @since 0.1.0\n     * @memberOf _\n     * @category Object\n     * @param {Object} object The object to inspect.\n     * @returns {Array} Returns the function names.\n     * @see _.functionsIn\n     * @example\n     *\n     * function Foo() {\n     *   this.a = _.constant('a');\n     *   this.b = _.constant('b');\n     * }\n     *\n     * Foo.prototype.c = _.constant('c');\n     *\n     * _.functions(new Foo);\n     * // => ['a', 'b']\n     */\n    function functions(object) {\n      return object == null ? [] : baseFunctions(object, keys(object));\n    }\n\n    /**\n     * Creates an array of function property names from own and inherited\n     * enumerable properties of `object`.\n     *\n     * @static\n     * @memberOf _\n     * @since 4.0.0\n     * @category Object\n     * @param {Object} object The object to inspect.\n     * @returns {Array} Returns the function names.\n     * @see _.functions\n     * @example\n     *\n     * function Foo() {\n     *   this.a = _.constant('a');\n     *   this.b = _.constant('b');\n     * }\n     *\n     * Foo.prototype.c = _.constant('c');\n     *\n     * _.functionsIn(new Foo);\n     * // => ['a', 'b', 'c']\n     */\n    function functionsIn(object) {\n      return object == null ? [] : baseFunctions(object, keysIn(object));\n    }\n\n    /**\n     * Gets the value at `path` of `object`. If the resolved value is\n     * `undefined`, the `defaultValue` is returned in its place.\n     *\n     * @static\n     * @memberOf _\n     * @since 3.7.0\n     * @category Object\n     * @param {Object} object The object to query.\n     * @param {Array|string} path The path of the property to get.\n     * @param {*} [defaultValue] The value returned for `undefined` resolved values.\n     * @returns {*} Returns the resolved value.\n     * @example\n     *\n     * var object = { 'a': [{ 'b': { 'c': 3 } }] };\n     *\n     * _.get(object, 'a[0].b.c');\n     * // => 3\n     *\n     * _.get(object, ['a', '0', 'b', 'c']);\n     * // => 3\n     *\n     * _.get(object, 'a.b.c', 'default');\n     * // => 'default'\n     */\n    function get(object, path, defaultValue) {\n      var result = object == null ? undefined : baseGet(object, path);\n      return result === undefined ? defaultValue : result;\n    }\n\n    /**\n     * Checks if `path` is a direct property of `object`.\n     *\n     * @static\n     * @since 0.1.0\n     * @memberOf _\n     * @category Object\n     * @param {Object} object The object to query.\n     * @param {Array|string} path The path to check.\n     * @returns {boolean} Returns `true` if `path` exists, else `false`.\n     * @example\n     *\n     * var object = { 'a': { 'b': 2 } };\n     * var other = _.create({ 'a': _.create({ 'b': 2 }) });\n     *\n     * _.has(object, 'a');\n     * // => true\n     *\n     * _.has(object, 'a.b');\n     * // => true\n     *\n     * _.has(object, ['a', 'b']);\n     * // => true\n     *\n     * _.has(other, 'a');\n     * // => false\n     */\n    function has(object, path) {\n      return object != null && hasPath(object, path, baseHas);\n    }\n\n    /**\n     * Checks if `path` is a direct or inherited property of `object`.\n     *\n     * @static\n     * @memberOf _\n     * @since 4.0.0\n     * @category Object\n     * @param {Object} object The object to query.\n     * @param {Array|string} path The path to check.\n     * @returns {boolean} Returns `true` if `path` exists, else `false`.\n     * @example\n     *\n     * var object = _.create({ 'a': _.create({ 'b': 2 }) });\n     *\n     * _.hasIn(object, 'a');\n     * // => true\n     *\n     * _.hasIn(object, 'a.b');\n     * // => true\n     *\n     * _.hasIn(object, ['a', 'b']);\n     * // => true\n     *\n     * _.hasIn(object, 'b');\n     * // => false\n     */\n    function hasIn(object, path) {\n      return object != null && hasPath(object, path, baseHasIn);\n    }\n\n    /**\n     * Creates an object composed of the inverted keys and values of `object`.\n     * If `object` contains duplicate values, subsequent values overwrite\n     * property assignments of previous values.\n     *\n     * @static\n     * @memberOf _\n     * @since 0.7.0\n     * @category Object\n     * @param {Object} object The object to invert.\n     * @returns {Object} Returns the new inverted object.\n     * @example\n     *\n     * var object = { 'a': 1, 'b': 2, 'c': 1 };\n     *\n     * _.invert(object);\n     * // => { '1': 'c', '2': 'b' }\n     */\n    var invert = createInverter(function(result, value, key) {\n      if (value != null &&\n          typeof value.toString != 'function') {\n        value = nativeObjectToString.call(value);\n      }\n\n      result[value] = key;\n    }, constant(identity));\n\n    /**\n     * This method is like `_.invert` except that the inverted object is generated\n     * from the results of running each element of `object` thru `iteratee`. The\n     * corresponding inverted value of each inverted key is an array of keys\n     * responsible for generating the inverted value. The iteratee is invoked\n     * with one argument: (value).\n     *\n     * @static\n     * @memberOf _\n     * @since 4.1.0\n     * @category Object\n     * @param {Object} object The object to invert.\n     * @param {Function} [iteratee=_.identity] The iteratee invoked per element.\n     * @returns {Object} Returns the new inverted object.\n     * @example\n     *\n     * var object = { 'a': 1, 'b': 2, 'c': 1 };\n     *\n     * _.invertBy(object);\n     * // => { '1': ['a', 'c'], '2': ['b'] }\n     *\n     * _.invertBy(object, function(value) {\n     *   return 'group' + value;\n     * });\n     * // => { 'group1': ['a', 'c'], 'group2': ['b'] }\n     */\n    var invertBy = createInverter(function(result, value, key) {\n      if (value != null &&\n          typeof value.toString != 'function') {\n        value = nativeObjectToString.call(value);\n      }\n\n      if (hasOwnProperty.call(result, value)) {\n        result[value].push(key);\n      } else {\n        result[value] = [key];\n      }\n    }, getIteratee);\n\n    /**\n     * Invokes the method at `path` of `object`.\n     *\n     * @static\n     * @memberOf _\n     * @since 4.0.0\n     * @category Object\n     * @param {Object} object The object to query.\n     * @param {Array|string} path The path of the method to invoke.\n     * @param {...*} [args] The arguments to invoke the method with.\n     * @returns {*} Returns the result of the invoked method.\n     * @example\n     *\n     * var object = { 'a': [{ 'b': { 'c': [1, 2, 3, 4] } }] };\n     *\n     * _.invoke(object, 'a[0].b.c.slice', 1, 3);\n     * // => [2, 3]\n     */\n    var invoke = baseRest(baseInvoke);\n\n    /**\n     * Creates an array of the own enumerable property names of `object`.\n     *\n     * **Note:** Non-object values are coerced to objects. See the\n     * [ES spec](http://ecma-international.org/ecma-262/7.0/#sec-object.keys)\n     * for more details.\n     *\n     * @static\n     * @since 0.1.0\n     * @memberOf _\n     * @category Object\n     * @param {Object} object The object to query.\n     * @returns {Array} Returns the array of property names.\n     * @example\n     *\n     * function Foo() {\n     *   this.a = 1;\n     *   this.b = 2;\n     * }\n     *\n     * Foo.prototype.c = 3;\n     *\n     * _.keys(new Foo);\n     * // => ['a', 'b'] (iteration order is not guaranteed)\n     *\n     * _.keys('hi');\n     * // => ['0', '1']\n     */\n    function keys(object) {\n      return isArrayLike(object) ? arrayLikeKeys(object) : baseKeys(object);\n    }\n\n    /**\n     * Creates an array of the own and inherited enumerable property names of `object`.\n     *\n     * **Note:** Non-object values are coerced to objects.\n     *\n     * @static\n     * @memberOf _\n     * @since 3.0.0\n     * @category Object\n     * @param {Object} object The object to query.\n     * @returns {Array} Returns the array of property names.\n     * @example\n     *\n     * function Foo() {\n     *   this.a = 1;\n     *   this.b = 2;\n     * }\n     *\n     * Foo.prototype.c = 3;\n     *\n     * _.keysIn(new Foo);\n     * // => ['a', 'b', 'c'] (iteration order is not guaranteed)\n     */\n    function keysIn(object) {\n      return isArrayLike(object) ? arrayLikeKeys(object, true) : baseKeysIn(object);\n    }\n\n    /**\n     * The opposite of `_.mapValues`; this method creates an object with the\n     * same values as `object` and keys generated by running each own enumerable\n     * string keyed property of `object` thru `iteratee`. The iteratee is invoked\n     * with three arguments: (value, key, object).\n     *\n     * @static\n     * @memberOf _\n     * @since 3.8.0\n     * @category Object\n     * @param {Object} object The object to iterate over.\n     * @param {Function} [iteratee=_.identity] The function invoked per iteration.\n     * @returns {Object} Returns the new mapped object.\n     * @see _.mapValues\n     * @example\n     *\n     * _.mapKeys({ 'a': 1, 'b': 2 }, function(value, key) {\n     *   return key + value;\n     * });\n     * // => { 'a1': 1, 'b2': 2 }\n     */\n    function mapKeys(object, iteratee) {\n      var result = {};\n      iteratee = getIteratee(iteratee, 3);\n\n      baseForOwn(object, function(value, key, object) {\n        baseAssignValue(result, iteratee(value, key, object), value);\n      });\n      return result;\n    }\n\n    /**\n     * Creates an object with the same keys as `object` and values generated\n     * by running each own enumerable string keyed property of `object` thru\n     * `iteratee`. The iteratee is invoked with three arguments:\n     * (value, key, object).\n     *\n     * @static\n     * @memberOf _\n     * @since 2.4.0\n     * @category Object\n     * @param {Object} object The object to iterate over.\n     * @param {Function} [iteratee=_.identity] The function invoked per iteration.\n     * @returns {Object} Returns the new mapped object.\n     * @see _.mapKeys\n     * @example\n     *\n     * var users = {\n     *   'fred':    { 'user': 'fred',    'age': 40 },\n     *   'pebbles': { 'user': 'pebbles', 'age': 1 }\n     * };\n     *\n     * _.mapValues(users, function(o) { return o.age; });\n     * // => { 'fred': 40, 'pebbles': 1 } (iteration order is not guaranteed)\n     *\n     * // The `_.property` iteratee shorthand.\n     * _.mapValues(users, 'age');\n     * // => { 'fred': 40, 'pebbles': 1 } (iteration order is not guaranteed)\n     */\n    function mapValues(object, iteratee) {\n      var result = {};\n      iteratee = getIteratee(iteratee, 3);\n\n      baseForOwn(object, function(value, key, object) {\n        baseAssignValue(result, key, iteratee(value, key, object));\n      });\n      return result;\n    }\n\n    /**\n     * This method is like `_.assign` except that it recursively merges own and\n     * inherited enumerable string keyed properties of source objects into the\n     * destination object. Source properties that resolve to `undefined` are\n     * skipped if a destination value exists. Array and plain object properties\n     * are merged recursively. Other objects and value types are overridden by\n     * assignment. Source objects are applied from left to right. Subsequent\n     * sources overwrite property assignments of previous sources.\n     *\n     * **Note:** This method mutates `object`.\n     *\n     * @static\n     * @memberOf _\n     * @since 0.5.0\n     * @category Object\n     * @param {Object} object The destination object.\n     * @param {...Object} [sources] The source objects.\n     * @returns {Object} Returns `object`.\n     * @example\n     *\n     * var object = {\n     *   'a': [{ 'b': 2 }, { 'd': 4 }]\n     * };\n     *\n     * var other = {\n     *   'a': [{ 'c': 3 }, { 'e': 5 }]\n     * };\n     *\n     * _.merge(object, other);\n     * // => { 'a': [{ 'b': 2, 'c': 3 }, { 'd': 4, 'e': 5 }] }\n     */\n    var merge = createAssigner(function(object, source, srcIndex) {\n      baseMerge(object, source, srcIndex);\n    });\n\n    /**\n     * This method is like `_.merge` except that it accepts `customizer` which\n     * is invoked to produce the merged values of the destination and source\n     * properties. If `customizer` returns `undefined`, merging is handled by the\n     * method instead. The `customizer` is invoked with six arguments:\n     * (objValue, srcValue, key, object, source, stack).\n     *\n     * **Note:** This method mutates `object`.\n     *\n     * @static\n     * @memberOf _\n     * @since 4.0.0\n     * @category Object\n     * @param {Object} object The destination object.\n     * @param {...Object} sources The source objects.\n     * @param {Function} customizer The function to customize assigned values.\n     * @returns {Object} Returns `object`.\n     * @example\n     *\n     * function customizer(objValue, srcValue) {\n     *   if (_.isArray(objValue)) {\n     *     return objValue.concat(srcValue);\n     *   }\n     * }\n     *\n     * var object = { 'a': [1], 'b': [2] };\n     * var other = { 'a': [3], 'b': [4] };\n     *\n     * _.mergeWith(object, other, customizer);\n     * // => { 'a': [1, 3], 'b': [2, 4] }\n     */\n    var mergeWith = createAssigner(function(object, source, srcIndex, customizer) {\n      baseMerge(object, source, srcIndex, customizer);\n    });\n\n    /**\n     * The opposite of `_.pick`; this method creates an object composed of the\n     * own and inherited enumerable property paths of `object` that are not omitted.\n     *\n     * **Note:** This method is considerably slower than `_.pick`.\n     *\n     * @static\n     * @since 0.1.0\n     * @memberOf _\n     * @category Object\n     * @param {Object} object The source object.\n     * @param {...(string|string[])} [paths] The property paths to omit.\n     * @returns {Object} Returns the new object.\n     * @example\n     *\n     * var object = { 'a': 1, 'b': '2', 'c': 3 };\n     *\n     * _.omit(object, ['a', 'c']);\n     * // => { 'b': '2' }\n     */\n    var omit = flatRest(function(object, paths) {\n      var result = {};\n      if (object == null) {\n        return result;\n      }\n      var isDeep = false;\n      paths = arrayMap(paths, function(path) {\n        path = castPath(path, object);\n        isDeep || (isDeep = path.length > 1);\n        return path;\n      });\n      copyObject(object, getAllKeysIn(object), result);\n      if (isDeep) {\n        result = baseClone(result, CLONE_DEEP_FLAG | CLONE_FLAT_FLAG | CLONE_SYMBOLS_FLAG, customOmitClone);\n      }\n      var length = paths.length;\n      while (length--) {\n        baseUnset(result, paths[length]);\n      }\n      return result;\n    });\n\n    /**\n     * The opposite of `_.pickBy`; this method creates an object composed of\n     * the own and inherited enumerable string keyed properties of `object` that\n     * `predicate` doesn't return truthy for. The predicate is invoked with two\n     * arguments: (value, key).\n     *\n     * @static\n     * @memberOf _\n     * @since 4.0.0\n     * @category Object\n     * @param {Object} object The source object.\n     * @param {Function} [predicate=_.identity] The function invoked per property.\n     * @returns {Object} Returns the new object.\n     * @example\n     *\n     * var object = { 'a': 1, 'b': '2', 'c': 3 };\n     *\n     * _.omitBy(object, _.isNumber);\n     * // => { 'b': '2' }\n     */\n    function omitBy(object, predicate) {\n      return pickBy(object, negate(getIteratee(predicate)));\n    }\n\n    /**\n     * Creates an object composed of the picked `object` properties.\n     *\n     * @static\n     * @since 0.1.0\n     * @memberOf _\n     * @category Object\n     * @param {Object} object The source object.\n     * @param {...(string|string[])} [paths] The property paths to pick.\n     * @returns {Object} Returns the new object.\n     * @example\n     *\n     * var object = { 'a': 1, 'b': '2', 'c': 3 };\n     *\n     * _.pick(object, ['a', 'c']);\n     * // => { 'a': 1, 'c': 3 }\n     */\n    var pick = flatRest(function(object, paths) {\n      return object == null ? {} : basePick(object, paths);\n    });\n\n    /**\n     * Creates an object composed of the `object` properties `predicate` returns\n     * truthy for. The predicate is invoked with two arguments: (value, key).\n     *\n     * @static\n     * @memberOf _\n     * @since 4.0.0\n     * @category Object\n     * @param {Object} object The source object.\n     * @param {Function} [predicate=_.identity] The function invoked per property.\n     * @returns {Object} Returns the new object.\n     * @example\n     *\n     * var object = { 'a': 1, 'b': '2', 'c': 3 };\n     *\n     * _.pickBy(object, _.isNumber);\n     * // => { 'a': 1, 'c': 3 }\n     */\n    function pickBy(object, predicate) {\n      if (object == null) {\n        return {};\n      }\n      var props = arrayMap(getAllKeysIn(object), function(prop) {\n        return [prop];\n      });\n      predicate = getIteratee(predicate);\n      return basePickBy(object, props, function(value, path) {\n        return predicate(value, path[0]);\n      });\n    }\n\n    /**\n     * This method is like `_.get` except that if the resolved value is a\n     * function it's invoked with the `this` binding of its parent object and\n     * its result is returned.\n     *\n     * @static\n     * @since 0.1.0\n     * @memberOf _\n     * @category Object\n     * @param {Object} object The object to query.\n     * @param {Array|string} path The path of the property to resolve.\n     * @param {*} [defaultValue] The value returned for `undefined` resolved values.\n     * @returns {*} Returns the resolved value.\n     * @example\n     *\n     * var object = { 'a': [{ 'b': { 'c1': 3, 'c2': _.constant(4) } }] };\n     *\n     * _.result(object, 'a[0].b.c1');\n     * // => 3\n     *\n     * _.result(object, 'a[0].b.c2');\n     * // => 4\n     *\n     * _.result(object, 'a[0].b.c3', 'default');\n     * // => 'default'\n     *\n     * _.result(object, 'a[0].b.c3', _.constant('default'));\n     * // => 'default'\n     */\n    function result(object, path, defaultValue) {\n      path = castPath(path, object);\n\n      var index = -1,\n          length = path.length;\n\n      // Ensure the loop is entered when path is empty.\n      if (!length) {\n        length = 1;\n        object = undefined;\n      }\n      while (++index < length) {\n        var value = object == null ? undefined : object[toKey(path[index])];\n        if (value === undefined) {\n          index = length;\n          value = defaultValue;\n        }\n        object = isFunction(value) ? value.call(object) : value;\n      }\n      return object;\n    }\n\n    /**\n     * Sets the value at `path` of `object`. If a portion of `path` doesn't exist,\n     * it's created. Arrays are created for missing index properties while objects\n     * are created for all other missing properties. Use `_.setWith` to customize\n     * `path` creation.\n     *\n     * **Note:** This method mutates `object`.\n     *\n     * @static\n     * @memberOf _\n     * @since 3.7.0\n     * @category Object\n     * @param {Object} object The object to modify.\n     * @param {Array|string} path The path of the property to set.\n     * @param {*} value The value to set.\n     * @returns {Object} Returns `object`.\n     * @example\n     *\n     * var object = { 'a': [{ 'b': { 'c': 3 } }] };\n     *\n     * _.set(object, 'a[0].b.c', 4);\n     * console.log(object.a[0].b.c);\n     * // => 4\n     *\n     * _.set(object, ['x', '0', 'y', 'z'], 5);\n     * console.log(object.x[0].y.z);\n     * // => 5\n     */\n    function set(object, path, value) {\n      return object == null ? object : baseSet(object, path, value);\n    }\n\n    /**\n     * This method is like `_.set` except that it accepts `customizer` which is\n     * invoked to produce the objects of `path`.  If `customizer` returns `undefined`\n     * path creation is handled by the method instead. The `customizer` is invoked\n     * with three arguments: (nsValue, key, nsObject).\n     *\n     * **Note:** This method mutates `object`.\n     *\n     * @static\n     * @memberOf _\n     * @since 4.0.0\n     * @category Object\n     * @param {Object} object The object to modify.\n     * @param {Array|string} path The path of the property to set.\n     * @param {*} value The value to set.\n     * @param {Function} [customizer] The function to customize assigned values.\n     * @returns {Object} Returns `object`.\n     * @example\n     *\n     * var object = {};\n     *\n     * _.setWith(object, '[0][1]', 'a', Object);\n     * // => { '0': { '1': 'a' } }\n     */\n    function setWith(object, path, value, customizer) {\n      customizer = typeof customizer == 'function' ? customizer : undefined;\n      return object == null ? object : baseSet(object, path, value, customizer);\n    }\n\n    /**\n     * Creates an array of own enumerable string keyed-value pairs for `object`\n     * which can be consumed by `_.fromPairs`. If `object` is a map or set, its\n     * entries are returned.\n     *\n     * @static\n     * @memberOf _\n     * @since 4.0.0\n     * @alias entries\n     * @category Object\n     * @param {Object} object The object to query.\n     * @returns {Array} Returns the key-value pairs.\n     * @example\n     *\n     * function Foo() {\n     *   this.a = 1;\n     *   this.b = 2;\n     * }\n     *\n     * Foo.prototype.c = 3;\n     *\n     * _.toPairs(new Foo);\n     * // => [['a', 1], ['b', 2]] (iteration order is not guaranteed)\n     */\n    var toPairs = createToPairs(keys);\n\n    /**\n     * Creates an array of own and inherited enumerable string keyed-value pairs\n     * for `object` which can be consumed by `_.fromPairs`. If `object` is a map\n     * or set, its entries are returned.\n     *\n     * @static\n     * @memberOf _\n     * @since 4.0.0\n     * @alias entriesIn\n     * @category Object\n     * @param {Object} object The object to query.\n     * @returns {Array} Returns the key-value pairs.\n     * @example\n     *\n     * function Foo() {\n     *   this.a = 1;\n     *   this.b = 2;\n     * }\n     *\n     * Foo.prototype.c = 3;\n     *\n     * _.toPairsIn(new Foo);\n     * // => [['a', 1], ['b', 2], ['c', 3]] (iteration order is not guaranteed)\n     */\n    var toPairsIn = createToPairs(keysIn);\n\n    /**\n     * An alternative to `_.reduce`; this method transforms `object` to a new\n     * `accumulator` object which is the result of running each of its own\n     * enumerable string keyed properties thru `iteratee`, with each invocation\n     * potentially mutating the `accumulator` object. If `accumulator` is not\n     * provided, a new object with the same `[[Prototype]]` will be used. The\n     * iteratee is invoked with four arguments: (accumulator, value, key, object).\n     * Iteratee functions may exit iteration early by explicitly returning `false`.\n     *\n     * @static\n     * @memberOf _\n     * @since 1.3.0\n     * @category Object\n     * @param {Object} object The object to iterate over.\n     * @param {Function} [iteratee=_.identity] The function invoked per iteration.\n     * @param {*} [accumulator] The custom accumulator value.\n     * @returns {*} Returns the accumulated value.\n     * @example\n     *\n     * _.transform([2, 3, 4], function(result, n) {\n     *   result.push(n *= n);\n     *   return n % 2 == 0;\n     * }, []);\n     * // => [4, 9]\n     *\n     * _.transform({ 'a': 1, 'b': 2, 'c': 1 }, function(result, value, key) {\n     *   (result[value] || (result[value] = [])).push(key);\n     * }, {});\n     * // => { '1': ['a', 'c'], '2': ['b'] }\n     */\n    function transform(object, iteratee, accumulator) {\n      var isArr = isArray(object),\n          isArrLike = isArr || isBuffer(object) || isTypedArray(object);\n\n      iteratee = getIteratee(iteratee, 4);\n      if (accumulator == null) {\n        var Ctor = object && object.constructor;\n        if (isArrLike) {\n          accumulator = isArr ? new Ctor : [];\n        }\n        else if (isObject(object)) {\n          accumulator = isFunction(Ctor) ? baseCreate(getPrototype(object)) : {};\n        }\n        else {\n          accumulator = {};\n        }\n      }\n      (isArrLike ? arrayEach : baseForOwn)(object, function(value, index, object) {\n        return iteratee(accumulator, value, index, object);\n      });\n      return accumulator;\n    }\n\n    /**\n     * Removes the property at `path` of `object`.\n     *\n     * **Note:** This method mutates `object`.\n     *\n     * @static\n     * @memberOf _\n     * @since 4.0.0\n     * @category Object\n     * @param {Object} object The object to modify.\n     * @param {Array|string} path The path of the property to unset.\n     * @returns {boolean} Returns `true` if the property is deleted, else `false`.\n     * @example\n     *\n     * var object = { 'a': [{ 'b': { 'c': 7 } }] };\n     * _.unset(object, 'a[0].b.c');\n     * // => true\n     *\n     * console.log(object);\n     * // => { 'a': [{ 'b': {} }] };\n     *\n     * _.unset(object, ['a', '0', 'b', 'c']);\n     * // => true\n     *\n     * console.log(object);\n     * // => { 'a': [{ 'b': {} }] };\n     */\n    function unset(object, path) {\n      return object == null ? true : baseUnset(object, path);\n    }\n\n    /**\n     * This method is like `_.set` except that accepts `updater` to produce the\n     * value to set. Use `_.updateWith` to customize `path` creation. The `updater`\n     * is invoked with one argument: (value).\n     *\n     * **Note:** This method mutates `object`.\n     *\n     * @static\n     * @memberOf _\n     * @since 4.6.0\n     * @category Object\n     * @param {Object} object The object to modify.\n     * @param {Array|string} path The path of the property to set.\n     * @param {Function} updater The function to produce the updated value.\n     * @returns {Object} Returns `object`.\n     * @example\n     *\n     * var object = { 'a': [{ 'b': { 'c': 3 } }] };\n     *\n     * _.update(object, 'a[0].b.c', function(n) { return n * n; });\n     * console.log(object.a[0].b.c);\n     * // => 9\n     *\n     * _.update(object, 'x[0].y.z', function(n) { return n ? n + 1 : 0; });\n     * console.log(object.x[0].y.z);\n     * // => 0\n     */\n    function update(object, path, updater) {\n      return object == null ? object : baseUpdate(object, path, castFunction(updater));\n    }\n\n    /**\n     * This method is like `_.update` except that it accepts `customizer` which is\n     * invoked to produce the objects of `path`.  If `customizer` returns `undefined`\n     * path creation is handled by the method instead. The `customizer` is invoked\n     * with three arguments: (nsValue, key, nsObject).\n     *\n     * **Note:** This method mutates `object`.\n     *\n     * @static\n     * @memberOf _\n     * @since 4.6.0\n     * @category Object\n     * @param {Object} object The object to modify.\n     * @param {Array|string} path The path of the property to set.\n     * @param {Function} updater The function to produce the updated value.\n     * @param {Function} [customizer] The function to customize assigned values.\n     * @returns {Object} Returns `object`.\n     * @example\n     *\n     * var object = {};\n     *\n     * _.updateWith(object, '[0][1]', _.constant('a'), Object);\n     * // => { '0': { '1': 'a' } }\n     */\n    function updateWith(object, path, updater, customizer) {\n      customizer = typeof customizer == 'function' ? customizer : undefined;\n      return object == null ? object : baseUpdate(object, path, castFunction(updater), customizer);\n    }\n\n    /**\n     * Creates an array of the own enumerable string keyed property values of `object`.\n     *\n     * **Note:** Non-object values are coerced to objects.\n     *\n     * @static\n     * @since 0.1.0\n     * @memberOf _\n     * @category Object\n     * @param {Object} object The object to query.\n     * @returns {Array} Returns the array of property values.\n     * @example\n     *\n     * function Foo() {\n     *   this.a = 1;\n     *   this.b = 2;\n     * }\n     *\n     * Foo.prototype.c = 3;\n     *\n     * _.values(new Foo);\n     * // => [1, 2] (iteration order is not guaranteed)\n     *\n     * _.values('hi');\n     * // => ['h', 'i']\n     */\n    function values(object) {\n      return object == null ? [] : baseValues(object, keys(object));\n    }\n\n    /**\n     * Creates an array of the own and inherited enumerable string keyed property\n     * values of `object`.\n     *\n     * **Note:** Non-object values are coerced to objects.\n     *\n     * @static\n     * @memberOf _\n     * @since 3.0.0\n     * @category Object\n     * @param {Object} object The object to query.\n     * @returns {Array} Returns the array of property values.\n     * @example\n     *\n     * function Foo() {\n     *   this.a = 1;\n     *   this.b = 2;\n     * }\n     *\n     * Foo.prototype.c = 3;\n     *\n     * _.valuesIn(new Foo);\n     * // => [1, 2, 3] (iteration order is not guaranteed)\n     */\n    function valuesIn(object) {\n      return object == null ? [] : baseValues(object, keysIn(object));\n    }\n\n    /*------------------------------------------------------------------------*/\n\n    /**\n     * Clamps `number` within the inclusive `lower` and `upper` bounds.\n     *\n     * @static\n     * @memberOf _\n     * @since 4.0.0\n     * @category Number\n     * @param {number} number The number to clamp.\n     * @param {number} [lower] The lower bound.\n     * @param {number} upper The upper bound.\n     * @returns {number} Returns the clamped number.\n     * @example\n     *\n     * _.clamp(-10, -5, 5);\n     * // => -5\n     *\n     * _.clamp(10, -5, 5);\n     * // => 5\n     */\n    function clamp(number, lower, upper) {\n      if (upper === undefined) {\n        upper = lower;\n        lower = undefined;\n      }\n      if (upper !== undefined) {\n        upper = toNumber(upper);\n        upper = upper === upper ? upper : 0;\n      }\n      if (lower !== undefined) {\n        lower = toNumber(lower);\n        lower = lower === lower ? lower : 0;\n      }\n      return baseClamp(toNumber(number), lower, upper);\n    }\n\n    /**\n     * Checks if `n` is between `start` and up to, but not including, `end`. If\n     * `end` is not specified, it's set to `start` with `start` then set to `0`.\n     * If `start` is greater than `end` the params are swapped to support\n     * negative ranges.\n     *\n     * @static\n     * @memberOf _\n     * @since 3.3.0\n     * @category Number\n     * @param {number} number The number to check.\n     * @param {number} [start=0] The start of the range.\n     * @param {number} end The end of the range.\n     * @returns {boolean} Returns `true` if `number` is in the range, else `false`.\n     * @see _.range, _.rangeRight\n     * @example\n     *\n     * _.inRange(3, 2, 4);\n     * // => true\n     *\n     * _.inRange(4, 8);\n     * // => true\n     *\n     * _.inRange(4, 2);\n     * // => false\n     *\n     * _.inRange(2, 2);\n     * // => false\n     *\n     * _.inRange(1.2, 2);\n     * // => true\n     *\n     * _.inRange(5.2, 4);\n     * // => false\n     *\n     * _.inRange(-3, -2, -6);\n     * // => true\n     */\n    function inRange(number, start, end) {\n      start = toFinite(start);\n      if (end === undefined) {\n        end = start;\n        start = 0;\n      } else {\n        end = toFinite(end);\n      }\n      number = toNumber(number);\n      return baseInRange(number, start, end);\n    }\n\n    /**\n     * Produces a random number between the inclusive `lower` and `upper` bounds.\n     * If only one argument is provided a number between `0` and the given number\n     * is returned. If `floating` is `true`, or either `lower` or `upper` are\n     * floats, a floating-point number is returned instead of an integer.\n     *\n     * **Note:** JavaScript follows the IEEE-754 standard for resolving\n     * floating-point values which can produce unexpected results.\n     *\n     * @static\n     * @memberOf _\n     * @since 0.7.0\n     * @category Number\n     * @param {number} [lower=0] The lower bound.\n     * @param {number} [upper=1] The upper bound.\n     * @param {boolean} [floating] Specify returning a floating-point number.\n     * @returns {number} Returns the random number.\n     * @example\n     *\n     * _.random(0, 5);\n     * // => an integer between 0 and 5\n     *\n     * _.random(5);\n     * // => also an integer between 0 and 5\n     *\n     * _.random(5, true);\n     * // => a floating-point number between 0 and 5\n     *\n     * _.random(1.2, 5.2);\n     * // => a floating-point number between 1.2 and 5.2\n     */\n    function random(lower, upper, floating) {\n      if (floating && typeof floating != 'boolean' && isIterateeCall(lower, upper, floating)) {\n        upper = floating = undefined;\n      }\n      if (floating === undefined) {\n        if (typeof upper == 'boolean') {\n          floating = upper;\n          upper = undefined;\n        }\n        else if (typeof lower == 'boolean') {\n          floating = lower;\n          lower = undefined;\n        }\n      }\n      if (lower === undefined && upper === undefined) {\n        lower = 0;\n        upper = 1;\n      }\n      else {\n        lower = toFinite(lower);\n        if (upper === undefined) {\n          upper = lower;\n          lower = 0;\n        } else {\n          upper = toFinite(upper);\n        }\n      }\n      if (lower > upper) {\n        var temp = lower;\n        lower = upper;\n        upper = temp;\n      }\n      if (floating || lower % 1 || upper % 1) {\n        var rand = nativeRandom();\n        return nativeMin(lower + (rand * (upper - lower + freeParseFloat('1e-' + ((rand + '').length - 1)))), upper);\n      }\n      return baseRandom(lower, upper);\n    }\n\n    /*------------------------------------------------------------------------*/\n\n    /**\n     * Converts `string` to [camel case](https://en.wikipedia.org/wiki/CamelCase).\n     *\n     * @static\n     * @memberOf _\n     * @since 3.0.0\n     * @category String\n     * @param {string} [string=''] The string to convert.\n     * @returns {string} Returns the camel cased string.\n     * @example\n     *\n     * _.camelCase('Foo Bar');\n     * // => 'fooBar'\n     *\n     * _.camelCase('--foo-bar--');\n     * // => 'fooBar'\n     *\n     * _.camelCase('__FOO_BAR__');\n     * // => 'fooBar'\n     */\n    var camelCase = createCompounder(function(result, word, index) {\n      word = word.toLowerCase();\n      return result + (index ? capitalize(word) : word);\n    });\n\n    /**\n     * Converts the first character of `string` to upper case and the remaining\n     * to lower case.\n     *\n     * @static\n     * @memberOf _\n     * @since 3.0.0\n     * @category String\n     * @param {string} [string=''] The string to capitalize.\n     * @returns {string} Returns the capitalized string.\n     * @example\n     *\n     * _.capitalize('FRED');\n     * // => 'Fred'\n     */\n    function capitalize(string) {\n      return upperFirst(toString(string).toLowerCase());\n    }\n\n    /**\n     * Deburrs `string` by converting\n     * [Latin-1 Supplement](https://en.wikipedia.org/wiki/Latin-1_Supplement_(Unicode_block)#Character_table)\n     * and [Latin Extended-A](https://en.wikipedia.org/wiki/Latin_Extended-A)\n     * letters to basic Latin letters and removing\n     * [combining diacritical marks](https://en.wikipedia.org/wiki/Combining_Diacritical_Marks).\n     *\n     * @static\n     * @memberOf _\n     * @since 3.0.0\n     * @category String\n     * @param {string} [string=''] The string to deburr.\n     * @returns {string} Returns the deburred string.\n     * @example\n     *\n     * _.deburr('déjà vu');\n     * // => 'deja vu'\n     */\n    function deburr(string) {\n      string = toString(string);\n      return string && string.replace(reLatin, deburrLetter).replace(reComboMark, '');\n    }\n\n    /**\n     * Checks if `string` ends with the given target string.\n     *\n     * @static\n     * @memberOf _\n     * @since 3.0.0\n     * @category String\n     * @param {string} [string=''] The string to inspect.\n     * @param {string} [target] The string to search for.\n     * @param {number} [position=string.length] The position to search up to.\n     * @returns {boolean} Returns `true` if `string` ends with `target`,\n     *  else `false`.\n     * @example\n     *\n     * _.endsWith('abc', 'c');\n     * // => true\n     *\n     * _.endsWith('abc', 'b');\n     * // => false\n     *\n     * _.endsWith('abc', 'b', 2);\n     * // => true\n     */\n    function endsWith(string, target, position) {\n      string = toString(string);\n      target = baseToString(target);\n\n      var length = string.length;\n      position = position === undefined\n        ? length\n        : baseClamp(toInteger(position), 0, length);\n\n      var end = position;\n      position -= target.length;\n      return position >= 0 && string.slice(position, end) == target;\n    }\n\n    /**\n     * Converts the characters \"&\", \"<\", \">\", '\"', and \"'\" in `string` to their\n     * corresponding HTML entities.\n     *\n     * **Note:** No other characters are escaped. To escape additional\n     * characters use a third-party library like [_he_](https://mths.be/he).\n     *\n     * Though the \">\" character is escaped for symmetry, characters like\n     * \">\" and \"/\" don't need escaping in HTML and have no special meaning\n     * unless they're part of a tag or unquoted attribute value. See\n     * [Mathias Bynens's article](https://mathiasbynens.be/notes/ambiguous-ampersands)\n     * (under \"semi-related fun fact\") for more details.\n     *\n     * When working with HTML you should always\n     * [quote attribute values](http://wonko.com/post/html-escaping) to reduce\n     * XSS vectors.\n     *\n     * @static\n     * @since 0.1.0\n     * @memberOf _\n     * @category String\n     * @param {string} [string=''] The string to escape.\n     * @returns {string} Returns the escaped string.\n     * @example\n     *\n     * _.escape('fred, barney, & pebbles');\n     * // => 'fred, barney, &amp; pebbles'\n     */\n    function escape(string) {\n      string = toString(string);\n      return (string && reHasUnescapedHtml.test(string))\n        ? string.replace(reUnescapedHtml, escapeHtmlChar)\n        : string;\n    }\n\n    /**\n     * Escapes the `RegExp` special characters \"^\", \"$\", \"\\\", \".\", \"*\", \"+\",\n     * \"?\", \"(\", \")\", \"[\", \"]\", \"{\", \"}\", and \"|\" in `string`.\n     *\n     * @static\n     * @memberOf _\n     * @since 3.0.0\n     * @category String\n     * @param {string} [string=''] The string to escape.\n     * @returns {string} Returns the escaped string.\n     * @example\n     *\n     * _.escapeRegExp('[lodash](https://lodash.com/)');\n     * // => '\\[lodash\\]\\(https://lodash\\.com/\\)'\n     */\n    function escapeRegExp(string) {\n      string = toString(string);\n      return (string && reHasRegExpChar.test(string))\n        ? string.replace(reRegExpChar, '\\\\$&')\n        : string;\n    }\n\n    /**\n     * Converts `string` to\n     * [kebab case](https://en.wikipedia.org/wiki/Letter_case#Special_case_styles).\n     *\n     * @static\n     * @memberOf _\n     * @since 3.0.0\n     * @category String\n     * @param {string} [string=''] The string to convert.\n     * @returns {string} Returns the kebab cased string.\n     * @example\n     *\n     * _.kebabCase('Foo Bar');\n     * // => 'foo-bar'\n     *\n     * _.kebabCase('fooBar');\n     * // => 'foo-bar'\n     *\n     * _.kebabCase('__FOO_BAR__');\n     * // => 'foo-bar'\n     */\n    var kebabCase = createCompounder(function(result, word, index) {\n      return result + (index ? '-' : '') + word.toLowerCase();\n    });\n\n    /**\n     * Converts `string`, as space separated words, to lower case.\n     *\n     * @static\n     * @memberOf _\n     * @since 4.0.0\n     * @category String\n     * @param {string} [string=''] The string to convert.\n     * @returns {string} Returns the lower cased string.\n     * @example\n     *\n     * _.lowerCase('--Foo-Bar--');\n     * // => 'foo bar'\n     *\n     * _.lowerCase('fooBar');\n     * // => 'foo bar'\n     *\n     * _.lowerCase('__FOO_BAR__');\n     * // => 'foo bar'\n     */\n    var lowerCase = createCompounder(function(result, word, index) {\n      return result + (index ? ' ' : '') + word.toLowerCase();\n    });\n\n    /**\n     * Converts the first character of `string` to lower case.\n     *\n     * @static\n     * @memberOf _\n     * @since 4.0.0\n     * @category String\n     * @param {string} [string=''] The string to convert.\n     * @returns {string} Returns the converted string.\n     * @example\n     *\n     * _.lowerFirst('Fred');\n     * // => 'fred'\n     *\n     * _.lowerFirst('FRED');\n     * // => 'fRED'\n     */\n    var lowerFirst = createCaseFirst('toLowerCase');\n\n    /**\n     * Pads `string` on the left and right sides if it's shorter than `length`.\n     * Padding characters are truncated if they can't be evenly divided by `length`.\n     *\n     * @static\n     * @memberOf _\n     * @since 3.0.0\n     * @category String\n     * @param {string} [string=''] The string to pad.\n     * @param {number} [length=0] The padding length.\n     * @param {string} [chars=' '] The string used as padding.\n     * @returns {string} Returns the padded string.\n     * @example\n     *\n     * _.pad('abc', 8);\n     * // => '  abc   '\n     *\n     * _.pad('abc', 8, '_-');\n     * // => '_-abc_-_'\n     *\n     * _.pad('abc', 3);\n     * // => 'abc'\n     */\n    function pad(string, length, chars) {\n      string = toString(string);\n      length = toInteger(length);\n\n      var strLength = length ? stringSize(string) : 0;\n      if (!length || strLength >= length) {\n        return string;\n      }\n      var mid = (length - strLength) / 2;\n      return (\n        createPadding(nativeFloor(mid), chars) +\n        string +\n        createPadding(nativeCeil(mid), chars)\n      );\n    }\n\n    /**\n     * Pads `string` on the right side if it's shorter than `length`. Padding\n     * characters are truncated if they exceed `length`.\n     *\n     * @static\n     * @memberOf _\n     * @since 4.0.0\n     * @category String\n     * @param {string} [string=''] The string to pad.\n     * @param {number} [length=0] The padding length.\n     * @param {string} [chars=' '] The string used as padding.\n     * @returns {string} Returns the padded string.\n     * @example\n     *\n     * _.padEnd('abc', 6);\n     * // => 'abc   '\n     *\n     * _.padEnd('abc', 6, '_-');\n     * // => 'abc_-_'\n     *\n     * _.padEnd('abc', 3);\n     * // => 'abc'\n     */\n    function padEnd(string, length, chars) {\n      string = toString(string);\n      length = toInteger(length);\n\n      var strLength = length ? stringSize(string) : 0;\n      return (length && strLength < length)\n        ? (string + createPadding(length - strLength, chars))\n        : string;\n    }\n\n    /**\n     * Pads `string` on the left side if it's shorter than `length`. Padding\n     * characters are truncated if they exceed `length`.\n     *\n     * @static\n     * @memberOf _\n     * @since 4.0.0\n     * @category String\n     * @param {string} [string=''] The string to pad.\n     * @param {number} [length=0] The padding length.\n     * @param {string} [chars=' '] The string used as padding.\n     * @returns {string} Returns the padded string.\n     * @example\n     *\n     * _.padStart('abc', 6);\n     * // => '   abc'\n     *\n     * _.padStart('abc', 6, '_-');\n     * // => '_-_abc'\n     *\n     * _.padStart('abc', 3);\n     * // => 'abc'\n     */\n    function padStart(string, length, chars) {\n      string = toString(string);\n      length = toInteger(length);\n\n      var strLength = length ? stringSize(string) : 0;\n      return (length && strLength < length)\n        ? (createPadding(length - strLength, chars) + string)\n        : string;\n    }\n\n    /**\n     * Converts `string` to an integer of the specified radix. If `radix` is\n     * `undefined` or `0`, a `radix` of `10` is used unless `value` is a\n     * hexadecimal, in which case a `radix` of `16` is used.\n     *\n     * **Note:** This method aligns with the\n     * [ES5 implementation](https://es5.github.io/#x15.1.2.2) of `parseInt`.\n     *\n     * @static\n     * @memberOf _\n     * @since 1.1.0\n     * @category String\n     * @param {string} string The string to convert.\n     * @param {number} [radix=10] The radix to interpret `value` by.\n     * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.\n     * @returns {number} Returns the converted integer.\n     * @example\n     *\n     * _.parseInt('08');\n     * // => 8\n     *\n     * _.map(['6', '08', '10'], _.parseInt);\n     * // => [6, 8, 10]\n     */\n    function parseInt(string, radix, guard) {\n      if (guard || radix == null) {\n        radix = 0;\n      } else if (radix) {\n        radix = +radix;\n      }\n      return nativeParseInt(toString(string).replace(reTrimStart, ''), radix || 0);\n    }\n\n    /**\n     * Repeats the given string `n` times.\n     *\n     * @static\n     * @memberOf _\n     * @since 3.0.0\n     * @category String\n     * @param {string} [string=''] The string to repeat.\n     * @param {number} [n=1] The number of times to repeat the string.\n     * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.\n     * @returns {string} Returns the repeated string.\n     * @example\n     *\n     * _.repeat('*', 3);\n     * // => '***'\n     *\n     * _.repeat('abc', 2);\n     * // => 'abcabc'\n     *\n     * _.repeat('abc', 0);\n     * // => ''\n     */\n    function repeat(string, n, guard) {\n      if ((guard ? isIterateeCall(string, n, guard) : n === undefined)) {\n        n = 1;\n      } else {\n        n = toInteger(n);\n      }\n      return baseRepeat(toString(string), n);\n    }\n\n    /**\n     * Replaces matches for `pattern` in `string` with `replacement`.\n     *\n     * **Note:** This method is based on\n     * [`String#replace`](https://mdn.io/String/replace).\n     *\n     * @static\n     * @memberOf _\n     * @since 4.0.0\n     * @category String\n     * @param {string} [string=''] The string to modify.\n     * @param {RegExp|string} pattern The pattern to replace.\n     * @param {Function|string} replacement The match replacement.\n     * @returns {string} Returns the modified string.\n     * @example\n     *\n     * _.replace('Hi Fred', 'Fred', 'Barney');\n     * // => 'Hi Barney'\n     */\n    function replace() {\n      var args = arguments,\n          string = toString(args[0]);\n\n      return args.length < 3 ? string : string.replace(args[1], args[2]);\n    }\n\n    /**\n     * Converts `string` to\n     * [snake case](https://en.wikipedia.org/wiki/Snake_case).\n     *\n     * @static\n     * @memberOf _\n     * @since 3.0.0\n     * @category String\n     * @param {string} [string=''] The string to convert.\n     * @returns {string} Returns the snake cased string.\n     * @example\n     *\n     * _.snakeCase('Foo Bar');\n     * // => 'foo_bar'\n     *\n     * _.snakeCase('fooBar');\n     * // => 'foo_bar'\n     *\n     * _.snakeCase('--FOO-BAR--');\n     * // => 'foo_bar'\n     */\n    var snakeCase = createCompounder(function(result, word, index) {\n      return result + (index ? '_' : '') + word.toLowerCase();\n    });\n\n    /**\n     * Splits `string` by `separator`.\n     *\n     * **Note:** This method is based on\n     * [`String#split`](https://mdn.io/String/split).\n     *\n     * @static\n     * @memberOf _\n     * @since 4.0.0\n     * @category String\n     * @param {string} [string=''] The string to split.\n     * @param {RegExp|string} separator The separator pattern to split by.\n     * @param {number} [limit] The length to truncate results to.\n     * @returns {Array} Returns the string segments.\n     * @example\n     *\n     * _.split('a-b-c', '-', 2);\n     * // => ['a', 'b']\n     */\n    function split(string, separator, limit) {\n      if (limit && typeof limit != 'number' && isIterateeCall(string, separator, limit)) {\n        separator = limit = undefined;\n      }\n      limit = limit === undefined ? MAX_ARRAY_LENGTH : limit >>> 0;\n      if (!limit) {\n        return [];\n      }\n      string = toString(string);\n      if (string && (\n            typeof separator == 'string' ||\n            (separator != null && !isRegExp(separator))\n          )) {\n        separator = baseToString(separator);\n        if (!separator && hasUnicode(string)) {\n          return castSlice(stringToArray(string), 0, limit);\n        }\n      }\n      return string.split(separator, limit);\n    }\n\n    /**\n     * Converts `string` to\n     * [start case](https://en.wikipedia.org/wiki/Letter_case#Stylistic_or_specialised_usage).\n     *\n     * @static\n     * @memberOf _\n     * @since 3.1.0\n     * @category String\n     * @param {string} [string=''] The string to convert.\n     * @returns {string} Returns the start cased string.\n     * @example\n     *\n     * _.startCase('--foo-bar--');\n     * // => 'Foo Bar'\n     *\n     * _.startCase('fooBar');\n     * // => 'Foo Bar'\n     *\n     * _.startCase('__FOO_BAR__');\n     * // => 'FOO BAR'\n     */\n    var startCase = createCompounder(function(result, word, index) {\n      return result + (index ? ' ' : '') + upperFirst(word);\n    });\n\n    /**\n     * Checks if `string` starts with the given target string.\n     *\n     * @static\n     * @memberOf _\n     * @since 3.0.0\n     * @category String\n     * @param {string} [string=''] The string to inspect.\n     * @param {string} [target] The string to search for.\n     * @param {number} [position=0] The position to search from.\n     * @returns {boolean} Returns `true` if `string` starts with `target`,\n     *  else `false`.\n     * @example\n     *\n     * _.startsWith('abc', 'a');\n     * // => true\n     *\n     * _.startsWith('abc', 'b');\n     * // => false\n     *\n     * _.startsWith('abc', 'b', 1);\n     * // => true\n     */\n    function startsWith(string, target, position) {\n      string = toString(string);\n      position = position == null\n        ? 0\n        : baseClamp(toInteger(position), 0, string.length);\n\n      target = baseToString(target);\n      return string.slice(position, position + target.length) == target;\n    }\n\n    /**\n     * Creates a compiled template function that can interpolate data properties\n     * in \"interpolate\" delimiters, HTML-escape interpolated data properties in\n     * \"escape\" delimiters, and execute JavaScript in \"evaluate\" delimiters. Data\n     * properties may be accessed as free variables in the template. If a setting\n     * object is given, it takes precedence over `_.templateSettings` values.\n     *\n     * **Note:** In the development build `_.template` utilizes\n     * [sourceURLs](http://www.html5rocks.com/en/tutorials/developertools/sourcemaps/#toc-sourceurl)\n     * for easier debugging.\n     *\n     * For more information on precompiling templates see\n     * [lodash's custom builds documentation](https://lodash.com/custom-builds).\n     *\n     * For more information on Chrome extension sandboxes see\n     * [Chrome's extensions documentation](https://developer.chrome.com/extensions/sandboxingEval).\n     *\n     * @static\n     * @since 0.1.0\n     * @memberOf _\n     * @category String\n     * @param {string} [string=''] The template string.\n     * @param {Object} [options={}] The options object.\n     * @param {RegExp} [options.escape=_.templateSettings.escape]\n     *  The HTML \"escape\" delimiter.\n     * @param {RegExp} [options.evaluate=_.templateSettings.evaluate]\n     *  The \"evaluate\" delimiter.\n     * @param {Object} [options.imports=_.templateSettings.imports]\n     *  An object to import into the template as free variables.\n     * @param {RegExp} [options.interpolate=_.templateSettings.interpolate]\n     *  The \"interpolate\" delimiter.\n     * @param {string} [options.sourceURL='lodash.templateSources[n]']\n     *  The sourceURL of the compiled template.\n     * @param {string} [options.variable='obj']\n     *  The data object variable name.\n     * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.\n     * @returns {Function} Returns the compiled template function.\n     * @example\n     *\n     * // Use the \"interpolate\" delimiter to create a compiled template.\n     * var compiled = _.template('hello <%= user %>!');\n     * compiled({ 'user': 'fred' });\n     * // => 'hello fred!'\n     *\n     * // Use the HTML \"escape\" delimiter to escape data property values.\n     * var compiled = _.template('<b><%- value %></b>');\n     * compiled({ 'value': '<script>' });\n     * // => '<b>&lt;script&gt;</b>'\n     *\n     * // Use the \"evaluate\" delimiter to execute JavaScript and generate HTML.\n     * var compiled = _.template('<% _.forEach(users, function(user) { %><li><%- user %></li><% }); %>');\n     * compiled({ 'users': ['fred', 'barney'] });\n     * // => '<li>fred</li><li>barney</li>'\n     *\n     * // Use the internal `print` function in \"evaluate\" delimiters.\n     * var compiled = _.template('<% print(\"hello \" + user); %>!');\n     * compiled({ 'user': 'barney' });\n     * // => 'hello barney!'\n     *\n     * // Use the ES template literal delimiter as an \"interpolate\" delimiter.\n     * // Disable support by replacing the \"interpolate\" delimiter.\n     * var compiled = _.template('hello ${ user }!');\n     * compiled({ 'user': 'pebbles' });\n     * // => 'hello pebbles!'\n     *\n     * // Use backslashes to treat delimiters as plain text.\n     * var compiled = _.template('<%= \"\\\\<%- value %\\\\>\" %>');\n     * compiled({ 'value': 'ignored' });\n     * // => '<%- value %>'\n     *\n     * // Use the `imports` option to import `jQuery` as `jq`.\n     * var text = '<% jq.each(users, function(user) { %><li><%- user %></li><% }); %>';\n     * var compiled = _.template(text, { 'imports': { 'jq': jQuery } });\n     * compiled({ 'users': ['fred', 'barney'] });\n     * // => '<li>fred</li><li>barney</li>'\n     *\n     * // Use the `sourceURL` option to specify a custom sourceURL for the template.\n     * var compiled = _.template('hello <%= user %>!', { 'sourceURL': '/basic/greeting.jst' });\n     * compiled(data);\n     * // => Find the source of \"greeting.jst\" under the Sources tab or Resources panel of the web inspector.\n     *\n     * // Use the `variable` option to ensure a with-statement isn't used in the compiled template.\n     * var compiled = _.template('hi <%= data.user %>!', { 'variable': 'data' });\n     * compiled.source;\n     * // => function(data) {\n     * //   var __t, __p = '';\n     * //   __p += 'hi ' + ((__t = ( data.user )) == null ? '' : __t) + '!';\n     * //   return __p;\n     * // }\n     *\n     * // Use custom template delimiters.\n     * _.templateSettings.interpolate = /{{([\\s\\S]+?)}}/g;\n     * var compiled = _.template('hello {{ user }}!');\n     * compiled({ 'user': 'mustache' });\n     * // => 'hello mustache!'\n     *\n     * // Use the `source` property to inline compiled templates for meaningful\n     * // line numbers in error messages and stack traces.\n     * fs.writeFileSync(path.join(process.cwd(), 'jst.js'), '\\\n     *   var JST = {\\\n     *     \"main\": ' + _.template(mainText).source + '\\\n     *   };\\\n     * ');\n     */\n    function template(string, options, guard) {\n      // Based on John Resig's `tmpl` implementation\n      // (http://ejohn.org/blog/javascript-micro-templating/)\n      // and Laura Doktorova's doT.js (https://github.com/olado/doT).\n      var settings = lodash.templateSettings;\n\n      if (guard && isIterateeCall(string, options, guard)) {\n        options = undefined;\n      }\n      string = toString(string);\n      options = assignInWith({}, options, settings, customDefaultsAssignIn);\n\n      var imports = assignInWith({}, options.imports, settings.imports, customDefaultsAssignIn),\n          importsKeys = keys(imports),\n          importsValues = baseValues(imports, importsKeys);\n\n      var isEscaping,\n          isEvaluating,\n          index = 0,\n          interpolate = options.interpolate || reNoMatch,\n          source = \"__p += '\";\n\n      // Compile the regexp to match each delimiter.\n      var reDelimiters = RegExp(\n        (options.escape || reNoMatch).source + '|' +\n        interpolate.source + '|' +\n        (interpolate === reInterpolate ? reEsTemplate : reNoMatch).source + '|' +\n        (options.evaluate || reNoMatch).source + '|$'\n      , 'g');\n\n      // Use a sourceURL for easier debugging.\n      var sourceURL = '//# sourceURL=' +\n        ('sourceURL' in options\n          ? options.sourceURL\n          : ('lodash.templateSources[' + (++templateCounter) + ']')\n        ) + '\\n';\n\n      string.replace(reDelimiters, function(match, escapeValue, interpolateValue, esTemplateValue, evaluateValue, offset) {\n        interpolateValue || (interpolateValue = esTemplateValue);\n\n        // Escape characters that can't be included in string literals.\n        source += string.slice(index, offset).replace(reUnescapedString, escapeStringChar);\n\n        // Replace delimiters with snippets.\n        if (escapeValue) {\n          isEscaping = true;\n          source += \"' +\\n__e(\" + escapeValue + \") +\\n'\";\n        }\n        if (evaluateValue) {\n          isEvaluating = true;\n          source += \"';\\n\" + evaluateValue + \";\\n__p += '\";\n        }\n        if (interpolateValue) {\n          source += \"' +\\n((__t = (\" + interpolateValue + \")) == null ? '' : __t) +\\n'\";\n        }\n        index = offset + match.length;\n\n        // The JS engine embedded in Adobe products needs `match` returned in\n        // order to produce the correct `offset` value.\n        return match;\n      });\n\n      source += \"';\\n\";\n\n      // If `variable` is not specified wrap a with-statement around the generated\n      // code to add the data object to the top of the scope chain.\n      var variable = options.variable;\n      if (!variable) {\n        source = 'with (obj) {\\n' + source + '\\n}\\n';\n      }\n      // Cleanup code by stripping empty strings.\n      source = (isEvaluating ? source.replace(reEmptyStringLeading, '') : source)\n        .replace(reEmptyStringMiddle, '$1')\n        .replace(reEmptyStringTrailing, '$1;');\n\n      // Frame code as the function body.\n      source = 'function(' + (variable || 'obj') + ') {\\n' +\n        (variable\n          ? ''\n          : 'obj || (obj = {});\\n'\n        ) +\n        \"var __t, __p = ''\" +\n        (isEscaping\n           ? ', __e = _.escape'\n           : ''\n        ) +\n        (isEvaluating\n          ? ', __j = Array.prototype.join;\\n' +\n            \"function print() { __p += __j.call(arguments, '') }\\n\"\n          : ';\\n'\n        ) +\n        source +\n        'return __p\\n}';\n\n      var result = attempt(function() {\n        return Function(importsKeys, sourceURL + 'return ' + source)\n          .apply(undefined, importsValues);\n      });\n\n      // Provide the compiled function's source by its `toString` method or\n      // the `source` property as a convenience for inlining compiled templates.\n      result.source = source;\n      if (isError(result)) {\n        throw result;\n      }\n      return result;\n    }\n\n    /**\n     * Converts `string`, as a whole, to lower case just like\n     * [String#toLowerCase](https://mdn.io/toLowerCase).\n     *\n     * @static\n     * @memberOf _\n     * @since 4.0.0\n     * @category String\n     * @param {string} [string=''] The string to convert.\n     * @returns {string} Returns the lower cased string.\n     * @example\n     *\n     * _.toLower('--Foo-Bar--');\n     * // => '--foo-bar--'\n     *\n     * _.toLower('fooBar');\n     * // => 'foobar'\n     *\n     * _.toLower('__FOO_BAR__');\n     * // => '__foo_bar__'\n     */\n    function toLower(value) {\n      return toString(value).toLowerCase();\n    }\n\n    /**\n     * Converts `string`, as a whole, to upper case just like\n     * [String#toUpperCase](https://mdn.io/toUpperCase).\n     *\n     * @static\n     * @memberOf _\n     * @since 4.0.0\n     * @category String\n     * @param {string} [string=''] The string to convert.\n     * @returns {string} Returns the upper cased string.\n     * @example\n     *\n     * _.toUpper('--foo-bar--');\n     * // => '--FOO-BAR--'\n     *\n     * _.toUpper('fooBar');\n     * // => 'FOOBAR'\n     *\n     * _.toUpper('__foo_bar__');\n     * // => '__FOO_BAR__'\n     */\n    function toUpper(value) {\n      return toString(value).toUpperCase();\n    }\n\n    /**\n     * Removes leading and trailing whitespace or specified characters from `string`.\n     *\n     * @static\n     * @memberOf _\n     * @since 3.0.0\n     * @category String\n     * @param {string} [string=''] The string to trim.\n     * @param {string} [chars=whitespace] The characters to trim.\n     * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.\n     * @returns {string} Returns the trimmed string.\n     * @example\n     *\n     * _.trim('  abc  ');\n     * // => 'abc'\n     *\n     * _.trim('-_-abc-_-', '_-');\n     * // => 'abc'\n     *\n     * _.map(['  foo  ', '  bar  '], _.trim);\n     * // => ['foo', 'bar']\n     */\n    function trim(string, chars, guard) {\n      string = toString(string);\n      if (string && (guard || chars === undefined)) {\n        return string.replace(reTrim, '');\n      }\n      if (!string || !(chars = baseToString(chars))) {\n        return string;\n      }\n      var strSymbols = stringToArray(string),\n          chrSymbols = stringToArray(chars),\n          start = charsStartIndex(strSymbols, chrSymbols),\n          end = charsEndIndex(strSymbols, chrSymbols) + 1;\n\n      return castSlice(strSymbols, start, end).join('');\n    }\n\n    /**\n     * Removes trailing whitespace or specified characters from `string`.\n     *\n     * @static\n     * @memberOf _\n     * @since 4.0.0\n     * @category String\n     * @param {string} [string=''] The string to trim.\n     * @param {string} [chars=whitespace] The characters to trim.\n     * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.\n     * @returns {string} Returns the trimmed string.\n     * @example\n     *\n     * _.trimEnd('  abc  ');\n     * // => '  abc'\n     *\n     * _.trimEnd('-_-abc-_-', '_-');\n     * // => '-_-abc'\n     */\n    function trimEnd(string, chars, guard) {\n      string = toString(string);\n      if (string && (guard || chars === undefined)) {\n        return string.replace(reTrimEnd, '');\n      }\n      if (!string || !(chars = baseToString(chars))) {\n        return string;\n      }\n      var strSymbols = stringToArray(string),\n          end = charsEndIndex(strSymbols, stringToArray(chars)) + 1;\n\n      return castSlice(strSymbols, 0, end).join('');\n    }\n\n    /**\n     * Removes leading whitespace or specified characters from `string`.\n     *\n     * @static\n     * @memberOf _\n     * @since 4.0.0\n     * @category String\n     * @param {string} [string=''] The string to trim.\n     * @param {string} [chars=whitespace] The characters to trim.\n     * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.\n     * @returns {string} Returns the trimmed string.\n     * @example\n     *\n     * _.trimStart('  abc  ');\n     * // => 'abc  '\n     *\n     * _.trimStart('-_-abc-_-', '_-');\n     * // => 'abc-_-'\n     */\n    function trimStart(string, chars, guard) {\n      string = toString(string);\n      if (string && (guard || chars === undefined)) {\n        return string.replace(reTrimStart, '');\n      }\n      if (!string || !(chars = baseToString(chars))) {\n        return string;\n      }\n      var strSymbols = stringToArray(string),\n          start = charsStartIndex(strSymbols, stringToArray(chars));\n\n      return castSlice(strSymbols, start).join('');\n    }\n\n    /**\n     * Truncates `string` if it's longer than the given maximum string length.\n     * The last characters of the truncated string are replaced with the omission\n     * string which defaults to \"...\".\n     *\n     * @static\n     * @memberOf _\n     * @since 4.0.0\n     * @category String\n     * @param {string} [string=''] The string to truncate.\n     * @param {Object} [options={}] The options object.\n     * @param {number} [options.length=30] The maximum string length.\n     * @param {string} [options.omission='...'] The string to indicate text is omitted.\n     * @param {RegExp|string} [options.separator] The separator pattern to truncate to.\n     * @returns {string} Returns the truncated string.\n     * @example\n     *\n     * _.truncate('hi-diddly-ho there, neighborino');\n     * // => 'hi-diddly-ho there, neighbo...'\n     *\n     * _.truncate('hi-diddly-ho there, neighborino', {\n     *   'length': 24,\n     *   'separator': ' '\n     * });\n     * // => 'hi-diddly-ho there,...'\n     *\n     * _.truncate('hi-diddly-ho there, neighborino', {\n     *   'length': 24,\n     *   'separator': /,? +/\n     * });\n     * // => 'hi-diddly-ho there...'\n     *\n     * _.truncate('hi-diddly-ho there, neighborino', {\n     *   'omission': ' [...]'\n     * });\n     * // => 'hi-diddly-ho there, neig [...]'\n     */\n    function truncate(string, options) {\n      var length = DEFAULT_TRUNC_LENGTH,\n          omission = DEFAULT_TRUNC_OMISSION;\n\n      if (isObject(options)) {\n        var separator = 'separator' in options ? options.separator : separator;\n        length = 'length' in options ? toInteger(options.length) : length;\n        omission = 'omission' in options ? baseToString(options.omission) : omission;\n      }\n      string = toString(string);\n\n      var strLength = string.length;\n      if (hasUnicode(string)) {\n        var strSymbols = stringToArray(string);\n        strLength = strSymbols.length;\n      }\n      if (length >= strLength) {\n        return string;\n      }\n      var end = length - stringSize(omission);\n      if (end < 1) {\n        return omission;\n      }\n      var result = strSymbols\n        ? castSlice(strSymbols, 0, end).join('')\n        : string.slice(0, end);\n\n      if (separator === undefined) {\n        return result + omission;\n      }\n      if (strSymbols) {\n        end += (result.length - end);\n      }\n      if (isRegExp(separator)) {\n        if (string.slice(end).search(separator)) {\n          var match,\n              substring = result;\n\n          if (!separator.global) {\n            separator = RegExp(separator.source, toString(reFlags.exec(separator)) + 'g');\n          }\n          separator.lastIndex = 0;\n          while ((match = separator.exec(substring))) {\n            var newEnd = match.index;\n          }\n          result = result.slice(0, newEnd === undefined ? end : newEnd);\n        }\n      } else if (string.indexOf(baseToString(separator), end) != end) {\n        var index = result.lastIndexOf(separator);\n        if (index > -1) {\n          result = result.slice(0, index);\n        }\n      }\n      return result + omission;\n    }\n\n    /**\n     * The inverse of `_.escape`; this method converts the HTML entities\n     * `&amp;`, `&lt;`, `&gt;`, `&quot;`, and `&#39;` in `string` to\n     * their corresponding characters.\n     *\n     * **Note:** No other HTML entities are unescaped. To unescape additional\n     * HTML entities use a third-party library like [_he_](https://mths.be/he).\n     *\n     * @static\n     * @memberOf _\n     * @since 0.6.0\n     * @category String\n     * @param {string} [string=''] The string to unescape.\n     * @returns {string} Returns the unescaped string.\n     * @example\n     *\n     * _.unescape('fred, barney, &amp; pebbles');\n     * // => 'fred, barney, & pebbles'\n     */\n    function unescape(string) {\n      string = toString(string);\n      return (string && reHasEscapedHtml.test(string))\n        ? string.replace(reEscapedHtml, unescapeHtmlChar)\n        : string;\n    }\n\n    /**\n     * Converts `string`, as space separated words, to upper case.\n     *\n     * @static\n     * @memberOf _\n     * @since 4.0.0\n     * @category String\n     * @param {string} [string=''] The string to convert.\n     * @returns {string} Returns the upper cased string.\n     * @example\n     *\n     * _.upperCase('--foo-bar');\n     * // => 'FOO BAR'\n     *\n     * _.upperCase('fooBar');\n     * // => 'FOO BAR'\n     *\n     * _.upperCase('__foo_bar__');\n     * // => 'FOO BAR'\n     */\n    var upperCase = createCompounder(function(result, word, index) {\n      return result + (index ? ' ' : '') + word.toUpperCase();\n    });\n\n    /**\n     * Converts the first character of `string` to upper case.\n     *\n     * @static\n     * @memberOf _\n     * @since 4.0.0\n     * @category String\n     * @param {string} [string=''] The string to convert.\n     * @returns {string} Returns the converted string.\n     * @example\n     *\n     * _.upperFirst('fred');\n     * // => 'Fred'\n     *\n     * _.upperFirst('FRED');\n     * // => 'FRED'\n     */\n    var upperFirst = createCaseFirst('toUpperCase');\n\n    /**\n     * Splits `string` into an array of its words.\n     *\n     * @static\n     * @memberOf _\n     * @since 3.0.0\n     * @category String\n     * @param {string} [string=''] The string to inspect.\n     * @param {RegExp|string} [pattern] The pattern to match words.\n     * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.\n     * @returns {Array} Returns the words of `string`.\n     * @example\n     *\n     * _.words('fred, barney, & pebbles');\n     * // => ['fred', 'barney', 'pebbles']\n     *\n     * _.words('fred, barney, & pebbles', /[^, ]+/g);\n     * // => ['fred', 'barney', '&', 'pebbles']\n     */\n    function words(string, pattern, guard) {\n      string = toString(string);\n      pattern = guard ? undefined : pattern;\n\n      if (pattern === undefined) {\n        return hasUnicodeWord(string) ? unicodeWords(string) : asciiWords(string);\n      }\n      return string.match(pattern) || [];\n    }\n\n    /*------------------------------------------------------------------------*/\n\n    /**\n     * Attempts to invoke `func`, returning either the result or the caught error\n     * object. Any additional arguments are provided to `func` when it's invoked.\n     *\n     * @static\n     * @memberOf _\n     * @since 3.0.0\n     * @category Util\n     * @param {Function} func The function to attempt.\n     * @param {...*} [args] The arguments to invoke `func` with.\n     * @returns {*} Returns the `func` result or error object.\n     * @example\n     *\n     * // Avoid throwing errors for invalid selectors.\n     * var elements = _.attempt(function(selector) {\n     *   return document.querySelectorAll(selector);\n     * }, '>_>');\n     *\n     * if (_.isError(elements)) {\n     *   elements = [];\n     * }\n     */\n    var attempt = baseRest(function(func, args) {\n      try {\n        return apply(func, undefined, args);\n      } catch (e) {\n        return isError(e) ? e : new Error(e);\n      }\n    });\n\n    /**\n     * Binds methods of an object to the object itself, overwriting the existing\n     * method.\n     *\n     * **Note:** This method doesn't set the \"length\" property of bound functions.\n     *\n     * @static\n     * @since 0.1.0\n     * @memberOf _\n     * @category Util\n     * @param {Object} object The object to bind and assign the bound methods to.\n     * @param {...(string|string[])} methodNames The object method names to bind.\n     * @returns {Object} Returns `object`.\n     * @example\n     *\n     * var view = {\n     *   'label': 'docs',\n     *   'click': function() {\n     *     console.log('clicked ' + this.label);\n     *   }\n     * };\n     *\n     * _.bindAll(view, ['click']);\n     * jQuery(element).on('click', view.click);\n     * // => Logs 'clicked docs' when clicked.\n     */\n    var bindAll = flatRest(function(object, methodNames) {\n      arrayEach(methodNames, function(key) {\n        key = toKey(key);\n        baseAssignValue(object, key, bind(object[key], object));\n      });\n      return object;\n    });\n\n    /**\n     * Creates a function that iterates over `pairs` and invokes the corresponding\n     * function of the first predicate to return truthy. The predicate-function\n     * pairs are invoked with the `this` binding and arguments of the created\n     * function.\n     *\n     * @static\n     * @memberOf _\n     * @since 4.0.0\n     * @category Util\n     * @param {Array} pairs The predicate-function pairs.\n     * @returns {Function} Returns the new composite function.\n     * @example\n     *\n     * var func = _.cond([\n     *   [_.matches({ 'a': 1 }),           _.constant('matches A')],\n     *   [_.conforms({ 'b': _.isNumber }), _.constant('matches B')],\n     *   [_.stubTrue,                      _.constant('no match')]\n     * ]);\n     *\n     * func({ 'a': 1, 'b': 2 });\n     * // => 'matches A'\n     *\n     * func({ 'a': 0, 'b': 1 });\n     * // => 'matches B'\n     *\n     * func({ 'a': '1', 'b': '2' });\n     * // => 'no match'\n     */\n    function cond(pairs) {\n      var length = pairs == null ? 0 : pairs.length,\n          toIteratee = getIteratee();\n\n      pairs = !length ? [] : arrayMap(pairs, function(pair) {\n        if (typeof pair[1] != 'function') {\n          throw new TypeError(FUNC_ERROR_TEXT);\n        }\n        return [toIteratee(pair[0]), pair[1]];\n      });\n\n      return baseRest(function(args) {\n        var index = -1;\n        while (++index < length) {\n          var pair = pairs[index];\n          if (apply(pair[0], this, args)) {\n            return apply(pair[1], this, args);\n          }\n        }\n      });\n    }\n\n    /**\n     * Creates a function that invokes the predicate properties of `source` with\n     * the corresponding property values of a given object, returning `true` if\n     * all predicates return truthy, else `false`.\n     *\n     * **Note:** The created function is equivalent to `_.conformsTo` with\n     * `source` partially applied.\n     *\n     * @static\n     * @memberOf _\n     * @since 4.0.0\n     * @category Util\n     * @param {Object} source The object of property predicates to conform to.\n     * @returns {Function} Returns the new spec function.\n     * @example\n     *\n     * var objects = [\n     *   { 'a': 2, 'b': 1 },\n     *   { 'a': 1, 'b': 2 }\n     * ];\n     *\n     * _.filter(objects, _.conforms({ 'b': function(n) { return n > 1; } }));\n     * // => [{ 'a': 1, 'b': 2 }]\n     */\n    function conforms(source) {\n      return baseConforms(baseClone(source, CLONE_DEEP_FLAG));\n    }\n\n    /**\n     * Creates a function that returns `value`.\n     *\n     * @static\n     * @memberOf _\n     * @since 2.4.0\n     * @category Util\n     * @param {*} value The value to return from the new function.\n     * @returns {Function} Returns the new constant function.\n     * @example\n     *\n     * var objects = _.times(2, _.constant({ 'a': 1 }));\n     *\n     * console.log(objects);\n     * // => [{ 'a': 1 }, { 'a': 1 }]\n     *\n     * console.log(objects[0] === objects[1]);\n     * // => true\n     */\n    function constant(value) {\n      return function() {\n        return value;\n      };\n    }\n\n    /**\n     * Checks `value` to determine whether a default value should be returned in\n     * its place. The `defaultValue` is returned if `value` is `NaN`, `null`,\n     * or `undefined`.\n     *\n     * @static\n     * @memberOf _\n     * @since 4.14.0\n     * @category Util\n     * @param {*} value The value to check.\n     * @param {*} defaultValue The default value.\n     * @returns {*} Returns the resolved value.\n     * @example\n     *\n     * _.defaultTo(1, 10);\n     * // => 1\n     *\n     * _.defaultTo(undefined, 10);\n     * // => 10\n     */\n    function defaultTo(value, defaultValue) {\n      return (value == null || value !== value) ? defaultValue : value;\n    }\n\n    /**\n     * Creates a function that returns the result of invoking the given functions\n     * with the `this` binding of the created function, where each successive\n     * invocation is supplied the return value of the previous.\n     *\n     * @static\n     * @memberOf _\n     * @since 3.0.0\n     * @category Util\n     * @param {...(Function|Function[])} [funcs] The functions to invoke.\n     * @returns {Function} Returns the new composite function.\n     * @see _.flowRight\n     * @example\n     *\n     * function square(n) {\n     *   return n * n;\n     * }\n     *\n     * var addSquare = _.flow([_.add, square]);\n     * addSquare(1, 2);\n     * // => 9\n     */\n    var flow = createFlow();\n\n    /**\n     * This method is like `_.flow` except that it creates a function that\n     * invokes the given functions from right to left.\n     *\n     * @static\n     * @since 3.0.0\n     * @memberOf _\n     * @category Util\n     * @param {...(Function|Function[])} [funcs] The functions to invoke.\n     * @returns {Function} Returns the new composite function.\n     * @see _.flow\n     * @example\n     *\n     * function square(n) {\n     *   return n * n;\n     * }\n     *\n     * var addSquare = _.flowRight([square, _.add]);\n     * addSquare(1, 2);\n     * // => 9\n     */\n    var flowRight = createFlow(true);\n\n    /**\n     * This method returns the first argument it receives.\n     *\n     * @static\n     * @since 0.1.0\n     * @memberOf _\n     * @category Util\n     * @param {*} value Any value.\n     * @returns {*} Returns `value`.\n     * @example\n     *\n     * var object = { 'a': 1 };\n     *\n     * console.log(_.identity(object) === object);\n     * // => true\n     */\n    function identity(value) {\n      return value;\n    }\n\n    /**\n     * Creates a function that invokes `func` with the arguments of the created\n     * function. If `func` is a property name, the created function returns the\n     * property value for a given element. If `func` is an array or object, the\n     * created function returns `true` for elements that contain the equivalent\n     * source properties, otherwise it returns `false`.\n     *\n     * @static\n     * @since 4.0.0\n     * @memberOf _\n     * @category Util\n     * @param {*} [func=_.identity] The value to convert to a callback.\n     * @returns {Function} Returns the callback.\n     * @example\n     *\n     * var users = [\n     *   { 'user': 'barney', 'age': 36, 'active': true },\n     *   { 'user': 'fred',   'age': 40, 'active': false }\n     * ];\n     *\n     * // The `_.matches` iteratee shorthand.\n     * _.filter(users, _.iteratee({ 'user': 'barney', 'active': true }));\n     * // => [{ 'user': 'barney', 'age': 36, 'active': true }]\n     *\n     * // The `_.matchesProperty` iteratee shorthand.\n     * _.filter(users, _.iteratee(['user', 'fred']));\n     * // => [{ 'user': 'fred', 'age': 40 }]\n     *\n     * // The `_.property` iteratee shorthand.\n     * _.map(users, _.iteratee('user'));\n     * // => ['barney', 'fred']\n     *\n     * // Create custom iteratee shorthands.\n     * _.iteratee = _.wrap(_.iteratee, function(iteratee, func) {\n     *   return !_.isRegExp(func) ? iteratee(func) : function(string) {\n     *     return func.test(string);\n     *   };\n     * });\n     *\n     * _.filter(['abc', 'def'], /ef/);\n     * // => ['def']\n     */\n    function iteratee(func) {\n      return baseIteratee(typeof func == 'function' ? func : baseClone(func, CLONE_DEEP_FLAG));\n    }\n\n    /**\n     * Creates a function that performs a partial deep comparison between a given\n     * object and `source`, returning `true` if the given object has equivalent\n     * property values, else `false`.\n     *\n     * **Note:** The created function is equivalent to `_.isMatch` with `source`\n     * partially applied.\n     *\n     * Partial comparisons will match empty array and empty object `source`\n     * values against any array or object value, respectively. See `_.isEqual`\n     * for a list of supported value comparisons.\n     *\n     * @static\n     * @memberOf _\n     * @since 3.0.0\n     * @category Util\n     * @param {Object} source The object of property values to match.\n     * @returns {Function} Returns the new spec function.\n     * @example\n     *\n     * var objects = [\n     *   { 'a': 1, 'b': 2, 'c': 3 },\n     *   { 'a': 4, 'b': 5, 'c': 6 }\n     * ];\n     *\n     * _.filter(objects, _.matches({ 'a': 4, 'c': 6 }));\n     * // => [{ 'a': 4, 'b': 5, 'c': 6 }]\n     */\n    function matches(source) {\n      return baseMatches(baseClone(source, CLONE_DEEP_FLAG));\n    }\n\n    /**\n     * Creates a function that performs a partial deep comparison between the\n     * value at `path` of a given object to `srcValue`, returning `true` if the\n     * object value is equivalent, else `false`.\n     *\n     * **Note:** Partial comparisons will match empty array and empty object\n     * `srcValue` values against any array or object value, respectively. See\n     * `_.isEqual` for a list of supported value comparisons.\n     *\n     * @static\n     * @memberOf _\n     * @since 3.2.0\n     * @category Util\n     * @param {Array|string} path The path of the property to get.\n     * @param {*} srcValue The value to match.\n     * @returns {Function} Returns the new spec function.\n     * @example\n     *\n     * var objects = [\n     *   { 'a': 1, 'b': 2, 'c': 3 },\n     *   { 'a': 4, 'b': 5, 'c': 6 }\n     * ];\n     *\n     * _.find(objects, _.matchesProperty('a', 4));\n     * // => { 'a': 4, 'b': 5, 'c': 6 }\n     */\n    function matchesProperty(path, srcValue) {\n      return baseMatchesProperty(path, baseClone(srcValue, CLONE_DEEP_FLAG));\n    }\n\n    /**\n     * Creates a function that invokes the method at `path` of a given object.\n     * Any additional arguments are provided to the invoked method.\n     *\n     * @static\n     * @memberOf _\n     * @since 3.7.0\n     * @category Util\n     * @param {Array|string} path The path of the method to invoke.\n     * @param {...*} [args] The arguments to invoke the method with.\n     * @returns {Function} Returns the new invoker function.\n     * @example\n     *\n     * var objects = [\n     *   { 'a': { 'b': _.constant(2) } },\n     *   { 'a': { 'b': _.constant(1) } }\n     * ];\n     *\n     * _.map(objects, _.method('a.b'));\n     * // => [2, 1]\n     *\n     * _.map(objects, _.method(['a', 'b']));\n     * // => [2, 1]\n     */\n    var method = baseRest(function(path, args) {\n      return function(object) {\n        return baseInvoke(object, path, args);\n      };\n    });\n\n    /**\n     * The opposite of `_.method`; this method creates a function that invokes\n     * the method at a given path of `object`. Any additional arguments are\n     * provided to the invoked method.\n     *\n     * @static\n     * @memberOf _\n     * @since 3.7.0\n     * @category Util\n     * @param {Object} object The object to query.\n     * @param {...*} [args] The arguments to invoke the method with.\n     * @returns {Function} Returns the new invoker function.\n     * @example\n     *\n     * var array = _.times(3, _.constant),\n     *     object = { 'a': array, 'b': array, 'c': array };\n     *\n     * _.map(['a[2]', 'c[0]'], _.methodOf(object));\n     * // => [2, 0]\n     *\n     * _.map([['a', '2'], ['c', '0']], _.methodOf(object));\n     * // => [2, 0]\n     */\n    var methodOf = baseRest(function(object, args) {\n      return function(path) {\n        return baseInvoke(object, path, args);\n      };\n    });\n\n    /**\n     * Adds all own enumerable string keyed function properties of a source\n     * object to the destination object. If `object` is a function, then methods\n     * are added to its prototype as well.\n     *\n     * **Note:** Use `_.runInContext` to create a pristine `lodash` function to\n     * avoid conflicts caused by modifying the original.\n     *\n     * @static\n     * @since 0.1.0\n     * @memberOf _\n     * @category Util\n     * @param {Function|Object} [object=lodash] The destination object.\n     * @param {Object} source The object of functions to add.\n     * @param {Object} [options={}] The options object.\n     * @param {boolean} [options.chain=true] Specify whether mixins are chainable.\n     * @returns {Function|Object} Returns `object`.\n     * @example\n     *\n     * function vowels(string) {\n     *   return _.filter(string, function(v) {\n     *     return /[aeiou]/i.test(v);\n     *   });\n     * }\n     *\n     * _.mixin({ 'vowels': vowels });\n     * _.vowels('fred');\n     * // => ['e']\n     *\n     * _('fred').vowels().value();\n     * // => ['e']\n     *\n     * _.mixin({ 'vowels': vowels }, { 'chain': false });\n     * _('fred').vowels();\n     * // => ['e']\n     */\n    function mixin(object, source, options) {\n      var props = keys(source),\n          methodNames = baseFunctions(source, props);\n\n      if (options == null &&\n          !(isObject(source) && (methodNames.length || !props.length))) {\n        options = source;\n        source = object;\n        object = this;\n        methodNames = baseFunctions(source, keys(source));\n      }\n      var chain = !(isObject(options) && 'chain' in options) || !!options.chain,\n          isFunc = isFunction(object);\n\n      arrayEach(methodNames, function(methodName) {\n        var func = source[methodName];\n        object[methodName] = func;\n        if (isFunc) {\n          object.prototype[methodName] = function() {\n            var chainAll = this.__chain__;\n            if (chain || chainAll) {\n              var result = object(this.__wrapped__),\n                  actions = result.__actions__ = copyArray(this.__actions__);\n\n              actions.push({ 'func': func, 'args': arguments, 'thisArg': object });\n              result.__chain__ = chainAll;\n              return result;\n            }\n            return func.apply(object, arrayPush([this.value()], arguments));\n          };\n        }\n      });\n\n      return object;\n    }\n\n    /**\n     * Reverts the `_` variable to its previous value and returns a reference to\n     * the `lodash` function.\n     *\n     * @static\n     * @since 0.1.0\n     * @memberOf _\n     * @category Util\n     * @returns {Function} Returns the `lodash` function.\n     * @example\n     *\n     * var lodash = _.noConflict();\n     */\n    function noConflict() {\n      if (root._ === this) {\n        root._ = oldDash;\n      }\n      return this;\n    }\n\n    /**\n     * This method returns `undefined`.\n     *\n     * @static\n     * @memberOf _\n     * @since 2.3.0\n     * @category Util\n     * @example\n     *\n     * _.times(2, _.noop);\n     * // => [undefined, undefined]\n     */\n    function noop() {\n      // No operation performed.\n    }\n\n    /**\n     * Creates a function that gets the argument at index `n`. If `n` is negative,\n     * the nth argument from the end is returned.\n     *\n     * @static\n     * @memberOf _\n     * @since 4.0.0\n     * @category Util\n     * @param {number} [n=0] The index of the argument to return.\n     * @returns {Function} Returns the new pass-thru function.\n     * @example\n     *\n     * var func = _.nthArg(1);\n     * func('a', 'b', 'c', 'd');\n     * // => 'b'\n     *\n     * var func = _.nthArg(-2);\n     * func('a', 'b', 'c', 'd');\n     * // => 'c'\n     */\n    function nthArg(n) {\n      n = toInteger(n);\n      return baseRest(function(args) {\n        return baseNth(args, n);\n      });\n    }\n\n    /**\n     * Creates a function that invokes `iteratees` with the arguments it receives\n     * and returns their results.\n     *\n     * @static\n     * @memberOf _\n     * @since 4.0.0\n     * @category Util\n     * @param {...(Function|Function[])} [iteratees=[_.identity]]\n     *  The iteratees to invoke.\n     * @returns {Function} Returns the new function.\n     * @example\n     *\n     * var func = _.over([Math.max, Math.min]);\n     *\n     * func(1, 2, 3, 4);\n     * // => [4, 1]\n     */\n    var over = createOver(arrayMap);\n\n    /**\n     * Creates a function that checks if **all** of the `predicates` return\n     * truthy when invoked with the arguments it receives.\n     *\n     * @static\n     * @memberOf _\n     * @since 4.0.0\n     * @category Util\n     * @param {...(Function|Function[])} [predicates=[_.identity]]\n     *  The predicates to check.\n     * @returns {Function} Returns the new function.\n     * @example\n     *\n     * var func = _.overEvery([Boolean, isFinite]);\n     *\n     * func('1');\n     * // => true\n     *\n     * func(null);\n     * // => false\n     *\n     * func(NaN);\n     * // => false\n     */\n    var overEvery = createOver(arrayEvery);\n\n    /**\n     * Creates a function that checks if **any** of the `predicates` return\n     * truthy when invoked with the arguments it receives.\n     *\n     * @static\n     * @memberOf _\n     * @since 4.0.0\n     * @category Util\n     * @param {...(Function|Function[])} [predicates=[_.identity]]\n     *  The predicates to check.\n     * @returns {Function} Returns the new function.\n     * @example\n     *\n     * var func = _.overSome([Boolean, isFinite]);\n     *\n     * func('1');\n     * // => true\n     *\n     * func(null);\n     * // => true\n     *\n     * func(NaN);\n     * // => false\n     */\n    var overSome = createOver(arraySome);\n\n    /**\n     * Creates a function that returns the value at `path` of a given object.\n     *\n     * @static\n     * @memberOf _\n     * @since 2.4.0\n     * @category Util\n     * @param {Array|string} path The path of the property to get.\n     * @returns {Function} Returns the new accessor function.\n     * @example\n     *\n     * var objects = [\n     *   { 'a': { 'b': 2 } },\n     *   { 'a': { 'b': 1 } }\n     * ];\n     *\n     * _.map(objects, _.property('a.b'));\n     * // => [2, 1]\n     *\n     * _.map(_.sortBy(objects, _.property(['a', 'b'])), 'a.b');\n     * // => [1, 2]\n     */\n    function property(path) {\n      return isKey(path) ? baseProperty(toKey(path)) : basePropertyDeep(path);\n    }\n\n    /**\n     * The opposite of `_.property`; this method creates a function that returns\n     * the value at a given path of `object`.\n     *\n     * @static\n     * @memberOf _\n     * @since 3.0.0\n     * @category Util\n     * @param {Object} object The object to query.\n     * @returns {Function} Returns the new accessor function.\n     * @example\n     *\n     * var array = [0, 1, 2],\n     *     object = { 'a': array, 'b': array, 'c': array };\n     *\n     * _.map(['a[2]', 'c[0]'], _.propertyOf(object));\n     * // => [2, 0]\n     *\n     * _.map([['a', '2'], ['c', '0']], _.propertyOf(object));\n     * // => [2, 0]\n     */\n    function propertyOf(object) {\n      return function(path) {\n        return object == null ? undefined : baseGet(object, path);\n      };\n    }\n\n    /**\n     * Creates an array of numbers (positive and/or negative) progressing from\n     * `start` up to, but not including, `end`. A step of `-1` is used if a negative\n     * `start` is specified without an `end` or `step`. If `end` is not specified,\n     * it's set to `start` with `start` then set to `0`.\n     *\n     * **Note:** JavaScript follows the IEEE-754 standard for resolving\n     * floating-point values which can produce unexpected results.\n     *\n     * @static\n     * @since 0.1.0\n     * @memberOf _\n     * @category Util\n     * @param {number} [start=0] The start of the range.\n     * @param {number} end The end of the range.\n     * @param {number} [step=1] The value to increment or decrement by.\n     * @returns {Array} Returns the range of numbers.\n     * @see _.inRange, _.rangeRight\n     * @example\n     *\n     * _.range(4);\n     * // => [0, 1, 2, 3]\n     *\n     * _.range(-4);\n     * // => [0, -1, -2, -3]\n     *\n     * _.range(1, 5);\n     * // => [1, 2, 3, 4]\n     *\n     * _.range(0, 20, 5);\n     * // => [0, 5, 10, 15]\n     *\n     * _.range(0, -4, -1);\n     * // => [0, -1, -2, -3]\n     *\n     * _.range(1, 4, 0);\n     * // => [1, 1, 1]\n     *\n     * _.range(0);\n     * // => []\n     */\n    var range = createRange();\n\n    /**\n     * This method is like `_.range` except that it populates values in\n     * descending order.\n     *\n     * @static\n     * @memberOf _\n     * @since 4.0.0\n     * @category Util\n     * @param {number} [start=0] The start of the range.\n     * @param {number} end The end of the range.\n     * @param {number} [step=1] The value to increment or decrement by.\n     * @returns {Array} Returns the range of numbers.\n     * @see _.inRange, _.range\n     * @example\n     *\n     * _.rangeRight(4);\n     * // => [3, 2, 1, 0]\n     *\n     * _.rangeRight(-4);\n     * // => [-3, -2, -1, 0]\n     *\n     * _.rangeRight(1, 5);\n     * // => [4, 3, 2, 1]\n     *\n     * _.rangeRight(0, 20, 5);\n     * // => [15, 10, 5, 0]\n     *\n     * _.rangeRight(0, -4, -1);\n     * // => [-3, -2, -1, 0]\n     *\n     * _.rangeRight(1, 4, 0);\n     * // => [1, 1, 1]\n     *\n     * _.rangeRight(0);\n     * // => []\n     */\n    var rangeRight = createRange(true);\n\n    /**\n     * This method returns a new empty array.\n     *\n     * @static\n     * @memberOf _\n     * @since 4.13.0\n     * @category Util\n     * @returns {Array} Returns the new empty array.\n     * @example\n     *\n     * var arrays = _.times(2, _.stubArray);\n     *\n     * console.log(arrays);\n     * // => [[], []]\n     *\n     * console.log(arrays[0] === arrays[1]);\n     * // => false\n     */\n    function stubArray() {\n      return [];\n    }\n\n    /**\n     * This method returns `false`.\n     *\n     * @static\n     * @memberOf _\n     * @since 4.13.0\n     * @category Util\n     * @returns {boolean} Returns `false`.\n     * @example\n     *\n     * _.times(2, _.stubFalse);\n     * // => [false, false]\n     */\n    function stubFalse() {\n      return false;\n    }\n\n    /**\n     * This method returns a new empty object.\n     *\n     * @static\n     * @memberOf _\n     * @since 4.13.0\n     * @category Util\n     * @returns {Object} Returns the new empty object.\n     * @example\n     *\n     * var objects = _.times(2, _.stubObject);\n     *\n     * console.log(objects);\n     * // => [{}, {}]\n     *\n     * console.log(objects[0] === objects[1]);\n     * // => false\n     */\n    function stubObject() {\n      return {};\n    }\n\n    /**\n     * This method returns an empty string.\n     *\n     * @static\n     * @memberOf _\n     * @since 4.13.0\n     * @category Util\n     * @returns {string} Returns the empty string.\n     * @example\n     *\n     * _.times(2, _.stubString);\n     * // => ['', '']\n     */\n    function stubString() {\n      return '';\n    }\n\n    /**\n     * This method returns `true`.\n     *\n     * @static\n     * @memberOf _\n     * @since 4.13.0\n     * @category Util\n     * @returns {boolean} Returns `true`.\n     * @example\n     *\n     * _.times(2, _.stubTrue);\n     * // => [true, true]\n     */\n    function stubTrue() {\n      return true;\n    }\n\n    /**\n     * Invokes the iteratee `n` times, returning an array of the results of\n     * each invocation. The iteratee is invoked with one argument; (index).\n     *\n     * @static\n     * @since 0.1.0\n     * @memberOf _\n     * @category Util\n     * @param {number} n The number of times to invoke `iteratee`.\n     * @param {Function} [iteratee=_.identity] The function invoked per iteration.\n     * @returns {Array} Returns the array of results.\n     * @example\n     *\n     * _.times(3, String);\n     * // => ['0', '1', '2']\n     *\n     *  _.times(4, _.constant(0));\n     * // => [0, 0, 0, 0]\n     */\n    function times(n, iteratee) {\n      n = toInteger(n);\n      if (n < 1 || n > MAX_SAFE_INTEGER) {\n        return [];\n      }\n      var index = MAX_ARRAY_LENGTH,\n          length = nativeMin(n, MAX_ARRAY_LENGTH);\n\n      iteratee = getIteratee(iteratee);\n      n -= MAX_ARRAY_LENGTH;\n\n      var result = baseTimes(length, iteratee);\n      while (++index < n) {\n        iteratee(index);\n      }\n      return result;\n    }\n\n    /**\n     * Converts `value` to a property path array.\n     *\n     * @static\n     * @memberOf _\n     * @since 4.0.0\n     * @category Util\n     * @param {*} value The value to convert.\n     * @returns {Array} Returns the new property path array.\n     * @example\n     *\n     * _.toPath('a.b.c');\n     * // => ['a', 'b', 'c']\n     *\n     * _.toPath('a[0].b.c');\n     * // => ['a', '0', 'b', 'c']\n     */\n    function toPath(value) {\n      if (isArray(value)) {\n        return arrayMap(value, toKey);\n      }\n      return isSymbol(value) ? [value] : copyArray(stringToPath(toString(value)));\n    }\n\n    /**\n     * Generates a unique ID. If `prefix` is given, the ID is appended to it.\n     *\n     * @static\n     * @since 0.1.0\n     * @memberOf _\n     * @category Util\n     * @param {string} [prefix=''] The value to prefix the ID with.\n     * @returns {string} Returns the unique ID.\n     * @example\n     *\n     * _.uniqueId('contact_');\n     * // => 'contact_104'\n     *\n     * _.uniqueId();\n     * // => '105'\n     */\n    function uniqueId(prefix) {\n      var id = ++idCounter;\n      return toString(prefix) + id;\n    }\n\n    /*------------------------------------------------------------------------*/\n\n    /**\n     * Adds two numbers.\n     *\n     * @static\n     * @memberOf _\n     * @since 3.4.0\n     * @category Math\n     * @param {number} augend The first number in an addition.\n     * @param {number} addend The second number in an addition.\n     * @returns {number} Returns the total.\n     * @example\n     *\n     * _.add(6, 4);\n     * // => 10\n     */\n    var add = createMathOperation(function(augend, addend) {\n      return augend + addend;\n    }, 0);\n\n    /**\n     * Computes `number` rounded up to `precision`.\n     *\n     * @static\n     * @memberOf _\n     * @since 3.10.0\n     * @category Math\n     * @param {number} number The number to round up.\n     * @param {number} [precision=0] The precision to round up to.\n     * @returns {number} Returns the rounded up number.\n     * @example\n     *\n     * _.ceil(4.006);\n     * // => 5\n     *\n     * _.ceil(6.004, 2);\n     * // => 6.01\n     *\n     * _.ceil(6040, -2);\n     * // => 6100\n     */\n    var ceil = createRound('ceil');\n\n    /**\n     * Divide two numbers.\n     *\n     * @static\n     * @memberOf _\n     * @since 4.7.0\n     * @category Math\n     * @param {number} dividend The first number in a division.\n     * @param {number} divisor The second number in a division.\n     * @returns {number} Returns the quotient.\n     * @example\n     *\n     * _.divide(6, 4);\n     * // => 1.5\n     */\n    var divide = createMathOperation(function(dividend, divisor) {\n      return dividend / divisor;\n    }, 1);\n\n    /**\n     * Computes `number` rounded down to `precision`.\n     *\n     * @static\n     * @memberOf _\n     * @since 3.10.0\n     * @category Math\n     * @param {number} number The number to round down.\n     * @param {number} [precision=0] The precision to round down to.\n     * @returns {number} Returns the rounded down number.\n     * @example\n     *\n     * _.floor(4.006);\n     * // => 4\n     *\n     * _.floor(0.046, 2);\n     * // => 0.04\n     *\n     * _.floor(4060, -2);\n     * // => 4000\n     */\n    var floor = createRound('floor');\n\n    /**\n     * Computes the maximum value of `array`. If `array` is empty or falsey,\n     * `undefined` is returned.\n     *\n     * @static\n     * @since 0.1.0\n     * @memberOf _\n     * @category Math\n     * @param {Array} array The array to iterate over.\n     * @returns {*} Returns the maximum value.\n     * @example\n     *\n     * _.max([4, 2, 8, 6]);\n     * // => 8\n     *\n     * _.max([]);\n     * // => undefined\n     */\n    function max(array) {\n      return (array && array.length)\n        ? baseExtremum(array, identity, baseGt)\n        : undefined;\n    }\n\n    /**\n     * This method is like `_.max` except that it accepts `iteratee` which is\n     * invoked for each element in `array` to generate the criterion by which\n     * the value is ranked. The iteratee is invoked with one argument: (value).\n     *\n     * @static\n     * @memberOf _\n     * @since 4.0.0\n     * @category Math\n     * @param {Array} array The array to iterate over.\n     * @param {Function} [iteratee=_.identity] The iteratee invoked per element.\n     * @returns {*} Returns the maximum value.\n     * @example\n     *\n     * var objects = [{ 'n': 1 }, { 'n': 2 }];\n     *\n     * _.maxBy(objects, function(o) { return o.n; });\n     * // => { 'n': 2 }\n     *\n     * // The `_.property` iteratee shorthand.\n     * _.maxBy(objects, 'n');\n     * // => { 'n': 2 }\n     */\n    function maxBy(array, iteratee) {\n      return (array && array.length)\n        ? baseExtremum(array, getIteratee(iteratee, 2), baseGt)\n        : undefined;\n    }\n\n    /**\n     * Computes the mean of the values in `array`.\n     *\n     * @static\n     * @memberOf _\n     * @since 4.0.0\n     * @category Math\n     * @param {Array} array The array to iterate over.\n     * @returns {number} Returns the mean.\n     * @example\n     *\n     * _.mean([4, 2, 8, 6]);\n     * // => 5\n     */\n    function mean(array) {\n      return baseMean(array, identity);\n    }\n\n    /**\n     * This method is like `_.mean` except that it accepts `iteratee` which is\n     * invoked for each element in `array` to generate the value to be averaged.\n     * The iteratee is invoked with one argument: (value).\n     *\n     * @static\n     * @memberOf _\n     * @since 4.7.0\n     * @category Math\n     * @param {Array} array The array to iterate over.\n     * @param {Function} [iteratee=_.identity] The iteratee invoked per element.\n     * @returns {number} Returns the mean.\n     * @example\n     *\n     * var objects = [{ 'n': 4 }, { 'n': 2 }, { 'n': 8 }, { 'n': 6 }];\n     *\n     * _.meanBy(objects, function(o) { return o.n; });\n     * // => 5\n     *\n     * // The `_.property` iteratee shorthand.\n     * _.meanBy(objects, 'n');\n     * // => 5\n     */\n    function meanBy(array, iteratee) {\n      return baseMean(array, getIteratee(iteratee, 2));\n    }\n\n    /**\n     * Computes the minimum value of `array`. If `array` is empty or falsey,\n     * `undefined` is returned.\n     *\n     * @static\n     * @since 0.1.0\n     * @memberOf _\n     * @category Math\n     * @param {Array} array The array to iterate over.\n     * @returns {*} Returns the minimum value.\n     * @example\n     *\n     * _.min([4, 2, 8, 6]);\n     * // => 2\n     *\n     * _.min([]);\n     * // => undefined\n     */\n    function min(array) {\n      return (array && array.length)\n        ? baseExtremum(array, identity, baseLt)\n        : undefined;\n    }\n\n    /**\n     * This method is like `_.min` except that it accepts `iteratee` which is\n     * invoked for each element in `array` to generate the criterion by which\n     * the value is ranked. The iteratee is invoked with one argument: (value).\n     *\n     * @static\n     * @memberOf _\n     * @since 4.0.0\n     * @category Math\n     * @param {Array} array The array to iterate over.\n     * @param {Function} [iteratee=_.identity] The iteratee invoked per element.\n     * @returns {*} Returns the minimum value.\n     * @example\n     *\n     * var objects = [{ 'n': 1 }, { 'n': 2 }];\n     *\n     * _.minBy(objects, function(o) { return o.n; });\n     * // => { 'n': 1 }\n     *\n     * // The `_.property` iteratee shorthand.\n     * _.minBy(objects, 'n');\n     * // => { 'n': 1 }\n     */\n    function minBy(array, iteratee) {\n      return (array && array.length)\n        ? baseExtremum(array, getIteratee(iteratee, 2), baseLt)\n        : undefined;\n    }\n\n    /**\n     * Multiply two numbers.\n     *\n     * @static\n     * @memberOf _\n     * @since 4.7.0\n     * @category Math\n     * @param {number} multiplier The first number in a multiplication.\n     * @param {number} multiplicand The second number in a multiplication.\n     * @returns {number} Returns the product.\n     * @example\n     *\n     * _.multiply(6, 4);\n     * // => 24\n     */\n    var multiply = createMathOperation(function(multiplier, multiplicand) {\n      return multiplier * multiplicand;\n    }, 1);\n\n    /**\n     * Computes `number` rounded to `precision`.\n     *\n     * @static\n     * @memberOf _\n     * @since 3.10.0\n     * @category Math\n     * @param {number} number The number to round.\n     * @param {number} [precision=0] The precision to round to.\n     * @returns {number} Returns the rounded number.\n     * @example\n     *\n     * _.round(4.006);\n     * // => 4\n     *\n     * _.round(4.006, 2);\n     * // => 4.01\n     *\n     * _.round(4060, -2);\n     * // => 4100\n     */\n    var round = createRound('round');\n\n    /**\n     * Subtract two numbers.\n     *\n     * @static\n     * @memberOf _\n     * @since 4.0.0\n     * @category Math\n     * @param {number} minuend The first number in a subtraction.\n     * @param {number} subtrahend The second number in a subtraction.\n     * @returns {number} Returns the difference.\n     * @example\n     *\n     * _.subtract(6, 4);\n     * // => 2\n     */\n    var subtract = createMathOperation(function(minuend, subtrahend) {\n      return minuend - subtrahend;\n    }, 0);\n\n    /**\n     * Computes the sum of the values in `array`.\n     *\n     * @static\n     * @memberOf _\n     * @since 3.4.0\n     * @category Math\n     * @param {Array} array The array to iterate over.\n     * @returns {number} Returns the sum.\n     * @example\n     *\n     * _.sum([4, 2, 8, 6]);\n     * // => 20\n     */\n    function sum(array) {\n      return (array && array.length)\n        ? baseSum(array, identity)\n        : 0;\n    }\n\n    /**\n     * This method is like `_.sum` except that it accepts `iteratee` which is\n     * invoked for each element in `array` to generate the value to be summed.\n     * The iteratee is invoked with one argument: (value).\n     *\n     * @static\n     * @memberOf _\n     * @since 4.0.0\n     * @category Math\n     * @param {Array} array The array to iterate over.\n     * @param {Function} [iteratee=_.identity] The iteratee invoked per element.\n     * @returns {number} Returns the sum.\n     * @example\n     *\n     * var objects = [{ 'n': 4 }, { 'n': 2 }, { 'n': 8 }, { 'n': 6 }];\n     *\n     * _.sumBy(objects, function(o) { return o.n; });\n     * // => 20\n     *\n     * // The `_.property` iteratee shorthand.\n     * _.sumBy(objects, 'n');\n     * // => 20\n     */\n    function sumBy(array, iteratee) {\n      return (array && array.length)\n        ? baseSum(array, getIteratee(iteratee, 2))\n        : 0;\n    }\n\n    /*------------------------------------------------------------------------*/\n\n    // Add methods that return wrapped values in chain sequences.\n    lodash.after = after;\n    lodash.ary = ary;\n    lodash.assign = assign;\n    lodash.assignIn = assignIn;\n    lodash.assignInWith = assignInWith;\n    lodash.assignWith = assignWith;\n    lodash.at = at;\n    lodash.before = before;\n    lodash.bind = bind;\n    lodash.bindAll = bindAll;\n    lodash.bindKey = bindKey;\n    lodash.castArray = castArray;\n    lodash.chain = chain;\n    lodash.chunk = chunk;\n    lodash.compact = compact;\n    lodash.concat = concat;\n    lodash.cond = cond;\n    lodash.conforms = conforms;\n    lodash.constant = constant;\n    lodash.countBy = countBy;\n    lodash.create = create;\n    lodash.curry = curry;\n    lodash.curryRight = curryRight;\n    lodash.debounce = debounce;\n    lodash.defaults = defaults;\n    lodash.defaultsDeep = defaultsDeep;\n    lodash.defer = defer;\n    lodash.delay = delay;\n    lodash.difference = difference;\n    lodash.differenceBy = differenceBy;\n    lodash.differenceWith = differenceWith;\n    lodash.drop = drop;\n    lodash.dropRight = dropRight;\n    lodash.dropRightWhile = dropRightWhile;\n    lodash.dropWhile = dropWhile;\n    lodash.fill = fill;\n    lodash.filter = filter;\n    lodash.flatMap = flatMap;\n    lodash.flatMapDeep = flatMapDeep;\n    lodash.flatMapDepth = flatMapDepth;\n    lodash.flatten = flatten;\n    lodash.flattenDeep = flattenDeep;\n    lodash.flattenDepth = flattenDepth;\n    lodash.flip = flip;\n    lodash.flow = flow;\n    lodash.flowRight = flowRight;\n    lodash.fromPairs = fromPairs;\n    lodash.functions = functions;\n    lodash.functionsIn = functionsIn;\n    lodash.groupBy = groupBy;\n    lodash.initial = initial;\n    lodash.intersection = intersection;\n    lodash.intersectionBy = intersectionBy;\n    lodash.intersectionWith = intersectionWith;\n    lodash.invert = invert;\n    lodash.invertBy = invertBy;\n    lodash.invokeMap = invokeMap;\n    lodash.iteratee = iteratee;\n    lodash.keyBy = keyBy;\n    lodash.keys = keys;\n    lodash.keysIn = keysIn;\n    lodash.map = map;\n    lodash.mapKeys = mapKeys;\n    lodash.mapValues = mapValues;\n    lodash.matches = matches;\n    lodash.matchesProperty = matchesProperty;\n    lodash.memoize = memoize;\n    lodash.merge = merge;\n    lodash.mergeWith = mergeWith;\n    lodash.method = method;\n    lodash.methodOf = methodOf;\n    lodash.mixin = mixin;\n    lodash.negate = negate;\n    lodash.nthArg = nthArg;\n    lodash.omit = omit;\n    lodash.omitBy = omitBy;\n    lodash.once = once;\n    lodash.orderBy = orderBy;\n    lodash.over = over;\n    lodash.overArgs = overArgs;\n    lodash.overEvery = overEvery;\n    lodash.overSome = overSome;\n    lodash.partial = partial;\n    lodash.partialRight = partialRight;\n    lodash.partition = partition;\n    lodash.pick = pick;\n    lodash.pickBy = pickBy;\n    lodash.property = property;\n    lodash.propertyOf = propertyOf;\n    lodash.pull = pull;\n    lodash.pullAll = pullAll;\n    lodash.pullAllBy = pullAllBy;\n    lodash.pullAllWith = pullAllWith;\n    lodash.pullAt = pullAt;\n    lodash.range = range;\n    lodash.rangeRight = rangeRight;\n    lodash.rearg = rearg;\n    lodash.reject = reject;\n    lodash.remove = remove;\n    lodash.rest = rest;\n    lodash.reverse = reverse;\n    lodash.sampleSize = sampleSize;\n    lodash.set = set;\n    lodash.setWith = setWith;\n    lodash.shuffle = shuffle;\n    lodash.slice = slice;\n    lodash.sortBy = sortBy;\n    lodash.sortedUniq = sortedUniq;\n    lodash.sortedUniqBy = sortedUniqBy;\n    lodash.split = split;\n    lodash.spread = spread;\n    lodash.tail = tail;\n    lodash.take = take;\n    lodash.takeRight = takeRight;\n    lodash.takeRightWhile = takeRightWhile;\n    lodash.takeWhile = takeWhile;\n    lodash.tap = tap;\n    lodash.throttle = throttle;\n    lodash.thru = thru;\n    lodash.toArray = toArray;\n    lodash.toPairs = toPairs;\n    lodash.toPairsIn = toPairsIn;\n    lodash.toPath = toPath;\n    lodash.toPlainObject = toPlainObject;\n    lodash.transform = transform;\n    lodash.unary = unary;\n    lodash.union = union;\n    lodash.unionBy = unionBy;\n    lodash.unionWith = unionWith;\n    lodash.uniq = uniq;\n    lodash.uniqBy = uniqBy;\n    lodash.uniqWith = uniqWith;\n    lodash.unset = unset;\n    lodash.unzip = unzip;\n    lodash.unzipWith = unzipWith;\n    lodash.update = update;\n    lodash.updateWith = updateWith;\n    lodash.values = values;\n    lodash.valuesIn = valuesIn;\n    lodash.without = without;\n    lodash.words = words;\n    lodash.wrap = wrap;\n    lodash.xor = xor;\n    lodash.xorBy = xorBy;\n    lodash.xorWith = xorWith;\n    lodash.zip = zip;\n    lodash.zipObject = zipObject;\n    lodash.zipObjectDeep = zipObjectDeep;\n    lodash.zipWith = zipWith;\n\n    // Add aliases.\n    lodash.entries = toPairs;\n    lodash.entriesIn = toPairsIn;\n    lodash.extend = assignIn;\n    lodash.extendWith = assignInWith;\n\n    // Add methods to `lodash.prototype`.\n    mixin(lodash, lodash);\n\n    /*------------------------------------------------------------------------*/\n\n    // Add methods that return unwrapped values in chain sequences.\n    lodash.add = add;\n    lodash.attempt = attempt;\n    lodash.camelCase = camelCase;\n    lodash.capitalize = capitalize;\n    lodash.ceil = ceil;\n    lodash.clamp = clamp;\n    lodash.clone = clone;\n    lodash.cloneDeep = cloneDeep;\n    lodash.cloneDeepWith = cloneDeepWith;\n    lodash.cloneWith = cloneWith;\n    lodash.conformsTo = conformsTo;\n    lodash.deburr = deburr;\n    lodash.defaultTo = defaultTo;\n    lodash.divide = divide;\n    lodash.endsWith = endsWith;\n    lodash.eq = eq;\n    lodash.escape = escape;\n    lodash.escapeRegExp = escapeRegExp;\n    lodash.every = every;\n    lodash.find = find;\n    lodash.findIndex = findIndex;\n    lodash.findKey = findKey;\n    lodash.findLast = findLast;\n    lodash.findLastIndex = findLastIndex;\n    lodash.findLastKey = findLastKey;\n    lodash.floor = floor;\n    lodash.forEach = forEach;\n    lodash.forEachRight = forEachRight;\n    lodash.forIn = forIn;\n    lodash.forInRight = forInRight;\n    lodash.forOwn = forOwn;\n    lodash.forOwnRight = forOwnRight;\n    lodash.get = get;\n    lodash.gt = gt;\n    lodash.gte = gte;\n    lodash.has = has;\n    lodash.hasIn = hasIn;\n    lodash.head = head;\n    lodash.identity = identity;\n    lodash.includes = includes;\n    lodash.indexOf = indexOf;\n    lodash.inRange = inRange;\n    lodash.invoke = invoke;\n    lodash.isArguments = isArguments;\n    lodash.isArray = isArray;\n    lodash.isArrayBuffer = isArrayBuffer;\n    lodash.isArrayLike = isArrayLike;\n    lodash.isArrayLikeObject = isArrayLikeObject;\n    lodash.isBoolean = isBoolean;\n    lodash.isBuffer = isBuffer;\n    lodash.isDate = isDate;\n    lodash.isElement = isElement;\n    lodash.isEmpty = isEmpty;\n    lodash.isEqual = isEqual;\n    lodash.isEqualWith = isEqualWith;\n    lodash.isError = isError;\n    lodash.isFinite = isFinite;\n    lodash.isFunction = isFunction;\n    lodash.isInteger = isInteger;\n    lodash.isLength = isLength;\n    lodash.isMap = isMap;\n    lodash.isMatch = isMatch;\n    lodash.isMatchWith = isMatchWith;\n    lodash.isNaN = isNaN;\n    lodash.isNative = isNative;\n    lodash.isNil = isNil;\n    lodash.isNull = isNull;\n    lodash.isNumber = isNumber;\n    lodash.isObject = isObject;\n    lodash.isObjectLike = isObjectLike;\n    lodash.isPlainObject = isPlainObject;\n    lodash.isRegExp = isRegExp;\n    lodash.isSafeInteger = isSafeInteger;\n    lodash.isSet = isSet;\n    lodash.isString = isString;\n    lodash.isSymbol = isSymbol;\n    lodash.isTypedArray = isTypedArray;\n    lodash.isUndefined = isUndefined;\n    lodash.isWeakMap = isWeakMap;\n    lodash.isWeakSet = isWeakSet;\n    lodash.join = join;\n    lodash.kebabCase = kebabCase;\n    lodash.last = last;\n    lodash.lastIndexOf = lastIndexOf;\n    lodash.lowerCase = lowerCase;\n    lodash.lowerFirst = lowerFirst;\n    lodash.lt = lt;\n    lodash.lte = lte;\n    lodash.max = max;\n    lodash.maxBy = maxBy;\n    lodash.mean = mean;\n    lodash.meanBy = meanBy;\n    lodash.min = min;\n    lodash.minBy = minBy;\n    lodash.stubArray = stubArray;\n    lodash.stubFalse = stubFalse;\n    lodash.stubObject = stubObject;\n    lodash.stubString = stubString;\n    lodash.stubTrue = stubTrue;\n    lodash.multiply = multiply;\n    lodash.nth = nth;\n    lodash.noConflict = noConflict;\n    lodash.noop = noop;\n    lodash.now = now;\n    lodash.pad = pad;\n    lodash.padEnd = padEnd;\n    lodash.padStart = padStart;\n    lodash.parseInt = parseInt;\n    lodash.random = random;\n    lodash.reduce = reduce;\n    lodash.reduceRight = reduceRight;\n    lodash.repeat = repeat;\n    lodash.replace = replace;\n    lodash.result = result;\n    lodash.round = round;\n    lodash.runInContext = runInContext;\n    lodash.sample = sample;\n    lodash.size = size;\n    lodash.snakeCase = snakeCase;\n    lodash.some = some;\n    lodash.sortedIndex = sortedIndex;\n    lodash.sortedIndexBy = sortedIndexBy;\n    lodash.sortedIndexOf = sortedIndexOf;\n    lodash.sortedLastIndex = sortedLastIndex;\n    lodash.sortedLastIndexBy = sortedLastIndexBy;\n    lodash.sortedLastIndexOf = sortedLastIndexOf;\n    lodash.startCase = startCase;\n    lodash.startsWith = startsWith;\n    lodash.subtract = subtract;\n    lodash.sum = sum;\n    lodash.sumBy = sumBy;\n    lodash.template = template;\n    lodash.times = times;\n    lodash.toFinite = toFinite;\n    lodash.toInteger = toInteger;\n    lodash.toLength = toLength;\n    lodash.toLower = toLower;\n    lodash.toNumber = toNumber;\n    lodash.toSafeInteger = toSafeInteger;\n    lodash.toString = toString;\n    lodash.toUpper = toUpper;\n    lodash.trim = trim;\n    lodash.trimEnd = trimEnd;\n    lodash.trimStart = trimStart;\n    lodash.truncate = truncate;\n    lodash.unescape = unescape;\n    lodash.uniqueId = uniqueId;\n    lodash.upperCase = upperCase;\n    lodash.upperFirst = upperFirst;\n\n    // Add aliases.\n    lodash.each = forEach;\n    lodash.eachRight = forEachRight;\n    lodash.first = head;\n\n    mixin(lodash, (function() {\n      var source = {};\n      baseForOwn(lodash, function(func, methodName) {\n        if (!hasOwnProperty.call(lodash.prototype, methodName)) {\n          source[methodName] = func;\n        }\n      });\n      return source;\n    }()), { 'chain': false });\n\n    /*------------------------------------------------------------------------*/\n\n    /**\n     * The semantic version number.\n     *\n     * @static\n     * @memberOf _\n     * @type {string}\n     */\n    lodash.VERSION = VERSION;\n\n    // Assign default placeholders.\n    arrayEach(['bind', 'bindKey', 'curry', 'curryRight', 'partial', 'partialRight'], function(methodName) {\n      lodash[methodName].placeholder = lodash;\n    });\n\n    // Add `LazyWrapper` methods for `_.drop` and `_.take` variants.\n    arrayEach(['drop', 'take'], function(methodName, index) {\n      LazyWrapper.prototype[methodName] = function(n) {\n        n = n === undefined ? 1 : nativeMax(toInteger(n), 0);\n\n        var result = (this.__filtered__ && !index)\n          ? new LazyWrapper(this)\n          : this.clone();\n\n        if (result.__filtered__) {\n          result.__takeCount__ = nativeMin(n, result.__takeCount__);\n        } else {\n          result.__views__.push({\n            'size': nativeMin(n, MAX_ARRAY_LENGTH),\n            'type': methodName + (result.__dir__ < 0 ? 'Right' : '')\n          });\n        }\n        return result;\n      };\n\n      LazyWrapper.prototype[methodName + 'Right'] = function(n) {\n        return this.reverse()[methodName](n).reverse();\n      };\n    });\n\n    // Add `LazyWrapper` methods that accept an `iteratee` value.\n    arrayEach(['filter', 'map', 'takeWhile'], function(methodName, index) {\n      var type = index + 1,\n          isFilter = type == LAZY_FILTER_FLAG || type == LAZY_WHILE_FLAG;\n\n      LazyWrapper.prototype[methodName] = function(iteratee) {\n        var result = this.clone();\n        result.__iteratees__.push({\n          'iteratee': getIteratee(iteratee, 3),\n          'type': type\n        });\n        result.__filtered__ = result.__filtered__ || isFilter;\n        return result;\n      };\n    });\n\n    // Add `LazyWrapper` methods for `_.head` and `_.last`.\n    arrayEach(['head', 'last'], function(methodName, index) {\n      var takeName = 'take' + (index ? 'Right' : '');\n\n      LazyWrapper.prototype[methodName] = function() {\n        return this[takeName](1).value()[0];\n      };\n    });\n\n    // Add `LazyWrapper` methods for `_.initial` and `_.tail`.\n    arrayEach(['initial', 'tail'], function(methodName, index) {\n      var dropName = 'drop' + (index ? '' : 'Right');\n\n      LazyWrapper.prototype[methodName] = function() {\n        return this.__filtered__ ? new LazyWrapper(this) : this[dropName](1);\n      };\n    });\n\n    LazyWrapper.prototype.compact = function() {\n      return this.filter(identity);\n    };\n\n    LazyWrapper.prototype.find = function(predicate) {\n      return this.filter(predicate).head();\n    };\n\n    LazyWrapper.prototype.findLast = function(predicate) {\n      return this.reverse().find(predicate);\n    };\n\n    LazyWrapper.prototype.invokeMap = baseRest(function(path, args) {\n      if (typeof path == 'function') {\n        return new LazyWrapper(this);\n      }\n      return this.map(function(value) {\n        return baseInvoke(value, path, args);\n      });\n    });\n\n    LazyWrapper.prototype.reject = function(predicate) {\n      return this.filter(negate(getIteratee(predicate)));\n    };\n\n    LazyWrapper.prototype.slice = function(start, end) {\n      start = toInteger(start);\n\n      var result = this;\n      if (result.__filtered__ && (start > 0 || end < 0)) {\n        return new LazyWrapper(result);\n      }\n      if (start < 0) {\n        result = result.takeRight(-start);\n      } else if (start) {\n        result = result.drop(start);\n      }\n      if (end !== undefined) {\n        end = toInteger(end);\n        result = end < 0 ? result.dropRight(-end) : result.take(end - start);\n      }\n      return result;\n    };\n\n    LazyWrapper.prototype.takeRightWhile = function(predicate) {\n      return this.reverse().takeWhile(predicate).reverse();\n    };\n\n    LazyWrapper.prototype.toArray = function() {\n      return this.take(MAX_ARRAY_LENGTH);\n    };\n\n    // Add `LazyWrapper` methods to `lodash.prototype`.\n    baseForOwn(LazyWrapper.prototype, function(func, methodName) {\n      var checkIteratee = /^(?:filter|find|map|reject)|While$/.test(methodName),\n          isTaker = /^(?:head|last)$/.test(methodName),\n          lodashFunc = lodash[isTaker ? ('take' + (methodName == 'last' ? 'Right' : '')) : methodName],\n          retUnwrapped = isTaker || /^find/.test(methodName);\n\n      if (!lodashFunc) {\n        return;\n      }\n      lodash.prototype[methodName] = function() {\n        var value = this.__wrapped__,\n            args = isTaker ? [1] : arguments,\n            isLazy = value instanceof LazyWrapper,\n            iteratee = args[0],\n            useLazy = isLazy || isArray(value);\n\n        var interceptor = function(value) {\n          var result = lodashFunc.apply(lodash, arrayPush([value], args));\n          return (isTaker && chainAll) ? result[0] : result;\n        };\n\n        if (useLazy && checkIteratee && typeof iteratee == 'function' && iteratee.length != 1) {\n          // Avoid lazy use if the iteratee has a \"length\" value other than `1`.\n          isLazy = useLazy = false;\n        }\n        var chainAll = this.__chain__,\n            isHybrid = !!this.__actions__.length,\n            isUnwrapped = retUnwrapped && !chainAll,\n            onlyLazy = isLazy && !isHybrid;\n\n        if (!retUnwrapped && useLazy) {\n          value = onlyLazy ? value : new LazyWrapper(this);\n          var result = func.apply(value, args);\n          result.__actions__.push({ 'func': thru, 'args': [interceptor], 'thisArg': undefined });\n          return new LodashWrapper(result, chainAll);\n        }\n        if (isUnwrapped && onlyLazy) {\n          return func.apply(this, args);\n        }\n        result = this.thru(interceptor);\n        return isUnwrapped ? (isTaker ? result.value()[0] : result.value()) : result;\n      };\n    });\n\n    // Add `Array` methods to `lodash.prototype`.\n    arrayEach(['pop', 'push', 'shift', 'sort', 'splice', 'unshift'], function(methodName) {\n      var func = arrayProto[methodName],\n          chainName = /^(?:push|sort|unshift)$/.test(methodName) ? 'tap' : 'thru',\n          retUnwrapped = /^(?:pop|shift)$/.test(methodName);\n\n      lodash.prototype[methodName] = function() {\n        var args = arguments;\n        if (retUnwrapped && !this.__chain__) {\n          var value = this.value();\n          return func.apply(isArray(value) ? value : [], args);\n        }\n        return this[chainName](function(value) {\n          return func.apply(isArray(value) ? value : [], args);\n        });\n      };\n    });\n\n    // Map minified method names to their real names.\n    baseForOwn(LazyWrapper.prototype, function(func, methodName) {\n      var lodashFunc = lodash[methodName];\n      if (lodashFunc) {\n        var key = (lodashFunc.name + ''),\n            names = realNames[key] || (realNames[key] = []);\n\n        names.push({ 'name': methodName, 'func': lodashFunc });\n      }\n    });\n\n    realNames[createHybrid(undefined, WRAP_BIND_KEY_FLAG).name] = [{\n      'name': 'wrapper',\n      'func': undefined\n    }];\n\n    // Add methods to `LazyWrapper`.\n    LazyWrapper.prototype.clone = lazyClone;\n    LazyWrapper.prototype.reverse = lazyReverse;\n    LazyWrapper.prototype.value = lazyValue;\n\n    // Add chain sequence methods to the `lodash` wrapper.\n    lodash.prototype.at = wrapperAt;\n    lodash.prototype.chain = wrapperChain;\n    lodash.prototype.commit = wrapperCommit;\n    lodash.prototype.next = wrapperNext;\n    lodash.prototype.plant = wrapperPlant;\n    lodash.prototype.reverse = wrapperReverse;\n    lodash.prototype.toJSON = lodash.prototype.valueOf = lodash.prototype.value = wrapperValue;\n\n    // Add lazy aliases.\n    lodash.prototype.first = lodash.prototype.head;\n\n    if (symIterator) {\n      lodash.prototype[symIterator] = wrapperToIterator;\n    }\n    return lodash;\n  });\n\n  /*--------------------------------------------------------------------------*/\n\n  // Export lodash.\n  var _ = runInContext();\n\n  // Some AMD build optimizers, like r.js, check for condition patterns like:\n  if (typeof define == 'function' && typeof define.amd == 'object' && define.amd) {\n    // Expose Lodash on the global object to prevent errors when Lodash is\n    // loaded by a script tag in the presence of an AMD loader.\n    // See http://requirejs.org/docs/errors.html#mismatch for more details.\n    // Use `_.noConflict` to remove Lodash from the global object.\n    root._ = _;\n\n    // Define as an anonymous module so, through path mapping, it can be\n    // referenced as the \"underscore\" module.\n    define(function() {\n      return _;\n    });\n  }\n  // Check for `exports` after `define` in case a build optimizer adds it.\n  else if (freeModule) {\n    // Export for Node.js.\n    (freeModule.exports = _)._ = _;\n    // Export for CommonJS support.\n    freeExports._ = _;\n  }\n  else {\n    // Export to the global object.\n    root._ = _;\n  }\n}.call(this));\n","import hotkeys from 'hotkeys-js';\nimport _ from 'lodash'\nimport { eventNames } from 'cluster';\n\n//TODO: place this somewhere else, check for duplicates\nconst fabricCustomAttribute = ['id', 'sid', 'typeSID','filePath', 'palaceID']\nconst baseUrl = process.env.BASE_URL\n\nEnv = window.Env\n\nexport const getNewPalaceId = ()=>{\n  if (_.isUndefined(Env.db.lastPalaceID)) {\n    Env.db.lastPalaceID = 0\n  }\n  return Env.db.lastPalaceID++\n}\n\nexport const getAll = () => Env.db.palaceList\nexport const get = (id) => _.find(getAll(),  (palace) => palace.id ==  id)\nexport const create = (obj={}) => {\n  const palace = {\n    sequence: [], ...obj, id: getNewPalaceId()\n  }\n  Env.db.palaceList.push(palace)\n  return palace\n}\n\nexport const transformImagePath = (imageObjects)=> {\n  imageObjects.forEach((imageObject)=>{\n    const src = baseUrl + \"/public/img/original/\" + imageObject.filePath\n    imageObject.src = src\n  })\n}\n\nexport const load = (canvas, palace, cb=(()=>{})) => {\n  canvas.clear()\n  if (palace && palace.fabricObject) {\n    transformImagePath(palace.fabricObject.objects)\n    console.log(\"cb\", cb)\n    canvas.loadFromJSON(palace.fabricObject, cb)\n    if (!palace.viewportTransform) {\n      palace.viewportTransform = [1, 0, 0, 1, 0, 0]\n    }\n    canvas.setViewportTransform(palace.viewportTransform)\n  } else {\n    console.error(\"canvas is empty\")\n  }\n  Env.db.currentPalaceID = palace.id\n}\n\n// const loadPalace = (canvas, palace) => {\n//   canvas.clear()\n//   if (palace && palace.fabricObject) {\n//     const transformImagePath = (imageObjects)=> {\n//       imageObjects.forEach((imageObject)=>{\n//         imageObject.src = \"http://localhost:3050/public/img/original/\" + imageObject.filePath\n//         console.log(\"src\", imageObject)\n//       })\n//     }\n//     transformImagePath(palace.fabricObject.objects)\n//     canvas.loadFromJSON(palace.fabricObject)\n//     if (!palace.viewportTransform) {\n//       palace.viewportTransform = [1, 0, 0, 1, 0, 0]\n//     }\n//     canvas.setViewportTransform(palace.viewportTransform)\n//   } else {\n//     addSimpleObjects(canvas)\n//   }\n//   Env.db.currentPalaceID = palace.id\n// }\n\n\nexport const loadOrCreate = (canvas, palace) => {\n  if (palace) {\n    load(canvas, palace)\n  } else {\n    palace = create({name: 'new palace'})\n    load(canvas, palace)\n  }\n}\nexport const replaceCurrent = (palace) => {\n  saveCurrent()\n  load(Env.currentFabric, palace)\n}\n\n\nexport const getCurrent = () => {\n  const palace = get(Env.db.currentPalaceID)\n  if (palace) {\n    return palace\n  } else if (Env.db.palaceList.length > 1) {\n    return Env.db.palaceList[0]\n  } else {\n    return null\n  }\n}\nexport const saveCurrent = ()=> {\n  const palace = getCurrent()\n  if (palace) {\n    const savedFabric = Env.currentFabric.toJSON(fabricCustomAttribute)\n    palace.fabricObject = savedFabric\n    palace.viewportTransform = Env.currentFabric.viewportTransform\n  } else {\n    console.warn('No current palace')\n  }\n}\n\nexport const getSeed = ()=> _.find(getAll(), x=>x.name == \"seed-palace\")\n\n\nexport const activateSelection = ()=>{\n  Env.currentFabric.selection = true\n  Env.currentFabric.getObjects().forEach((object)=>{\n    object.set('selectable', true)\n  })\n}\nexport const deactivateSelection = ()=>{\n  console.log(\"desactivateSelection\")\n  Env.currentFabric.selection = false\n  Env.currentFabric.getObjects().forEach((object)=>{\n    object.set('selectable', false)\n  })\n}\nexport const checkSelection = () => {\n  if (hotkeys.isPressed('space') || hotkeys.isPressed('alt')){\n    deactivateSelection()\n  } else {\n    activateSelection()\n  }\n}","import $ from 'jquery'\n\n// ************\n// quick preview\n// ************\nlet $quickPreview\n\n\nexport const attach = () => {\n  $quickPreview = $(`<div class='goa-quickpreview'></div>`)\n  $quickPreview.css({\n    'position': 'absolute',\n    'display': 'flex',\n    'top': '0',\n    'align-items': 'center',\n    'justify-content': 'center',\n    'height': '100vh',\n    'width': '100vw',\n    'z-index': '9999999',\n    'pointer-events': 'none',\n  })\n  $(document.body).append($quickPreview)\n}\n\nlet t\nlet $el = $(`<div />`)\n\nexport const setObject = (obj) => {\n  // clearTimeout(t)\n  if (obj.typeSID === \"subject\") {\n    $el = $(`\n      <div>\n        ${obj.sid}\n      </div>`)\n  } else if (obj.src) {\n    $el = $(`<img src='${obj.src}' />`)\n    $el.css({\n      'max-height': '100%',\n      'max-width': '100%',\n      'border-radius': '5px',\n      'box-shadow': '3px 3px 50px rgba(0, 0, 0, .3)'\n    })\n    //TODO: set the classlink somewhere else\n    // $('.app-wrapper-overlay').fadeIn(100)\n    $('.app-wrapper-overlay').show()\n    $('.app-wrapper').css({\n      '-webkit-filter': 'blur(10px)'\n    })\n    $quickPreview.html($el)\n  }\n}\n\nexport const clear = () => {\n  //TODO: set the classlink somewhere else\n  // t = setTimeout(()=>{\n    // $el.fadeOut(100)\n    // $('.app-wrapper-overlay').fadeOut(100, ()=>{\n    $('.app-wrapper-overlay').hide()\n      $('.app-wrapper').css({\n        '-webkit-filter': ''\n      })\n      $quickPreview.html('')\n    // })\n  // }, 100)\n}\n\n","// Copyright Joyent, Inc. and other Node contributors.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a\n// copy of this software and associated documentation files (the\n// \"Software\"), to deal in the Software without restriction, including\n// without limitation the rights to use, copy, modify, merge, publish,\n// distribute, sublicense, and/or sell copies of the Software, and to permit\n// persons to whom the Software is furnished to do so, subject to the\n// following conditions:\n//\n// The above copyright notice and this permission notice shall be included\n// in all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS\n// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN\n// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,\n// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE\n// USE OR OTHER DEALINGS IN THE SOFTWARE.\n\n// resolves . and .. elements in a path array with directory names there\n// must be no slashes, empty elements, or device names (c:\\) in the array\n// (so also no leading and trailing slashes - it does not distinguish\n// relative and absolute paths)\nfunction normalizeArray(parts, allowAboveRoot) {\n  // if the path tries to go above the root, `up` ends up > 0\n  var up = 0;\n  for (var i = parts.length - 1; i >= 0; i--) {\n    var last = parts[i];\n    if (last === '.') {\n      parts.splice(i, 1);\n    } else if (last === '..') {\n      parts.splice(i, 1);\n      up++;\n    } else if (up) {\n      parts.splice(i, 1);\n      up--;\n    }\n  }\n\n  // if the path is allowed to go above the root, restore leading ..s\n  if (allowAboveRoot) {\n    for (; up--; up) {\n      parts.unshift('..');\n    }\n  }\n\n  return parts;\n}\n\n// Split a filename into [root, dir, basename, ext], unix version\n// 'root' is just a slash, or nothing.\nvar splitPathRe =\n    /^(\\/?|)([\\s\\S]*?)((?:\\.{1,2}|[^\\/]+?|)(\\.[^.\\/]*|))(?:[\\/]*)$/;\nvar splitPath = function(filename) {\n  return splitPathRe.exec(filename).slice(1);\n};\n\n// path.resolve([from ...], to)\n// posix version\nexports.resolve = function() {\n  var resolvedPath = '',\n      resolvedAbsolute = false;\n\n  for (var i = arguments.length - 1; i >= -1 && !resolvedAbsolute; i--) {\n    var path = (i >= 0) ? arguments[i] : process.cwd();\n\n    // Skip empty and invalid entries\n    if (typeof path !== 'string') {\n      throw new TypeError('Arguments to path.resolve must be strings');\n    } else if (!path) {\n      continue;\n    }\n\n    resolvedPath = path + '/' + resolvedPath;\n    resolvedAbsolute = path.charAt(0) === '/';\n  }\n\n  // At this point the path should be resolved to a full absolute path, but\n  // handle relative paths to be safe (might happen when process.cwd() fails)\n\n  // Normalize the path\n  resolvedPath = normalizeArray(filter(resolvedPath.split('/'), function(p) {\n    return !!p;\n  }), !resolvedAbsolute).join('/');\n\n  return ((resolvedAbsolute ? '/' : '') + resolvedPath) || '.';\n};\n\n// path.normalize(path)\n// posix version\nexports.normalize = function(path) {\n  var isAbsolute = exports.isAbsolute(path),\n      trailingSlash = substr(path, -1) === '/';\n\n  // Normalize the path\n  path = normalizeArray(filter(path.split('/'), function(p) {\n    return !!p;\n  }), !isAbsolute).join('/');\n\n  if (!path && !isAbsolute) {\n    path = '.';\n  }\n  if (path && trailingSlash) {\n    path += '/';\n  }\n\n  return (isAbsolute ? '/' : '') + path;\n};\n\n// posix version\nexports.isAbsolute = function(path) {\n  return path.charAt(0) === '/';\n};\n\n// posix version\nexports.join = function() {\n  var paths = Array.prototype.slice.call(arguments, 0);\n  return exports.normalize(filter(paths, function(p, index) {\n    if (typeof p !== 'string') {\n      throw new TypeError('Arguments to path.join must be strings');\n    }\n    return p;\n  }).join('/'));\n};\n\n\n// path.relative(from, to)\n// posix version\nexports.relative = function(from, to) {\n  from = exports.resolve(from).substr(1);\n  to = exports.resolve(to).substr(1);\n\n  function trim(arr) {\n    var start = 0;\n    for (; start < arr.length; start++) {\n      if (arr[start] !== '') break;\n    }\n\n    var end = arr.length - 1;\n    for (; end >= 0; end--) {\n      if (arr[end] !== '') break;\n    }\n\n    if (start > end) return [];\n    return arr.slice(start, end - start + 1);\n  }\n\n  var fromParts = trim(from.split('/'));\n  var toParts = trim(to.split('/'));\n\n  var length = Math.min(fromParts.length, toParts.length);\n  var samePartsLength = length;\n  for (var i = 0; i < length; i++) {\n    if (fromParts[i] !== toParts[i]) {\n      samePartsLength = i;\n      break;\n    }\n  }\n\n  var outputParts = [];\n  for (var i = samePartsLength; i < fromParts.length; i++) {\n    outputParts.push('..');\n  }\n\n  outputParts = outputParts.concat(toParts.slice(samePartsLength));\n\n  return outputParts.join('/');\n};\n\nexports.sep = '/';\nexports.delimiter = ':';\n\nexports.dirname = function(path) {\n  var result = splitPath(path),\n      root = result[0],\n      dir = result[1];\n\n  if (!root && !dir) {\n    // No dirname whatsoever\n    return '.';\n  }\n\n  if (dir) {\n    // It has a dirname, strip trailing slash\n    dir = dir.substr(0, dir.length - 1);\n  }\n\n  return root + dir;\n};\n\n\nexports.basename = function(path, ext) {\n  var f = splitPath(path)[2];\n  // TODO: make this comparison case-insensitive on windows?\n  if (ext && f.substr(-1 * ext.length) === ext) {\n    f = f.substr(0, f.length - ext.length);\n  }\n  return f;\n};\n\n\nexports.extname = function(path) {\n  return splitPath(path)[3];\n};\n\nfunction filter (xs, f) {\n    if (xs.filter) return xs.filter(f);\n    var res = [];\n    for (var i = 0; i < xs.length; i++) {\n        if (f(xs[i], i, xs)) res.push(xs[i]);\n    }\n    return res;\n}\n\n// String.prototype.substr - negative index don't work in IE8\nvar substr = 'ab'.substr(-1) === 'b'\n    ? function (str, start, len) { return str.substr(start, len) }\n    : function (str, start, len) {\n        if (start < 0) start = str.length + start;\n        return str.substr(start, len);\n    }\n;\n","/* @flow */\n/*::\n\ntype DotenvParseOptions = {\n  debug?: boolean\n}\n\n// keys and values from src\ntype DotenvParseOutput = { [string]: string }\n\ntype DotenvConfigOptions = {\n  path?: string, // path to .env file\n  encoding?: string, // encoding of .env file\n  debug?: string // turn on logging for debugging purposes\n}\n\ntype DotenvConfigOutput = {\n  parsed?: DotenvParseOutput,\n  error?: Error\n}\n\n*/\n\nconst fs = require('fs')\nconst path = require('path')\n\nfunction log (message /*: string */) {\n  console.log(`[dotenv][DEBUG] ${message}`)\n}\n\n// Parses src into an Object\nfunction parse (src /*: string | Buffer */, options /*: ?DotenvParseOptions */) /*: DotenvParseOutput */ {\n  const debug = Boolean(options && options.debug)\n  const obj = {}\n\n  // convert Buffers before splitting into lines and processing\n  src.toString().split('\\n').forEach(function (line, idx) {\n    // matching \"KEY' and 'VAL' in 'KEY=VAL'\n    const keyValueArr = line.match(/^\\s*([\\w.-]+)\\s*=\\s*(.*)?\\s*$/)\n    // matched?\n    if (keyValueArr != null) {\n      const key = keyValueArr[1]\n\n      // default undefined or missing values to empty string\n      let value = keyValueArr[2] || ''\n\n      // expand newlines in quoted values\n      const len = value ? value.length : 0\n      if (len > 0 && value.charAt(0) === '\"' && value.charAt(len - 1) === '\"') {\n        value = value.replace(/\\\\n/gm, '\\n')\n      }\n\n      // remove any surrounding quotes and extra spaces\n      value = value.replace(/(^['\"]|['\"]$)/g, '').trim()\n\n      obj[key] = value\n    } else if (debug) {\n      log(`did not match key and value when parsing line ${idx + 1}: ${line}`)\n    }\n  })\n\n  return obj\n}\n\n// Populates process.env from .env file\nfunction config (options /*: ?DotenvConfigOptions */) /*: DotenvConfigOutput */ {\n  let dotenvPath = path.resolve(process.cwd(), '.env')\n  let encoding /*: string */ = 'utf8'\n  let debug = false\n\n  if (options) {\n    if (options.path != null) {\n      dotenvPath = options.path\n    }\n    if (options.encoding != null) {\n      encoding = options.encoding\n    }\n    if (options.debug != null) {\n      debug = true\n    }\n  }\n\n  try {\n    // specifying an encoding returns a string instead of a buffer\n    const parsed = parse(fs.readFileSync(dotenvPath, { encoding }), { debug })\n\n    Object.keys(parsed).forEach(function (key) {\n      if (!process.env.hasOwnProperty(key)) {\n        process.env[key] = parsed[key]\n      } else if (debug) {\n        log(`\"${key}\" is already defined in \\`process.env\\` and will not be overwritten`)\n      }\n    })\n\n    return { parsed }\n  } catch (e) {\n    return { error: e }\n  }\n}\n\nmodule.exports.config = config\nmodule.exports.load = config\nmodule.exports.parse = parse\n","const Env = {db:{}}\nwindow.Env = Env\n\nimport $ from 'jquery'\nimport _ from 'lodash'\n\nimport 'jquery.fancytree/dist/skin-lion/ui.fancytree.css';  // CSS or LESS\n\nimport {createTree} from 'jquery.fancytree';\n\nimport 'jquery.fancytree/dist/modules/jquery.fancytree.edit';\nimport 'jquery.fancytree/dist/modules/jquery.fancytree.filter';\n\n\nimport {fabric} from 'fabric'\nimport * as dat from 'dat.gui'\nimport FuzzySearch from 'fuzzy-search';\nimport { Draggable } from '@shopify/draggable';\nimport {fromEvent, pipe} from 'rxjs';\nimport { map, filter, switchMap,take, takeUntil, skipUntil, mergeMap} from 'rxjs/operators';\nimport ee from 'event-emitter'\n\nimport * as Palace from './models/palace'\n\nimport * as quickpreview from './tools/quickpreview'\n\nrequire('dotenv').load()\n\nquickpreview.attach()\n\n// golden-layout need to have jquery in the window context.\n// TODO: solve this issue better\nwindow.$ = $\nwindow.jQuery = $\n\nimport './styles/base.styl'\n\n// import React from \"react\"\n// import ReactDOM from \"react-dom\"\n// window.React = React\n// window.ReactDOM = ReactDOM\n\nimport hotkeys from 'hotkeys-js';\nhotkeys()\n\n\nconst baseUrl = process.env.BASE_URL\n\n\n\n// ************\n// palace functions\n// ************\n\n// const getPalace = (id) => {\n//   return Env.db.palaceList.find( (palace) => palace.id ==  id)\n// }\n// const getCurrentPalace = () => {\n//   const palace = getPalace(Env.db.currentPalaceID)\n//   if (palace) {\n//     return palace\n//   } else if (Env.db.palaceList.length > 1) {\n//     return Env.db.palaceList[0]\n//   } else {\n//     return null\n//   }\n// }\n\n\n\n\n\nlet currentCanvasTarget\nconst checkCanvasForPreview = (shift) => {\n  if (currentCanvasTarget && currentCanvasTarget.src && shift) {\n    quickpreview.setObject(currentCanvasTarget)\n  } else {\n    quickpreview.clear()\n  }\n}\n$(document).on('keydown', (e)=>{\n  console.log(\"checking\", e.originalEvent.code === 'ShiftLeft' || e.originalEvent.code === 'ShiftRight')\n  if (e.originalEvent.code === 'ShiftLeft' || e.originalEvent.code === 'ShiftRight') {\n    checkCanvasForPreview(true)\n  }\n})\n$(document).on('keyup', (e)=>{\n  if (e.originalEvent.code === 'ShiftLeft' || e.originalEvent.code === 'ShiftRight') {\n    quickpreview.clear()\n  }\n})\nconst loadCanva = () => {\n\n  const height = window.innerHeight\n  const width = window.innerWidth\n  const canvasElement = document.createElement('canvas')\n  $('.app-wrapper').html(canvasElement)\n  const canvas = new fabric.Canvas(canvasElement);\n  // $(document.body).html(canvasElement)\n  canvas.on('mouse:over', function(e) {\n    // debugger\n    currentCanvasTarget = e.target\n    checkCanvasForPreview(hotkeys.isPressed('shift'))\n    canvas.renderAll();\n  });\n\n  canvas.on('mouse:out', function(e) {\n    currentCanvasTarget = undefined\n    quickpreview.clear()\n  })\n\n  const render = () => {\n    canvas.setHeight(height);\n    canvas.setWidth(width);\n    canvas.renderAll()\n  }\n  render()\n  // TODO: resize canva onresize window\n\n\n  const startZoomOffset = {}\n  let startZoomOn = false\n  let startZoom = 1\n\n  return {\n    canvasElement: canvasElement,\n    canvas: canvas,\n  }\n}\nconst {canvas} = loadCanva()\nEnv.currentFabric = canvas\n\nconst renderPalace = (palaceName) => {\n  // should fetch storage.inspiration.goa.io/p/{palaceName}\n  // but now for testing purpose, get all the from storage.inspiration.goa.io\n  fetch(`${baseUrl}/public/palaces/${palaceName}.json?${Date.now()}`, {cache: \"no-store\"}).then((res)=>{\n    return res.json()\n  }).then((palace)=>{\n    // const palace = db.palaceList.find((palace)=>palace.name === palaceName)\n    // console.log(\"palacel, palace\", palace)\n    console.log(\"load canvas\")\n    Palace.load(canvas, palace, ()=>{\n      Palace.deactivateSelection()\n    })\n    canvas.selection = false\n    // console.log(\"canvas\")\n    canvas.getObjects().forEach(x=>x.set('selectable', false))\n    // loadPalace(canvas, palace)\n\n  })\n}\nconst url = new URL(location);\nconst palace = url.searchParams.get(\"palace\")\nrenderPalace(palace)\n\n// // ************\n// // quick preview\n// // ************\n// let $quickPreview\n// $quickPreview = $(`<div class='quickpreview'></div>`)\n// $quickPreview.css({\n//   'position': 'absolute',\n//   'top': 1,\n//   'display': 'flex',\n//   'align-items': 'center',\n//   'justify-content': 'center',\n//   'height': '100vh',\n//   'width': '100vw',\n//   'z-index': '9999999',\n//   'pointer-events': 'none',\n// })\n// const $body = $(document.body)\n// $body.append($quickPreview)\n// $body.css({\n//   'overflow': 'hidden',\n//   'background': '#faf8f5'\n// })\n\n\n// const setQuickPreview = (src) => {\n//   console.log('setQuickPreview', src)\n//   const $img = $(`<img src='${src}' />`)\n//   $img.css({\n//     'max-height': '100%',\n//     'max-width': '100%',\n//     'border-radius': '5px',\n//   })\n//   $('.lm_goldenlayout').css({'-webkit-filter': 'blur(10px)'})\n//   $quickPreview.html($img)\n// }\n// const clearQuickPreview = () => {\n//   $('.lm_goldenlayout').css({'-webkit-filter': ''})\n//   $quickPreview.html('')\n// }"]}