{"version":3,"sources":["node_modules/muuri/dist/muuri.module.js","src/utils/muuri-interface.ts"],"names":["GRID_INSTANCES","ITEM_ELEMENT_MAP","Map","ACTION_SWAP","ACTION_MOVE","EVENT_SYNCHRONIZE","EVENT_LAYOUT_START","EVENT_LAYOUT_END","EVENT_LAYOUT_ABORT","EVENT_ADD","EVENT_REMOVE","EVENT_SHOW_START","EVENT_SHOW_END","EVENT_HIDE_START","EVENT_HIDE_END","EVENT_FILTER","EVENT_SORT","EVENT_MOVE","EVENT_SEND","EVENT_BEFORE_SEND","EVENT_RECEIVE","EVENT_BEFORE_RECEIVE","EVENT_DRAG_INIT","EVENT_DRAG_START","EVENT_DRAG_MOVE","EVENT_DRAG_SCROLL","EVENT_DRAG_END","EVENT_DRAG_RELEASE_START","EVENT_DRAG_RELEASE_END","EVENT_DESTROY","HAS_TOUCH_EVENTS","window","HAS_POINTER_EVENTS","PointerEvent","HAS_MS_POINTER_EVENTS","navigator","msPointerEnabled","MAX_SAFE_FLOAT32_INTEGER","Emitter","this","_events","_queue","_counter","_clearOnEmit","prototype","on","event","listener","listeners","push","off","length","index","indexOf","splice","clear","emit","queue","startIndex","argsLength","arguments","args","apply","shift","i","endIndex","burst","countListeners","destroy","pointerout","waitDuration","EdgeHack","dragger","_dragger","_timeout","_outEvent","_isActive","_addBehaviour","bind","_removeBehaviour","_onTimeout","_resetData","_onStart","_onOut","addEventListener","removeEventListener","clearTimeout","e","pointerType","_getTrackedTouch","setTimeout","isActive","_onCancel","vendorPrefixes","cache$2","getPrefixedPropName","style","prop","prefixedProp","camelProp","toUpperCase","slice","hasPassiveEvents","isPassiveEventsSupported","passiveOpts","Object","defineProperty","get","ua","userAgent","toLowerCase","isEdge","isIE","isFirefox","isAndroid","listenerOptions","passive","taProp","taPropPrefixed","document","documentElement","taDefaultValue","Dragger","element","cssProps","_element","_emitter","_isDestroyed","_cssProps","_touchAction","_pointerId","_startTime","_startX","_startY","_currentX","_currentY","_onMove","_onEnd","_edgeHack","setCssProps","setTouchAction","_preventDefault","_inputEvents","start","_pointerEvents","move","cancel","end","_msPointerEvents","_touchEvents","_mouseEvents","_emitterEvents","_activeInstances","preventDefault","cancelable","_activateInstance","instance","_bindListeners","_deactivateInstance","_unbindListeners","_getEventPointerId","pointerId","changedTouches","identifier","_getTouchById","id","_reset","_createEvent","type","touch","srcEvent","distance","getDistance","deltaX","getDeltaX","deltaY","getDeltaY","deltaTime","getDeltaTime","isFirst","isFinal","touches","screenX","screenY","clientX","clientY","pageX","pageY","target","_emit","Date","now","value","newProps","currentProps","x","y","Math","sqrt","eventName","dt","raf","requestAnimationFrame","webkitRequestAnimationFrame","mozRequestAnimationFrame","msRequestAnimationFrame","callback","Ticker","numLanes","_nextStep","_lanes","_stepQueue","_stepCallbacks","_step","TickerLane","time","lanes","stepQueue","stepCallbacks","j","laneQueue","laneCallbacks","laneIndices","callbacks","indices","add","laneIndex","remove","undefined","LAYOUT_READ","LAYOUT_WRITE","VISIBILITY_READ","VISIBILITY_WRITE","DRAG_START_READ","DRAG_START_WRITE","DRAG_MOVE_READ","DRAG_MOVE_WRITE","DRAG_SCROLL_READ","DRAG_SCROLL_WRITE","DRAG_SORT_READ","PLACEHOLDER_LAYOUT_READ","PLACEHOLDER_LAYOUT_WRITE","PLACEHOLDER_RESIZE_WRITE","AUTO_SCROLL_READ","AUTO_SCROLL_WRITE","DEBOUNCE_READ","LANE_READ","LANE_READ_TAIL","LANE_WRITE","ticker","addLayoutTick","itemId","read","write","cancelLayoutTick","addVisibilityTick","cancelVisibilityTick","addDragStartTick","cancelDragStartTick","addDragMoveTick","cancelDragMoveTick","addDragScrollTick","cancelDragScrollTick","addDragSortTick","cancelDragSortTick","addPlaceholderLayoutTick","cancelPlaceholderLayoutTick","addPlaceholderResizeTick","cancelPlaceholderResizeTick","addAutoScrollTick","cancelAutoScrollTick","addDebounceTick","debounceId","cancelDebounceTick","AXIS_X","AXIS_Y","FORWARD","BACKWARD","LEFT","RIGHT","UP","DOWN","functionType","isFunction","val","cache$1","WeakMap","getStyle","styles","getComputedStyle","set","getPropertyValue","getStyleAsFloat","el","parseFloat","DOC_ELEM","BODY","body","THRESHOLD_DATA","offset","getScrollElement","getScrollLeft","pageXOffset","scrollLeft","getScrollTop","pageYOffset","scrollTop","getScrollLeftMax","scrollWidth","clientWidth","getScrollTopMax","scrollHeight","clientHeight","getContentRect","result","width","height","left","right","top","bottom","bcr","getBoundingClientRect","borderLeft","clientLeft","borderTop","clientTop","getItemAutoScrollSettings","item","_drag","_getGrid","_settings","dragAutoScroll","prepareItemScrollSync","_prepareScroll","applyItemScrollSync","drag","_scrollDiffX","_scrollDiffY","_setTranslate","_left","_top","computeThreshold","threshold","safeZone","itemSize","targetSize","min","max","ScrollRequest","reset","onStop","isEnding","direction","maxValue","speed","duration","action","hasReachedEnd","computeCurrentScrollValue","computeNextScrollValue","delta","nextValue","computeSpeed","data","tick","onStart","sort","ScrollAction","requestX","requestY","addRequest","request","removeRequest","computeScrollValues","scroll","scrollTo","Pool","createItem","releaseItem","pool","pick","pop","release","isOverlapping","a","b","getIntersectionArea","getIntersectionScore","area","maxArea","RECT_1","RECT_2","AutoScroller","_isTicking","_tickTime","_tickDeltaTime","_items","_actions","_requests","_requestOverlapCheck","_dragPositions","_dragDirections","_overlapCheckInterval","_requestPool","_actionPool","_readTick","_writeTick","smoothSpeed","maxSpeed","acceleration","deceleration","targetSpeed","factor","currentSpeed","nextSpeed","pointerHandle","pointerSize","rect","size","w","h","pX","pY","_updateRequests","_updateActions","_applyActions","_startTicking","_stopTicking","_getItemHandleRect","handle","itemDrag","ev","_dragMoveEvent","_dragStartEvent","_clientX","_clientY","_width","_height","_requestItemScroll","axis","reqMap","_id","_cancelItemScroll","_checkItemOverlap","checkX","checkY","settings","targets","dragDirections","dragDirectionX","dragDirectionY","itemRect","testRect","testElement","testAxisX","testAxisY","testScore","testPriority","testThreshold","testDirection","testDistance","testMaxScrollX","testMaxScrollY","xElement","xPriority","Infinity","xThreshold","xScore","xDirection","xDistance","xMaxScroll","yElement","yPriority","yThreshold","yScore","yDirection","yDistance","yMaxScroll","priority","_updateScrollRequest","scrollRequest","targetCount","testIsAxisX","testScroll","testMaxScroll","smoothStop","items","requestsX","requestsY","reqX","reqY","checkTime","needsCheck","_requestAction","actions","isAxisX","requests","_updateDragDirection","dragPositions","x1","y1","x2","y2","addItem","updateItem","removeItem","isItemScrollingX","isItemScrollingY","isItemScrolling","ElProto","Element","matchesFn","matches","matchesSelector","webkitMatchesSelector","mozMatchesSelector","msMatchesSelector","oMatchesSelector","elementMatches","selector","call","addClass","className","classList","tempArray","numberType","arrayInsert","array","concat","normalizeArrayIndex","sizeOffset","maxIndex","arrayMove","fromIndex","toIndex","from","to","arraySwap","withIndex","indexA","indexB","temp","transformProp","styleNameRegEx","prefixRegex","msPrefixRegex","getStyleName","property","styleName","replace","transformStyle","transformNone$1","displayInline","displayNone","displayStyle","isTransformed","transform","display","getContainingBlock","doc","res","parentElement","offsetA","offsetB","offsetDiff","getOffset","offsetData","self","getOffsetDiff","elemA","elemB","compareContainingBlocks","isScrollableOverflow","isScrollable","getScrollableAncestors","getRootNode","DocumentFragment","host","parentNode","translateValue","transformNone","rxMat3d","rxMatTx","rxMat3dTx","rxNextItem","getTranslate","isMat3d","test","tX","tY","removeClass","trim","IS_IOS","platform","maxTouchPoints","START_PREDICATE_INACTIVE","START_PREDICATE_PENDING","START_PREDICATE_RESOLVED","SCROLL_LISTENER_OPTIONS","ItemDrag","grid","getGrid","_item","_gridId","_isMigrating","_startPredicate","dragStartPredicate","defaultStartPredicate","_startPredicateState","_startPredicateResult","_isSortNeeded","_sortTimer","_blockedSortIndex","_sortX1","_sortX2","_sortY1","_sortY2","_preStartCheck","_preEndCheck","_onScroll","_prepareStart","_applyStart","_prepareMove","_applyMove","_applyScroll","_handleSort","_handleSortDelayed","_handle","dragHandle","querySelector","dragCssProps","autoScroller","options","button","isTrusted","defaultPrevented","_finishStartPredicate","predicate","_startPredicateData","config","delay","delayTimer","_resolveStartPredicate","_forceResolveStartPredicate","_resetStartPredicate","defaultSortPredicate","targetRect","returnData","gridsArray","minThreshold","maxThreshold","getTargetGrid","rootGrid","dragSort","bestScore","gridScore","grids","container","containerRect","Array","isArray","_updateBoundingRect","innerWidth","_right","innerHeight","_bottom","sortThreshold","sortAction","migrateAction","isMigration","gridOffsetLeft","gridOffsetTop","matchScore","matchIndex","hasValidTargets","score","_gridX","_marginLeft","_gridY","_marginTop","_updateBorders","_borderLeft","_borderTop","stop","_finishMigration","_cancelSort","_isStarted","_unbindScrollListeners","draggingClass","itemDraggingClass","appendChild","force","_container","_containingBlock","_dragPrevMoveEvent","_scrollEvent","_scrollers","_moveDiffX","_moveDiffY","_containerDiffX","_containerDiffY","_bindScrollListeners","gridContainer","dragContainer","scrollers","gridScrollers","isClick","abs","openAnchorHref","_resetHeuristics","_checkHeuristics","dragSortHeuristics","minDist","minDragDistance","diffX","diffY","canCheckBounceBack","minBounceBackAngle","angle","atan2","prevAngle","deltaAngle","sin","cos","sortDuringScroll","shouldSort","sortInterval","_checkOverlap","_finishSort","isSortEnabled","needsFinalCheck","currentGrid","currentIndex","targetGrid","targetIndex","targetItem","dragSortPredicate","_hasListeners","layout","fromGrid","toGrid","_sortData","send","appendTo","layoutSender","layoutReceiver","_dragRelease","targetGridElement","targetSettings","targetContainer","currentSettings","currentContainer","currentVisClass","itemVisibleClass","itemHiddenClass","nextVisClass","translate","itemClass","_refreshDimensions","dragEnabled","_visibility","setStyles","visibleStyles","hiddenStyles","isResolved","containingBlock","elementRect","hasDragContainer","migrate","_migrate","isPositioning","_layout","isReleasing","dragPlaceholder","enabled","_dragPlaceholder","create","dragAxis","nextEvent","prevEvent","moveDiffX","moveDiffY","scrollDiffX","scrollDiffY","tagName","href","getAttribute","open","location","getCurrentStyles","unprefixRegEx","cache","getUnprefixedPropName","nativeCode","isNative","feat","S","Symbol","toString","HAS_WEB_ANIMATIONS","animate","HAS_NATIVE_WEB_ANIMATIONS","Animator","_animation","_duration","_easing","_callback","_props","_values","_onFinish","propsFrom","propsTo","opts","onFinish","animation","currentValues","easing","cancelAnimation","propName","propCount","propIndex","createFrame","onfinish","isAnimating","props","prefix","frame","getTranslateString","ItemDragPlaceholder","_className","_didMigrate","_resetAfterLayout","_transX","_transY","_nextTransX","_nextTransY","_setupAnimation","_startAnimation","_updateDimensions","_onLayoutStart","_onLayoutEnd","_onReleaseEnd","_onMigrate","_onHide","isInstant","nextLeft","nextTop","currentLeft","currentTop","nextX","nextY","animEnabled","layoutDuration","getElement","currentX","currentY","currentStyles","targetStyles","layoutEasing","nextGrid","createElement","itemPlaceholderClass","position","onCreate","removeChild","onRemove","updateDimensions","ItemDragRelease","_isPositioningStarted","itemReleasingClass","dragRelease","useDragContainer","_placeToGrid","_nextLayoutData","abort","didReparent","isJustReleased","needsReflow","releasingClass","MIN_ANIMATION_DISTANCE","ItemLayout","elementStyle","_isInterrupted","_currentStyles","_targetStyles","_nextLeft","_nextTop","_offsetLeft","_offsetTop","_skipNextAnimation","_animOptions","_finish","instant","gridSettings","animDuration","animEasing","_updateOffsets","processCallbackQueue","itemPositioningClass","_tX","_tY","xDiff","yDiff","ItemMigrate","isVisible","targetElement","targetItems","containerDiff","translateX","translateY","getItem","gridElement","ItemVisibility","childElement","children","Error","_isHidden","_isHiding","_isShowing","_childElement","_currentStyleProps","_finishShow","_finishHide","show","hide","currentStyleProps","_removeCurrentStyles","toVisible","showDuration","hideDuration","showEasing","hideEasing","createUid","Item","has","_marginRight","_marginBottom","getWidth","getHeight","getMargin","getPosition","isShowing","isHiding","isDragging","isDestroyed","_refreshSortData","getters","sortData","_addToLayout","_removeFromLayout","_canSkipLayout","_destroy","removeElement","delete","createPackerProcessor","isWorker","FILL_GAPS","HORIZONTAL","ALIGN_RIGHT","ALIGN_BOTTOM","ROUNDING","EPS","MIN_SLOT_SIZE","roundNumber","number","PackerProcessor","currentRects","nextRects","rectTarget","rectStore","slotSizes","rectId","slotIndex","slotData","sortRectsLeftTop","sortRectsTopLeft","computeLayout","slots","fillGaps","horizontal","alignRight","alignBottom","rounding","isPreProcessed","bump","slotWidth","slotHeight","slot","computeNextSlot","ignoreCurrentRects","shards","getRect","addRect","splitRect","purgeRects","hole","isRectAWithinRectB","rectA","rectB","rectIds","aId","bId","PACKET_INDEX_WIDTH","PACKET_INDEX_HEIGHT","PACKET_INDEX_OPTIONS","PACKET_HEADER_SLOTS","processor","onmessage","msg","Float32Array","subarray","postMessage","buffer","blobUrl","activeWorkers","createWorkerProcessors","amount","workers","URL","createObjectURL","Blob","worker","Worker","destroyWorkerProcessors","onerror","onmessageerror","terminate","revokeObjectURL","isWorkerProcessorsSupported","PACKET_INDEX_ID","Packer","numWorkers","_options","_processor","_layoutQueue","_layouts","_layoutCallbacks","_layoutWorkers","_layoutWorkerData","_workers","_onWorkerMessage","setOptions","_sendToWorker","layoutId","_finalizeLayout","_grid","isHorizontal","isBorderBox","_boxSizing","_borderRight","_borderBottom","createLayout","cancelLayout","queueIndex","key","debounce","fn","durationMs","timer","lastTime","isCanceled","htmlCollectionType","nodeListType","isNodeList","objectType","objectToStringType","isPlainObject","noop","toArray","NUMBER_TYPE","STRING_TYPE","INSTANT_LAYOUT","Grid","isElementInDom","composed","contains","mergeSettings","defaultOptions","normalizeStyles","_isLayoutFinished","_onLayoutDataReceived","containerClass","bindLayoutOnResize","layoutOnResize","getInitialGridElements","layoutOnInit","defaultPacker","opacity","touchAction","userSelect","userDrag","tapHighlightColor","touchCallout","contentZooming","getItems","refreshItems","hiddenItemStyles","visibility","refreshSortData","synchronize","fragment","createDocumentFragment","unfinishedLayout","nextLayoutId","layoutItems","gridWidth","gridHeight","layoutSettings","elements","newItems","needsLayout","active","allItems","removeElements","_setItemsVisibility","filter","itemsToShow","itemsToHide","isPredicateString","isPredicateFn","syncWithLayout","tryFinishCounter","tryFinish","sortComparer","isDescending","origItems","indexMap","defaultComparer","criteriaName","criteriaOrder","valA","valB","createIndexMap","compareIndexMap","customComparer","comparer","descending","split","map","isSwap","fromItem","toItem","layoutStyles","unbindLayoutOnResize","itemsToLayout","numItems","counter","hasLayoutChanged","startEvent","endEvent","method","completedItems","hiddenItems","triggerVisibilityChange","interrupted","defaultSettings","userSettings","mergeObjects","source","sourceKeys","keys","isSourceObject","_resizeHandler","normalized","docElemStyle","itemA","itemB","createGrid","component","overlayEl","addOverlay","zIndex","cursor","dragCursor","removeOverlay","gridHandleSelector","gridConstructorOptions","gridOptions","dragContainerSelector","muuriGrid","Muuri","querySelectorAll","gridItemSelector","destroyGrid","MuuriHelper"],"mappings":"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","sourcesContent":["/**\n* Muuri v0.9.5\n* https://muuri.dev/\n* Copyright (c) 2015-present, Haltu Oy\n* Released under the MIT license\n* https://github.com/haltu/muuri/blob/master/LICENSE.md\n* @license MIT\n*\n* Muuri Packer\n* Copyright (c) 2016-present, Niklas Rämö \n* @license MIT\n*\n* Muuri Ticker / Muuri Emitter / Muuri Dragger\n* Copyright (c) 2018-present, Niklas Rämö \n* @license MIT\n*\n* Muuri AutoScroller\n* Copyright (c) 2019-present, Niklas Rämö \n* @license MIT\n*/\n\nvar GRID_INSTANCES = {};\nvar ITEM_ELEMENT_MAP = typeof Map === 'function' ? new Map() : null;\n\nvar ACTION_SWAP = 'swap';\nvar ACTION_MOVE = 'move';\n\nvar EVENT_SYNCHRONIZE = 'synchronize';\nvar EVENT_LAYOUT_START = 'layoutStart';\nvar EVENT_LAYOUT_END = 'layoutEnd';\nvar EVENT_LAYOUT_ABORT = 'layoutAbort';\nvar EVENT_ADD = 'add';\nvar EVENT_REMOVE = 'remove';\nvar EVENT_SHOW_START = 'showStart';\nvar EVENT_SHOW_END = 'showEnd';\nvar EVENT_HIDE_START = 'hideStart';\nvar EVENT_HIDE_END = 'hideEnd';\nvar EVENT_FILTER = 'filter';\nvar EVENT_SORT = 'sort';\nvar EVENT_MOVE = 'move';\nvar EVENT_SEND = 'send';\nvar EVENT_BEFORE_SEND = 'beforeSend';\nvar EVENT_RECEIVE = 'receive';\nvar EVENT_BEFORE_RECEIVE = 'beforeReceive';\nvar EVENT_DRAG_INIT = 'dragInit';\nvar EVENT_DRAG_START = 'dragStart';\nvar EVENT_DRAG_MOVE = 'dragMove';\nvar EVENT_DRAG_SCROLL = 'dragScroll';\nvar EVENT_DRAG_END = 'dragEnd';\nvar EVENT_DRAG_RELEASE_START = 'dragReleaseStart';\nvar EVENT_DRAG_RELEASE_END = 'dragReleaseEnd';\nvar EVENT_DESTROY = 'destroy';\n\nvar HAS_TOUCH_EVENTS = 'ontouchstart' in window;\nvar HAS_POINTER_EVENTS = !!window.PointerEvent;\nvar HAS_MS_POINTER_EVENTS = !!window.navigator.msPointerEnabled;\n\nvar MAX_SAFE_FLOAT32_INTEGER = 16777216;\n\n/**\n * Event emitter constructor.\n *\n * @class\n */\nfunction Emitter() {\n this._events = {};\n this._queue = [];\n this._counter = 0;\n this._clearOnEmit = false;\n}\n\n/**\n * Public prototype methods\n * ************************\n */\n\n/**\n * Bind an event listener.\n *\n * @public\n * @param {String} event\n * @param {Function} listener\n * @returns {Emitter}\n */\nEmitter.prototype.on = function (event, listener) {\n if (!this._events || !event || !listener) return this;\n\n // Get listeners queue and create it if it does not exist.\n var listeners = this._events[event];\n if (!listeners) listeners = this._events[event] = [];\n\n // Add the listener to the queue.\n listeners.push(listener);\n\n return this;\n};\n\n/**\n * Unbind all event listeners that match the provided listener function.\n *\n * @public\n * @param {String} event\n * @param {Function} listener\n * @returns {Emitter}\n */\nEmitter.prototype.off = function (event, listener) {\n if (!this._events || !event || !listener) return this;\n\n // Get listeners and return immediately if none is found.\n var listeners = this._events[event];\n if (!listeners || !listeners.length) return this;\n\n // Remove all matching listeners.\n var index;\n while ((index = listeners.indexOf(listener)) !== -1) {\n listeners.splice(index, 1);\n }\n\n return this;\n};\n\n/**\n * Unbind all listeners of the provided event.\n *\n * @public\n * @param {String} event\n * @returns {Emitter}\n */\nEmitter.prototype.clear = function (event) {\n if (!this._events || !event) return this;\n\n var listeners = this._events[event];\n if (listeners) {\n listeners.length = 0;\n delete this._events[event];\n }\n\n return this;\n};\n\n/**\n * Emit all listeners in a specified event with the provided arguments.\n *\n * @public\n * @param {String} event\n * @param {...*} [args]\n * @returns {Emitter}\n */\nEmitter.prototype.emit = function (event) {\n if (!this._events || !event) {\n this._clearOnEmit = false;\n return this;\n }\n\n // Get event listeners and quit early if there's no listeners.\n var listeners = this._events[event];\n if (!listeners || !listeners.length) {\n this._clearOnEmit = false;\n return this;\n }\n\n var queue = this._queue;\n var startIndex = queue.length;\n var argsLength = arguments.length - 1;\n var args;\n\n // If we have more than 3 arguments let's put the arguments in an array and\n // apply it to the listeners.\n if (argsLength > 3) {\n args = [];\n args.push.apply(args, arguments);\n args.shift();\n }\n\n // Add the current listeners to the callback queue before we process them.\n // This is necessary to guarantee that all of the listeners are called in\n // correct order even if new event listeners are removed/added during\n // processing and/or events are emitted during processing.\n queue.push.apply(queue, listeners);\n\n // Reset the event's listeners if need be.\n if (this._clearOnEmit) {\n listeners.length = 0;\n this._clearOnEmit = false;\n }\n\n // Increment queue counter. This is needed for the scenarios where emit is\n // triggered while the queue is already processing. We need to keep track of\n // how many \"queue processors\" there are active so that we can safely reset\n // the queue in the end when the last queue processor is finished.\n ++this._counter;\n\n // Process the queue (the specific part of it for this emit).\n var i = startIndex;\n var endIndex = queue.length;\n for (; i < endIndex; i++) {\n // prettier-ignore\n argsLength === 0 ? queue[i]() :\n argsLength === 1 ? queue[i](arguments[1]) :\n argsLength === 2 ? queue[i](arguments[1], arguments[2]) :\n argsLength === 3 ? queue[i](arguments[1], arguments[2], arguments[3]) :\n queue[i].apply(null, args);\n\n // Stop processing if the emitter is destroyed.\n if (!this._events) return this;\n }\n\n // Decrement queue process counter.\n --this._counter;\n\n // Reset the queue if there are no more queue processes running.\n if (!this._counter) queue.length = 0;\n\n return this;\n};\n\n/**\n * Emit all listeners in a specified event with the provided arguments and\n * remove the event's listeners just before calling the them. This method allows\n * the emitter to serve as a queue where all listeners are called only once.\n *\n * @public\n * @param {String} event\n * @param {...*} [args]\n * @returns {Emitter}\n */\nEmitter.prototype.burst = function () {\n if (!this._events) return this;\n this._clearOnEmit = true;\n this.emit.apply(this, arguments);\n return this;\n};\n\n/**\n * Check how many listeners there are for a specific event.\n *\n * @public\n * @param {String} event\n * @returns {Boolean}\n */\nEmitter.prototype.countListeners = function (event) {\n if (!this._events) return 0;\n var listeners = this._events[event];\n return listeners ? listeners.length : 0;\n};\n\n/**\n * Destroy emitter instance. Basically just removes all bound listeners.\n *\n * @public\n * @returns {Emitter}\n */\nEmitter.prototype.destroy = function () {\n if (!this._events) return this;\n this._queue.length = this._counter = 0;\n this._events = null;\n return this;\n};\n\nvar pointerout = HAS_POINTER_EVENTS ? 'pointerout' : HAS_MS_POINTER_EVENTS ? 'MSPointerOut' : '';\nvar waitDuration = 100;\n\n/**\n * If you happen to use Edge or IE on a touch capable device there is a\n * a specific case where pointercancel and pointerend events are never emitted,\n * even though one them should always be emitted when you release your finger\n * from the screen. The bug appears specifically when Muuri shifts the dragged\n * element's position in the DOM after pointerdown event, IE and Edge don't like\n * that behaviour and quite often forget to emit the pointerend/pointercancel\n * event. But, they do emit pointerout event so we utilize that here.\n * Specifically, if there has been no pointermove event within 100 milliseconds\n * since the last pointerout event we force cancel the drag operation. This hack\n * works surprisingly well 99% of the time. There is that 1% chance there still\n * that dragged items get stuck but it is what it is.\n *\n * @class\n * @param {Dragger} dragger\n */\nfunction EdgeHack(dragger) {\n if (!pointerout) return;\n\n this._dragger = dragger;\n this._timeout = null;\n this._outEvent = null;\n this._isActive = false;\n\n this._addBehaviour = this._addBehaviour.bind(this);\n this._removeBehaviour = this._removeBehaviour.bind(this);\n this._onTimeout = this._onTimeout.bind(this);\n this._resetData = this._resetData.bind(this);\n this._onStart = this._onStart.bind(this);\n this._onOut = this._onOut.bind(this);\n\n this._dragger.on('start', this._onStart);\n}\n\n/**\n * @private\n */\nEdgeHack.prototype._addBehaviour = function () {\n if (this._isActive) return;\n this._isActive = true;\n this._dragger.on('move', this._resetData);\n this._dragger.on('cancel', this._removeBehaviour);\n this._dragger.on('end', this._removeBehaviour);\n window.addEventListener(pointerout, this._onOut);\n};\n\n/**\n * @private\n */\nEdgeHack.prototype._removeBehaviour = function () {\n if (!this._isActive) return;\n this._dragger.off('move', this._resetData);\n this._dragger.off('cancel', this._removeBehaviour);\n this._dragger.off('end', this._removeBehaviour);\n window.removeEventListener(pointerout, this._onOut);\n this._resetData();\n this._isActive = false;\n};\n\n/**\n * @private\n */\nEdgeHack.prototype._resetData = function () {\n window.clearTimeout(this._timeout);\n this._timeout = null;\n this._outEvent = null;\n};\n\n/**\n * @private\n * @param {(PointerEvent|TouchEvent|MouseEvent)} e\n */\nEdgeHack.prototype._onStart = function (e) {\n if (e.pointerType === 'mouse') return;\n this._addBehaviour();\n};\n\n/**\n * @private\n * @param {(PointerEvent|TouchEvent|MouseEvent)} e\n */\nEdgeHack.prototype._onOut = function (e) {\n if (!this._dragger._getTrackedTouch(e)) return;\n this._resetData();\n this._outEvent = e;\n this._timeout = window.setTimeout(this._onTimeout, waitDuration);\n};\n\n/**\n * @private\n */\nEdgeHack.prototype._onTimeout = function () {\n var e = this._outEvent;\n this._resetData();\n if (this._dragger.isActive()) this._dragger._onCancel(e);\n};\n\n/**\n * @public\n */\nEdgeHack.prototype.destroy = function () {\n if (!pointerout) return;\n this._dragger.off('start', this._onStart);\n this._removeBehaviour();\n};\n\n// Playing it safe here, test all potential prefixes capitalized and lowercase.\nvar vendorPrefixes = ['', 'webkit', 'moz', 'ms', 'o', 'Webkit', 'Moz', 'MS', 'O'];\nvar cache$2 = {};\n\n/**\n * Get prefixed CSS property name when given a non-prefixed CSS property name.\n * Returns null if the property is not supported at all.\n *\n * @param {CSSStyleDeclaration} style\n * @param {String} prop\n * @returns {String}\n */\nfunction getPrefixedPropName(style, prop) {\n var prefixedProp = cache$2[prop] || '';\n if (prefixedProp) return prefixedProp;\n\n var camelProp = prop[0].toUpperCase() + prop.slice(1);\n var i = 0;\n while (i < vendorPrefixes.length) {\n prefixedProp = vendorPrefixes[i] ? vendorPrefixes[i] + camelProp : prop;\n if (prefixedProp in style) {\n cache$2[prop] = prefixedProp;\n return prefixedProp;\n }\n ++i;\n }\n\n return '';\n}\n\n/**\n * Check if passive events are supported.\n * https://github.com/WICG/EventListenerOptions/blob/gh-pages/explainer.md#feature-detection\n *\n * @returns {Boolean}\n */\nfunction hasPassiveEvents() {\n var isPassiveEventsSupported = false;\n\n try {\n var passiveOpts = Object.defineProperty({}, 'passive', {\n get: function () {\n isPassiveEventsSupported = true;\n },\n });\n window.addEventListener('testPassive', null, passiveOpts);\n window.removeEventListener('testPassive', null, passiveOpts);\n } catch (e) {}\n\n return isPassiveEventsSupported;\n}\n\nvar ua = window.navigator.userAgent.toLowerCase();\nvar isEdge = ua.indexOf('edge') > -1;\nvar isIE = ua.indexOf('trident') > -1;\nvar isFirefox = ua.indexOf('firefox') > -1;\nvar isAndroid = ua.indexOf('android') > -1;\n\nvar listenerOptions = hasPassiveEvents() ? { passive: true } : false;\n\nvar taProp = 'touchAction';\nvar taPropPrefixed = getPrefixedPropName(document.documentElement.style, taProp);\nvar taDefaultValue = 'auto';\n\n/**\n * Creates a new Dragger instance for an element.\n *\n * @public\n * @class\n * @param {HTMLElement} element\n * @param {Object} [cssProps]\n */\nfunction Dragger(element, cssProps) {\n this._element = element;\n this._emitter = new Emitter();\n this._isDestroyed = false;\n this._cssProps = {};\n this._touchAction = '';\n this._isActive = false;\n\n this._pointerId = null;\n this._startTime = 0;\n this._startX = 0;\n this._startY = 0;\n this._currentX = 0;\n this._currentY = 0;\n\n this._onStart = this._onStart.bind(this);\n this._onMove = this._onMove.bind(this);\n this._onCancel = this._onCancel.bind(this);\n this._onEnd = this._onEnd.bind(this);\n\n // Can't believe had to build a freaking class for a hack!\n this._edgeHack = null;\n if ((isEdge || isIE) && (HAS_POINTER_EVENTS || HAS_MS_POINTER_EVENTS)) {\n this._edgeHack = new EdgeHack(this);\n }\n\n // Apply initial CSS props.\n this.setCssProps(cssProps);\n\n // If touch action was not provided with initial CSS props let's assume it's\n // auto.\n if (!this._touchAction) {\n this.setTouchAction(taDefaultValue);\n }\n\n // Prevent native link/image dragging for the item and it's children.\n element.addEventListener('dragstart', Dragger._preventDefault, false);\n\n // Listen to start event.\n element.addEventListener(Dragger._inputEvents.start, this._onStart, listenerOptions);\n}\n\n/**\n * Protected properties\n * ********************\n */\n\nDragger._pointerEvents = {\n start: 'pointerdown',\n move: 'pointermove',\n cancel: 'pointercancel',\n end: 'pointerup',\n};\n\nDragger._msPointerEvents = {\n start: 'MSPointerDown',\n move: 'MSPointerMove',\n cancel: 'MSPointerCancel',\n end: 'MSPointerUp',\n};\n\nDragger._touchEvents = {\n start: 'touchstart',\n move: 'touchmove',\n cancel: 'touchcancel',\n end: 'touchend',\n};\n\nDragger._mouseEvents = {\n start: 'mousedown',\n move: 'mousemove',\n cancel: '',\n end: 'mouseup',\n};\n\nDragger._inputEvents = (function () {\n if (HAS_TOUCH_EVENTS) return Dragger._touchEvents;\n if (HAS_POINTER_EVENTS) return Dragger._pointerEvents;\n if (HAS_MS_POINTER_EVENTS) return Dragger._msPointerEvents;\n return Dragger._mouseEvents;\n})();\n\nDragger._emitter = new Emitter();\n\nDragger._emitterEvents = {\n start: 'start',\n move: 'move',\n end: 'end',\n cancel: 'cancel',\n};\n\nDragger._activeInstances = [];\n\n/**\n * Protected static methods\n * ************************\n */\n\nDragger._preventDefault = function (e) {\n if (e.preventDefault && e.cancelable !== false) e.preventDefault();\n};\n\nDragger._activateInstance = function (instance) {\n var index = Dragger._activeInstances.indexOf(instance);\n if (index > -1) return;\n\n Dragger._activeInstances.push(instance);\n Dragger._emitter.on(Dragger._emitterEvents.move, instance._onMove);\n Dragger._emitter.on(Dragger._emitterEvents.cancel, instance._onCancel);\n Dragger._emitter.on(Dragger._emitterEvents.end, instance._onEnd);\n\n if (Dragger._activeInstances.length === 1) {\n Dragger._bindListeners();\n }\n};\n\nDragger._deactivateInstance = function (instance) {\n var index = Dragger._activeInstances.indexOf(instance);\n if (index === -1) return;\n\n Dragger._activeInstances.splice(index, 1);\n Dragger._emitter.off(Dragger._emitterEvents.move, instance._onMove);\n Dragger._emitter.off(Dragger._emitterEvents.cancel, instance._onCancel);\n Dragger._emitter.off(Dragger._emitterEvents.end, instance._onEnd);\n\n if (!Dragger._activeInstances.length) {\n Dragger._unbindListeners();\n }\n};\n\nDragger._bindListeners = function () {\n window.addEventListener(Dragger._inputEvents.move, Dragger._onMove, listenerOptions);\n window.addEventListener(Dragger._inputEvents.end, Dragger._onEnd, listenerOptions);\n if (Dragger._inputEvents.cancel) {\n window.addEventListener(Dragger._inputEvents.cancel, Dragger._onCancel, listenerOptions);\n }\n};\n\nDragger._unbindListeners = function () {\n window.removeEventListener(Dragger._inputEvents.move, Dragger._onMove, listenerOptions);\n window.removeEventListener(Dragger._inputEvents.end, Dragger._onEnd, listenerOptions);\n if (Dragger._inputEvents.cancel) {\n window.removeEventListener(Dragger._inputEvents.cancel, Dragger._onCancel, listenerOptions);\n }\n};\n\nDragger._getEventPointerId = function (event) {\n // If we have pointer id available let's use it.\n if (typeof event.pointerId === 'number') {\n return event.pointerId;\n }\n\n // For touch events let's get the first changed touch's identifier.\n if (event.changedTouches) {\n return event.changedTouches[0] ? event.changedTouches[0].identifier : null;\n }\n\n // For mouse/other events let's provide a static id.\n return 1;\n};\n\nDragger._getTouchById = function (event, id) {\n // If we have a pointer event return the whole event if there's a match, and\n // null otherwise.\n if (typeof event.pointerId === 'number') {\n return event.pointerId === id ? event : null;\n }\n\n // For touch events let's check if there's a changed touch object that matches\n // the pointerId in which case return the touch object.\n if (event.changedTouches) {\n for (var i = 0; i < event.changedTouches.length; i++) {\n if (event.changedTouches[i].identifier === id) {\n return event.changedTouches[i];\n }\n }\n return null;\n }\n\n // For mouse/other events let's assume there's only one pointer and just\n // return the event.\n return event;\n};\n\nDragger._onMove = function (e) {\n Dragger._emitter.emit(Dragger._emitterEvents.move, e);\n};\n\nDragger._onCancel = function (e) {\n Dragger._emitter.emit(Dragger._emitterEvents.cancel, e);\n};\n\nDragger._onEnd = function (e) {\n Dragger._emitter.emit(Dragger._emitterEvents.end, e);\n};\n\n/**\n * Private prototype methods\n * *************************\n */\n\n/**\n * Reset current drag operation (if any).\n *\n * @private\n */\nDragger.prototype._reset = function () {\n this._pointerId = null;\n this._startTime = 0;\n this._startX = 0;\n this._startY = 0;\n this._currentX = 0;\n this._currentY = 0;\n this._isActive = false;\n Dragger._deactivateInstance(this);\n};\n\n/**\n * Create a custom dragger event from a raw event.\n *\n * @private\n * @param {String} type\n * @param {(PointerEvent|TouchEvent|MouseEvent)} e\n * @returns {Object}\n */\nDragger.prototype._createEvent = function (type, e) {\n var touch = this._getTrackedTouch(e);\n return {\n // Hammer.js compatibility interface.\n type: type,\n srcEvent: e,\n distance: this.getDistance(),\n deltaX: this.getDeltaX(),\n deltaY: this.getDeltaY(),\n deltaTime: type === Dragger._emitterEvents.start ? 0 : this.getDeltaTime(),\n isFirst: type === Dragger._emitterEvents.start,\n isFinal: type === Dragger._emitterEvents.end || type === Dragger._emitterEvents.cancel,\n pointerType: e.pointerType || (e.touches ? 'touch' : 'mouse'),\n // Partial Touch API interface.\n identifier: this._pointerId,\n screenX: touch.screenX,\n screenY: touch.screenY,\n clientX: touch.clientX,\n clientY: touch.clientY,\n pageX: touch.pageX,\n pageY: touch.pageY,\n target: touch.target,\n };\n};\n\n/**\n * Emit a raw event as dragger event internally.\n *\n * @private\n * @param {String} type\n * @param {(PointerEvent|TouchEvent|MouseEvent)} e\n */\nDragger.prototype._emit = function (type, e) {\n this._emitter.emit(type, this._createEvent(type, e));\n};\n\n/**\n * If the provided event is a PointerEvent this method will return it if it has\n * the same pointerId as the instance. If the provided event is a TouchEvent\n * this method will try to look for a Touch instance in the changedTouches that\n * has an identifier matching this instance's pointerId. If the provided event\n * is a MouseEvent (or just any other event than PointerEvent or TouchEvent)\n * it will be returned immediately.\n *\n * @private\n * @param {(PointerEvent|TouchEvent|MouseEvent)} e\n * @returns {?(Touch|PointerEvent|MouseEvent)}\n */\nDragger.prototype._getTrackedTouch = function (e) {\n if (this._pointerId === null) return null;\n return Dragger._getTouchById(e, this._pointerId);\n};\n\n/**\n * Handler for start event.\n *\n * @private\n * @param {(PointerEvent|TouchEvent|MouseEvent)} e\n */\nDragger.prototype._onStart = function (e) {\n if (this._isDestroyed) return;\n\n // If pointer id is already assigned let's return early.\n if (this._pointerId !== null) return;\n\n // Get (and set) pointer id.\n this._pointerId = Dragger._getEventPointerId(e);\n if (this._pointerId === null) return;\n\n // Setup initial data and emit start event.\n var touch = this._getTrackedTouch(e);\n this._startX = this._currentX = touch.clientX;\n this._startY = this._currentY = touch.clientY;\n this._startTime = Date.now();\n this._isActive = true;\n this._emit(Dragger._emitterEvents.start, e);\n\n // If the drag procedure was not reset within the start procedure let's\n // activate the instance (start listening to move/cancel/end events).\n if (this._isActive) {\n Dragger._activateInstance(this);\n }\n};\n\n/**\n * Handler for move event.\n *\n * @private\n * @param {(PointerEvent|TouchEvent|MouseEvent)} e\n */\nDragger.prototype._onMove = function (e) {\n var touch = this._getTrackedTouch(e);\n if (!touch) return;\n this._currentX = touch.clientX;\n this._currentY = touch.clientY;\n this._emit(Dragger._emitterEvents.move, e);\n};\n\n/**\n * Handler for cancel event.\n *\n * @private\n * @param {(PointerEvent|TouchEvent|MouseEvent)} e\n */\nDragger.prototype._onCancel = function (e) {\n if (!this._getTrackedTouch(e)) return;\n this._emit(Dragger._emitterEvents.cancel, e);\n this._reset();\n};\n\n/**\n * Handler for end event.\n *\n * @private\n * @param {(PointerEvent|TouchEvent|MouseEvent)} e\n */\nDragger.prototype._onEnd = function (e) {\n if (!this._getTrackedTouch(e)) return;\n this._emit(Dragger._emitterEvents.end, e);\n this._reset();\n};\n\n/**\n * Public prototype methods\n * ************************\n */\n\n/**\n * Check if the element is being dragged at the moment.\n *\n * @public\n * @returns {Boolean}\n */\nDragger.prototype.isActive = function () {\n return this._isActive;\n};\n\n/**\n * Set element's touch-action CSS property.\n *\n * @public\n * @param {String} value\n */\nDragger.prototype.setTouchAction = function (value) {\n // Store unmodified touch action value (we trust user input here).\n this._touchAction = value;\n\n // Set touch-action style.\n if (taPropPrefixed) {\n this._cssProps[taPropPrefixed] = '';\n this._element.style[taPropPrefixed] = value;\n }\n\n // If we have an unsupported touch-action value let's add a special listener\n // that prevents default action on touch start event. A dirty hack, but best\n // we can do for now. The other options would be to somehow polyfill the\n // unsupported touch action behavior with custom heuristics which sounds like\n // a can of worms. We do a special exception here for Firefox Android which's\n // touch-action does not work properly if the dragged element is moved in the\n // the DOM tree on touchstart.\n if (HAS_TOUCH_EVENTS) {\n this._element.removeEventListener(Dragger._touchEvents.start, Dragger._preventDefault, true);\n if (this._element.style[taPropPrefixed] !== value || (isFirefox && isAndroid)) {\n this._element.addEventListener(Dragger._touchEvents.start, Dragger._preventDefault, true);\n }\n }\n};\n\n/**\n * Update element's CSS properties. Accepts an object with camel cased style\n * props with value pairs as it's first argument.\n *\n * @public\n * @param {Object} [newProps]\n */\nDragger.prototype.setCssProps = function (newProps) {\n if (!newProps) return;\n\n var currentProps = this._cssProps;\n var element = this._element;\n var prop;\n var prefixedProp;\n\n // Reset current props.\n for (prop in currentProps) {\n element.style[prop] = currentProps[prop];\n delete currentProps[prop];\n }\n\n // Set new props.\n for (prop in newProps) {\n // Make sure we have a value for the prop.\n if (!newProps[prop]) continue;\n\n // Special handling for touch-action.\n if (prop === taProp) {\n this.setTouchAction(newProps[prop]);\n continue;\n }\n\n // Get prefixed prop and skip if it does not exist.\n prefixedProp = getPrefixedPropName(element.style, prop);\n if (!prefixedProp) continue;\n\n // Store the prop and add the style.\n currentProps[prefixedProp] = '';\n element.style[prefixedProp] = newProps[prop];\n }\n};\n\n/**\n * How much the pointer has moved on x-axis from start position, in pixels.\n * Positive value indicates movement from left to right.\n *\n * @public\n * @returns {Number}\n */\nDragger.prototype.getDeltaX = function () {\n return this._currentX - this._startX;\n};\n\n/**\n * How much the pointer has moved on y-axis from start position, in pixels.\n * Positive value indicates movement from top to bottom.\n *\n * @public\n * @returns {Number}\n */\nDragger.prototype.getDeltaY = function () {\n return this._currentY - this._startY;\n};\n\n/**\n * How far (in pixels) has pointer moved from start position.\n *\n * @public\n * @returns {Number}\n */\nDragger.prototype.getDistance = function () {\n var x = this.getDeltaX();\n var y = this.getDeltaY();\n return Math.sqrt(x * x + y * y);\n};\n\n/**\n * How long has pointer been dragged.\n *\n * @public\n * @returns {Number}\n */\nDragger.prototype.getDeltaTime = function () {\n return this._startTime ? Date.now() - this._startTime : 0;\n};\n\n/**\n * Bind drag event listeners.\n *\n * @public\n * @param {String} eventName\n * - 'start', 'move', 'cancel' or 'end'.\n * @param {Function} listener\n */\nDragger.prototype.on = function (eventName, listener) {\n this._emitter.on(eventName, listener);\n};\n\n/**\n * Unbind drag event listeners.\n *\n * @public\n * @param {String} eventName\n * - 'start', 'move', 'cancel' or 'end'.\n * @param {Function} listener\n */\nDragger.prototype.off = function (eventName, listener) {\n this._emitter.off(eventName, listener);\n};\n\n/**\n * Destroy the instance and unbind all drag event listeners.\n *\n * @public\n */\nDragger.prototype.destroy = function () {\n if (this._isDestroyed) return;\n\n var element = this._element;\n\n if (this._edgeHack) this._edgeHack.destroy();\n\n // Reset data and deactivate the instance.\n this._reset();\n\n // Destroy emitter.\n this._emitter.destroy();\n\n // Unbind event handlers.\n element.removeEventListener(Dragger._inputEvents.start, this._onStart, listenerOptions);\n element.removeEventListener('dragstart', Dragger._preventDefault, false);\n element.removeEventListener(Dragger._touchEvents.start, Dragger._preventDefault, true);\n\n // Reset styles.\n for (var prop in this._cssProps) {\n element.style[prop] = this._cssProps[prop];\n delete this._cssProps[prop];\n }\n\n // Reset data.\n this._element = null;\n\n // Mark as destroyed.\n this._isDestroyed = true;\n};\n\nvar dt = 1000 / 60;\n\nvar raf = (\n window.requestAnimationFrame ||\n window.webkitRequestAnimationFrame ||\n window.mozRequestAnimationFrame ||\n window.msRequestAnimationFrame ||\n function (callback) {\n return this.setTimeout(function () {\n callback(Date.now());\n }, dt);\n }\n).bind(window);\n\n/**\n * A ticker system for handling DOM reads and writes in an efficient way.\n *\n * @class\n */\nfunction Ticker(numLanes) {\n this._nextStep = null;\n this._lanes = [];\n this._stepQueue = [];\n this._stepCallbacks = {};\n this._step = this._step.bind(this);\n for (var i = 0; i < numLanes; i++) {\n this._lanes.push(new TickerLane());\n }\n}\n\nTicker.prototype._step = function (time) {\n var lanes = this._lanes;\n var stepQueue = this._stepQueue;\n var stepCallbacks = this._stepCallbacks;\n var i, j, id, laneQueue, laneCallbacks, laneIndices;\n\n this._nextStep = null;\n\n for (i = 0; i < lanes.length; i++) {\n laneQueue = lanes[i].queue;\n laneCallbacks = lanes[i].callbacks;\n laneIndices = lanes[i].indices;\n for (j = 0; j < laneQueue.length; j++) {\n id = laneQueue[j];\n if (!id) continue;\n stepQueue.push(id);\n stepCallbacks[id] = laneCallbacks[id];\n delete laneCallbacks[id];\n delete laneIndices[id];\n }\n laneQueue.length = 0;\n }\n\n for (i = 0; i < stepQueue.length; i++) {\n id = stepQueue[i];\n if (stepCallbacks[id]) stepCallbacks[id](time);\n delete stepCallbacks[id];\n }\n\n stepQueue.length = 0;\n};\n\nTicker.prototype.add = function (laneIndex, id, callback) {\n this._lanes[laneIndex].add(id, callback);\n if (!this._nextStep) this._nextStep = raf(this._step);\n};\n\nTicker.prototype.remove = function (laneIndex, id) {\n this._lanes[laneIndex].remove(id);\n};\n\n/**\n * A lane for ticker.\n *\n * @class\n */\nfunction TickerLane() {\n this.queue = [];\n this.indices = {};\n this.callbacks = {};\n}\n\nTickerLane.prototype.add = function (id, callback) {\n var index = this.indices[id];\n if (index !== undefined) this.queue[index] = undefined;\n this.queue.push(id);\n this.callbacks[id] = callback;\n this.indices[id] = this.queue.length - 1;\n};\n\nTickerLane.prototype.remove = function (id) {\n var index = this.indices[id];\n if (index === undefined) return;\n this.queue[index] = undefined;\n delete this.callbacks[id];\n delete this.indices[id];\n};\n\nvar LAYOUT_READ = 'layoutRead';\nvar LAYOUT_WRITE = 'layoutWrite';\nvar VISIBILITY_READ = 'visibilityRead';\nvar VISIBILITY_WRITE = 'visibilityWrite';\nvar DRAG_START_READ = 'dragStartRead';\nvar DRAG_START_WRITE = 'dragStartWrite';\nvar DRAG_MOVE_READ = 'dragMoveRead';\nvar DRAG_MOVE_WRITE = 'dragMoveWrite';\nvar DRAG_SCROLL_READ = 'dragScrollRead';\nvar DRAG_SCROLL_WRITE = 'dragScrollWrite';\nvar DRAG_SORT_READ = 'dragSortRead';\nvar PLACEHOLDER_LAYOUT_READ = 'placeholderLayoutRead';\nvar PLACEHOLDER_LAYOUT_WRITE = 'placeholderLayoutWrite';\nvar PLACEHOLDER_RESIZE_WRITE = 'placeholderResizeWrite';\nvar AUTO_SCROLL_READ = 'autoScrollRead';\nvar AUTO_SCROLL_WRITE = 'autoScrollWrite';\nvar DEBOUNCE_READ = 'debounceRead';\n\nvar LANE_READ = 0;\nvar LANE_READ_TAIL = 1;\nvar LANE_WRITE = 2;\n\nvar ticker = new Ticker(3);\n\nfunction addLayoutTick(itemId, read, write) {\n ticker.add(LANE_READ, LAYOUT_READ + itemId, read);\n ticker.add(LANE_WRITE, LAYOUT_WRITE + itemId, write);\n}\n\nfunction cancelLayoutTick(itemId) {\n ticker.remove(LANE_READ, LAYOUT_READ + itemId);\n ticker.remove(LANE_WRITE, LAYOUT_WRITE + itemId);\n}\n\nfunction addVisibilityTick(itemId, read, write) {\n ticker.add(LANE_READ, VISIBILITY_READ + itemId, read);\n ticker.add(LANE_WRITE, VISIBILITY_WRITE + itemId, write);\n}\n\nfunction cancelVisibilityTick(itemId) {\n ticker.remove(LANE_READ, VISIBILITY_READ + itemId);\n ticker.remove(LANE_WRITE, VISIBILITY_WRITE + itemId);\n}\n\nfunction addDragStartTick(itemId, read, write) {\n ticker.add(LANE_READ, DRAG_START_READ + itemId, read);\n ticker.add(LANE_WRITE, DRAG_START_WRITE + itemId, write);\n}\n\nfunction cancelDragStartTick(itemId) {\n ticker.remove(LANE_READ, DRAG_START_READ + itemId);\n ticker.remove(LANE_WRITE, DRAG_START_WRITE + itemId);\n}\n\nfunction addDragMoveTick(itemId, read, write) {\n ticker.add(LANE_READ, DRAG_MOVE_READ + itemId, read);\n ticker.add(LANE_WRITE, DRAG_MOVE_WRITE + itemId, write);\n}\n\nfunction cancelDragMoveTick(itemId) {\n ticker.remove(LANE_READ, DRAG_MOVE_READ + itemId);\n ticker.remove(LANE_WRITE, DRAG_MOVE_WRITE + itemId);\n}\n\nfunction addDragScrollTick(itemId, read, write) {\n ticker.add(LANE_READ, DRAG_SCROLL_READ + itemId, read);\n ticker.add(LANE_WRITE, DRAG_SCROLL_WRITE + itemId, write);\n}\n\nfunction cancelDragScrollTick(itemId) {\n ticker.remove(LANE_READ, DRAG_SCROLL_READ + itemId);\n ticker.remove(LANE_WRITE, DRAG_SCROLL_WRITE + itemId);\n}\n\nfunction addDragSortTick(itemId, read) {\n ticker.add(LANE_READ_TAIL, DRAG_SORT_READ + itemId, read);\n}\n\nfunction cancelDragSortTick(itemId) {\n ticker.remove(LANE_READ_TAIL, DRAG_SORT_READ + itemId);\n}\n\nfunction addPlaceholderLayoutTick(itemId, read, write) {\n ticker.add(LANE_READ, PLACEHOLDER_LAYOUT_READ + itemId, read);\n ticker.add(LANE_WRITE, PLACEHOLDER_LAYOUT_WRITE + itemId, write);\n}\n\nfunction cancelPlaceholderLayoutTick(itemId) {\n ticker.remove(LANE_READ, PLACEHOLDER_LAYOUT_READ + itemId);\n ticker.remove(LANE_WRITE, PLACEHOLDER_LAYOUT_WRITE + itemId);\n}\n\nfunction addPlaceholderResizeTick(itemId, write) {\n ticker.add(LANE_WRITE, PLACEHOLDER_RESIZE_WRITE + itemId, write);\n}\n\nfunction cancelPlaceholderResizeTick(itemId) {\n ticker.remove(LANE_WRITE, PLACEHOLDER_RESIZE_WRITE + itemId);\n}\n\nfunction addAutoScrollTick(read, write) {\n ticker.add(LANE_READ, AUTO_SCROLL_READ, read);\n ticker.add(LANE_WRITE, AUTO_SCROLL_WRITE, write);\n}\n\nfunction cancelAutoScrollTick() {\n ticker.remove(LANE_READ, AUTO_SCROLL_READ);\n ticker.remove(LANE_WRITE, AUTO_SCROLL_WRITE);\n}\n\nfunction addDebounceTick(debounceId, read) {\n ticker.add(LANE_READ, DEBOUNCE_READ + debounceId, read);\n}\n\nfunction cancelDebounceTick(debounceId) {\n ticker.remove(LANE_READ, DEBOUNCE_READ + debounceId);\n}\n\nvar AXIS_X = 1;\nvar AXIS_Y = 2;\nvar FORWARD = 4;\nvar BACKWARD = 8;\nvar LEFT = AXIS_X | BACKWARD;\nvar RIGHT = AXIS_X | FORWARD;\nvar UP = AXIS_Y | BACKWARD;\nvar DOWN = AXIS_Y | FORWARD;\n\nvar functionType = 'function';\n\n/**\n * Check if a value is a function.\n *\n * @param {*} val\n * @returns {Boolean}\n */\nfunction isFunction(val) {\n return typeof val === functionType;\n}\n\nvar cache$1 = typeof WeakMap === 'function' ? new WeakMap() : null;\n\n/**\n * Returns the computed value of an element's style property as a string.\n *\n * @param {HTMLElement} element\n * @param {String} style\n * @returns {String}\n */\nfunction getStyle(element, style) {\n var styles = cache$1 && cache$1.get(element);\n\n if (!styles) {\n styles = window.getComputedStyle(element, null);\n if (cache$1) cache$1.set(element, styles);\n }\n\n return styles.getPropertyValue(style);\n}\n\n/**\n * Returns the computed value of an element's style property transformed into\n * a float value.\n *\n * @param {HTMLElement} el\n * @param {String} style\n * @returns {Number}\n */\nfunction getStyleAsFloat(el, style) {\n return parseFloat(getStyle(el, style)) || 0;\n}\n\nvar DOC_ELEM = document.documentElement;\nvar BODY = document.body;\nvar THRESHOLD_DATA = { value: 0, offset: 0 };\n\n/**\n * @param {HTMLElement|Window} element\n * @returns {HTMLElement|Window}\n */\nfunction getScrollElement(element) {\n if (element === window || element === DOC_ELEM || element === BODY) {\n return window;\n } else {\n return element;\n }\n}\n\n/**\n * @param {HTMLElement|Window} element\n * @returns {Number}\n */\nfunction getScrollLeft(element) {\n return element === window ? element.pageXOffset : element.scrollLeft;\n}\n\n/**\n * @param {HTMLElement|Window} element\n * @returns {Number}\n */\nfunction getScrollTop(element) {\n return element === window ? element.pageYOffset : element.scrollTop;\n}\n\n/**\n * @param {HTMLElement|Window} element\n * @returns {Number}\n */\nfunction getScrollLeftMax(element) {\n if (element === window) {\n return DOC_ELEM.scrollWidth - DOC_ELEM.clientWidth;\n } else {\n return element.scrollWidth - element.clientWidth;\n }\n}\n\n/**\n * @param {HTMLElement|Window} element\n * @returns {Number}\n */\nfunction getScrollTopMax(element) {\n if (element === window) {\n return DOC_ELEM.scrollHeight - DOC_ELEM.clientHeight;\n } else {\n return element.scrollHeight - element.clientHeight;\n }\n}\n\n/**\n * Get window's or element's client rectangle data relative to the element's\n * content dimensions (includes inner size + padding, excludes scrollbars,\n * borders and margins).\n *\n * @param {HTMLElement|Window} element\n * @returns {Rectangle}\n */\nfunction getContentRect(element, result) {\n result = result || {};\n\n if (element === window) {\n result.width = DOC_ELEM.clientWidth;\n result.height = DOC_ELEM.clientHeight;\n result.left = 0;\n result.right = result.width;\n result.top = 0;\n result.bottom = result.height;\n } else {\n var bcr = element.getBoundingClientRect();\n var borderLeft = element.clientLeft || getStyleAsFloat(element, 'border-left-width');\n var borderTop = element.clientTop || getStyleAsFloat(element, 'border-top-width');\n result.width = element.clientWidth;\n result.height = element.clientHeight;\n result.left = bcr.left + borderLeft;\n result.right = result.left + result.width;\n result.top = bcr.top + borderTop;\n result.bottom = result.top + result.height;\n }\n\n return result;\n}\n\n/**\n * @param {Item} item\n * @returns {Object}\n */\nfunction getItemAutoScrollSettings(item) {\n return item._drag._getGrid()._settings.dragAutoScroll;\n}\n\n/**\n * @param {Item} item\n */\nfunction prepareItemScrollSync(item) {\n if (!item._drag) return;\n item._drag._prepareScroll();\n}\n\n/**\n * @param {Item} item\n */\nfunction applyItemScrollSync(item) {\n if (!item._drag || !item._isActive) return;\n var drag = item._drag;\n drag._scrollDiffX = drag._scrollDiffY = 0;\n item._setTranslate(drag._left, drag._top);\n}\n\n/**\n * Compute threshold value and edge offset.\n *\n * @param {Number} threshold\n * @param {Number} safeZone\n * @param {Number} itemSize\n * @param {Number} targetSize\n * @returns {Object}\n */\nfunction computeThreshold(threshold, safeZone, itemSize, targetSize) {\n THRESHOLD_DATA.value = Math.min(targetSize / 2, threshold);\n THRESHOLD_DATA.offset =\n Math.max(0, itemSize + THRESHOLD_DATA.value * 2 + targetSize * safeZone - targetSize) / 2;\n return THRESHOLD_DATA;\n}\n\nfunction ScrollRequest() {\n this.reset();\n}\n\nScrollRequest.prototype.reset = function () {\n if (this.isActive) this.onStop();\n this.item = null;\n this.element = null;\n this.isActive = false;\n this.isEnding = false;\n this.direction = null;\n this.value = null;\n this.maxValue = 0;\n this.threshold = 0;\n this.distance = 0;\n this.speed = 0;\n this.duration = 0;\n this.action = null;\n};\n\nScrollRequest.prototype.hasReachedEnd = function () {\n return FORWARD & this.direction ? this.value >= this.maxValue : this.value <= 0;\n};\n\nScrollRequest.prototype.computeCurrentScrollValue = function () {\n if (this.value === null) {\n return AXIS_X & this.direction ? getScrollLeft(this.element) : getScrollTop(this.element);\n }\n return Math.max(0, Math.min(this.value, this.maxValue));\n};\n\nScrollRequest.prototype.computeNextScrollValue = function (deltaTime) {\n var delta = this.speed * (deltaTime / 1000);\n var nextValue = FORWARD & this.direction ? this.value + delta : this.value - delta;\n return Math.max(0, Math.min(nextValue, this.maxValue));\n};\n\nScrollRequest.prototype.computeSpeed = (function () {\n var data = {\n direction: null,\n threshold: 0,\n distance: 0,\n value: 0,\n maxValue: 0,\n deltaTime: 0,\n duration: 0,\n isEnding: false,\n };\n\n return function (deltaTime) {\n var item = this.item;\n var speed = getItemAutoScrollSettings(item).speed;\n\n if (isFunction(speed)) {\n data.direction = this.direction;\n data.threshold = this.threshold;\n data.distance = this.distance;\n data.value = this.value;\n data.maxValue = this.maxValue;\n data.duration = this.duration;\n data.speed = this.speed;\n data.deltaTime = deltaTime;\n data.isEnding = this.isEnding;\n return speed(item, this.element, data);\n } else {\n return speed;\n }\n };\n})();\n\nScrollRequest.prototype.tick = function (deltaTime) {\n if (!this.isActive) {\n this.isActive = true;\n this.onStart();\n }\n this.value = this.computeCurrentScrollValue();\n this.speed = this.computeSpeed(deltaTime);\n this.value = this.computeNextScrollValue(deltaTime);\n this.duration += deltaTime;\n return this.value;\n};\n\nScrollRequest.prototype.onStart = function () {\n var item = this.item;\n var onStart = getItemAutoScrollSettings(item).onStart;\n if (isFunction(onStart)) onStart(item, this.element, this.direction);\n};\n\nScrollRequest.prototype.onStop = function () {\n var item = this.item;\n var onStop = getItemAutoScrollSettings(item).onStop;\n if (isFunction(onStop)) onStop(item, this.element, this.direction);\n // Manually nudge sort to happen. There's a good chance that the item is still\n // after the scroll stops which means that the next sort will be triggered\n // only after the item is moved or it's parent scrolled.\n if (item._drag) item._drag.sort();\n};\n\nfunction ScrollAction() {\n this.element = null;\n this.requestX = null;\n this.requestY = null;\n this.scrollLeft = 0;\n this.scrollTop = 0;\n}\n\nScrollAction.prototype.reset = function () {\n if (this.requestX) this.requestX.action = null;\n if (this.requestY) this.requestY.action = null;\n this.element = null;\n this.requestX = null;\n this.requestY = null;\n this.scrollLeft = 0;\n this.scrollTop = 0;\n};\n\nScrollAction.prototype.addRequest = function (request) {\n if (AXIS_X & request.direction) {\n this.removeRequest(this.requestX);\n this.requestX = request;\n } else {\n this.removeRequest(this.requestY);\n this.requestY = request;\n }\n request.action = this;\n};\n\nScrollAction.prototype.removeRequest = function (request) {\n if (!request) return;\n if (this.requestX === request) {\n this.requestX = null;\n request.action = null;\n } else if (this.requestY === request) {\n this.requestY = null;\n request.action = null;\n }\n};\n\nScrollAction.prototype.computeScrollValues = function () {\n this.scrollLeft = this.requestX ? this.requestX.value : getScrollLeft(this.element);\n this.scrollTop = this.requestY ? this.requestY.value : getScrollTop(this.element);\n};\n\nScrollAction.prototype.scroll = function () {\n var element = this.element;\n if (!element) return;\n\n if (element.scrollTo) {\n element.scrollTo(this.scrollLeft, this.scrollTop);\n } else {\n element.scrollLeft = this.scrollLeft;\n element.scrollTop = this.scrollTop;\n }\n};\n\nfunction Pool(createItem, releaseItem) {\n this.pool = [];\n this.createItem = createItem;\n this.releaseItem = releaseItem;\n}\n\nPool.prototype.pick = function () {\n return this.pool.pop() || this.createItem();\n};\n\nPool.prototype.release = function (item) {\n this.releaseItem(item);\n if (this.pool.indexOf(item) !== -1) return;\n this.pool.push(item);\n};\n\nPool.prototype.reset = function () {\n this.pool.length = 0;\n};\n\n/**\n * Check if two rectangles are overlapping.\n *\n * @param {Object} a\n * @param {Object} b\n * @returns {Number}\n */\nfunction isOverlapping(a, b) {\n return !(\n a.left + a.width <= b.left ||\n b.left + b.width <= a.left ||\n a.top + a.height <= b.top ||\n b.top + b.height <= a.top\n );\n}\n\n/**\n * Calculate intersection area between two rectangle.\n *\n * @param {Object} a\n * @param {Object} b\n * @returns {Number}\n */\nfunction getIntersectionArea(a, b) {\n if (!isOverlapping(a, b)) return 0;\n var width = Math.min(a.left + a.width, b.left + b.width) - Math.max(a.left, b.left);\n var height = Math.min(a.top + a.height, b.top + b.height) - Math.max(a.top, b.top);\n return width * height;\n}\n\n/**\n * Calculate how many percent the intersection area of two rectangles is from\n * the maximum potential intersection area between the rectangles.\n *\n * @param {Object} a\n * @param {Object} b\n * @returns {Number}\n */\nfunction getIntersectionScore(a, b) {\n var area = getIntersectionArea(a, b);\n if (!area) return 0;\n var maxArea = Math.min(a.width, b.width) * Math.min(a.height, b.height);\n return (area / maxArea) * 100;\n}\n\nvar RECT_1 = {\n width: 0,\n height: 0,\n left: 0,\n right: 0,\n top: 0,\n bottom: 0,\n};\n\nvar RECT_2 = {\n width: 0,\n height: 0,\n left: 0,\n right: 0,\n top: 0,\n bottom: 0,\n};\n\nfunction AutoScroller() {\n this._isDestroyed = false;\n this._isTicking = false;\n this._tickTime = 0;\n this._tickDeltaTime = 0;\n this._items = [];\n this._actions = [];\n this._requests = {};\n this._requests[AXIS_X] = {};\n this._requests[AXIS_Y] = {};\n this._requestOverlapCheck = {};\n this._dragPositions = {};\n this._dragDirections = {};\n this._overlapCheckInterval = 150;\n\n this._requestPool = new Pool(\n function () {\n return new ScrollRequest();\n },\n function (request) {\n request.reset();\n }\n );\n\n this._actionPool = new Pool(\n function () {\n return new ScrollAction();\n },\n function (action) {\n action.reset();\n }\n );\n\n this._readTick = this._readTick.bind(this);\n this._writeTick = this._writeTick.bind(this);\n}\n\nAutoScroller.AXIS_X = AXIS_X;\nAutoScroller.AXIS_Y = AXIS_Y;\nAutoScroller.FORWARD = FORWARD;\nAutoScroller.BACKWARD = BACKWARD;\nAutoScroller.LEFT = LEFT;\nAutoScroller.RIGHT = RIGHT;\nAutoScroller.UP = UP;\nAutoScroller.DOWN = DOWN;\n\nAutoScroller.smoothSpeed = function (maxSpeed, acceleration, deceleration) {\n return function (item, element, data) {\n var targetSpeed = 0;\n if (!data.isEnding) {\n if (data.threshold > 0) {\n var factor = data.threshold - Math.max(0, data.distance);\n targetSpeed = (maxSpeed / data.threshold) * factor;\n } else {\n targetSpeed = maxSpeed;\n }\n }\n\n var currentSpeed = data.speed;\n var nextSpeed = targetSpeed;\n\n if (currentSpeed === targetSpeed) {\n return nextSpeed;\n }\n\n if (currentSpeed < targetSpeed) {\n nextSpeed = currentSpeed + acceleration * (data.deltaTime / 1000);\n return Math.min(targetSpeed, nextSpeed);\n } else {\n nextSpeed = currentSpeed - deceleration * (data.deltaTime / 1000);\n return Math.max(targetSpeed, nextSpeed);\n }\n };\n};\n\nAutoScroller.pointerHandle = function (pointerSize) {\n var rect = { left: 0, top: 0, width: 0, height: 0 };\n var size = pointerSize || 1;\n return function (item, x, y, w, h, pX, pY) {\n rect.left = pX - size * 0.5;\n rect.top = pY - size * 0.5;\n rect.width = size;\n rect.height = size;\n return rect;\n };\n};\n\nAutoScroller.prototype._readTick = function (time) {\n if (this._isDestroyed) return;\n if (time && this._tickTime) {\n this._tickDeltaTime = time - this._tickTime;\n this._tickTime = time;\n this._updateRequests();\n this._updateActions();\n } else {\n this._tickTime = time;\n this._tickDeltaTime = 0;\n }\n};\n\nAutoScroller.prototype._writeTick = function () {\n if (this._isDestroyed) return;\n this._applyActions();\n addAutoScrollTick(this._readTick, this._writeTick);\n};\n\nAutoScroller.prototype._startTicking = function () {\n this._isTicking = true;\n addAutoScrollTick(this._readTick, this._writeTick);\n};\n\nAutoScroller.prototype._stopTicking = function () {\n this._isTicking = false;\n this._tickTime = 0;\n this._tickDeltaTime = 0;\n cancelAutoScrollTick();\n};\n\nAutoScroller.prototype._getItemHandleRect = function (item, handle, rect) {\n var itemDrag = item._drag;\n\n if (handle) {\n var ev = itemDrag._dragMoveEvent || itemDrag._dragStartEvent;\n var data = handle(\n item,\n itemDrag._clientX,\n itemDrag._clientY,\n item._width,\n item._height,\n ev.clientX,\n ev.clientY\n );\n rect.left = data.left;\n rect.top = data.top;\n rect.width = data.width;\n rect.height = data.height;\n } else {\n rect.left = itemDrag._clientX;\n rect.top = itemDrag._clientY;\n rect.width = item._width;\n rect.height = item._height;\n }\n\n rect.right = rect.left + rect.width;\n rect.bottom = rect.top + rect.height;\n\n return rect;\n};\n\nAutoScroller.prototype._requestItemScroll = function (\n item,\n axis,\n element,\n direction,\n threshold,\n distance,\n maxValue\n) {\n var reqMap = this._requests[axis];\n var request = reqMap[item._id];\n\n if (request) {\n if (request.element !== element || request.direction !== direction) {\n request.reset();\n }\n } else {\n request = this._requestPool.pick();\n }\n\n request.item = item;\n request.element = element;\n request.direction = direction;\n request.threshold = threshold;\n request.distance = distance;\n request.maxValue = maxValue;\n reqMap[item._id] = request;\n};\n\nAutoScroller.prototype._cancelItemScroll = function (item, axis) {\n var reqMap = this._requests[axis];\n var request = reqMap[item._id];\n if (!request) return;\n if (request.action) request.action.removeRequest(request);\n this._requestPool.release(request);\n delete reqMap[item._id];\n};\n\nAutoScroller.prototype._checkItemOverlap = function (item, checkX, checkY) {\n var settings = getItemAutoScrollSettings(item);\n var targets = isFunction(settings.targets) ? settings.targets(item) : settings.targets;\n var threshold = settings.threshold;\n var safeZone = settings.safeZone;\n\n if (!targets || !targets.length) {\n checkX && this._cancelItemScroll(item, AXIS_X);\n checkY && this._cancelItemScroll(item, AXIS_Y);\n return;\n }\n\n var dragDirections = this._dragDirections[item._id];\n var dragDirectionX = dragDirections[0];\n var dragDirectionY = dragDirections[1];\n\n if (!dragDirectionX && !dragDirectionY) {\n checkX && this._cancelItemScroll(item, AXIS_X);\n checkY && this._cancelItemScroll(item, AXIS_Y);\n return;\n }\n\n var itemRect = this._getItemHandleRect(item, settings.handle, RECT_1);\n var testRect = RECT_2;\n\n var target = null;\n var testElement = null;\n var testAxisX = true;\n var testAxisY = true;\n var testScore = 0;\n var testPriority = 0;\n var testThreshold = null;\n var testDirection = null;\n var testDistance = 0;\n var testMaxScrollX = 0;\n var testMaxScrollY = 0;\n\n var xElement = null;\n var xPriority = -Infinity;\n var xThreshold = 0;\n var xScore = 0;\n var xDirection = null;\n var xDistance = 0;\n var xMaxScroll = 0;\n\n var yElement = null;\n var yPriority = -Infinity;\n var yThreshold = 0;\n var yScore = 0;\n var yDirection = null;\n var yDistance = 0;\n var yMaxScroll = 0;\n\n for (var i = 0; i < targets.length; i++) {\n target = targets[i];\n testAxisX = checkX && dragDirectionX && target.axis !== AXIS_Y;\n testAxisY = checkY && dragDirectionY && target.axis !== AXIS_X;\n testPriority = target.priority || 0;\n\n // Ignore this item if it's x-axis and y-axis priority is lower than\n // the currently matching item's.\n if ((!testAxisX || testPriority < xPriority) && (!testAxisY || testPriority < yPriority)) {\n continue;\n }\n\n testElement = getScrollElement(target.element || target);\n testMaxScrollX = testAxisX ? getScrollLeftMax(testElement) : -1;\n testMaxScrollY = testAxisY ? getScrollTopMax(testElement) : -1;\n\n // Ignore this item if there is no possibility to scroll.\n if (!testMaxScrollX && !testMaxScrollY) continue;\n\n testRect = getContentRect(testElement, testRect);\n testScore = getIntersectionScore(itemRect, testRect);\n\n // Ignore this item if it's not overlapping at all with the dragged item.\n if (testScore <= 0) continue;\n\n // Test x-axis.\n if (\n testAxisX &&\n testPriority >= xPriority &&\n testMaxScrollX > 0 &&\n (testPriority > xPriority || testScore > xScore)\n ) {\n testDirection = null;\n testThreshold = computeThreshold(\n typeof target.threshold === 'number' ? target.threshold : threshold,\n safeZone,\n itemRect.width,\n testRect.width\n );\n if (dragDirectionX === RIGHT) {\n testDistance = testRect.right + testThreshold.offset - itemRect.right;\n if (testDistance <= testThreshold.value && getScrollLeft(testElement) < testMaxScrollX) {\n testDirection = RIGHT;\n }\n } else if (dragDirectionX === LEFT) {\n testDistance = itemRect.left - (testRect.left - testThreshold.offset);\n if (testDistance <= testThreshold.value && getScrollLeft(testElement) > 0) {\n testDirection = LEFT;\n }\n }\n\n if (testDirection !== null) {\n xElement = testElement;\n xPriority = testPriority;\n xThreshold = testThreshold.value;\n xScore = testScore;\n xDirection = testDirection;\n xDistance = testDistance;\n xMaxScroll = testMaxScrollX;\n }\n }\n\n // Test y-axis.\n if (\n testAxisY &&\n testPriority >= yPriority &&\n testMaxScrollY > 0 &&\n (testPriority > yPriority || testScore > yScore)\n ) {\n testDirection = null;\n testThreshold = computeThreshold(\n typeof target.threshold === 'number' ? target.threshold : threshold,\n safeZone,\n itemRect.height,\n testRect.height\n );\n if (dragDirectionY === DOWN) {\n testDistance = testRect.bottom + testThreshold.offset - itemRect.bottom;\n if (testDistance <= testThreshold.value && getScrollTop(testElement) < testMaxScrollY) {\n testDirection = DOWN;\n }\n } else if (dragDirectionY === UP) {\n testDistance = itemRect.top - (testRect.top - testThreshold.offset);\n if (testDistance <= testThreshold.value && getScrollTop(testElement) > 0) {\n testDirection = UP;\n }\n }\n\n if (testDirection !== null) {\n yElement = testElement;\n yPriority = testPriority;\n yThreshold = testThreshold.value;\n yScore = testScore;\n yDirection = testDirection;\n yDistance = testDistance;\n yMaxScroll = testMaxScrollY;\n }\n }\n }\n\n // Request or cancel x-axis scroll.\n if (checkX) {\n if (xElement) {\n this._requestItemScroll(\n item,\n AXIS_X,\n xElement,\n xDirection,\n xThreshold,\n xDistance,\n xMaxScroll\n );\n } else {\n this._cancelItemScroll(item, AXIS_X);\n }\n }\n\n // Request or cancel y-axis scroll.\n if (checkY) {\n if (yElement) {\n this._requestItemScroll(\n item,\n AXIS_Y,\n yElement,\n yDirection,\n yThreshold,\n yDistance,\n yMaxScroll\n );\n } else {\n this._cancelItemScroll(item, AXIS_Y);\n }\n }\n};\n\nAutoScroller.prototype._updateScrollRequest = function (scrollRequest) {\n var item = scrollRequest.item;\n var settings = getItemAutoScrollSettings(item);\n var targets = isFunction(settings.targets) ? settings.targets(item) : settings.targets;\n var targetCount = (targets && targets.length) || 0;\n var threshold = settings.threshold;\n var safeZone = settings.safeZone;\n var itemRect = this._getItemHandleRect(item, settings.handle, RECT_1);\n var testRect = RECT_2;\n var target = null;\n var testElement = null;\n var testIsAxisX = false;\n var testScore = null;\n var testThreshold = null;\n var testDistance = null;\n var testScroll = null;\n var testMaxScroll = null;\n var hasReachedEnd = null;\n\n for (var i = 0; i < targetCount; i++) {\n target = targets[i];\n\n // Make sure we have a matching element.\n testElement = getScrollElement(target.element || target);\n if (testElement !== scrollRequest.element) continue;\n\n // Make sure we have a matching axis.\n testIsAxisX = !!(AXIS_X & scrollRequest.direction);\n if (testIsAxisX) {\n if (target.axis === AXIS_Y) continue;\n } else {\n if (target.axis === AXIS_X) continue;\n }\n\n // Stop scrolling if there is no room to scroll anymore.\n testMaxScroll = testIsAxisX ? getScrollLeftMax(testElement) : getScrollTopMax(testElement);\n if (testMaxScroll <= 0) {\n break;\n }\n\n testRect = getContentRect(testElement, testRect);\n testScore = getIntersectionScore(itemRect, testRect);\n\n // Stop scrolling if dragged item is not overlapping with the scroll\n // element anymore.\n if (testScore <= 0) {\n break;\n }\n\n // Compute threshold and edge offset.\n testThreshold = computeThreshold(\n typeof target.threshold === 'number' ? target.threshold : threshold,\n safeZone,\n testIsAxisX ? itemRect.width : itemRect.height,\n testIsAxisX ? testRect.width : testRect.height\n );\n\n // Compute distance (based on current direction).\n if (scrollRequest.direction === LEFT) {\n testDistance = itemRect.left - (testRect.left - testThreshold.offset);\n } else if (scrollRequest.direction === RIGHT) {\n testDistance = testRect.right + testThreshold.offset - itemRect.right;\n } else if (scrollRequest.direction === UP) {\n testDistance = itemRect.top - (testRect.top - testThreshold.offset);\n } else {\n testDistance = testRect.bottom + testThreshold.offset - itemRect.bottom;\n }\n\n // Stop scrolling if threshold is not exceeded.\n if (testDistance > testThreshold.value) {\n break;\n }\n\n // Stop scrolling if we have reached the end of the scroll value.\n testScroll = testIsAxisX ? getScrollLeft(testElement) : getScrollTop(testElement);\n hasReachedEnd =\n FORWARD & scrollRequest.direction ? testScroll >= testMaxScroll : testScroll <= 0;\n if (hasReachedEnd) {\n break;\n }\n\n // Scrolling can continue, let's update the values.\n scrollRequest.maxValue = testMaxScroll;\n scrollRequest.threshold = testThreshold.value;\n scrollRequest.distance = testDistance;\n scrollRequest.isEnding = false;\n return true;\n }\n\n // Before we end the request, let's see if we need to stop the scrolling\n // smoothly or immediately.\n if (settings.smoothStop === true && scrollRequest.speed > 0) {\n if (hasReachedEnd === null) hasReachedEnd = scrollRequest.hasReachedEnd();\n scrollRequest.isEnding = hasReachedEnd ? false : true;\n } else {\n scrollRequest.isEnding = false;\n }\n\n return scrollRequest.isEnding;\n};\n\nAutoScroller.prototype._updateRequests = function () {\n var items = this._items;\n var requestsX = this._requests[AXIS_X];\n var requestsY = this._requests[AXIS_Y];\n var item, reqX, reqY, checkTime, needsCheck, checkX, checkY;\n\n for (var i = 0; i < items.length; i++) {\n item = items[i];\n checkTime = this._requestOverlapCheck[item._id];\n needsCheck = checkTime > 0 && this._tickTime - checkTime > this._overlapCheckInterval;\n\n checkX = true;\n reqX = requestsX[item._id];\n if (reqX && reqX.isActive) {\n checkX = !this._updateScrollRequest(reqX);\n if (checkX) {\n needsCheck = true;\n this._cancelItemScroll(item, AXIS_X);\n }\n }\n\n checkY = true;\n reqY = requestsY[item._id];\n if (reqY && reqY.isActive) {\n checkY = !this._updateScrollRequest(reqY);\n if (checkY) {\n needsCheck = true;\n this._cancelItemScroll(item, AXIS_Y);\n }\n }\n\n if (needsCheck) {\n this._requestOverlapCheck[item._id] = 0;\n this._checkItemOverlap(item, checkX, checkY);\n }\n }\n};\n\nAutoScroller.prototype._requestAction = function (request, axis) {\n var actions = this._actions;\n var isAxisX = axis === AXIS_X;\n var action = null;\n\n for (var i = 0; i < actions.length; i++) {\n action = actions[i];\n\n // If the action's request does not match the request's -> skip.\n if (request.element !== action.element) {\n action = null;\n continue;\n }\n\n // If the request and action share the same element, but the request slot\n // for the requested axis is already reserved let's ignore and cancel this\n // request.\n if (isAxisX ? action.requestX : action.requestY) {\n this._cancelItemScroll(request.item, axis);\n return;\n }\n\n // Seems like we have found our action, let's break the loop.\n break;\n }\n\n if (!action) action = this._actionPool.pick();\n action.element = request.element;\n action.addRequest(request);\n\n request.tick(this._tickDeltaTime);\n actions.push(action);\n};\n\nAutoScroller.prototype._updateActions = function () {\n var items = this._items;\n var requests = this._requests;\n var actions = this._actions;\n var itemId;\n var reqX;\n var reqY;\n var i;\n\n // Generate actions.\n for (i = 0; i < items.length; i++) {\n itemId = items[i]._id;\n reqX = requests[AXIS_X][itemId];\n reqY = requests[AXIS_Y][itemId];\n if (reqX) this._requestAction(reqX, AXIS_X);\n if (reqY) this._requestAction(reqY, AXIS_Y);\n }\n\n // Compute actions' scroll values.\n for (i = 0; i < actions.length; i++) {\n actions[i].computeScrollValues();\n }\n};\n\nAutoScroller.prototype._applyActions = function () {\n var actions = this._actions;\n var items = this._items;\n var i;\n\n // No actions -> no scrolling.\n if (!actions.length) return;\n\n // Scroll all the required elements.\n for (i = 0; i < actions.length; i++) {\n actions[i].scroll();\n this._actionPool.release(actions[i]);\n }\n\n // Reset actions.\n actions.length = 0;\n\n // Sync the item position immediately after all the auto-scrolling business is\n // finished. Without this procedure the items will jitter during auto-scroll\n // (in some cases at least) since the drag scroll handler is async (bound to\n // raf tick). Note that this procedure should not emit any dragScroll events,\n // because otherwise they would be emitted twice for the same event.\n for (i = 0; i < items.length; i++) prepareItemScrollSync(items[i]);\n for (i = 0; i < items.length; i++) applyItemScrollSync(items[i]);\n};\n\nAutoScroller.prototype._updateDragDirection = function (item) {\n var dragPositions = this._dragPositions[item._id];\n var dragDirections = this._dragDirections[item._id];\n var x1 = item._drag._left;\n var y1 = item._drag._top;\n if (dragPositions.length) {\n var x2 = dragPositions[0];\n var y2 = dragPositions[1];\n dragDirections[0] = x1 > x2 ? RIGHT : x1 < x2 ? LEFT : dragDirections[0] || 0;\n dragDirections[1] = y1 > y2 ? DOWN : y1 < y2 ? UP : dragDirections[1] || 0;\n }\n dragPositions[0] = x1;\n dragPositions[1] = y1;\n};\n\nAutoScroller.prototype.addItem = function (item) {\n if (this._isDestroyed) return;\n var index = this._items.indexOf(item);\n if (index === -1) {\n this._items.push(item);\n this._requestOverlapCheck[item._id] = this._tickTime;\n this._dragDirections[item._id] = [0, 0];\n this._dragPositions[item._id] = [];\n if (!this._isTicking) this._startTicking();\n }\n};\n\nAutoScroller.prototype.updateItem = function (item) {\n if (this._isDestroyed) return;\n\n // Make sure the item still exists in the auto-scroller.\n if (!this._dragDirections[item._id]) return;\n\n this._updateDragDirection(item);\n if (!this._requestOverlapCheck[item._id]) {\n this._requestOverlapCheck[item._id] = this._tickTime;\n }\n};\n\nAutoScroller.prototype.removeItem = function (item) {\n if (this._isDestroyed) return;\n\n var index = this._items.indexOf(item);\n if (index === -1) return;\n\n var itemId = item._id;\n\n var reqX = this._requests[AXIS_X][itemId];\n if (reqX) {\n this._cancelItemScroll(item, AXIS_X);\n delete this._requests[AXIS_X][itemId];\n }\n\n var reqY = this._requests[AXIS_Y][itemId];\n if (reqY) {\n this._cancelItemScroll(item, AXIS_Y);\n delete this._requests[AXIS_Y][itemId];\n }\n\n delete this._requestOverlapCheck[itemId];\n delete this._dragPositions[itemId];\n delete this._dragDirections[itemId];\n this._items.splice(index, 1);\n\n if (this._isTicking && !this._items.length) {\n this._stopTicking();\n }\n};\n\nAutoScroller.prototype.isItemScrollingX = function (item) {\n var reqX = this._requests[AXIS_X][item._id];\n return !!(reqX && reqX.isActive);\n};\n\nAutoScroller.prototype.isItemScrollingY = function (item) {\n var reqY = this._requests[AXIS_Y][item._id];\n return !!(reqY && reqY.isActive);\n};\n\nAutoScroller.prototype.isItemScrolling = function (item) {\n return this.isItemScrollingX(item) || this.isItemScrollingY(item);\n};\n\nAutoScroller.prototype.destroy = function () {\n if (this._isDestroyed) return;\n\n var items = this._items.slice(0);\n for (var i = 0; i < items.length; i++) {\n this.removeItem(items[i]);\n }\n\n this._actions.length = 0;\n this._requestPool.reset();\n this._actionPool.reset();\n\n this._isDestroyed = true;\n};\n\nvar ElProto = window.Element.prototype;\nvar matchesFn =\n ElProto.matches ||\n ElProto.matchesSelector ||\n ElProto.webkitMatchesSelector ||\n ElProto.mozMatchesSelector ||\n ElProto.msMatchesSelector ||\n ElProto.oMatchesSelector ||\n function () {\n return false;\n };\n\n/**\n * Check if element matches a CSS selector.\n *\n * @param {Element} el\n * @param {String} selector\n * @returns {Boolean}\n */\nfunction elementMatches(el, selector) {\n return matchesFn.call(el, selector);\n}\n\n/**\n * Add class to an element.\n *\n * @param {HTMLElement} element\n * @param {String} className\n */\nfunction addClass(element, className) {\n if (!className) return;\n\n if (element.classList) {\n element.classList.add(className);\n } else {\n if (!elementMatches(element, '.' + className)) {\n element.className += ' ' + className;\n }\n }\n}\n\nvar tempArray = [];\nvar numberType = 'number';\n\n/**\n * Insert an item or an array of items to array to a specified index. Mutates\n * the array. The index can be negative in which case the items will be added\n * to the end of the array.\n *\n * @param {Array} array\n * @param {*} items\n * @param {Number} [index=-1]\n */\nfunction arrayInsert(array, items, index) {\n var startIndex = typeof index === numberType ? index : -1;\n if (startIndex < 0) startIndex = array.length - startIndex + 1;\n\n array.splice.apply(array, tempArray.concat(startIndex, 0, items));\n tempArray.length = 0;\n}\n\n/**\n * Normalize array index. Basically this function makes sure that the provided\n * array index is within the bounds of the provided array and also transforms\n * negative index to the matching positive index. The third (optional) argument\n * allows you to define offset for array's length in case you are adding items\n * to the array or removing items from the array.\n *\n * @param {Array} array\n * @param {Number} index\n * @param {Number} [sizeOffset]\n */\nfunction normalizeArrayIndex(array, index, sizeOffset) {\n var maxIndex = Math.max(0, array.length - 1 + (sizeOffset || 0));\n return index > maxIndex ? maxIndex : index < 0 ? Math.max(maxIndex + index + 1, 0) : index;\n}\n\n/**\n * Move array item to another index.\n *\n * @param {Array} array\n * @param {Number} fromIndex\n * - Index (positive or negative) of the item that will be moved.\n * @param {Number} toIndex\n * - Index (positive or negative) where the item should be moved to.\n */\nfunction arrayMove(array, fromIndex, toIndex) {\n // Make sure the array has two or more items.\n if (array.length < 2) return;\n\n // Normalize the indices.\n var from = normalizeArrayIndex(array, fromIndex);\n var to = normalizeArrayIndex(array, toIndex);\n\n // Add target item to the new position.\n if (from !== to) {\n array.splice(to, 0, array.splice(from, 1)[0]);\n }\n}\n\n/**\n * Swap array items.\n *\n * @param {Array} array\n * @param {Number} index\n * - Index (positive or negative) of the item that will be swapped.\n * @param {Number} withIndex\n * - Index (positive or negative) of the other item that will be swapped.\n */\nfunction arraySwap(array, index, withIndex) {\n // Make sure the array has two or more items.\n if (array.length < 2) return;\n\n // Normalize the indices.\n var indexA = normalizeArrayIndex(array, index);\n var indexB = normalizeArrayIndex(array, withIndex);\n var temp;\n\n // Swap the items.\n if (indexA !== indexB) {\n temp = array[indexA];\n array[indexA] = array[indexB];\n array[indexB] = temp;\n }\n}\n\nvar transformProp = getPrefixedPropName(document.documentElement.style, 'transform') || 'transform';\n\nvar styleNameRegEx = /([A-Z])/g;\nvar prefixRegex = /^(webkit-|moz-|ms-|o-)/;\nvar msPrefixRegex = /^(-m-s-)/;\n\n/**\n * Transforms a camel case style property to kebab case style property. Handles\n * vendor prefixed properties elegantly as well, e.g. \"WebkitTransform\" and\n * \"webkitTransform\" are both transformed into \"-webkit-transform\".\n *\n * @param {String} property\n * @returns {String}\n */\nfunction getStyleName(property) {\n // Initial slicing, turns \"fooBarProp\" into \"foo-bar-prop\".\n var styleName = property.replace(styleNameRegEx, '-$1').toLowerCase();\n\n // Handle properties that start with \"webkit\", \"moz\", \"ms\" or \"o\" prefix (we\n // need to add an extra '-' to the beginnig).\n styleName = styleName.replace(prefixRegex, '-$1');\n\n // Handle properties that start with \"MS\" prefix (we need to transform the\n // \"-m-s-\" into \"-ms-\").\n styleName = styleName.replace(msPrefixRegex, '-ms-');\n\n return styleName;\n}\n\nvar transformStyle = getStyleName(transformProp);\n\nvar transformNone$1 = 'none';\nvar displayInline = 'inline';\nvar displayNone = 'none';\nvar displayStyle = 'display';\n\n/**\n * Returns true if element is transformed, false if not. In practice the\n * element's display value must be anything else than \"none\" or \"inline\" as\n * well as have a valid transform value applied in order to be counted as a\n * transformed element.\n *\n * Borrowed from Mezr (v0.6.1):\n * https://github.com/niklasramo/mezr/blob/0.6.1/mezr.js#L661\n *\n * @param {HTMLElement} element\n * @returns {Boolean}\n */\nfunction isTransformed(element) {\n var transform = getStyle(element, transformStyle);\n if (!transform || transform === transformNone$1) return false;\n\n var display = getStyle(element, displayStyle);\n if (display === displayInline || display === displayNone) return false;\n\n return true;\n}\n\n/**\n * Returns an absolute positioned element's containing block, which is\n * considered to be the closest ancestor element that the target element's\n * positioning is relative to. Disclaimer: this only works as intended for\n * absolute positioned elements.\n *\n * @param {HTMLElement} element\n * @returns {(Document|Element)}\n */\nfunction getContainingBlock(element) {\n // As long as the containing block is an element, static and not\n // transformed, try to get the element's parent element and fallback to\n // document. https://github.com/niklasramo/mezr/blob/0.6.1/mezr.js#L339\n var doc = document;\n var res = element || doc;\n while (res && res !== doc && getStyle(res, 'position') === 'static' && !isTransformed(res)) {\n res = res.parentElement || doc;\n }\n return res;\n}\n\nvar offsetA = {};\nvar offsetB = {};\nvar offsetDiff = {};\n\n/**\n * Returns the element's document offset, which in practice means the vertical\n * and horizontal distance between the element's northwest corner and the\n * document's northwest corner. Note that this function always returns the same\n * object so be sure to read the data from it instead using it as a reference.\n *\n * @param {(Document|Element|Window)} element\n * @param {Object} [offsetData]\n * - Optional data object where the offset data will be inserted to. If not\n * provided a new object will be created for the return data.\n * @returns {Object}\n */\nfunction getOffset(element, offsetData) {\n var offset = offsetData || {};\n var rect;\n\n // Set up return data.\n offset.left = 0;\n offset.top = 0;\n\n // Document's offsets are always 0.\n if (element === document) return offset;\n\n // Add viewport scroll left/top to the respective offsets.\n offset.left = window.pageXOffset || 0;\n offset.top = window.pageYOffset || 0;\n\n // Window's offsets are the viewport scroll left/top values.\n if (element.self === window.self) return offset;\n\n // Add element's client rects to the offsets.\n rect = element.getBoundingClientRect();\n offset.left += rect.left;\n offset.top += rect.top;\n\n // Exclude element's borders from the offset.\n offset.left += getStyleAsFloat(element, 'border-left-width');\n offset.top += getStyleAsFloat(element, 'border-top-width');\n\n return offset;\n}\n\n/**\n * Calculate the offset difference two elements.\n *\n * @param {HTMLElement} elemA\n * @param {HTMLElement} elemB\n * @param {Boolean} [compareContainingBlocks=false]\n * - When this is set to true the containing blocks of the provided elements\n * will be used for calculating the difference. Otherwise the provided\n * elements will be compared directly.\n * @returns {Object}\n */\nfunction getOffsetDiff(elemA, elemB, compareContainingBlocks) {\n offsetDiff.left = 0;\n offsetDiff.top = 0;\n\n // If elements are same let's return early.\n if (elemA === elemB) return offsetDiff;\n\n // Compare containing blocks if necessary.\n if (compareContainingBlocks) {\n elemA = getContainingBlock(elemA);\n elemB = getContainingBlock(elemB);\n\n // If containing blocks are identical, let's return early.\n if (elemA === elemB) return offsetDiff;\n }\n\n // Finally, let's calculate the offset diff.\n getOffset(elemA, offsetA);\n getOffset(elemB, offsetB);\n offsetDiff.left = offsetB.left - offsetA.left;\n offsetDiff.top = offsetB.top - offsetA.top;\n\n return offsetDiff;\n}\n\n/**\n * Check if overflow style value is scrollable.\n *\n * @param {String} value\n * @returns {Boolean}\n */\nfunction isScrollableOverflow(value) {\n return value === 'auto' || value === 'scroll' || value === 'overlay';\n}\n\n/**\n * Check if an element is scrollable.\n *\n * @param {HTMLElement} element\n * @returns {Boolean}\n */\nfunction isScrollable(element) {\n return (\n isScrollableOverflow(getStyle(element, 'overflow')) ||\n isScrollableOverflow(getStyle(element, 'overflow-x')) ||\n isScrollableOverflow(getStyle(element, 'overflow-y'))\n );\n}\n\n/**\n * Collect element's ancestors that are potentially scrollable elements. The\n * provided element is also also included in the check, meaning that if it is\n * scrollable it is added to the result array.\n *\n * @param {HTMLElement} element\n * @param {Array} [result]\n * @returns {Array}\n */\nfunction getScrollableAncestors(element, result) {\n result = result || [];\n\n // Find scroll parents.\n while (element && element !== document) {\n // If element is inside ShadowDOM let's get it's host node from the real\n // DOM and continue looping.\n if (element.getRootNode && element instanceof DocumentFragment) {\n element = element.getRootNode().host;\n continue;\n }\n\n // If element is scrollable let's add it to the scrollable list.\n if (isScrollable(element)) {\n result.push(element);\n }\n\n element = element.parentNode;\n }\n\n // Always add window to the results.\n result.push(window);\n\n return result;\n}\n\nvar translateValue = {};\nvar transformNone = 'none';\nvar rxMat3d = /^matrix3d/;\nvar rxMatTx = /([^,]*,){4}/;\nvar rxMat3dTx = /([^,]*,){12}/;\nvar rxNextItem = /[^,]*,/;\n\n/**\n * Returns the element's computed translateX and translateY values as a floats.\n * The returned object is always the same object and updated every time this\n * function is called.\n *\n * @param {HTMLElement} element\n * @returns {Object}\n */\nfunction getTranslate(element) {\n translateValue.x = 0;\n translateValue.y = 0;\n\n var transform = getStyle(element, transformStyle);\n if (!transform || transform === transformNone) {\n return translateValue;\n }\n\n // Transform style can be in either matrix3d(...) or matrix(...).\n var isMat3d = rxMat3d.test(transform);\n var tX = transform.replace(isMat3d ? rxMat3dTx : rxMatTx, '');\n var tY = tX.replace(rxNextItem, '');\n\n translateValue.x = parseFloat(tX) || 0;\n translateValue.y = parseFloat(tY) || 0;\n\n return translateValue;\n}\n\n/**\n * Remove class from an element.\n *\n * @param {HTMLElement} element\n * @param {String} className\n */\nfunction removeClass(element, className) {\n if (!className) return;\n\n if (element.classList) {\n element.classList.remove(className);\n } else {\n if (elementMatches(element, '.' + className)) {\n element.className = (' ' + element.className + ' ')\n .replace(' ' + className + ' ', ' ')\n .trim();\n }\n }\n}\n\nvar IS_IOS =\n /^(iPad|iPhone|iPod)/.test(window.navigator.platform) ||\n (/^Mac/.test(window.navigator.platform) && window.navigator.maxTouchPoints > 1);\nvar START_PREDICATE_INACTIVE = 0;\nvar START_PREDICATE_PENDING = 1;\nvar START_PREDICATE_RESOLVED = 2;\nvar SCROLL_LISTENER_OPTIONS = hasPassiveEvents() ? { passive: true } : false;\n\n/**\n * Bind touch interaction to an item.\n *\n * @class\n * @param {Item} item\n */\nfunction ItemDrag(item) {\n var element = item._element;\n var grid = item.getGrid();\n var settings = grid._settings;\n\n this._item = item;\n this._gridId = grid._id;\n this._isDestroyed = false;\n this._isMigrating = false;\n\n // Start predicate data.\n this._startPredicate = isFunction(settings.dragStartPredicate)\n ? settings.dragStartPredicate\n : ItemDrag.defaultStartPredicate;\n this._startPredicateState = START_PREDICATE_INACTIVE;\n this._startPredicateResult = undefined;\n\n // Data for drag sort predicate heuristics.\n this._isSortNeeded = false;\n this._sortTimer = undefined;\n this._blockedSortIndex = null;\n this._sortX1 = 0;\n this._sortX2 = 0;\n this._sortY1 = 0;\n this._sortY2 = 0;\n\n // Setup item's initial drag data.\n this._reset();\n\n // Bind the methods that needs binding.\n this._preStartCheck = this._preStartCheck.bind(this);\n this._preEndCheck = this._preEndCheck.bind(this);\n this._onScroll = this._onScroll.bind(this);\n this._prepareStart = this._prepareStart.bind(this);\n this._applyStart = this._applyStart.bind(this);\n this._prepareMove = this._prepareMove.bind(this);\n this._applyMove = this._applyMove.bind(this);\n this._prepareScroll = this._prepareScroll.bind(this);\n this._applyScroll = this._applyScroll.bind(this);\n this._handleSort = this._handleSort.bind(this);\n this._handleSortDelayed = this._handleSortDelayed.bind(this);\n\n // Get drag handle element.\n this._handle = (settings.dragHandle && element.querySelector(settings.dragHandle)) || element;\n\n // Init dragger.\n this._dragger = new Dragger(this._handle, settings.dragCssProps);\n this._dragger.on('start', this._preStartCheck);\n this._dragger.on('move', this._preStartCheck);\n this._dragger.on('cancel', this._preEndCheck);\n this._dragger.on('end', this._preEndCheck);\n}\n\n/**\n * Public properties\n * *****************\n */\n\n/**\n * @public\n * @static\n * @type {AutoScroller}\n */\nItemDrag.autoScroller = new AutoScroller();\n\n/**\n * Public static methods\n * *********************\n */\n\n/**\n * Default drag start predicate handler that handles anchor elements\n * gracefully. The return value of this function defines if the drag is\n * started, rejected or pending. When true is returned the dragging is started\n * and when false is returned the dragging is rejected. If nothing is returned\n * the predicate will be called again on the next drag movement.\n *\n * @public\n * @static\n * @param {Item} item\n * @param {Object} event\n * @param {Object} [options]\n * - An optional options object which can be used to pass the predicate\n * it's options manually. By default the predicate retrieves the options\n * from the grid's settings.\n * @returns {(Boolean|undefined)}\n */\nItemDrag.defaultStartPredicate = function (item, event, options) {\n var drag = item._drag;\n\n // Make sure left button is pressed on mouse.\n if (event.isFirst && event.srcEvent.button) {\n return false;\n }\n\n // If the start event is trusted, non-cancelable and it's default action has\n // not been prevented it is in most cases a sign that the gesture would be\n // cancelled anyways right after it has started (e.g. starting drag while\n // the page is scrolling).\n if (\n !IS_IOS &&\n event.isFirst &&\n event.srcEvent.isTrusted === true &&\n event.srcEvent.defaultPrevented === false &&\n event.srcEvent.cancelable === false\n ) {\n return false;\n }\n\n // Final event logic. At this stage return value does not matter anymore,\n // the predicate is either resolved or it's not and there's nothing to do\n // about it. Here we just reset data and if the item element is a link\n // we follow it (if there has only been slight movement).\n if (event.isFinal) {\n drag._finishStartPredicate(event);\n return;\n }\n\n // Setup predicate data from options if not already set.\n var predicate = drag._startPredicateData;\n if (!predicate) {\n var config = options || drag._getGrid()._settings.dragStartPredicate || {};\n drag._startPredicateData = predicate = {\n distance: Math.max(config.distance, 0) || 0,\n delay: Math.max(config.delay, 0) || 0,\n };\n }\n\n // If delay is defined let's keep track of the latest event and initiate\n // delay if it has not been done yet.\n if (predicate.delay) {\n predicate.event = event;\n if (!predicate.delayTimer) {\n predicate.delayTimer = window.setTimeout(function () {\n predicate.delay = 0;\n if (drag._resolveStartPredicate(predicate.event)) {\n drag._forceResolveStartPredicate(predicate.event);\n drag._resetStartPredicate();\n }\n }, predicate.delay);\n }\n }\n\n return drag._resolveStartPredicate(event);\n};\n\n/**\n * Default drag sort predicate.\n *\n * @public\n * @static\n * @param {Item} item\n * @param {Object} [options]\n * @param {Number} [options.threshold=50]\n * @param {String} [options.action='move']\n * @returns {?Object}\n * - Returns `null` if no valid index was found. Otherwise returns drag sort\n * command.\n */\nItemDrag.defaultSortPredicate = (function () {\n var itemRect = {};\n var targetRect = {};\n var returnData = {};\n var gridsArray = [];\n var minThreshold = 1;\n var maxThreshold = 100;\n\n function getTargetGrid(item, rootGrid, threshold) {\n var target = null;\n var dragSort = rootGrid._settings.dragSort;\n var bestScore = -1;\n var gridScore;\n var grids;\n var grid;\n var container;\n var containerRect;\n var left;\n var top;\n var right;\n var bottom;\n var i;\n\n // Get potential target grids.\n if (dragSort === true) {\n gridsArray[0] = rootGrid;\n grids = gridsArray;\n } else if (isFunction(dragSort)) {\n grids = dragSort.call(rootGrid, item);\n }\n\n // Return immediately if there are no grids.\n if (!grids || !Array.isArray(grids) || !grids.length) {\n return target;\n }\n\n // Loop through the grids and get the best match.\n for (i = 0; i < grids.length; i++) {\n grid = grids[i];\n\n // Filter out all destroyed grids.\n if (grid._isDestroyed) continue;\n\n // Compute the grid's client rect an clamp the initial boundaries to\n // viewport dimensions.\n grid._updateBoundingRect();\n left = Math.max(0, grid._left);\n top = Math.max(0, grid._top);\n right = Math.min(window.innerWidth, grid._right);\n bottom = Math.min(window.innerHeight, grid._bottom);\n\n // The grid might be inside one or more elements that clip it's visibility\n // (e.g overflow scroll/hidden) so we want to find out the visible portion\n // of the grid in the viewport and use that in our calculations.\n container = grid._element.parentNode;\n while (\n container &&\n container !== document &&\n container !== document.documentElement &&\n container !== document.body\n ) {\n if (container.getRootNode && container instanceof DocumentFragment) {\n container = container.getRootNode().host;\n continue;\n }\n\n if (getStyle(container, 'overflow') !== 'visible') {\n containerRect = container.getBoundingClientRect();\n left = Math.max(left, containerRect.left);\n top = Math.max(top, containerRect.top);\n right = Math.min(right, containerRect.right);\n bottom = Math.min(bottom, containerRect.bottom);\n }\n\n if (getStyle(container, 'position') === 'fixed') {\n break;\n }\n\n container = container.parentNode;\n }\n\n // No need to go further if target rect does not have visible area.\n if (left >= right || top >= bottom) continue;\n\n // Check how much dragged element overlaps the container element.\n targetRect.left = left;\n targetRect.top = top;\n targetRect.width = right - left;\n targetRect.height = bottom - top;\n gridScore = getIntersectionScore(itemRect, targetRect);\n\n // Check if this grid is the best match so far.\n if (gridScore > threshold && gridScore > bestScore) {\n bestScore = gridScore;\n target = grid;\n }\n }\n\n // Always reset grids array.\n gridsArray.length = 0;\n\n return target;\n }\n\n return function (item, options) {\n var drag = item._drag;\n var rootGrid = drag._getGrid();\n\n // Get drag sort predicate settings.\n var sortThreshold = options && typeof options.threshold === 'number' ? options.threshold : 50;\n var sortAction = options && options.action === ACTION_SWAP ? ACTION_SWAP : ACTION_MOVE;\n var migrateAction =\n options && options.migrateAction === ACTION_SWAP ? ACTION_SWAP : ACTION_MOVE;\n\n // Sort threshold must be a positive number capped to a max value of 100. If\n // that's not the case this function will not work correctly. So let's clamp\n // the threshold just in case.\n sortThreshold = Math.min(Math.max(sortThreshold, minThreshold), maxThreshold);\n\n // Populate item rect data.\n itemRect.width = item._width;\n itemRect.height = item._height;\n itemRect.left = drag._clientX;\n itemRect.top = drag._clientY;\n\n // Calculate the target grid.\n var grid = getTargetGrid(item, rootGrid, sortThreshold);\n\n // Return early if we found no grid container element that overlaps the\n // dragged item enough.\n if (!grid) return null;\n\n var isMigration = item.getGrid() !== grid;\n var gridOffsetLeft = 0;\n var gridOffsetTop = 0;\n var matchScore = 0;\n var matchIndex = -1;\n var hasValidTargets = false;\n var target;\n var score;\n var i;\n\n // If item is moved within it's originating grid adjust item's left and\n // top props. Otherwise if item is moved to/within another grid get the\n // container element's offset (from the element's content edge).\n if (grid === rootGrid) {\n itemRect.left = drag._gridX + item._marginLeft;\n itemRect.top = drag._gridY + item._marginTop;\n } else {\n grid._updateBorders(1, 0, 1, 0);\n gridOffsetLeft = grid._left + grid._borderLeft;\n gridOffsetTop = grid._top + grid._borderTop;\n }\n\n // Loop through the target grid items and try to find the best match.\n for (i = 0; i < grid._items.length; i++) {\n target = grid._items[i];\n\n // If the target item is not active or the target item is the dragged\n // item let's skip to the next item.\n if (!target._isActive || target === item) {\n continue;\n }\n\n // Mark the grid as having valid target items.\n hasValidTargets = true;\n\n // Calculate the target's overlap score with the dragged item.\n targetRect.width = target._width;\n targetRect.height = target._height;\n targetRect.left = target._left + target._marginLeft + gridOffsetLeft;\n targetRect.top = target._top + target._marginTop + gridOffsetTop;\n score = getIntersectionScore(itemRect, targetRect);\n\n // Update best match index and score if the target's overlap score with\n // the dragged item is higher than the current best match score.\n if (score > matchScore) {\n matchIndex = i;\n matchScore = score;\n }\n }\n\n // If there is no valid match and the dragged item is being moved into\n // another grid we need to do some guess work here. If there simply are no\n // valid targets (which means that the dragged item will be the only active\n // item in the new grid) we can just add it as the first item. If we have\n // valid items in the new grid and the dragged item is overlapping one or\n // more of the items in the new grid let's make an exception with the\n // threshold and just pick the item which the dragged item is overlapping\n // most. However, if the dragged item is not overlapping any of the valid\n // items in the new grid let's position it as the last item in the grid.\n if (isMigration && matchScore < sortThreshold) {\n matchIndex = hasValidTargets ? matchIndex : 0;\n matchScore = sortThreshold;\n }\n\n // Check if the best match overlaps enough to justify a placement switch.\n if (matchScore >= sortThreshold) {\n returnData.grid = grid;\n returnData.index = matchIndex;\n returnData.action = isMigration ? migrateAction : sortAction;\n return returnData;\n }\n\n return null;\n };\n})();\n\n/**\n * Public prototype methods\n * ************************\n */\n\n/**\n * Abort dragging and reset drag data.\n *\n * @public\n */\nItemDrag.prototype.stop = function () {\n if (!this._isActive) return;\n\n // If the item is being dropped into another grid, finish it up and return\n // immediately.\n if (this._isMigrating) {\n this._finishMigration();\n return;\n }\n\n var item = this._item;\n var itemId = item._id;\n\n // Stop auto-scroll.\n ItemDrag.autoScroller.removeItem(item);\n\n // Cancel queued ticks.\n cancelDragStartTick(itemId);\n cancelDragMoveTick(itemId);\n cancelDragScrollTick(itemId);\n\n // Cancel sort procedure.\n this._cancelSort();\n\n if (this._isStarted) {\n // Remove scroll listeners.\n this._unbindScrollListeners();\n\n var element = item._element;\n var grid = this._getGrid();\n var draggingClass = grid._settings.itemDraggingClass;\n\n // Append item element to the container if it's not it's child. Also make\n // sure the translate values are adjusted to account for the DOM shift.\n if (element.parentNode !== grid._element) {\n grid._element.appendChild(element);\n item._setTranslate(this._gridX, this._gridY);\n\n // We need to do forced reflow to make sure the dragging class is removed\n // gracefully.\n // eslint-disable-next-line\n if (draggingClass) element.clientWidth;\n }\n\n // Remove dragging class.\n removeClass(element, draggingClass);\n }\n\n // Reset drag data.\n this._reset();\n};\n\n/**\n * Manually trigger drag sort. This is only needed for special edge cases where\n * e.g. you have disabled sort and want to trigger a sort right after enabling\n * it (and don't want to wait for the next move/scroll event).\n *\n * @private\n * @param {Boolean} [force=false]\n */\nItemDrag.prototype.sort = function (force) {\n var item = this._item;\n if (this._isActive && item._isActive && this._dragMoveEvent) {\n if (force === true) {\n this._handleSort();\n } else {\n addDragSortTick(item._id, this._handleSort);\n }\n }\n};\n\n/**\n * Destroy instance.\n *\n * @public\n */\nItemDrag.prototype.destroy = function () {\n if (this._isDestroyed) return;\n this.stop();\n this._dragger.destroy();\n ItemDrag.autoScroller.removeItem(this._item);\n this._isDestroyed = true;\n};\n\n/**\n * Private prototype methods\n * *************************\n */\n\n/**\n * Get Grid instance.\n *\n * @private\n * @returns {?Grid}\n */\nItemDrag.prototype._getGrid = function () {\n return GRID_INSTANCES[this._gridId] || null;\n};\n\n/**\n * Setup/reset drag data.\n *\n * @private\n */\nItemDrag.prototype._reset = function () {\n this._isActive = false;\n this._isStarted = false;\n\n // The dragged item's container element.\n this._container = null;\n\n // The dragged item's containing block.\n this._containingBlock = null;\n\n // Drag/scroll event data.\n this._dragStartEvent = null;\n this._dragMoveEvent = null;\n this._dragPrevMoveEvent = null;\n this._scrollEvent = null;\n\n // All the elements which need to be listened for scroll events during\n // dragging.\n this._scrollers = [];\n\n // The current translateX/translateY position.\n this._left = 0;\n this._top = 0;\n\n // Dragged element's current position within the grid.\n this._gridX = 0;\n this._gridY = 0;\n\n // Dragged element's current offset from window's northwest corner. Does\n // not account for element's margins.\n this._clientX = 0;\n this._clientY = 0;\n\n // Keep track of the clientX/Y diff for scrolling.\n this._scrollDiffX = 0;\n this._scrollDiffY = 0;\n\n // Keep track of the clientX/Y diff for moving.\n this._moveDiffX = 0;\n this._moveDiffY = 0;\n\n // Offset difference between the dragged element's temporary drag\n // container and it's original container.\n this._containerDiffX = 0;\n this._containerDiffY = 0;\n};\n\n/**\n * Bind drag scroll handlers to all scrollable ancestor elements of the\n * dragged element and the drag container element.\n *\n * @private\n */\nItemDrag.prototype._bindScrollListeners = function () {\n var gridContainer = this._getGrid()._element;\n var dragContainer = this._container;\n var scrollers = this._scrollers;\n var gridScrollers;\n var i;\n\n // Get dragged element's scrolling parents.\n scrollers.length = 0;\n getScrollableAncestors(this._item._element.parentNode, scrollers);\n\n // If drag container is defined and it's not the same element as grid\n // container then we need to add the grid container and it's scroll parents\n // to the elements which are going to be listener for scroll events.\n if (dragContainer !== gridContainer) {\n gridScrollers = [];\n getScrollableAncestors(gridContainer, gridScrollers);\n for (i = 0; i < gridScrollers.length; i++) {\n if (scrollers.indexOf(gridScrollers[i]) < 0) {\n scrollers.push(gridScrollers[i]);\n }\n }\n }\n\n // Bind scroll listeners.\n for (i = 0; i < scrollers.length; i++) {\n scrollers[i].addEventListener('scroll', this._onScroll, SCROLL_LISTENER_OPTIONS);\n }\n};\n\n/**\n * Unbind currently bound drag scroll handlers from all scrollable ancestor\n * elements of the dragged element and the drag container element.\n *\n * @private\n */\nItemDrag.prototype._unbindScrollListeners = function () {\n var scrollers = this._scrollers;\n var i;\n\n for (i = 0; i < scrollers.length; i++) {\n scrollers[i].removeEventListener('scroll', this._onScroll, SCROLL_LISTENER_OPTIONS);\n }\n\n scrollers.length = 0;\n};\n\n/**\n * Unbind currently bound drag scroll handlers from all scrollable ancestor\n * elements of the dragged element and the drag container element.\n *\n * @private\n * @param {Object} event\n * @returns {Boolean}\n */\nItemDrag.prototype._resolveStartPredicate = function (event) {\n var predicate = this._startPredicateData;\n if (event.distance < predicate.distance || predicate.delay) return;\n this._resetStartPredicate();\n return true;\n};\n\n/**\n * Forcefully resolve drag start predicate.\n *\n * @private\n * @param {Object} event\n */\nItemDrag.prototype._forceResolveStartPredicate = function (event) {\n if (!this._isDestroyed && this._startPredicateState === START_PREDICATE_PENDING) {\n this._startPredicateState = START_PREDICATE_RESOLVED;\n this._onStart(event);\n }\n};\n\n/**\n * Finalize start predicate.\n *\n * @private\n * @param {Object} event\n */\nItemDrag.prototype._finishStartPredicate = function (event) {\n var element = this._item._element;\n\n // Check if this is a click (very subjective heuristics).\n var isClick = Math.abs(event.deltaX) < 2 && Math.abs(event.deltaY) < 2 && event.deltaTime < 200;\n\n // Reset predicate.\n this._resetStartPredicate();\n\n // If the gesture can be interpreted as click let's try to open the element's\n // href url (if it is an anchor element).\n if (isClick) openAnchorHref(element);\n};\n\n/**\n * Reset drag sort heuristics.\n *\n * @private\n * @param {Number} x\n * @param {Number} y\n */\nItemDrag.prototype._resetHeuristics = function (x, y) {\n this._blockedSortIndex = null;\n this._sortX1 = this._sortX2 = x;\n this._sortY1 = this._sortY2 = y;\n};\n\n/**\n * Run heuristics and return true if overlap check can be performed, and false\n * if it can not.\n *\n * @private\n * @param {Number} x\n * @param {Number} y\n * @returns {Boolean}\n */\nItemDrag.prototype._checkHeuristics = function (x, y) {\n var settings = this._getGrid()._settings.dragSortHeuristics;\n var minDist = settings.minDragDistance;\n\n // Skip heuristics if not needed.\n if (minDist <= 0) {\n this._blockedSortIndex = null;\n return true;\n }\n\n var diffX = x - this._sortX2;\n var diffY = y - this._sortY2;\n\n // If we can't do proper bounce back check make sure that the blocked index\n // is not set.\n var canCheckBounceBack = minDist > 3 && settings.minBounceBackAngle > 0;\n if (!canCheckBounceBack) {\n this._blockedSortIndex = null;\n }\n\n if (Math.abs(diffX) > minDist || Math.abs(diffY) > minDist) {\n // Reset blocked index if angle changed enough. This check requires a\n // minimum value of 3 for minDragDistance to function properly.\n if (canCheckBounceBack) {\n var angle = Math.atan2(diffX, diffY);\n var prevAngle = Math.atan2(this._sortX2 - this._sortX1, this._sortY2 - this._sortY1);\n var deltaAngle = Math.atan2(Math.sin(angle - prevAngle), Math.cos(angle - prevAngle));\n if (Math.abs(deltaAngle) > settings.minBounceBackAngle) {\n this._blockedSortIndex = null;\n }\n }\n\n // Update points.\n this._sortX1 = this._sortX2;\n this._sortY1 = this._sortY2;\n this._sortX2 = x;\n this._sortY2 = y;\n\n return true;\n }\n\n return false;\n};\n\n/**\n * Reset for default drag start predicate function.\n *\n * @private\n */\nItemDrag.prototype._resetStartPredicate = function () {\n var predicate = this._startPredicateData;\n if (predicate) {\n if (predicate.delayTimer) {\n predicate.delayTimer = window.clearTimeout(predicate.delayTimer);\n }\n this._startPredicateData = null;\n }\n};\n\n/**\n * Handle the sorting procedure. Manage drag sort heuristics/interval and\n * check overlap when necessary.\n *\n * @private\n */\nItemDrag.prototype._handleSort = function () {\n if (!this._isActive) return;\n\n var settings = this._getGrid()._settings;\n\n // No sorting when drag sort is disabled. Also, account for the scenario where\n // dragSort is temporarily disabled during drag procedure so we need to reset\n // sort timer heuristics state too.\n if (\n !settings.dragSort ||\n (!settings.dragAutoScroll.sortDuringScroll && ItemDrag.autoScroller.isItemScrolling(this._item))\n ) {\n this._sortX1 = this._sortX2 = this._gridX;\n this._sortY1 = this._sortY2 = this._gridY;\n // We set this to true intentionally so that overlap check would be\n // triggered as soon as possible after sort becomes enabled again.\n this._isSortNeeded = true;\n if (this._sortTimer !== undefined) {\n this._sortTimer = window.clearTimeout(this._sortTimer);\n }\n return;\n }\n\n // If sorting is enabled we always need to run the heuristics check to keep\n // the tracked coordinates updated. We also allow an exception when the sort\n // timer is finished because the heuristics are intended to prevent overlap\n // checks based on the dragged element's immediate movement and a delayed\n // overlap check is valid if it comes through, because it was valid when it\n // was invoked.\n var shouldSort = this._checkHeuristics(this._gridX, this._gridY);\n if (!this._isSortNeeded && !shouldSort) return;\n\n var sortInterval = settings.dragSortHeuristics.sortInterval;\n if (sortInterval <= 0 || this._isSortNeeded) {\n this._isSortNeeded = false;\n if (this._sortTimer !== undefined) {\n this._sortTimer = window.clearTimeout(this._sortTimer);\n }\n this._checkOverlap();\n } else if (this._sortTimer === undefined) {\n this._sortTimer = window.setTimeout(this._handleSortDelayed, sortInterval);\n }\n};\n\n/**\n * Delayed sort handler.\n *\n * @private\n */\nItemDrag.prototype._handleSortDelayed = function () {\n this._isSortNeeded = true;\n this._sortTimer = undefined;\n addDragSortTick(this._item._id, this._handleSort);\n};\n\n/**\n * Cancel and reset sort procedure.\n *\n * @private\n */\nItemDrag.prototype._cancelSort = function () {\n this._isSortNeeded = false;\n if (this._sortTimer !== undefined) {\n this._sortTimer = window.clearTimeout(this._sortTimer);\n }\n cancelDragSortTick(this._item._id);\n};\n\n/**\n * Handle the ending of the drag procedure for sorting.\n *\n * @private\n */\nItemDrag.prototype._finishSort = function () {\n var isSortEnabled = this._getGrid()._settings.dragSort;\n var needsFinalCheck = isSortEnabled && (this._isSortNeeded || this._sortTimer !== undefined);\n this._cancelSort();\n if (needsFinalCheck) this._checkOverlap();\n};\n\n/**\n * Check (during drag) if an item is overlapping other items and based on\n * the configuration layout the items.\n *\n * @private\n */\nItemDrag.prototype._checkOverlap = function () {\n if (!this._isActive) return;\n\n var item = this._item;\n var settings = this._getGrid()._settings;\n var result;\n var currentGrid;\n var currentIndex;\n var targetGrid;\n var targetIndex;\n var targetItem;\n var sortAction;\n var isMigration;\n\n // Get overlap check result.\n if (isFunction(settings.dragSortPredicate)) {\n result = settings.dragSortPredicate(item, this._dragMoveEvent);\n } else {\n result = ItemDrag.defaultSortPredicate(item, settings.dragSortPredicate);\n }\n\n // Let's make sure the result object has a valid index before going further.\n if (!result || typeof result.index !== 'number') return;\n\n sortAction = result.action === ACTION_SWAP ? ACTION_SWAP : ACTION_MOVE;\n currentGrid = item.getGrid();\n targetGrid = result.grid || currentGrid;\n isMigration = currentGrid !== targetGrid;\n currentIndex = currentGrid._items.indexOf(item);\n targetIndex = normalizeArrayIndex(\n targetGrid._items,\n result.index,\n isMigration && sortAction === ACTION_MOVE ? 1 : 0\n );\n\n // Prevent position bounce.\n if (!isMigration && targetIndex === this._blockedSortIndex) {\n return;\n }\n\n // If the item was moved within it's current grid.\n if (!isMigration) {\n // Make sure the target index is not the current index.\n if (currentIndex !== targetIndex) {\n this._blockedSortIndex = currentIndex;\n\n // Do the sort.\n (sortAction === ACTION_SWAP ? arraySwap : arrayMove)(\n currentGrid._items,\n currentIndex,\n targetIndex\n );\n\n // Emit move event.\n if (currentGrid._hasListeners(EVENT_MOVE)) {\n currentGrid._emit(EVENT_MOVE, {\n item: item,\n fromIndex: currentIndex,\n toIndex: targetIndex,\n action: sortAction,\n });\n }\n\n // Layout the grid.\n currentGrid.layout();\n }\n }\n\n // If the item was moved to another grid.\n else {\n this._blockedSortIndex = null;\n\n // Let's fetch the target item when it's still in it's original index.\n targetItem = targetGrid._items[targetIndex];\n\n // Emit beforeSend event.\n if (currentGrid._hasListeners(EVENT_BEFORE_SEND)) {\n currentGrid._emit(EVENT_BEFORE_SEND, {\n item: item,\n fromGrid: currentGrid,\n fromIndex: currentIndex,\n toGrid: targetGrid,\n toIndex: targetIndex,\n });\n }\n\n // Emit beforeReceive event.\n if (targetGrid._hasListeners(EVENT_BEFORE_RECEIVE)) {\n targetGrid._emit(EVENT_BEFORE_RECEIVE, {\n item: item,\n fromGrid: currentGrid,\n fromIndex: currentIndex,\n toGrid: targetGrid,\n toIndex: targetIndex,\n });\n }\n\n // Update item's grid id reference.\n item._gridId = targetGrid._id;\n\n // Update drag instance's migrating indicator.\n this._isMigrating = item._gridId !== this._gridId;\n\n // Move item instance from current grid to target grid.\n currentGrid._items.splice(currentIndex, 1);\n arrayInsert(targetGrid._items, item, targetIndex);\n\n // Reset sort data.\n item._sortData = null;\n\n // Emit send event.\n if (currentGrid._hasListeners(EVENT_SEND)) {\n currentGrid._emit(EVENT_SEND, {\n item: item,\n fromGrid: currentGrid,\n fromIndex: currentIndex,\n toGrid: targetGrid,\n toIndex: targetIndex,\n });\n }\n\n // Emit receive event.\n if (targetGrid._hasListeners(EVENT_RECEIVE)) {\n targetGrid._emit(EVENT_RECEIVE, {\n item: item,\n fromGrid: currentGrid,\n fromIndex: currentIndex,\n toGrid: targetGrid,\n toIndex: targetIndex,\n });\n }\n\n // If the sort action is \"swap\" let's respect it and send the target item\n // (if it exists) from the target grid to the originating grid. This process\n // is done on purpose after the dragged item placed within the target grid\n // so that we can keep this implementation as simple as possible utilizing\n // the existing API.\n if (sortAction === ACTION_SWAP && targetItem && targetItem.isActive()) {\n // Sanity check to make sure that the target item is still part of the\n // target grid. It could have been manipulated in the event handlers.\n if (targetGrid._items.indexOf(targetItem) > -1) {\n targetGrid.send(targetItem, currentGrid, currentIndex, {\n appendTo: this._container || document.body,\n layoutSender: false,\n layoutReceiver: false,\n });\n }\n }\n\n // Layout both grids.\n currentGrid.layout();\n targetGrid.layout();\n }\n};\n\n/**\n * If item is dragged into another grid, finish the migration process\n * gracefully.\n *\n * @private\n */\nItemDrag.prototype._finishMigration = function () {\n var item = this._item;\n var release = item._dragRelease;\n var element = item._element;\n var isActive = item._isActive;\n var targetGrid = item.getGrid();\n var targetGridElement = targetGrid._element;\n var targetSettings = targetGrid._settings;\n var targetContainer = targetSettings.dragContainer || targetGridElement;\n var currentSettings = this._getGrid()._settings;\n var currentContainer = element.parentNode;\n var currentVisClass = isActive\n ? currentSettings.itemVisibleClass\n : currentSettings.itemHiddenClass;\n var nextVisClass = isActive ? targetSettings.itemVisibleClass : targetSettings.itemHiddenClass;\n var translate;\n var offsetDiff;\n\n // Destroy current drag. Note that we need to set the migrating flag to\n // false first, because otherwise we create an infinite loop between this\n // and the drag.stop() method.\n this._isMigrating = false;\n this.destroy();\n\n // Update item class.\n if (currentSettings.itemClass !== targetSettings.itemClass) {\n removeClass(element, currentSettings.itemClass);\n addClass(element, targetSettings.itemClass);\n }\n\n // Update visibility class.\n if (currentVisClass !== nextVisClass) {\n removeClass(element, currentVisClass);\n addClass(element, nextVisClass);\n }\n\n // Move the item inside the target container if it's different than the\n // current container.\n if (targetContainer !== currentContainer) {\n targetContainer.appendChild(element);\n offsetDiff = getOffsetDiff(currentContainer, targetContainer, true);\n translate = getTranslate(element);\n translate.x -= offsetDiff.left;\n translate.y -= offsetDiff.top;\n }\n\n // Update item's cached dimensions.\n item._refreshDimensions();\n\n // Calculate the offset difference between target's drag container (if any)\n // and actual grid container element. We save it later for the release\n // process.\n offsetDiff = getOffsetDiff(targetContainer, targetGridElement, true);\n release._containerDiffX = offsetDiff.left;\n release._containerDiffY = offsetDiff.top;\n\n // Recreate item's drag handler.\n item._drag = targetSettings.dragEnabled ? new ItemDrag(item) : null;\n\n // Adjust the position of the item element if it was moved from a container\n // to another.\n if (targetContainer !== currentContainer) {\n item._setTranslate(translate.x, translate.y);\n }\n\n // Update child element's styles to reflect the current visibility state.\n item._visibility.setStyles(isActive ? targetSettings.visibleStyles : targetSettings.hiddenStyles);\n\n // Start the release.\n release.start();\n};\n\n/**\n * Drag pre-start handler.\n *\n * @private\n * @param {Object} event\n */\nItemDrag.prototype._preStartCheck = function (event) {\n // Let's activate drag start predicate state.\n if (this._startPredicateState === START_PREDICATE_INACTIVE) {\n this._startPredicateState = START_PREDICATE_PENDING;\n }\n\n // If predicate is pending try to resolve it.\n if (this._startPredicateState === START_PREDICATE_PENDING) {\n this._startPredicateResult = this._startPredicate(this._item, event);\n if (this._startPredicateResult === true) {\n this._startPredicateState = START_PREDICATE_RESOLVED;\n this._onStart(event);\n } else if (this._startPredicateResult === false) {\n this._resetStartPredicate(event);\n this._dragger._reset();\n this._startPredicateState = START_PREDICATE_INACTIVE;\n }\n }\n\n // Otherwise if predicate is resolved and drag is active, move the item.\n else if (this._startPredicateState === START_PREDICATE_RESOLVED && this._isActive) {\n this._onMove(event);\n }\n};\n\n/**\n * Drag pre-end handler.\n *\n * @private\n * @param {Object} event\n */\nItemDrag.prototype._preEndCheck = function (event) {\n var isResolved = this._startPredicateState === START_PREDICATE_RESOLVED;\n\n // Do final predicate check to allow user to unbind stuff for the current\n // drag procedure within the predicate callback. The return value of this\n // check will have no effect to the state of the predicate.\n this._startPredicate(this._item, event);\n\n this._startPredicateState = START_PREDICATE_INACTIVE;\n\n if (!isResolved || !this._isActive) return;\n\n if (this._isStarted) {\n this._onEnd(event);\n } else {\n this.stop();\n }\n};\n\n/**\n * Drag start handler.\n *\n * @private\n * @param {Object} event\n */\nItemDrag.prototype._onStart = function (event) {\n var item = this._item;\n if (!item._isActive) return;\n\n this._isActive = true;\n this._dragStartEvent = event;\n ItemDrag.autoScroller.addItem(item);\n\n addDragStartTick(item._id, this._prepareStart, this._applyStart);\n};\n\n/**\n * Prepare item to be dragged.\n *\n * @private\n * ItemDrag.prototype\n */\nItemDrag.prototype._prepareStart = function () {\n if (!this._isActive) return;\n\n var item = this._item;\n if (!item._isActive) return;\n\n var element = item._element;\n var grid = this._getGrid();\n var settings = grid._settings;\n var gridContainer = grid._element;\n var dragContainer = settings.dragContainer || gridContainer;\n var containingBlock = getContainingBlock(dragContainer);\n var translate = getTranslate(element);\n var elementRect = element.getBoundingClientRect();\n var hasDragContainer = dragContainer !== gridContainer;\n\n this._container = dragContainer;\n this._containingBlock = containingBlock;\n this._clientX = elementRect.left;\n this._clientY = elementRect.top;\n this._left = this._gridX = translate.x;\n this._top = this._gridY = translate.y;\n this._scrollDiffX = this._scrollDiffY = 0;\n this._moveDiffX = this._moveDiffY = 0;\n\n this._resetHeuristics(this._gridX, this._gridY);\n\n // If a specific drag container is set and it is different from the\n // grid's container element we store the offset between containers.\n if (hasDragContainer) {\n var offsetDiff = getOffsetDiff(containingBlock, gridContainer);\n this._containerDiffX = offsetDiff.left;\n this._containerDiffY = offsetDiff.top;\n }\n};\n\n/**\n * Start drag for the item.\n *\n * @private\n */\nItemDrag.prototype._applyStart = function () {\n if (!this._isActive) return;\n\n var item = this._item;\n if (!item._isActive) return;\n\n var grid = this._getGrid();\n var element = item._element;\n var release = item._dragRelease;\n var migrate = item._migrate;\n var hasDragContainer = this._container !== grid._element;\n\n if (item.isPositioning()) {\n item._layout.stop(true, this._left, this._top);\n }\n\n if (migrate._isActive) {\n this._left -= migrate._containerDiffX;\n this._top -= migrate._containerDiffY;\n this._gridX -= migrate._containerDiffX;\n this._gridY -= migrate._containerDiffY;\n migrate.stop(true, this._left, this._top);\n }\n\n if (item.isReleasing()) {\n release._reset();\n }\n\n if (grid._settings.dragPlaceholder.enabled) {\n item._dragPlaceholder.create();\n }\n\n this._isStarted = true;\n\n grid._emit(EVENT_DRAG_INIT, item, this._dragStartEvent);\n\n if (hasDragContainer) {\n // If the dragged element is a child of the drag container all we need to\n // do is setup the relative drag position data.\n if (element.parentNode === this._container) {\n this._gridX -= this._containerDiffX;\n this._gridY -= this._containerDiffY;\n }\n // Otherwise we need to append the element inside the correct container,\n // setup the actual drag position data and adjust the element's translate\n // values to account for the DOM position shift.\n else {\n this._left += this._containerDiffX;\n this._top += this._containerDiffY;\n this._container.appendChild(element);\n item._setTranslate(this._left, this._top);\n }\n }\n\n addClass(element, grid._settings.itemDraggingClass);\n this._bindScrollListeners();\n grid._emit(EVENT_DRAG_START, item, this._dragStartEvent);\n};\n\n/**\n * Drag move handler.\n *\n * @private\n * @param {Object} event\n */\nItemDrag.prototype._onMove = function (event) {\n var item = this._item;\n\n if (!item._isActive) {\n this.stop();\n return;\n }\n\n this._dragMoveEvent = event;\n addDragMoveTick(item._id, this._prepareMove, this._applyMove);\n addDragSortTick(item._id, this._handleSort);\n};\n\n/**\n * Prepare dragged item for moving.\n *\n * @private\n */\nItemDrag.prototype._prepareMove = function () {\n if (!this._isActive) return;\n\n var item = this._item;\n if (!item._isActive) return;\n\n var settings = this._getGrid()._settings;\n var axis = settings.dragAxis;\n var nextEvent = this._dragMoveEvent;\n var prevEvent = this._dragPrevMoveEvent || this._dragStartEvent || nextEvent;\n\n // Update horizontal position data.\n if (axis !== 'y') {\n var moveDiffX = nextEvent.clientX - prevEvent.clientX;\n this._left = this._left - this._moveDiffX + moveDiffX;\n this._gridX = this._gridX - this._moveDiffX + moveDiffX;\n this._clientX = this._clientX - this._moveDiffX + moveDiffX;\n this._moveDiffX = moveDiffX;\n }\n\n // Update vertical position data.\n if (axis !== 'x') {\n var moveDiffY = nextEvent.clientY - prevEvent.clientY;\n this._top = this._top - this._moveDiffY + moveDiffY;\n this._gridY = this._gridY - this._moveDiffY + moveDiffY;\n this._clientY = this._clientY - this._moveDiffY + moveDiffY;\n this._moveDiffY = moveDiffY;\n }\n\n this._dragPrevMoveEvent = nextEvent;\n};\n\n/**\n * Apply movement to dragged item.\n *\n * @private\n */\nItemDrag.prototype._applyMove = function () {\n if (!this._isActive) return;\n\n var item = this._item;\n if (!item._isActive) return;\n\n this._moveDiffX = this._moveDiffY = 0;\n item._setTranslate(this._left, this._top);\n this._getGrid()._emit(EVENT_DRAG_MOVE, item, this._dragMoveEvent);\n ItemDrag.autoScroller.updateItem(item);\n};\n\n/**\n * Drag scroll handler.\n *\n * @private\n * @param {Object} event\n */\nItemDrag.prototype._onScroll = function (event) {\n var item = this._item;\n\n if (!item._isActive) {\n this.stop();\n return;\n }\n\n this._scrollEvent = event;\n addDragScrollTick(item._id, this._prepareScroll, this._applyScroll);\n addDragSortTick(item._id, this._handleSort);\n};\n\n/**\n * Prepare dragged item for scrolling.\n *\n * @private\n */\nItemDrag.prototype._prepareScroll = function () {\n if (!this._isActive) return;\n\n // If item is not active do nothing.\n var item = this._item;\n if (!item._isActive) return;\n\n var element = item._element;\n var grid = this._getGrid();\n var gridContainer = grid._element;\n var rect = element.getBoundingClientRect();\n\n // Update container diff.\n if (this._container !== gridContainer) {\n var offsetDiff = getOffsetDiff(this._containingBlock, gridContainer);\n this._containerDiffX = offsetDiff.left;\n this._containerDiffY = offsetDiff.top;\n }\n\n // Update horizontal position data.\n var scrollDiffX = this._clientX - this._moveDiffX - rect.left;\n this._left = this._left - this._scrollDiffX + scrollDiffX;\n this._scrollDiffX = scrollDiffX;\n\n // Update vertical position data.\n var scrollDiffY = this._clientY - this._moveDiffY - rect.top;\n this._top = this._top - this._scrollDiffY + scrollDiffY;\n this._scrollDiffY = scrollDiffY;\n\n // Update grid position.\n this._gridX = this._left - this._containerDiffX;\n this._gridY = this._top - this._containerDiffY;\n};\n\n/**\n * Apply scroll to dragged item.\n *\n * @private\n */\nItemDrag.prototype._applyScroll = function () {\n if (!this._isActive) return;\n\n var item = this._item;\n if (!item._isActive) return;\n\n this._scrollDiffX = this._scrollDiffY = 0;\n item._setTranslate(this._left, this._top);\n this._getGrid()._emit(EVENT_DRAG_SCROLL, item, this._scrollEvent);\n};\n\n/**\n * Drag end handler.\n *\n * @private\n * @param {Object} event\n */\nItemDrag.prototype._onEnd = function (event) {\n var item = this._item;\n var element = item._element;\n var grid = this._getGrid();\n var settings = grid._settings;\n var release = item._dragRelease;\n\n // If item is not active, reset drag.\n if (!item._isActive) {\n this.stop();\n return;\n }\n\n // Cancel queued ticks.\n cancelDragStartTick(item._id);\n cancelDragMoveTick(item._id);\n cancelDragScrollTick(item._id);\n\n // Finish sort procedure (does final overlap check if needed).\n this._finishSort();\n\n // Remove scroll listeners.\n this._unbindScrollListeners();\n\n // Setup release data.\n release._containerDiffX = this._containerDiffX;\n release._containerDiffY = this._containerDiffY;\n\n // Reset drag data.\n this._reset();\n\n // Remove drag class name from element.\n removeClass(element, settings.itemDraggingClass);\n\n // Stop auto-scroll.\n ItemDrag.autoScroller.removeItem(item);\n\n // Emit dragEnd event.\n grid._emit(EVENT_DRAG_END, item, event);\n\n // Finish up the migration process or start the release process.\n this._isMigrating ? this._finishMigration() : release.start();\n};\n\n/**\n * Private helpers\n * ***************\n */\n\n/**\n * Check if an element is an anchor element and open the href url if possible.\n *\n * @param {HTMLElement} element\n */\nfunction openAnchorHref(element) {\n // Make sure the element is anchor element.\n if (element.tagName.toLowerCase() !== 'a') return;\n\n // Get href and make sure it exists.\n var href = element.getAttribute('href');\n if (!href) return;\n\n // Finally let's navigate to the link href.\n var target = element.getAttribute('target');\n if (target && target !== '_self') {\n window.open(href, target);\n } else {\n window.location.href = href;\n }\n}\n\n/**\n * Get current values of the provided styles definition object or array.\n *\n * @param {HTMLElement} element\n * @param {(Object|Array} styles\n * @return {Object}\n */\nfunction getCurrentStyles(element, styles) {\n var result = {};\n var prop, i;\n\n if (Array.isArray(styles)) {\n for (i = 0; i < styles.length; i++) {\n prop = styles[i];\n result[prop] = getStyle(element, getStyleName(prop));\n }\n } else {\n for (prop in styles) {\n result[prop] = getStyle(element, getStyleName(prop));\n }\n }\n\n return result;\n}\n\nvar unprefixRegEx = /^(webkit|moz|ms|o|Webkit|Moz|MS|O)(?=[A-Z])/;\nvar cache = {};\n\n/**\n * Remove any potential vendor prefixes from a property name.\n *\n * @param {String} prop\n * @returns {String}\n */\nfunction getUnprefixedPropName(prop) {\n var result = cache[prop];\n if (result) return result;\n\n result = prop.replace(unprefixRegEx, '');\n\n if (result !== prop) {\n result = result[0].toLowerCase() + result.slice(1);\n }\n\n cache[prop] = result;\n\n return result;\n}\n\nvar nativeCode = '[native code]';\n\n/**\n * Check if a value (e.g. a method or constructor) is native code. Good for\n * detecting when a polyfill is used and when not.\n *\n * @param {*} feat\n * @returns {Boolean}\n */\nfunction isNative(feat) {\n var S = window.Symbol;\n return !!(\n feat &&\n isFunction(S) &&\n isFunction(S.toString) &&\n S(feat).toString().indexOf(nativeCode) > -1\n );\n}\n\n/**\n * Set inline styles to an element.\n *\n * @param {HTMLElement} element\n * @param {Object} styles\n */\nfunction setStyles(element, styles) {\n for (var prop in styles) {\n element.style[prop] = styles[prop];\n }\n}\n\nvar HAS_WEB_ANIMATIONS = !!(Element && isFunction(Element.prototype.animate));\nvar HAS_NATIVE_WEB_ANIMATIONS = !!(Element && isNative(Element.prototype.animate));\n\n/**\n * Item animation handler powered by Web Animations API.\n *\n * @class\n * @param {HTMLElement} element\n */\nfunction Animator(element) {\n this._element = element;\n this._animation = null;\n this._duration = 0;\n this._easing = '';\n this._callback = null;\n this._props = [];\n this._values = [];\n this._isDestroyed = false;\n this._onFinish = this._onFinish.bind(this);\n}\n\n/**\n * Public prototype methods\n * ************************\n */\n\n/**\n * Start instance's animation. Automatically stops current animation if it is\n * running.\n *\n * @public\n * @param {Object} propsFrom\n * @param {Object} propsTo\n * @param {Object} [options]\n * @param {Number} [options.duration=300]\n * @param {String} [options.easing='ease']\n * @param {Function} [options.onFinish]\n */\nAnimator.prototype.start = function (propsFrom, propsTo, options) {\n if (this._isDestroyed) return;\n\n var element = this._element;\n var opts = options || {};\n\n // If we don't have web animations available let's not animate.\n if (!HAS_WEB_ANIMATIONS) {\n setStyles(element, propsTo);\n this._callback = isFunction(opts.onFinish) ? opts.onFinish : null;\n this._onFinish();\n return;\n }\n\n var animation = this._animation;\n var currentProps = this._props;\n var currentValues = this._values;\n var duration = opts.duration || 300;\n var easing = opts.easing || 'ease';\n var cancelAnimation = false;\n var propName, propCount, propIndex;\n\n // If we have an existing animation running, let's check if it needs to be\n // cancelled or if it can continue running.\n if (animation) {\n propCount = 0;\n\n // Cancel animation if duration or easing has changed.\n if (duration !== this._duration || easing !== this._easing) {\n cancelAnimation = true;\n }\n\n // Check if the requested animation target props and values match with the\n // current props and values.\n if (!cancelAnimation) {\n for (propName in propsTo) {\n ++propCount;\n propIndex = currentProps.indexOf(propName);\n if (propIndex === -1 || propsTo[propName] !== currentValues[propIndex]) {\n cancelAnimation = true;\n break;\n }\n }\n\n // Check if the target props count matches current props count. This is\n // needed for the edge case scenario where target props contain the same\n // styles as current props, but the current props have some additional\n // props.\n if (propCount !== currentProps.length) {\n cancelAnimation = true;\n }\n }\n }\n\n // Cancel animation (if required).\n if (cancelAnimation) animation.cancel();\n\n // Store animation callback.\n this._callback = isFunction(opts.onFinish) ? opts.onFinish : null;\n\n // If we have a running animation that does not need to be cancelled, let's\n // call it a day here and let it run.\n if (animation && !cancelAnimation) return;\n\n // Store target props and values to instance.\n currentProps.length = currentValues.length = 0;\n for (propName in propsTo) {\n currentProps.push(propName);\n currentValues.push(propsTo[propName]);\n }\n\n // Start the animation. We need to provide unprefixed property names to the\n // Web Animations polyfill if it is being used. If we have native Web\n // Animations available we need to provide prefixed properties instead.\n this._duration = duration;\n this._easing = easing;\n this._animation = element.animate(\n [\n createFrame(propsFrom, HAS_NATIVE_WEB_ANIMATIONS),\n createFrame(propsTo, HAS_NATIVE_WEB_ANIMATIONS),\n ],\n {\n duration: duration,\n easing: easing,\n }\n );\n this._animation.onfinish = this._onFinish;\n\n // Set the end styles. This makes sure that the element stays at the end\n // values after animation is finished.\n setStyles(element, propsTo);\n};\n\n/**\n * Stop instance's current animation if running.\n *\n * @public\n */\nAnimator.prototype.stop = function () {\n if (this._isDestroyed || !this._animation) return;\n this._animation.cancel();\n this._animation = this._callback = null;\n this._props.length = this._values.length = 0;\n};\n\n/**\n * Read the current values of the element's animated styles from the DOM.\n *\n * @public\n * @return {Object}\n */\nAnimator.prototype.getCurrentStyles = function () {\n return getCurrentStyles(element, currentProps);\n};\n\n/**\n * Check if the item is being animated currently.\n *\n * @public\n * @return {Boolean}\n */\nAnimator.prototype.isAnimating = function () {\n return !!this._animation;\n};\n\n/**\n * Destroy the instance and stop current animation if it is running.\n *\n * @public\n */\nAnimator.prototype.destroy = function () {\n if (this._isDestroyed) return;\n this.stop();\n this._element = null;\n this._isDestroyed = true;\n};\n\n/**\n * Private prototype methods\n * *************************\n */\n\n/**\n * Animation end handler.\n *\n * @private\n */\nAnimator.prototype._onFinish = function () {\n var callback = this._callback;\n this._animation = this._callback = null;\n this._props.length = this._values.length = 0;\n callback && callback();\n};\n\n/**\n * Private helpers\n * ***************\n */\n\nfunction createFrame(props, prefix) {\n var frame = {};\n for (var prop in props) {\n frame[prefix ? prop : getUnprefixedPropName(prop)] = props[prop];\n }\n return frame;\n}\n\n/**\n * Transform translateX and translateY value into CSS transform style\n * property's value.\n *\n * @param {Number} x\n * @param {Number} y\n * @returns {String}\n */\nfunction getTranslateString(x, y) {\n return 'translateX(' + x + 'px) translateY(' + y + 'px)';\n}\n\n/**\n * Drag placeholder.\n *\n * @class\n * @param {Item} item\n */\nfunction ItemDragPlaceholder(item) {\n this._item = item;\n this._animation = new Animator();\n this._element = null;\n this._className = '';\n this._didMigrate = false;\n this._resetAfterLayout = false;\n this._left = 0;\n this._top = 0;\n this._transX = 0;\n this._transY = 0;\n this._nextTransX = 0;\n this._nextTransY = 0;\n\n // Bind animation handlers.\n this._setupAnimation = this._setupAnimation.bind(this);\n this._startAnimation = this._startAnimation.bind(this);\n this._updateDimensions = this._updateDimensions.bind(this);\n\n // Bind event handlers.\n this._onLayoutStart = this._onLayoutStart.bind(this);\n this._onLayoutEnd = this._onLayoutEnd.bind(this);\n this._onReleaseEnd = this._onReleaseEnd.bind(this);\n this._onMigrate = this._onMigrate.bind(this);\n this._onHide = this._onHide.bind(this);\n}\n\n/**\n * Private prototype methods\n * *************************\n */\n\n/**\n * Update placeholder's dimensions to match the item's dimensions.\n *\n * @private\n */\nItemDragPlaceholder.prototype._updateDimensions = function () {\n if (!this.isActive()) return;\n setStyles(this._element, {\n width: this._item._width + 'px',\n height: this._item._height + 'px',\n });\n};\n\n/**\n * Move placeholder to a new position.\n *\n * @private\n * @param {Item[]} items\n * @param {Boolean} isInstant\n */\nItemDragPlaceholder.prototype._onLayoutStart = function (items, isInstant) {\n var item = this._item;\n\n // If the item is not part of the layout anymore reset placeholder.\n if (items.indexOf(item) === -1) {\n this.reset();\n return;\n }\n\n var nextLeft = item._left;\n var nextTop = item._top;\n var currentLeft = this._left;\n var currentTop = this._top;\n\n // Keep track of item layout position.\n this._left = nextLeft;\n this._top = nextTop;\n\n // If item's position did not change, and the item did not migrate and the\n // layout is not instant and we can safely skip layout.\n if (!isInstant && !this._didMigrate && currentLeft === nextLeft && currentTop === nextTop) {\n return;\n }\n\n // Slots data is calculated with item margins added to them so we need to add\n // item's left and top margin to the slot data to get the placeholder's\n // next position.\n var nextX = nextLeft + item._marginLeft;\n var nextY = nextTop + item._marginTop;\n\n // Just snap to new position without any animations if no animation is\n // required or if placeholder moves between grids.\n var grid = item.getGrid();\n var animEnabled = !isInstant && grid._settings.layoutDuration > 0;\n if (!animEnabled || this._didMigrate) {\n // Cancel potential (queued) layout tick.\n cancelPlaceholderLayoutTick(item._id);\n\n // Snap placeholder to correct position.\n this._element.style[transformProp] = getTranslateString(nextX, nextY);\n this._animation.stop();\n\n // Move placeholder inside correct container after migration.\n if (this._didMigrate) {\n grid.getElement().appendChild(this._element);\n this._didMigrate = false;\n }\n\n return;\n }\n\n // Start the placeholder's layout animation in the next tick. We do this to\n // avoid layout thrashing.\n this._nextTransX = nextX;\n this._nextTransY = nextY;\n addPlaceholderLayoutTick(item._id, this._setupAnimation, this._startAnimation);\n};\n\n/**\n * Prepare placeholder for layout animation.\n *\n * @private\n */\nItemDragPlaceholder.prototype._setupAnimation = function () {\n if (!this.isActive()) return;\n\n var translate = getTranslate(this._element);\n this._transX = translate.x;\n this._transY = translate.y;\n};\n\n/**\n * Start layout animation.\n *\n * @private\n */\nItemDragPlaceholder.prototype._startAnimation = function () {\n if (!this.isActive()) return;\n\n var animation = this._animation;\n var currentX = this._transX;\n var currentY = this._transY;\n var nextX = this._nextTransX;\n var nextY = this._nextTransY;\n\n // If placeholder is already in correct position let's just stop animation\n // and be done with it.\n if (currentX === nextX && currentY === nextY) {\n if (animation.isAnimating()) {\n this._element.style[transformProp] = getTranslateString(nextX, nextY);\n animation.stop();\n }\n return;\n }\n\n // Otherwise let's start the animation.\n var settings = this._item.getGrid()._settings;\n var currentStyles = {};\n var targetStyles = {};\n currentStyles[transformProp] = getTranslateString(currentX, currentY);\n targetStyles[transformProp] = getTranslateString(nextX, nextY);\n animation.start(currentStyles, targetStyles, {\n duration: settings.layoutDuration,\n easing: settings.layoutEasing,\n onFinish: this._onLayoutEnd,\n });\n};\n\n/**\n * Layout end handler.\n *\n * @private\n */\nItemDragPlaceholder.prototype._onLayoutEnd = function () {\n if (this._resetAfterLayout) {\n this.reset();\n }\n};\n\n/**\n * Drag end handler. This handler is called when dragReleaseEnd event is\n * emitted and receives the event data as it's argument.\n *\n * @private\n * @param {Item} item\n */\nItemDragPlaceholder.prototype._onReleaseEnd = function (item) {\n if (item._id === this._item._id) {\n // If the placeholder is not animating anymore we can safely reset it.\n if (!this._animation.isAnimating()) {\n this.reset();\n return;\n }\n\n // If the placeholder item is still animating here, let's wait for it to\n // finish it's animation.\n this._resetAfterLayout = true;\n }\n};\n\n/**\n * Migration start handler. This handler is called when beforeSend event is\n * emitted and receives the event data as it's argument.\n *\n * @private\n * @param {Object} data\n * @param {Item} data.item\n * @param {Grid} data.fromGrid\n * @param {Number} data.fromIndex\n * @param {Grid} data.toGrid\n * @param {Number} data.toIndex\n */\nItemDragPlaceholder.prototype._onMigrate = function (data) {\n // Make sure we have a matching item.\n if (data.item !== this._item) return;\n\n var grid = this._item.getGrid();\n var nextGrid = data.toGrid;\n\n // Unbind listeners from current grid.\n grid.off(EVENT_DRAG_RELEASE_END, this._onReleaseEnd);\n grid.off(EVENT_LAYOUT_START, this._onLayoutStart);\n grid.off(EVENT_BEFORE_SEND, this._onMigrate);\n grid.off(EVENT_HIDE_START, this._onHide);\n\n // Bind listeners to the next grid.\n nextGrid.on(EVENT_DRAG_RELEASE_END, this._onReleaseEnd);\n nextGrid.on(EVENT_LAYOUT_START, this._onLayoutStart);\n nextGrid.on(EVENT_BEFORE_SEND, this._onMigrate);\n nextGrid.on(EVENT_HIDE_START, this._onHide);\n\n // Mark the item as migrated.\n this._didMigrate = true;\n};\n\n/**\n * Reset placeholder if the associated item is hidden.\n *\n * @private\n * @param {Item[]} items\n */\nItemDragPlaceholder.prototype._onHide = function (items) {\n if (items.indexOf(this._item) > -1) this.reset();\n};\n\n/**\n * Public prototype methods\n * ************************\n */\n\n/**\n * Create placeholder. Note that this method only writes to DOM and does not\n * read anything from DOM so it should not cause any additional layout\n * thrashing when it's called at the end of the drag start procedure.\n *\n * @public\n */\nItemDragPlaceholder.prototype.create = function () {\n // If we already have placeholder set up we can skip the initiation logic.\n if (this.isActive()) {\n this._resetAfterLayout = false;\n return;\n }\n\n var item = this._item;\n var grid = item.getGrid();\n var settings = grid._settings;\n var animation = this._animation;\n\n // Keep track of layout position.\n this._left = item._left;\n this._top = item._top;\n\n // Create placeholder element.\n var element;\n if (isFunction(settings.dragPlaceholder.createElement)) {\n element = settings.dragPlaceholder.createElement(item);\n } else {\n element = document.createElement('div');\n }\n this._element = element;\n\n // Update element to animation instance.\n animation._element = element;\n\n // Add placeholder class to the placeholder element.\n this._className = settings.itemPlaceholderClass || '';\n if (this._className) {\n addClass(element, this._className);\n }\n\n // Set initial styles.\n setStyles(element, {\n position: 'absolute',\n left: '0px',\n top: '0px',\n width: item._width + 'px',\n height: item._height + 'px',\n });\n\n // Set initial position.\n element.style[transformProp] = getTranslateString(\n item._left + item._marginLeft,\n item._top + item._marginTop\n );\n\n // Bind event listeners.\n grid.on(EVENT_LAYOUT_START, this._onLayoutStart);\n grid.on(EVENT_DRAG_RELEASE_END, this._onReleaseEnd);\n grid.on(EVENT_BEFORE_SEND, this._onMigrate);\n grid.on(EVENT_HIDE_START, this._onHide);\n\n // onCreate hook.\n if (isFunction(settings.dragPlaceholder.onCreate)) {\n settings.dragPlaceholder.onCreate(item, element);\n }\n\n // Insert the placeholder element to the grid.\n grid.getElement().appendChild(element);\n};\n\n/**\n * Reset placeholder data.\n *\n * @public\n */\nItemDragPlaceholder.prototype.reset = function () {\n if (!this.isActive()) return;\n\n var element = this._element;\n var item = this._item;\n var grid = item.getGrid();\n var settings = grid._settings;\n var animation = this._animation;\n\n // Reset flag.\n this._resetAfterLayout = false;\n\n // Cancel potential (queued) layout tick.\n cancelPlaceholderLayoutTick(item._id);\n cancelPlaceholderResizeTick(item._id);\n\n // Reset animation instance.\n animation.stop();\n animation._element = null;\n\n // Unbind event listeners.\n grid.off(EVENT_DRAG_RELEASE_END, this._onReleaseEnd);\n grid.off(EVENT_LAYOUT_START, this._onLayoutStart);\n grid.off(EVENT_BEFORE_SEND, this._onMigrate);\n grid.off(EVENT_HIDE_START, this._onHide);\n\n // Remove placeholder class from the placeholder element.\n if (this._className) {\n removeClass(element, this._className);\n this._className = '';\n }\n\n // Remove element.\n element.parentNode.removeChild(element);\n this._element = null;\n\n // onRemove hook. Note that here we use the current grid's onRemove callback\n // so if the item has migrated during drag the onRemove method will not be\n // the originating grid's method.\n if (isFunction(settings.dragPlaceholder.onRemove)) {\n settings.dragPlaceholder.onRemove(item, element);\n }\n};\n\n/**\n * Check if placeholder is currently active (visible).\n *\n * @public\n * @returns {Boolean}\n */\nItemDragPlaceholder.prototype.isActive = function () {\n return !!this._element;\n};\n\n/**\n * Get placeholder element.\n *\n * @public\n * @returns {?HTMLElement}\n */\nItemDragPlaceholder.prototype.getElement = function () {\n return this._element;\n};\n\n/**\n * Update placeholder's dimensions to match the item's dimensions. Note that\n * the updating is done asynchronously in the next tick to avoid layout\n * thrashing.\n *\n * @public\n */\nItemDragPlaceholder.prototype.updateDimensions = function () {\n if (!this.isActive()) return;\n addPlaceholderResizeTick(this._item._id, this._updateDimensions);\n};\n\n/**\n * Destroy placeholder instance.\n *\n * @public\n */\nItemDragPlaceholder.prototype.destroy = function () {\n this.reset();\n this._animation.destroy();\n this._item = this._animation = null;\n};\n\n/**\n * The release process handler constructor. Although this might seem as proper\n * fit for the drag process this needs to be separated into it's own logic\n * because there might be a scenario where drag is disabled, but the release\n * process still needs to be implemented (dragging from a grid to another).\n *\n * @class\n * @param {Item} item\n */\nfunction ItemDragRelease(item) {\n this._item = item;\n this._isActive = false;\n this._isDestroyed = false;\n this._isPositioningStarted = false;\n this._containerDiffX = 0;\n this._containerDiffY = 0;\n}\n\n/**\n * Public prototype methods\n * ************************\n */\n\n/**\n * Start the release process of an item.\n *\n * @public\n */\nItemDragRelease.prototype.start = function () {\n if (this._isDestroyed || this._isActive) return;\n\n var item = this._item;\n var grid = item.getGrid();\n var settings = grid._settings;\n\n this._isActive = true;\n addClass(item._element, settings.itemReleasingClass);\n if (!settings.dragRelease.useDragContainer) {\n this._placeToGrid();\n }\n grid._emit(EVENT_DRAG_RELEASE_START, item);\n\n // Let's start layout manually _only_ if there is no unfinished layout in\n // about to finish.\n if (!grid._nextLayoutData) item._layout.start(false);\n};\n\n/**\n * End the release process of an item. This method can be used to abort an\n * ongoing release process (animation) or finish the release process.\n *\n * @public\n * @param {Boolean} [abort=false]\n * - Should the release be aborted? When true, the release end event won't be\n * emitted. Set to true only when you need to abort the release process\n * while the item is animating to it's position.\n * @param {Number} [left]\n * - The element's current translateX value (optional).\n * @param {Number} [top]\n * - The element's current translateY value (optional).\n */\nItemDragRelease.prototype.stop = function (abort, left, top) {\n if (this._isDestroyed || !this._isActive) return;\n\n var item = this._item;\n var grid = item.getGrid();\n\n if (!abort && (left === undefined || top === undefined)) {\n left = item._left;\n top = item._top;\n }\n\n var didReparent = this._placeToGrid(left, top);\n this._reset(didReparent);\n\n if (!abort) grid._emit(EVENT_DRAG_RELEASE_END, item);\n};\n\nItemDragRelease.prototype.isJustReleased = function () {\n return this._isActive && this._isPositioningStarted === false;\n};\n\n/**\n * Destroy instance.\n *\n * @public\n */\nItemDragRelease.prototype.destroy = function () {\n if (this._isDestroyed) return;\n this.stop(true);\n this._item = null;\n this._isDestroyed = true;\n};\n\n/**\n * Private prototype methods\n * *************************\n */\n\n/**\n * Move the element back to the grid container element if it does not exist\n * there already.\n *\n * @private\n * @param {Number} [left]\n * - The element's current translateX value (optional).\n * @param {Number} [top]\n * - The element's current translateY value (optional).\n * @returns {Boolean}\n * - Returns `true` if the element was reparented.\n */\nItemDragRelease.prototype._placeToGrid = function (left, top) {\n if (this._isDestroyed) return;\n\n var item = this._item;\n var element = item._element;\n var container = item.getGrid()._element;\n var didReparent = false;\n\n if (element.parentNode !== container) {\n if (left === undefined || top === undefined) {\n var translate = getTranslate(element);\n left = translate.x - this._containerDiffX;\n top = translate.y - this._containerDiffY;\n }\n\n container.appendChild(element);\n item._setTranslate(left, top);\n didReparent = true;\n }\n\n this._containerDiffX = 0;\n this._containerDiffY = 0;\n\n return didReparent;\n};\n\n/**\n * Reset data and remove releasing class.\n *\n * @private\n * @param {Boolean} [needsReflow]\n */\nItemDragRelease.prototype._reset = function (needsReflow) {\n if (this._isDestroyed) return;\n\n var item = this._item;\n var releasingClass = item.getGrid()._settings.itemReleasingClass;\n\n this._isActive = false;\n this._isPositioningStarted = false;\n this._containerDiffX = 0;\n this._containerDiffY = 0;\n\n // If the element was just reparented we need to do a forced reflow to remove\n // the class gracefully.\n if (releasingClass) {\n // eslint-disable-next-line\n if (needsReflow) item._element.clientWidth;\n removeClass(item._element, releasingClass);\n }\n};\n\nvar MIN_ANIMATION_DISTANCE = 2;\n\n/**\n * Layout manager for Item instance, handles the positioning of an item.\n *\n * @class\n * @param {Item} item\n */\nfunction ItemLayout(item) {\n var element = item._element;\n var elementStyle = element.style;\n\n this._item = item;\n this._isActive = false;\n this._isDestroyed = false;\n this._isInterrupted = false;\n this._currentStyles = {};\n this._targetStyles = {};\n this._nextLeft = 0;\n this._nextTop = 0;\n this._offsetLeft = 0;\n this._offsetTop = 0;\n this._skipNextAnimation = false;\n this._animOptions = {\n onFinish: this._finish.bind(this),\n duration: 0,\n easing: 0,\n };\n\n // Set element's initial position styles.\n elementStyle.left = '0px';\n elementStyle.top = '0px';\n item._setTranslate(0, 0);\n\n this._animation = new Animator(element);\n this._queue = 'layout-' + item._id;\n\n // Bind animation handlers and finish method.\n this._setupAnimation = this._setupAnimation.bind(this);\n this._startAnimation = this._startAnimation.bind(this);\n}\n\n/**\n * Public prototype methods\n * ************************\n */\n\n/**\n * Start item layout based on it's current data.\n *\n * @public\n * @param {Boolean} instant\n * @param {Function} [onFinish]\n */\nItemLayout.prototype.start = function (instant, onFinish) {\n if (this._isDestroyed) return;\n\n var item = this._item;\n var release = item._dragRelease;\n var gridSettings = item.getGrid()._settings;\n var isPositioning = this._isActive;\n var isJustReleased = release.isJustReleased();\n var animDuration = isJustReleased\n ? gridSettings.dragRelease.duration\n : gridSettings.layoutDuration;\n var animEasing = isJustReleased ? gridSettings.dragRelease.easing : gridSettings.layoutEasing;\n var animEnabled = !instant && !this._skipNextAnimation && animDuration > 0;\n\n // If the item is currently positioning cancel potential queued layout tick\n // and process current layout callback queue with interrupted flag on.\n if (isPositioning) {\n cancelLayoutTick(item._id);\n item._emitter.burst(this._queue, true, item);\n }\n\n // Mark release positioning as started.\n if (isJustReleased) release._isPositioningStarted = true;\n\n // Push the callback to the callback queue.\n if (isFunction(onFinish)) {\n item._emitter.on(this._queue, onFinish);\n }\n\n // Reset animation skipping flag.\n this._skipNextAnimation = false;\n\n // If no animations are needed, easy peasy!\n if (!animEnabled) {\n this._updateOffsets();\n item._setTranslate(this._nextLeft, this._nextTop);\n this._animation.stop();\n this._finish();\n return;\n }\n\n // Let's make sure an ongoing animation's callback is cancelled before going\n // further. Without this there's a chance that the animation will finish\n // before the next tick and mess up our logic.\n if (this._animation.isAnimating()) {\n this._animation._animation.onfinish = null;\n }\n\n // Kick off animation to be started in the next tick.\n this._isActive = true;\n this._animOptions.easing = animEasing;\n this._animOptions.duration = animDuration;\n this._isInterrupted = isPositioning;\n addLayoutTick(item._id, this._setupAnimation, this._startAnimation);\n};\n\n/**\n * Stop item's position animation if it is currently animating.\n *\n * @public\n * @param {Boolean} processCallbackQueue\n * @param {Number} [left]\n * @param {Number} [top]\n */\nItemLayout.prototype.stop = function (processCallbackQueue, left, top) {\n if (this._isDestroyed || !this._isActive) return;\n\n var item = this._item;\n\n // Cancel animation init.\n cancelLayoutTick(item._id);\n\n // Stop animation.\n if (this._animation.isAnimating()) {\n if (left === undefined || top === undefined) {\n var translate = getTranslate(item._element);\n left = translate.x;\n top = translate.y;\n }\n item._setTranslate(left, top);\n this._animation.stop();\n }\n\n // Remove positioning class.\n removeClass(item._element, item.getGrid()._settings.itemPositioningClass);\n\n // Reset active state.\n this._isActive = false;\n\n // Process callback queue if needed.\n if (processCallbackQueue) {\n item._emitter.burst(this._queue, true, item);\n }\n};\n\n/**\n * Destroy the instance and stop current animation if it is running.\n *\n * @public\n */\nItemLayout.prototype.destroy = function () {\n if (this._isDestroyed) return;\n\n var elementStyle = this._item._element.style;\n\n this.stop(true, 0, 0);\n this._item._emitter.clear(this._queue);\n this._animation.destroy();\n\n elementStyle[transformProp] = '';\n elementStyle.left = '';\n elementStyle.top = '';\n\n this._item = null;\n this._currentStyles = null;\n this._targetStyles = null;\n this._animOptions = null;\n this._isDestroyed = true;\n};\n\n/**\n * Private prototype methods\n * *************************\n */\n\n/**\n * Calculate and update item's current layout offset data.\n *\n * @private\n */\nItemLayout.prototype._updateOffsets = function () {\n if (this._isDestroyed) return;\n\n var item = this._item;\n var migrate = item._migrate;\n var release = item._dragRelease;\n\n this._offsetLeft = release._isActive\n ? release._containerDiffX\n : migrate._isActive\n ? migrate._containerDiffX\n : 0;\n\n this._offsetTop = release._isActive\n ? release._containerDiffY\n : migrate._isActive\n ? migrate._containerDiffY\n : 0;\n\n this._nextLeft = this._item._left + this._offsetLeft;\n this._nextTop = this._item._top + this._offsetTop;\n};\n\n/**\n * Finish item layout procedure.\n *\n * @private\n */\nItemLayout.prototype._finish = function () {\n if (this._isDestroyed) return;\n\n var item = this._item;\n var migrate = item._migrate;\n var release = item._dragRelease;\n\n // Update internal translate values.\n item._tX = this._nextLeft;\n item._tY = this._nextTop;\n\n // Mark the item as inactive and remove positioning classes.\n if (this._isActive) {\n this._isActive = false;\n removeClass(item._element, item.getGrid()._settings.itemPositioningClass);\n }\n\n // Finish up release and migration.\n if (release._isActive) release.stop();\n if (migrate._isActive) migrate.stop();\n\n // Process the callback queue.\n item._emitter.burst(this._queue, false, item);\n};\n\n/**\n * Prepare item for layout animation.\n *\n * @private\n */\nItemLayout.prototype._setupAnimation = function () {\n var item = this._item;\n if (item._tX === undefined || item._tY === undefined) {\n var translate = getTranslate(item._element);\n item._tX = translate.x;\n item._tY = translate.y;\n }\n};\n\n/**\n * Start layout animation.\n *\n * @private\n */\nItemLayout.prototype._startAnimation = function () {\n var item = this._item;\n var settings = item.getGrid()._settings;\n var isInstant = this._animOptions.duration <= 0;\n\n // Let's update the offset data and target styles.\n this._updateOffsets();\n\n var xDiff = Math.abs(item._left - (item._tX - this._offsetLeft));\n var yDiff = Math.abs(item._top - (item._tY - this._offsetTop));\n\n // If there is no need for animation or if the item is already in correct\n // position (or near it) let's finish the process early.\n if (isInstant || (xDiff < MIN_ANIMATION_DISTANCE && yDiff < MIN_ANIMATION_DISTANCE)) {\n if (xDiff || yDiff || this._isInterrupted) {\n item._setTranslate(this._nextLeft, this._nextTop);\n }\n this._animation.stop();\n this._finish();\n return;\n }\n\n // Set item's positioning class if needed.\n if (!this._isInterrupted) {\n addClass(item._element, settings.itemPositioningClass);\n }\n\n // Get current/next styles for animation.\n this._currentStyles[transformProp] = getTranslateString(item._tX, item._tY);\n this._targetStyles[transformProp] = getTranslateString(this._nextLeft, this._nextTop);\n\n // Set internal translation values to undefined for the duration of the\n // animation since they will be changing on each animation frame for the\n // duration of the animation and tracking them would mean reading the DOM on\n // each frame, which is pretty darn expensive.\n item._tX = item._tY = undefined;\n\n // Start animation.\n this._animation.start(this._currentStyles, this._targetStyles, this._animOptions);\n};\n\n/**\n * The migrate process handler constructor.\n *\n * @class\n * @param {Item} item\n */\nfunction ItemMigrate(item) {\n // Private props.\n this._item = item;\n this._isActive = false;\n this._isDestroyed = false;\n this._container = false;\n this._containerDiffX = 0;\n this._containerDiffY = 0;\n}\n\n/**\n * Public prototype methods\n * ************************\n */\n\n/**\n * Start the migrate process of an item.\n *\n * @public\n * @param {Grid} targetGrid\n * @param {(HTMLElement|Number|Item)} position\n * @param {HTMLElement} [container]\n */\nItemMigrate.prototype.start = function (targetGrid, position, container) {\n if (this._isDestroyed) return;\n\n var item = this._item;\n var element = item._element;\n var isActive = item.isActive();\n var isVisible = item.isVisible();\n var grid = item.getGrid();\n var settings = grid._settings;\n var targetSettings = targetGrid._settings;\n var targetElement = targetGrid._element;\n var targetItems = targetGrid._items;\n var currentIndex = grid._items.indexOf(item);\n var targetContainer = container || document.body;\n var targetIndex;\n var targetItem;\n var currentContainer;\n var offsetDiff;\n var containerDiff;\n var translate;\n var translateX;\n var translateY;\n var currentVisClass;\n var nextVisClass;\n\n // Get target index.\n if (typeof position === 'number') {\n targetIndex = normalizeArrayIndex(targetItems, position, 1);\n } else {\n targetItem = targetGrid.getItem(position);\n if (!targetItem) return;\n targetIndex = targetItems.indexOf(targetItem);\n }\n\n // Get current translateX and translateY values if needed.\n if (item.isPositioning() || this._isActive || item.isReleasing()) {\n translate = getTranslate(element);\n translateX = translate.x;\n translateY = translate.y;\n }\n\n // Abort current positioning.\n if (item.isPositioning()) {\n item._layout.stop(true, translateX, translateY);\n }\n\n // Abort current migration.\n if (this._isActive) {\n translateX -= this._containerDiffX;\n translateY -= this._containerDiffY;\n this.stop(true, translateX, translateY);\n }\n\n // Abort current release.\n if (item.isReleasing()) {\n translateX -= item._dragRelease._containerDiffX;\n translateY -= item._dragRelease._containerDiffY;\n item._dragRelease.stop(true, translateX, translateY);\n }\n\n // Stop current visibility animation.\n item._visibility.stop(true);\n\n // Destroy current drag.\n if (item._drag) item._drag.destroy();\n\n // Emit beforeSend event.\n if (grid._hasListeners(EVENT_BEFORE_SEND)) {\n grid._emit(EVENT_BEFORE_SEND, {\n item: item,\n fromGrid: grid,\n fromIndex: currentIndex,\n toGrid: targetGrid,\n toIndex: targetIndex,\n });\n }\n\n // Emit beforeReceive event.\n if (targetGrid._hasListeners(EVENT_BEFORE_RECEIVE)) {\n targetGrid._emit(EVENT_BEFORE_RECEIVE, {\n item: item,\n fromGrid: grid,\n fromIndex: currentIndex,\n toGrid: targetGrid,\n toIndex: targetIndex,\n });\n }\n\n // Update item class.\n if (settings.itemClass !== targetSettings.itemClass) {\n removeClass(element, settings.itemClass);\n addClass(element, targetSettings.itemClass);\n }\n\n // Update visibility class.\n currentVisClass = isVisible ? settings.itemVisibleClass : settings.itemHiddenClass;\n nextVisClass = isVisible ? targetSettings.itemVisibleClass : targetSettings.itemHiddenClass;\n if (currentVisClass !== nextVisClass) {\n removeClass(element, currentVisClass);\n addClass(element, nextVisClass);\n }\n\n // Move item instance from current grid to target grid.\n grid._items.splice(currentIndex, 1);\n arrayInsert(targetItems, item, targetIndex);\n\n // Update item's grid id reference.\n item._gridId = targetGrid._id;\n\n // If item is active we need to move the item inside the target container for\n // the duration of the (potential) animation if it's different than the\n // current container.\n if (isActive) {\n currentContainer = element.parentNode;\n if (targetContainer !== currentContainer) {\n targetContainer.appendChild(element);\n offsetDiff = getOffsetDiff(targetContainer, currentContainer, true);\n if (!translate) {\n translate = getTranslate(element);\n translateX = translate.x;\n translateY = translate.y;\n }\n item._setTranslate(translateX + offsetDiff.left, translateY + offsetDiff.top);\n }\n }\n // If item is not active let's just append it to the target grid's element.\n else {\n targetElement.appendChild(element);\n }\n\n // Update child element's styles to reflect the current visibility state.\n item._visibility.setStyles(\n isVisible ? targetSettings.visibleStyles : targetSettings.hiddenStyles\n );\n\n // Get offset diff for the migration data, if the item is active.\n if (isActive) {\n containerDiff = getOffsetDiff(targetContainer, targetElement, true);\n }\n\n // Update item's cached dimensions.\n item._refreshDimensions();\n\n // Reset item's sort data.\n item._sortData = null;\n\n // Create new drag handler.\n item._drag = targetSettings.dragEnabled ? new ItemDrag(item) : null;\n\n // Setup migration data.\n if (isActive) {\n this._isActive = true;\n this._container = targetContainer;\n this._containerDiffX = containerDiff.left;\n this._containerDiffY = containerDiff.top;\n } else {\n this._isActive = false;\n this._container = null;\n this._containerDiffX = 0;\n this._containerDiffY = 0;\n }\n\n // Emit send event.\n if (grid._hasListeners(EVENT_SEND)) {\n grid._emit(EVENT_SEND, {\n item: item,\n fromGrid: grid,\n fromIndex: currentIndex,\n toGrid: targetGrid,\n toIndex: targetIndex,\n });\n }\n\n // Emit receive event.\n if (targetGrid._hasListeners(EVENT_RECEIVE)) {\n targetGrid._emit(EVENT_RECEIVE, {\n item: item,\n fromGrid: grid,\n fromIndex: currentIndex,\n toGrid: targetGrid,\n toIndex: targetIndex,\n });\n }\n};\n\n/**\n * End the migrate process of an item. This method can be used to abort an\n * ongoing migrate process (animation) or finish the migrate process.\n *\n * @public\n * @param {Boolean} [abort=false]\n * - Should the migration be aborted?\n * @param {Number} [left]\n * - The element's current translateX value (optional).\n * @param {Number} [top]\n * - The element's current translateY value (optional).\n */\nItemMigrate.prototype.stop = function (abort, left, top) {\n if (this._isDestroyed || !this._isActive) return;\n\n var item = this._item;\n var element = item._element;\n var grid = item.getGrid();\n var gridElement = grid._element;\n var translate;\n\n if (this._container !== gridElement) {\n if (left === undefined || top === undefined) {\n if (abort) {\n translate = getTranslate(element);\n left = translate.x - this._containerDiffX;\n top = translate.y - this._containerDiffY;\n } else {\n left = item._left;\n top = item._top;\n }\n }\n\n gridElement.appendChild(element);\n item._setTranslate(left, top);\n }\n\n this._isActive = false;\n this._container = null;\n this._containerDiffX = 0;\n this._containerDiffY = 0;\n};\n\n/**\n * Destroy instance.\n *\n * @public\n */\nItemMigrate.prototype.destroy = function () {\n if (this._isDestroyed) return;\n this.stop(true);\n this._item = null;\n this._isDestroyed = true;\n};\n\n/**\n * Visibility manager for Item instance, handles visibility of an item.\n *\n * @class\n * @param {Item} item\n */\nfunction ItemVisibility(item) {\n var isActive = item._isActive;\n var element = item._element;\n var childElement = element.children[0];\n var settings = item.getGrid()._settings;\n\n if (!childElement) {\n throw new Error('No valid child element found within item element.');\n }\n\n this._item = item;\n this._isDestroyed = false;\n this._isHidden = !isActive;\n this._isHiding = false;\n this._isShowing = false;\n this._childElement = childElement;\n this._currentStyleProps = [];\n this._animation = new Animator(childElement);\n this._queue = 'visibility-' + item._id;\n this._finishShow = this._finishShow.bind(this);\n this._finishHide = this._finishHide.bind(this);\n\n element.style.display = isActive ? '' : 'none';\n addClass(element, isActive ? settings.itemVisibleClass : settings.itemHiddenClass);\n this.setStyles(isActive ? settings.visibleStyles : settings.hiddenStyles);\n}\n\n/**\n * Public prototype methods\n * ************************\n */\n\n/**\n * Show item.\n *\n * @public\n * @param {Boolean} instant\n * @param {Function} [onFinish]\n */\nItemVisibility.prototype.show = function (instant, onFinish) {\n if (this._isDestroyed) return;\n\n var item = this._item;\n var element = item._element;\n var callback = isFunction(onFinish) ? onFinish : null;\n var grid = item.getGrid();\n var settings = grid._settings;\n\n // If item is visible call the callback and be done with it.\n if (!this._isShowing && !this._isHidden) {\n callback && callback(false, item);\n return;\n }\n\n // If item is showing and does not need to be shown instantly, let's just\n // push callback to the callback queue and be done with it.\n if (this._isShowing && !instant) {\n callback && item._emitter.on(this._queue, callback);\n return;\n }\n\n // If the item is hiding or hidden process the current visibility callback\n // queue with the interrupted flag active, update classes and set display\n // to block if necessary.\n if (!this._isShowing) {\n item._emitter.burst(this._queue, true, item);\n removeClass(element, settings.itemHiddenClass);\n addClass(element, settings.itemVisibleClass);\n if (!this._isHiding) element.style.display = '';\n }\n\n // Push callback to the callback queue.\n callback && item._emitter.on(this._queue, callback);\n\n // Update visibility states.\n this._isShowing = true;\n this._isHiding = this._isHidden = false;\n\n // Finally let's start show animation.\n this._startAnimation(true, instant, this._finishShow);\n};\n\n/**\n * Hide item.\n *\n * @public\n * @param {Boolean} instant\n * @param {Function} [onFinish]\n */\nItemVisibility.prototype.hide = function (instant, onFinish) {\n if (this._isDestroyed) return;\n\n var item = this._item;\n var element = item._element;\n var callback = isFunction(onFinish) ? onFinish : null;\n var grid = item.getGrid();\n var settings = grid._settings;\n\n // If item is already hidden call the callback and be done with it.\n if (!this._isHiding && this._isHidden) {\n callback && callback(false, item);\n return;\n }\n\n // If item is hiding and does not need to be hidden instantly, let's just\n // push callback to the callback queue and be done with it.\n if (this._isHiding && !instant) {\n callback && item._emitter.on(this._queue, callback);\n return;\n }\n\n // If the item is showing or visible process the current visibility callback\n // queue with the interrupted flag active, update classes and set display\n // to block if necessary.\n if (!this._isHiding) {\n item._emitter.burst(this._queue, true, item);\n addClass(element, settings.itemHiddenClass);\n removeClass(element, settings.itemVisibleClass);\n }\n\n // Push callback to the callback queue.\n callback && item._emitter.on(this._queue, callback);\n\n // Update visibility states.\n this._isHidden = this._isHiding = true;\n this._isShowing = false;\n\n // Finally let's start hide animation.\n this._startAnimation(false, instant, this._finishHide);\n};\n\n/**\n * Stop current hiding/showing process.\n *\n * @public\n * @param {Boolean} processCallbackQueue\n */\nItemVisibility.prototype.stop = function (processCallbackQueue) {\n if (this._isDestroyed) return;\n if (!this._isHiding && !this._isShowing) return;\n\n var item = this._item;\n\n cancelVisibilityTick(item._id);\n this._animation.stop();\n if (processCallbackQueue) {\n item._emitter.burst(this._queue, true, item);\n }\n};\n\n/**\n * Reset all existing visibility styles and apply new visibility styles to the\n * visibility element. This method should be used to set styles when there is a\n * chance that the current style properties differ from the new ones (basically\n * on init and on migrations).\n *\n * @public\n * @param {Object} styles\n */\nItemVisibility.prototype.setStyles = function (styles) {\n var childElement = this._childElement;\n var currentStyleProps = this._currentStyleProps;\n this._removeCurrentStyles();\n for (var prop in styles) {\n currentStyleProps.push(prop);\n childElement.style[prop] = styles[prop];\n }\n};\n\n/**\n * Destroy the instance and stop current animation if it is running.\n *\n * @public\n */\nItemVisibility.prototype.destroy = function () {\n if (this._isDestroyed) return;\n\n var item = this._item;\n var element = item._element;\n var grid = item.getGrid();\n var settings = grid._settings;\n\n this.stop(true);\n item._emitter.clear(this._queue);\n this._animation.destroy();\n this._removeCurrentStyles();\n removeClass(element, settings.itemVisibleClass);\n removeClass(element, settings.itemHiddenClass);\n element.style.display = '';\n\n // Reset state.\n this._isHiding = this._isShowing = false;\n this._isDestroyed = this._isHidden = true;\n};\n\n/**\n * Private prototype methods\n * *************************\n */\n\n/**\n * Start visibility animation.\n *\n * @private\n * @param {Boolean} toVisible\n * @param {Boolean} [instant]\n * @param {Function} [onFinish]\n */\nItemVisibility.prototype._startAnimation = function (toVisible, instant, onFinish) {\n if (this._isDestroyed) return;\n\n var item = this._item;\n var animation = this._animation;\n var childElement = this._childElement;\n var settings = item.getGrid()._settings;\n var targetStyles = toVisible ? settings.visibleStyles : settings.hiddenStyles;\n var duration = toVisible ? settings.showDuration : settings.hideDuration;\n var easing = toVisible ? settings.showEasing : settings.hideEasing;\n var isInstant = instant || duration <= 0;\n var currentStyles;\n\n // No target styles? Let's quit early.\n if (!targetStyles) {\n onFinish && onFinish();\n return;\n }\n\n // Cancel queued visibility tick.\n cancelVisibilityTick(item._id);\n\n // If we need to apply the styles instantly without animation.\n if (isInstant) {\n setStyles(childElement, targetStyles);\n animation.stop();\n onFinish && onFinish();\n return;\n }\n\n // Let's make sure an ongoing animation's callback is cancelled before going\n // further. Without this there's a chance that the animation will finish\n // before the next tick and mess up our logic.\n if (animation.isAnimating()) {\n animation._animation.onfinish = null;\n }\n\n // Start the animation in the next tick (to avoid layout thrashing).\n addVisibilityTick(\n item._id,\n function () {\n currentStyles = getCurrentStyles(childElement, targetStyles);\n },\n function () {\n animation.start(currentStyles, targetStyles, {\n duration: duration,\n easing: easing,\n onFinish: onFinish,\n });\n }\n );\n};\n\n/**\n * Finish show procedure.\n *\n * @private\n */\nItemVisibility.prototype._finishShow = function () {\n if (this._isHidden) return;\n this._isShowing = false;\n this._item._emitter.burst(this._queue, false, this._item);\n};\n\n/**\n * Finish hide procedure.\n *\n * @private\n */\nItemVisibility.prototype._finishHide = function () {\n if (!this._isHidden) return;\n var item = this._item;\n this._isHiding = false;\n item._layout.stop(true, 0, 0);\n item._element.style.display = 'none';\n item._emitter.burst(this._queue, false, item);\n};\n\n/**\n * Remove currently applied visibility related inline style properties.\n *\n * @private\n */\nItemVisibility.prototype._removeCurrentStyles = function () {\n var childElement = this._childElement;\n var currentStyleProps = this._currentStyleProps;\n\n for (var i = 0; i < currentStyleProps.length; i++) {\n childElement.style[currentStyleProps[i]] = '';\n }\n\n currentStyleProps.length = 0;\n};\n\nvar id = 0;\n\n/**\n * Returns a unique numeric id (increments a base value on every call).\n * @returns {Number}\n */\nfunction createUid() {\n return ++id;\n}\n\n/**\n * Creates a new Item instance for a Grid instance.\n *\n * @class\n * @param {Grid} grid\n * @param {HTMLElement} element\n * @param {Boolean} [isActive]\n */\nfunction Item(grid, element, isActive) {\n var settings = grid._settings;\n\n // Store item/element pair to a map (for faster item querying by element).\n if (ITEM_ELEMENT_MAP) {\n if (ITEM_ELEMENT_MAP.has(element)) {\n throw new Error('You can only create one Muuri Item per element!');\n } else {\n ITEM_ELEMENT_MAP.set(element, this);\n }\n }\n\n this._id = createUid();\n this._gridId = grid._id;\n this._element = element;\n this._isDestroyed = false;\n this._left = 0;\n this._top = 0;\n this._width = 0;\n this._height = 0;\n this._marginLeft = 0;\n this._marginRight = 0;\n this._marginTop = 0;\n this._marginBottom = 0;\n this._tX = undefined;\n this._tY = undefined;\n this._sortData = null;\n this._emitter = new Emitter();\n\n // If the provided item element is not a direct child of the grid container\n // element, append it to the grid container. Note, we are indeed reading the\n // DOM here but it's a property that does not cause reflowing.\n if (element.parentNode !== grid._element) {\n grid._element.appendChild(element);\n }\n\n // Set item class.\n addClass(element, settings.itemClass);\n\n // If isActive is not defined, let's try to auto-detect it. Note, we are\n // indeed reading the DOM here but it's a property that does not cause\n // reflowing.\n if (typeof isActive !== 'boolean') {\n isActive = getStyle(element, 'display') !== 'none';\n }\n\n // Set up active state (defines if the item is considered part of the layout\n // or not).\n this._isActive = isActive;\n\n // Setup visibility handler.\n this._visibility = new ItemVisibility(this);\n\n // Set up layout handler.\n this._layout = new ItemLayout(this);\n\n // Set up migration handler data.\n this._migrate = new ItemMigrate(this);\n\n // Set up drag handler.\n this._drag = settings.dragEnabled ? new ItemDrag(this) : null;\n\n // Set up release handler. Note that although this is fully linked to dragging\n // this still needs to be always instantiated to handle migration scenarios\n // correctly.\n this._dragRelease = new ItemDragRelease(this);\n\n // Set up drag placeholder handler. Note that although this is fully linked to\n // dragging this still needs to be always instantiated to handle migration\n // scenarios correctly.\n this._dragPlaceholder = new ItemDragPlaceholder(this);\n\n // Note! You must call the following methods before you start using the\n // instance. They are deliberately not called in the end as it would cause\n // potentially a massive amount of reflows if multiple items were instantiated\n // in a loop.\n // this._refreshDimensions();\n // this._refreshSortData();\n}\n\n/**\n * Public prototype methods\n * ************************\n */\n\n/**\n * Get the instance grid reference.\n *\n * @public\n * @returns {Grid}\n */\nItem.prototype.getGrid = function () {\n return GRID_INSTANCES[this._gridId];\n};\n\n/**\n * Get the instance element.\n *\n * @public\n * @returns {HTMLElement}\n */\nItem.prototype.getElement = function () {\n return this._element;\n};\n\n/**\n * Get instance element's cached width.\n *\n * @public\n * @returns {Number}\n */\nItem.prototype.getWidth = function () {\n return this._width;\n};\n\n/**\n * Get instance element's cached height.\n *\n * @public\n * @returns {Number}\n */\nItem.prototype.getHeight = function () {\n return this._height;\n};\n\n/**\n * Get instance element's cached margins.\n *\n * @public\n * @returns {Object}\n * - The returned object contains left, right, top and bottom properties\n * which indicate the item element's cached margins.\n */\nItem.prototype.getMargin = function () {\n return {\n left: this._marginLeft,\n right: this._marginRight,\n top: this._marginTop,\n bottom: this._marginBottom,\n };\n};\n\n/**\n * Get instance element's cached position.\n *\n * @public\n * @returns {Object}\n * - The returned object contains left and top properties which indicate the\n * item element's cached position in the grid.\n */\nItem.prototype.getPosition = function () {\n return {\n left: this._left,\n top: this._top,\n };\n};\n\n/**\n * Is the item active?\n *\n * @public\n * @returns {Boolean}\n */\nItem.prototype.isActive = function () {\n return this._isActive;\n};\n\n/**\n * Is the item visible?\n *\n * @public\n * @returns {Boolean}\n */\nItem.prototype.isVisible = function () {\n return !!this._visibility && !this._visibility._isHidden;\n};\n\n/**\n * Is the item being animated to visible?\n *\n * @public\n * @returns {Boolean}\n */\nItem.prototype.isShowing = function () {\n return !!(this._visibility && this._visibility._isShowing);\n};\n\n/**\n * Is the item being animated to hidden?\n *\n * @public\n * @returns {Boolean}\n */\nItem.prototype.isHiding = function () {\n return !!(this._visibility && this._visibility._isHiding);\n};\n\n/**\n * Is the item positioning?\n *\n * @public\n * @returns {Boolean}\n */\nItem.prototype.isPositioning = function () {\n return !!(this._layout && this._layout._isActive);\n};\n\n/**\n * Is the item being dragged (or queued for dragging)?\n *\n * @public\n * @returns {Boolean}\n */\nItem.prototype.isDragging = function () {\n return !!(this._drag && this._drag._isActive);\n};\n\n/**\n * Is the item being released?\n *\n * @public\n * @returns {Boolean}\n */\nItem.prototype.isReleasing = function () {\n return !!(this._dragRelease && this._dragRelease._isActive);\n};\n\n/**\n * Is the item destroyed?\n *\n * @public\n * @returns {Boolean}\n */\nItem.prototype.isDestroyed = function () {\n return this._isDestroyed;\n};\n\n/**\n * Private prototype methods\n * *************************\n */\n\n/**\n * Recalculate item's dimensions.\n *\n * @private\n * @param {Boolean} [force=false]\n */\nItem.prototype._refreshDimensions = function (force) {\n if (this._isDestroyed) return;\n if (force !== true && this._visibility._isHidden) return;\n\n var element = this._element;\n var dragPlaceholder = this._dragPlaceholder;\n var rect = element.getBoundingClientRect();\n\n // Calculate width and height.\n this._width = rect.width;\n this._height = rect.height;\n\n // Calculate margins (ignore negative margins).\n this._marginLeft = Math.max(0, getStyleAsFloat(element, 'margin-left'));\n this._marginRight = Math.max(0, getStyleAsFloat(element, 'margin-right'));\n this._marginTop = Math.max(0, getStyleAsFloat(element, 'margin-top'));\n this._marginBottom = Math.max(0, getStyleAsFloat(element, 'margin-bottom'));\n\n // Keep drag placeholder's dimensions synced with the item's.\n if (dragPlaceholder) dragPlaceholder.updateDimensions();\n};\n\n/**\n * Fetch and store item's sort data.\n *\n * @private\n */\nItem.prototype._refreshSortData = function () {\n if (this._isDestroyed) return;\n\n var data = (this._sortData = {});\n var getters = this.getGrid()._settings.sortData;\n var prop;\n\n for (prop in getters) {\n data[prop] = getters[prop](this, this._element);\n }\n};\n\n/**\n * Add item to layout.\n *\n * @private\n */\nItem.prototype._addToLayout = function (left, top) {\n if (this._isActive === true) return;\n this._isActive = true;\n this._left = left || 0;\n this._top = top || 0;\n};\n\n/**\n * Remove item from layout.\n *\n * @private\n */\nItem.prototype._removeFromLayout = function () {\n if (this._isActive === false) return;\n this._isActive = false;\n this._left = 0;\n this._top = 0;\n};\n\n/**\n * Check if the layout procedure can be skipped for the item.\n *\n * @private\n * @param {Number} left\n * @param {Number} top\n * @returns {Boolean}\n */\nItem.prototype._canSkipLayout = function (left, top) {\n return (\n this._left === left &&\n this._top === top &&\n !this._migrate._isActive &&\n !this._layout._skipNextAnimation &&\n !this._dragRelease.isJustReleased()\n );\n};\n\n/**\n * Set the provided left and top arguments as the item element's translate\n * values in the DOM. This method keeps track of the currently applied\n * translate values and skips the update operation if the provided values are\n * identical to the currently applied values. Returns `false` if there was no\n * need for update and `true` if the translate value was updated.\n *\n * @private\n * @param {Number} left\n * @param {Number} top\n * @returns {Boolean}\n */\nItem.prototype._setTranslate = function (left, top) {\n if (this._tX === left && this._tY === top) return false;\n this._tX = left;\n this._tY = top;\n this._element.style[transformProp] = getTranslateString(left, top);\n return true;\n};\n\n/**\n * Destroy item instance.\n *\n * @private\n * @param {Boolean} [removeElement=false]\n */\nItem.prototype._destroy = function (removeElement) {\n if (this._isDestroyed) return;\n\n var element = this._element;\n var grid = this.getGrid();\n var settings = grid._settings;\n\n // Destroy handlers.\n this._dragPlaceholder.destroy();\n this._dragRelease.destroy();\n this._migrate.destroy();\n this._layout.destroy();\n this._visibility.destroy();\n if (this._drag) this._drag.destroy();\n\n // Destroy emitter.\n this._emitter.destroy();\n\n // Remove item class.\n removeClass(element, settings.itemClass);\n\n // Remove element from DOM.\n if (removeElement) element.parentNode.removeChild(element);\n\n // Remove item/element pair from map.\n if (ITEM_ELEMENT_MAP) ITEM_ELEMENT_MAP.delete(element);\n\n // Reset state.\n this._isActive = false;\n this._isDestroyed = true;\n};\n\nfunction createPackerProcessor(isWorker) {\n var FILL_GAPS = 1;\n var HORIZONTAL = 2;\n var ALIGN_RIGHT = 4;\n var ALIGN_BOTTOM = 8;\n var ROUNDING = 16;\n\n var EPS = 0.001;\n var MIN_SLOT_SIZE = 0.5;\n\n // Rounds number first to three decimal precision and then floors the result\n // to two decimal precision.\n // Math.floor(Math.round(number * 1000) / 10) / 100\n function roundNumber(number) {\n return ((((number * 1000 + 0.5) << 0) / 10) << 0) / 100;\n }\n\n /**\n * @class\n */\n function PackerProcessor() {\n this.currentRects = [];\n this.nextRects = [];\n this.rectTarget = {};\n this.rectStore = [];\n this.slotSizes = [];\n this.rectId = 0;\n this.slotIndex = -1;\n this.slotData = { left: 0, top: 0, width: 0, height: 0 };\n this.sortRectsLeftTop = this.sortRectsLeftTop.bind(this);\n this.sortRectsTopLeft = this.sortRectsTopLeft.bind(this);\n }\n\n /**\n * Takes a layout object as an argument and computes positions (slots) for the\n * layout items. Also computes the final width and height of the layout. The\n * provided layout object's slots array is mutated as well as the width and\n * height properties.\n *\n * @param {Object} layout\n * @param {Number} layout.width\n * - The start (current) width of the layout in pixels.\n * @param {Number} layout.height\n * - The start (current) height of the layout in pixels.\n * @param {(Item[]|Number[])} layout.items\n * - List of Muuri.Item instances or a list of item dimensions\n * (e.g [ item1Width, item1Height, item2Width, item2Height, ... ]).\n * @param {(Array|Float32Array)} layout.slots\n * - An Array/Float32Array instance which's length should equal to\n * the amount of items times two. The position (width and height) of each\n * item will be written into this array.\n * @param {Number} settings\n * - The layout's settings as bitmasks.\n * @returns {Object}\n */\n PackerProcessor.prototype.computeLayout = function (layout, settings) {\n var items = layout.items;\n var slots = layout.slots;\n var fillGaps = !!(settings & FILL_GAPS);\n var horizontal = !!(settings & HORIZONTAL);\n var alignRight = !!(settings & ALIGN_RIGHT);\n var alignBottom = !!(settings & ALIGN_BOTTOM);\n var rounding = !!(settings & ROUNDING);\n var isPreProcessed = typeof items[0] === 'number';\n var i, bump, item, slotWidth, slotHeight, slot;\n\n // No need to go further if items do not exist.\n if (!items.length) return layout;\n\n // Compute slots for the items.\n bump = isPreProcessed ? 2 : 1;\n for (i = 0; i < items.length; i += bump) {\n // If items are pre-processed it means that items array contains only\n // the raw dimensions of the items. Otherwise we assume it is an array\n // of normal Muuri items.\n if (isPreProcessed) {\n slotWidth = items[i];\n slotHeight = items[i + 1];\n } else {\n item = items[i];\n slotWidth = item._width + item._marginLeft + item._marginRight;\n slotHeight = item._height + item._marginTop + item._marginBottom;\n }\n\n // If rounding is enabled let's round the item's width and height to\n // make the layout algorithm a bit more stable. This has a performance\n // cost so don't use this if not necessary.\n if (rounding) {\n slotWidth = roundNumber(slotWidth);\n slotHeight = roundNumber(slotHeight);\n }\n\n // Get slot data.\n slot = this.computeNextSlot(layout, slotWidth, slotHeight, fillGaps, horizontal);\n\n // Update layout width/height.\n if (horizontal) {\n if (slot.left + slot.width > layout.width) {\n layout.width = slot.left + slot.width;\n }\n } else {\n if (slot.top + slot.height > layout.height) {\n layout.height = slot.top + slot.height;\n }\n }\n\n // Add item slot data to layout slots.\n slots[++this.slotIndex] = slot.left;\n slots[++this.slotIndex] = slot.top;\n\n // Store the size too (for later usage) if needed.\n if (alignRight || alignBottom) {\n this.slotSizes.push(slot.width, slot.height);\n }\n }\n\n // If the alignment is set to right we need to adjust the results.\n if (alignRight) {\n for (i = 0; i < slots.length; i += 2) {\n slots[i] = layout.width - (slots[i] + this.slotSizes[i]);\n }\n }\n\n // If the alignment is set to bottom we need to adjust the results.\n if (alignBottom) {\n for (i = 1; i < slots.length; i += 2) {\n slots[i] = layout.height - (slots[i] + this.slotSizes[i]);\n }\n }\n\n // Reset stuff.\n this.slotSizes.length = 0;\n this.currentRects.length = 0;\n this.nextRects.length = 0;\n this.rectStore.length = 0;\n this.rectId = 0;\n this.slotIndex = -1;\n\n return layout;\n };\n\n /**\n * Calculate next slot in the layout. Returns a slot object with position and\n * dimensions data. The returned object is reused between calls.\n *\n * @param {Object} layout\n * @param {Number} slotWidth\n * @param {Number} slotHeight\n * @param {Boolean} fillGaps\n * @param {Boolean} horizontal\n * @returns {Object}\n */\n PackerProcessor.prototype.computeNextSlot = function (\n layout,\n slotWidth,\n slotHeight,\n fillGaps,\n horizontal\n ) {\n var slot = this.slotData;\n var currentRects = this.currentRects;\n var nextRects = this.nextRects;\n var ignoreCurrentRects = false;\n var rect;\n var rectId;\n var shards;\n var i;\n var j;\n\n // Reset new slots.\n nextRects.length = 0;\n\n // Set item slot initial data.\n slot.left = null;\n slot.top = null;\n slot.width = slotWidth;\n slot.height = slotHeight;\n\n // Try to find position for the slot from the existing free spaces in the\n // layout.\n for (i = 0; i < currentRects.length; i++) {\n rectId = currentRects[i];\n if (!rectId) continue;\n rect = this.getRect(rectId);\n if (slot.width <= rect.width + EPS && slot.height <= rect.height + EPS) {\n slot.left = rect.left;\n slot.top = rect.top;\n break;\n }\n }\n\n // If no position was found for the slot let's position the slot to\n // the bottom left (in vertical mode) or top right (in horizontal mode) of\n // the layout.\n if (slot.left === null) {\n if (horizontal) {\n slot.left = layout.width;\n slot.top = 0;\n } else {\n slot.left = 0;\n slot.top = layout.height;\n }\n\n // If gaps don't need filling let's throw away all the current free spaces\n // (currentRects).\n if (!fillGaps) {\n ignoreCurrentRects = true;\n }\n }\n\n // In vertical mode, if the slot's bottom overlaps the layout's bottom.\n if (!horizontal && slot.top + slot.height > layout.height + EPS) {\n // If slot is not aligned to the left edge, create a new free space to the\n // left of the slot.\n if (slot.left > MIN_SLOT_SIZE) {\n nextRects.push(this.addRect(0, layout.height, slot.left, Infinity));\n }\n\n // If slot is not aligned to the right edge, create a new free space to\n // the right of the slot.\n if (slot.left + slot.width < layout.width - MIN_SLOT_SIZE) {\n nextRects.push(\n this.addRect(\n slot.left + slot.width,\n layout.height,\n layout.width - slot.left - slot.width,\n Infinity\n )\n );\n }\n\n // Update layout height.\n layout.height = slot.top + slot.height;\n }\n\n // In horizontal mode, if the slot's right overlaps the layout's right edge.\n if (horizontal && slot.left + slot.width > layout.width + EPS) {\n // If slot is not aligned to the top, create a new free space above the\n // slot.\n if (slot.top > MIN_SLOT_SIZE) {\n nextRects.push(this.addRect(layout.width, 0, Infinity, slot.top));\n }\n\n // If slot is not aligned to the bottom, create a new free space below\n // the slot.\n if (slot.top + slot.height < layout.height - MIN_SLOT_SIZE) {\n nextRects.push(\n this.addRect(\n layout.width,\n slot.top + slot.height,\n Infinity,\n layout.height - slot.top - slot.height\n )\n );\n }\n\n // Update layout width.\n layout.width = slot.left + slot.width;\n }\n\n // Clean up the current free spaces making sure none of them overlap with\n // the slot. Split all overlapping free spaces into smaller shards that do\n // not overlap with the slot.\n if (!ignoreCurrentRects) {\n if (fillGaps) i = 0;\n for (; i < currentRects.length; i++) {\n rectId = currentRects[i];\n if (!rectId) continue;\n rect = this.getRect(rectId);\n shards = this.splitRect(rect, slot);\n for (j = 0; j < shards.length; j++) {\n rectId = shards[j];\n rect = this.getRect(rectId);\n // Make sure that the free space is within the boundaries of the\n // layout. This routine is critical to the algorithm as it makes sure\n // that there are no leftover spaces with infinite height/width.\n // It's also essential that we don't compare values absolutely to each\n // other but leave a little headroom (EPSILON) to get rid of false\n // positives.\n if (\n horizontal ? rect.left + EPS < layout.width - EPS : rect.top + EPS < layout.height - EPS\n ) {\n nextRects.push(rectId);\n }\n }\n }\n }\n\n // Sanitize and sort all the new free spaces that will be used in the next\n // iteration. This procedure is critical to make the bin-packing algorithm\n // work. The free spaces have to be in correct order in the beginning of the\n // next iteration.\n if (nextRects.length > 1) {\n this.purgeRects(nextRects).sort(horizontal ? this.sortRectsLeftTop : this.sortRectsTopLeft);\n }\n\n // Finally we need to make sure that `this.currentRects` points to\n // `nextRects` array as that is used in the next iteration's beginning when\n // we try to find a space for the next slot.\n this.currentRects = nextRects;\n this.nextRects = currentRects;\n\n return slot;\n };\n\n /**\n * Add a new rectangle to the rectangle store. Returns the id of the new\n * rectangle.\n *\n * @param {Number} left\n * @param {Number} top\n * @param {Number} width\n * @param {Number} height\n * @returns {Number}\n */\n PackerProcessor.prototype.addRect = function (left, top, width, height) {\n var rectId = ++this.rectId;\n this.rectStore[rectId] = left || 0;\n this.rectStore[++this.rectId] = top || 0;\n this.rectStore[++this.rectId] = width || 0;\n this.rectStore[++this.rectId] = height || 0;\n return rectId;\n };\n\n /**\n * Get rectangle data from the rectangle store by id. Optionally you can\n * provide a target object where the rectangle data will be written in. By\n * default an internal object is reused as a target object.\n *\n * @param {Number} id\n * @param {Object} [target]\n * @returns {Object}\n */\n PackerProcessor.prototype.getRect = function (id, target) {\n if (!target) target = this.rectTarget;\n target.left = this.rectStore[id] || 0;\n target.top = this.rectStore[++id] || 0;\n target.width = this.rectStore[++id] || 0;\n target.height = this.rectStore[++id] || 0;\n return target;\n };\n\n /**\n * Punch a hole into a rectangle and return the shards (1-4).\n *\n * @param {Object} rect\n * @param {Object} hole\n * @returns {Number[]}\n */\n PackerProcessor.prototype.splitRect = (function () {\n var shards = [];\n var width = 0;\n var height = 0;\n return function (rect, hole) {\n // Reset old shards.\n shards.length = 0;\n\n // If the slot does not overlap with the hole add slot to the return data\n // as is. Note that in this case we are eager to keep the slot as is if\n // possible so we use the EPSILON in favour of that logic.\n if (\n rect.left + rect.width <= hole.left + EPS ||\n hole.left + hole.width <= rect.left + EPS ||\n rect.top + rect.height <= hole.top + EPS ||\n hole.top + hole.height <= rect.top + EPS\n ) {\n shards.push(this.addRect(rect.left, rect.top, rect.width, rect.height));\n return shards;\n }\n\n // Left split.\n width = hole.left - rect.left;\n if (width >= MIN_SLOT_SIZE) {\n shards.push(this.addRect(rect.left, rect.top, width, rect.height));\n }\n\n // Right split.\n width = rect.left + rect.width - (hole.left + hole.width);\n if (width >= MIN_SLOT_SIZE) {\n shards.push(this.addRect(hole.left + hole.width, rect.top, width, rect.height));\n }\n\n // Top split.\n height = hole.top - rect.top;\n if (height >= MIN_SLOT_SIZE) {\n shards.push(this.addRect(rect.left, rect.top, rect.width, height));\n }\n\n // Bottom split.\n height = rect.top + rect.height - (hole.top + hole.height);\n if (height >= MIN_SLOT_SIZE) {\n shards.push(this.addRect(rect.left, hole.top + hole.height, rect.width, height));\n }\n\n return shards;\n };\n })();\n\n /**\n * Check if a rectangle is fully within another rectangle.\n *\n * @param {Object} a\n * @param {Object} b\n * @returns {Boolean}\n */\n PackerProcessor.prototype.isRectAWithinRectB = function (a, b) {\n return (\n a.left + EPS >= b.left &&\n a.top + EPS >= b.top &&\n a.left + a.width - EPS <= b.left + b.width &&\n a.top + a.height - EPS <= b.top + b.height\n );\n };\n\n /**\n * Loops through an array of rectangle ids and resets all that are fully\n * within another rectangle in the array. Resetting in this case means that\n * the rectangle id value is replaced with zero.\n *\n * @param {Number[]} rectIds\n * @returns {Number[]}\n */\n PackerProcessor.prototype.purgeRects = (function () {\n var rectA = {};\n var rectB = {};\n return function (rectIds) {\n var i = rectIds.length;\n var j;\n\n while (i--) {\n j = rectIds.length;\n if (!rectIds[i]) continue;\n this.getRect(rectIds[i], rectA);\n while (j--) {\n if (!rectIds[j] || i === j) continue;\n this.getRect(rectIds[j], rectB);\n if (this.isRectAWithinRectB(rectA, rectB)) {\n rectIds[i] = 0;\n break;\n }\n }\n }\n\n return rectIds;\n };\n })();\n\n /**\n * Sort rectangles with top-left gravity.\n *\n * @param {Number} aId\n * @param {Number} bId\n * @returns {Number}\n */\n PackerProcessor.prototype.sortRectsTopLeft = (function () {\n var rectA = {};\n var rectB = {};\n return function (aId, bId) {\n this.getRect(aId, rectA);\n this.getRect(bId, rectB);\n\n return rectA.top < rectB.top && rectA.top + EPS < rectB.top\n ? -1\n : rectA.top > rectB.top && rectA.top - EPS > rectB.top\n ? 1\n : rectA.left < rectB.left && rectA.left + EPS < rectB.left\n ? -1\n : rectA.left > rectB.left && rectA.left - EPS > rectB.left\n ? 1\n : 0;\n };\n })();\n\n /**\n * Sort rectangles with left-top gravity.\n *\n * @param {Number} aId\n * @param {Number} bId\n * @returns {Number}\n */\n PackerProcessor.prototype.sortRectsLeftTop = (function () {\n var rectA = {};\n var rectB = {};\n return function (aId, bId) {\n this.getRect(aId, rectA);\n this.getRect(bId, rectB);\n return rectA.left < rectB.left && rectA.left + EPS < rectB.left\n ? -1\n : rectA.left > rectB.left && rectA.left - EPS < rectB.left\n ? 1\n : rectA.top < rectB.top && rectA.top + EPS < rectB.top\n ? -1\n : rectA.top > rectB.top && rectA.top - EPS > rectB.top\n ? 1\n : 0;\n };\n })();\n\n if (isWorker) {\n var PACKET_INDEX_WIDTH = 1;\n var PACKET_INDEX_HEIGHT = 2;\n var PACKET_INDEX_OPTIONS = 3;\n var PACKET_HEADER_SLOTS = 4;\n var processor = new PackerProcessor();\n\n self.onmessage = function (msg) {\n var data = new Float32Array(msg.data);\n var items = data.subarray(PACKET_HEADER_SLOTS, data.length);\n var slots = new Float32Array(items.length);\n var settings = data[PACKET_INDEX_OPTIONS];\n var layout = {\n items: items,\n slots: slots,\n width: data[PACKET_INDEX_WIDTH],\n height: data[PACKET_INDEX_HEIGHT],\n };\n\n // Compute the layout (width / height / slots).\n processor.computeLayout(layout, settings);\n\n // Copy layout data to the return data.\n data[PACKET_INDEX_WIDTH] = layout.width;\n data[PACKET_INDEX_HEIGHT] = layout.height;\n data.set(layout.slots, PACKET_HEADER_SLOTS);\n\n // Send layout back to the main thread.\n postMessage(data.buffer, [data.buffer]);\n };\n }\n\n return PackerProcessor;\n}\n\nvar PackerProcessor = createPackerProcessor();\n\n//\n// WORKER UTILS\n//\n\nvar blobUrl = null;\nvar activeWorkers = [];\n\nfunction createWorkerProcessors(amount, onmessage) {\n var workers = [];\n\n if (amount > 0) {\n if (!blobUrl) {\n blobUrl = URL.createObjectURL(\n new Blob(['(' + createPackerProcessor.toString() + ')(true)'], {\n type: 'application/javascript',\n })\n );\n }\n\n for (var i = 0, worker; i < amount; i++) {\n worker = new Worker(blobUrl);\n if (onmessage) worker.onmessage = onmessage;\n workers.push(worker);\n activeWorkers.push(worker);\n }\n }\n\n return workers;\n}\n\nfunction destroyWorkerProcessors(workers) {\n var worker;\n var index;\n\n for (var i = 0; i < workers.length; i++) {\n worker = workers[i];\n worker.onmessage = null;\n worker.onerror = null;\n worker.onmessageerror = null;\n worker.terminate();\n\n index = activeWorkers.indexOf(worker);\n if (index > -1) activeWorkers.splice(index, 1);\n }\n\n if (blobUrl && !activeWorkers.length) {\n URL.revokeObjectURL(blobUrl);\n blobUrl = null;\n }\n}\n\nfunction isWorkerProcessorsSupported() {\n return !!(window.Worker && window.URL && window.Blob);\n}\n\nvar FILL_GAPS = 1;\nvar HORIZONTAL = 2;\nvar ALIGN_RIGHT = 4;\nvar ALIGN_BOTTOM = 8;\nvar ROUNDING = 16;\nvar PACKET_INDEX_ID = 0;\nvar PACKET_INDEX_WIDTH = 1;\nvar PACKET_INDEX_HEIGHT = 2;\nvar PACKET_INDEX_OPTIONS = 3;\nvar PACKET_HEADER_SLOTS = 4;\n\n/**\n * @class\n * @param {Number} [numWorkers=0]\n * @param {Object} [options]\n * @param {Boolean} [options.fillGaps=false]\n * @param {Boolean} [options.horizontal=false]\n * @param {Boolean} [options.alignRight=false]\n * @param {Boolean} [options.alignBottom=false]\n * @param {Boolean} [options.rounding=false]\n */\nfunction Packer(numWorkers, options) {\n this._options = 0;\n this._processor = null;\n this._layoutQueue = [];\n this._layouts = {};\n this._layoutCallbacks = {};\n this._layoutWorkers = {};\n this._layoutWorkerData = {};\n this._workers = [];\n this._onWorkerMessage = this._onWorkerMessage.bind(this);\n\n // Set initial options.\n this.setOptions(options);\n\n // Init the worker(s) or the processor if workers can't be used.\n numWorkers = typeof numWorkers === 'number' ? Math.max(0, numWorkers) : 0;\n if (numWorkers && isWorkerProcessorsSupported()) {\n try {\n this._workers = createWorkerProcessors(numWorkers, this._onWorkerMessage);\n } catch (e) {\n this._processor = new PackerProcessor();\n }\n } else {\n this._processor = new PackerProcessor();\n }\n}\n\nPacker.prototype._sendToWorker = function () {\n if (!this._layoutQueue.length || !this._workers.length) return;\n\n var layoutId = this._layoutQueue.shift();\n var worker = this._workers.pop();\n var data = this._layoutWorkerData[layoutId];\n\n delete this._layoutWorkerData[layoutId];\n this._layoutWorkers[layoutId] = worker;\n worker.postMessage(data.buffer, [data.buffer]);\n};\n\nPacker.prototype._onWorkerMessage = function (msg) {\n var data = new Float32Array(msg.data);\n var layoutId = data[PACKET_INDEX_ID];\n var layout = this._layouts[layoutId];\n var callback = this._layoutCallbacks[layoutId];\n var worker = this._layoutWorkers[layoutId];\n\n if (layout) delete this._layouts[layoutId];\n if (callback) delete this._layoutCallbacks[layoutId];\n if (worker) delete this._layoutWorkers[layoutId];\n\n if (layout && callback) {\n layout.width = data[PACKET_INDEX_WIDTH];\n layout.height = data[PACKET_INDEX_HEIGHT];\n layout.slots = data.subarray(PACKET_HEADER_SLOTS, data.length);\n this._finalizeLayout(layout);\n callback(layout);\n }\n\n if (worker) {\n this._workers.push(worker);\n this._sendToWorker();\n }\n};\n\nPacker.prototype._finalizeLayout = function (layout) {\n var grid = layout._grid;\n var isHorizontal = layout._settings & HORIZONTAL;\n var isBorderBox = grid._boxSizing === 'border-box';\n\n delete layout._grid;\n delete layout._settings;\n\n layout.styles = {};\n\n if (isHorizontal) {\n layout.styles.width =\n (isBorderBox ? layout.width + grid._borderLeft + grid._borderRight : layout.width) + 'px';\n } else {\n layout.styles.height =\n (isBorderBox ? layout.height + grid._borderTop + grid._borderBottom : layout.height) + 'px';\n }\n\n return layout;\n};\n\n/**\n * @public\n * @param {Object} [options]\n * @param {Boolean} [options.fillGaps]\n * @param {Boolean} [options.horizontal]\n * @param {Boolean} [options.alignRight]\n * @param {Boolean} [options.alignBottom]\n * @param {Boolean} [options.rounding]\n */\nPacker.prototype.setOptions = function (options) {\n if (!options) return;\n\n var fillGaps;\n if (typeof options.fillGaps === 'boolean') {\n fillGaps = options.fillGaps ? FILL_GAPS : 0;\n } else {\n fillGaps = this._options & FILL_GAPS;\n }\n\n var horizontal;\n if (typeof options.horizontal === 'boolean') {\n horizontal = options.horizontal ? HORIZONTAL : 0;\n } else {\n horizontal = this._options & HORIZONTAL;\n }\n\n var alignRight;\n if (typeof options.alignRight === 'boolean') {\n alignRight = options.alignRight ? ALIGN_RIGHT : 0;\n } else {\n alignRight = this._options & ALIGN_RIGHT;\n }\n\n var alignBottom;\n if (typeof options.alignBottom === 'boolean') {\n alignBottom = options.alignBottom ? ALIGN_BOTTOM : 0;\n } else {\n alignBottom = this._options & ALIGN_BOTTOM;\n }\n\n var rounding;\n if (typeof options.rounding === 'boolean') {\n rounding = options.rounding ? ROUNDING : 0;\n } else {\n rounding = this._options & ROUNDING;\n }\n\n this._options = fillGaps | horizontal | alignRight | alignBottom | rounding;\n};\n\n/**\n * @public\n * @param {Grid} grid\n * @param {Number} layoutId\n * @param {Item[]} items\n * @param {Number} width\n * @param {Number} height\n * @param {Function} callback\n * @returns {?Function}\n */\nPacker.prototype.createLayout = function (grid, layoutId, items, width, height, callback) {\n if (this._layouts[layoutId]) {\n throw new Error('A layout with the provided id is currently being processed.');\n }\n\n var horizontal = this._options & HORIZONTAL;\n var layout = {\n id: layoutId,\n items: items,\n slots: null,\n width: horizontal ? 0 : width,\n height: !horizontal ? 0 : height,\n // Temporary data, which will be removed before sending the layout data\n // outside of Packer's context.\n _grid: grid,\n _settings: this._options,\n };\n\n // If there are no items let's call the callback immediately.\n if (!items.length) {\n layout.slots = [];\n this._finalizeLayout(layout);\n callback(layout);\n return;\n }\n\n // Create layout synchronously if needed.\n if (this._processor) {\n layout.slots = window.Float32Array\n ? new Float32Array(items.length * 2)\n : new Array(items.length * 2);\n this._processor.computeLayout(layout, layout._settings);\n this._finalizeLayout(layout);\n callback(layout);\n return;\n }\n\n // Worker data.\n var data = new Float32Array(PACKET_HEADER_SLOTS + items.length * 2);\n\n // Worker data header.\n data[PACKET_INDEX_ID] = layoutId;\n data[PACKET_INDEX_WIDTH] = layout.width;\n data[PACKET_INDEX_HEIGHT] = layout.height;\n data[PACKET_INDEX_OPTIONS] = layout._settings;\n\n // Worker data items.\n var i, j, item;\n for (i = 0, j = PACKET_HEADER_SLOTS - 1, item; i < items.length; i++) {\n item = items[i];\n data[++j] = item._width + item._marginLeft + item._marginRight;\n data[++j] = item._height + item._marginTop + item._marginBottom;\n }\n\n this._layoutQueue.push(layoutId);\n this._layouts[layoutId] = layout;\n this._layoutCallbacks[layoutId] = callback;\n this._layoutWorkerData[layoutId] = data;\n\n this._sendToWorker();\n\n return this.cancelLayout.bind(this, layoutId);\n};\n\n/**\n * @public\n * @param {Number} layoutId\n */\nPacker.prototype.cancelLayout = function (layoutId) {\n var layout = this._layouts[layoutId];\n if (!layout) return;\n\n delete this._layouts[layoutId];\n delete this._layoutCallbacks[layoutId];\n\n if (this._layoutWorkerData[layoutId]) {\n delete this._layoutWorkerData[layoutId];\n var queueIndex = this._layoutQueue.indexOf(layoutId);\n if (queueIndex > -1) this._layoutQueue.splice(queueIndex, 1);\n }\n};\n\n/**\n * @public\n */\nPacker.prototype.destroy = function () {\n // Move all currently used workers back in the workers array.\n for (var key in this._layoutWorkers) {\n this._workers.push(this._layoutWorkers[key]);\n }\n\n // Destroy all instance's workers.\n destroyWorkerProcessors(this._workers);\n\n // Reset data.\n this._workers.length = 0;\n this._layoutQueue.length = 0;\n this._layouts = {};\n this._layoutCallbacks = {};\n this._layoutWorkers = {};\n this._layoutWorkerData = {};\n};\n\nvar debounceId = 0;\n\n/**\n * Returns a function, that, as long as it continues to be invoked, will not\n * be triggered. The function will be called after it stops being called for\n * N milliseconds. The returned function accepts one argument which, when\n * being `true`, cancels the debounce function immediately. When the debounce\n * function is canceled it cannot be invoked again.\n *\n * @param {Function} fn\n * @param {Number} durationMs\n * @returns {Function}\n */\nfunction debounce(fn, durationMs) {\n var id = ++debounceId;\n var timer = 0;\n var lastTime = 0;\n var isCanceled = false;\n var tick = function (time) {\n if (isCanceled) return;\n\n if (lastTime) timer -= time - lastTime;\n lastTime = time;\n\n if (timer > 0) {\n addDebounceTick(id, tick);\n } else {\n timer = lastTime = 0;\n fn();\n }\n };\n\n return function (cancel) {\n if (isCanceled) return;\n\n if (durationMs <= 0) {\n if (cancel !== true) fn();\n return;\n }\n\n if (cancel === true) {\n isCanceled = true;\n timer = lastTime = 0;\n tick = undefined;\n cancelDebounceTick(id);\n return;\n }\n\n if (timer <= 0) {\n timer = durationMs;\n tick(0);\n } else {\n timer = durationMs;\n }\n };\n}\n\nvar htmlCollectionType = '[object HTMLCollection]';\nvar nodeListType = '[object NodeList]';\n\n/**\n * Check if a value is a node list or a html collection.\n *\n * @param {*} val\n * @returns {Boolean}\n */\nfunction isNodeList(val) {\n var type = Object.prototype.toString.call(val);\n return type === htmlCollectionType || type === nodeListType;\n}\n\nvar objectType = 'object';\nvar objectToStringType = '[object Object]';\nvar toString = Object.prototype.toString;\n\n/**\n * Check if a value is a plain object.\n *\n * @param {*} val\n * @returns {Boolean}\n */\nfunction isPlainObject(val) {\n return typeof val === objectType && toString.call(val) === objectToStringType;\n}\n\nfunction noop() {}\n\n/**\n * Converts a value to an array or clones an array.\n *\n * @param {*} val\n * @returns {Array}\n */\nfunction toArray(val) {\n return isNodeList(val) ? Array.prototype.slice.call(val) : Array.prototype.concat(val);\n}\n\nvar NUMBER_TYPE = 'number';\nvar STRING_TYPE = 'string';\nvar INSTANT_LAYOUT = 'instant';\nvar layoutId = 0;\n\n/**\n * Creates a new Grid instance.\n *\n * @class\n * @param {(HTMLElement|String)} element\n * @param {Object} [options]\n * @param {(String|HTMLElement[]|NodeList|HTMLCollection)} [options.items=\"*\"]\n * @param {Number} [options.showDuration=300]\n * @param {String} [options.showEasing=\"ease\"]\n * @param {Object} [options.visibleStyles={opacity: \"1\", transform: \"scale(1)\"}]\n * @param {Number} [options.hideDuration=300]\n * @param {String} [options.hideEasing=\"ease\"]\n * @param {Object} [options.hiddenStyles={opacity: \"0\", transform: \"scale(0.5)\"}]\n * @param {(Function|Object)} [options.layout]\n * @param {Boolean} [options.layout.fillGaps=false]\n * @param {Boolean} [options.layout.horizontal=false]\n * @param {Boolean} [options.layout.alignRight=false]\n * @param {Boolean} [options.layout.alignBottom=false]\n * @param {Boolean} [options.layout.rounding=false]\n * @param {(Boolean|Number)} [options.layoutOnResize=150]\n * @param {Boolean} [options.layoutOnInit=true]\n * @param {Number} [options.layoutDuration=300]\n * @param {String} [options.layoutEasing=\"ease\"]\n * @param {?Object} [options.sortData=null]\n * @param {Boolean} [options.dragEnabled=false]\n * @param {?String} [options.dragHandle=null]\n * @param {?HtmlElement} [options.dragContainer=null]\n * @param {?Function} [options.dragStartPredicate]\n * @param {Number} [options.dragStartPredicate.distance=0]\n * @param {Number} [options.dragStartPredicate.delay=0]\n * @param {String} [options.dragAxis=\"xy\"]\n * @param {(Boolean|Function)} [options.dragSort=true]\n * @param {Object} [options.dragSortHeuristics]\n * @param {Number} [options.dragSortHeuristics.sortInterval=100]\n * @param {Number} [options.dragSortHeuristics.minDragDistance=10]\n * @param {Number} [options.dragSortHeuristics.minBounceBackAngle=1]\n * @param {(Function|Object)} [options.dragSortPredicate]\n * @param {Number} [options.dragSortPredicate.threshold=50]\n * @param {String} [options.dragSortPredicate.action=\"move\"]\n * @param {String} [options.dragSortPredicate.migrateAction=\"move\"]\n * @param {Object} [options.dragRelease]\n * @param {Number} [options.dragRelease.duration=300]\n * @param {String} [options.dragRelease.easing=\"ease\"]\n * @param {Boolean} [options.dragRelease.useDragContainer=true]\n * @param {Object} [options.dragCssProps]\n * @param {Object} [options.dragPlaceholder]\n * @param {Boolean} [options.dragPlaceholder.enabled=false]\n * @param {?Function} [options.dragPlaceholder.createElement=null]\n * @param {?Function} [options.dragPlaceholder.onCreate=null]\n * @param {?Function} [options.dragPlaceholder.onRemove=null]\n * @param {Object} [options.dragAutoScroll]\n * @param {(Function|Array)} [options.dragAutoScroll.targets=[]]\n * @param {?Function} [options.dragAutoScroll.handle=null]\n * @param {Number} [options.dragAutoScroll.threshold=50]\n * @param {Number} [options.dragAutoScroll.safeZone=0.2]\n * @param {(Function|Number)} [options.dragAutoScroll.speed]\n * @param {Boolean} [options.dragAutoScroll.sortDuringScroll=true]\n * @param {Boolean} [options.dragAutoScroll.smoothStop=false]\n * @param {?Function} [options.dragAutoScroll.onStart=null]\n * @param {?Function} [options.dragAutoScroll.onStop=null]\n * @param {String} [options.containerClass=\"muuri\"]\n * @param {String} [options.itemClass=\"muuri-item\"]\n * @param {String} [options.itemVisibleClass=\"muuri-item-visible\"]\n * @param {String} [options.itemHiddenClass=\"muuri-item-hidden\"]\n * @param {String} [options.itemPositioningClass=\"muuri-item-positioning\"]\n * @param {String} [options.itemDraggingClass=\"muuri-item-dragging\"]\n * @param {String} [options.itemReleasingClass=\"muuri-item-releasing\"]\n * @param {String} [options.itemPlaceholderClass=\"muuri-item-placeholder\"]\n */\nfunction Grid(element, options) {\n // Allow passing element as selector string\n if (typeof element === STRING_TYPE) {\n element = document.querySelector(element);\n }\n\n // Throw an error if the container element is not body element or does not\n // exist within the body element.\n var isElementInDom = element.getRootNode\n ? element.getRootNode({ composed: true }) === document\n : document.body.contains(element);\n if (!isElementInDom || element === document.documentElement) {\n throw new Error('Container element must be an existing DOM element.');\n }\n\n // Create instance settings by merging the options with default options.\n var settings = mergeSettings(Grid.defaultOptions, options);\n settings.visibleStyles = normalizeStyles(settings.visibleStyles);\n settings.hiddenStyles = normalizeStyles(settings.hiddenStyles);\n if (!isFunction(settings.dragSort)) {\n settings.dragSort = !!settings.dragSort;\n }\n\n this._id = createUid();\n this._element = element;\n this._settings = settings;\n this._isDestroyed = false;\n this._items = [];\n this._layout = {\n id: 0,\n items: [],\n slots: [],\n };\n this._isLayoutFinished = true;\n this._nextLayoutData = null;\n this._emitter = new Emitter();\n this._onLayoutDataReceived = this._onLayoutDataReceived.bind(this);\n\n // Store grid instance to the grid instances collection.\n GRID_INSTANCES[this._id] = this;\n\n // Add container element's class name.\n addClass(element, settings.containerClass);\n\n // If layoutOnResize option is a valid number sanitize it and bind the resize\n // handler.\n bindLayoutOnResize(this, settings.layoutOnResize);\n\n // Add initial items.\n this.add(getInitialGridElements(element, settings.items), { layout: false });\n\n // Layout on init if necessary.\n if (settings.layoutOnInit) {\n this.layout(true);\n }\n}\n\n/**\n * Public properties\n * *****************\n */\n\n/**\n * @public\n * @static\n * @see Item\n */\nGrid.Item = Item;\n\n/**\n * @public\n * @static\n * @see ItemLayout\n */\nGrid.ItemLayout = ItemLayout;\n\n/**\n * @public\n * @static\n * @see ItemVisibility\n */\nGrid.ItemVisibility = ItemVisibility;\n\n/**\n * @public\n * @static\n * @see ItemMigrate\n */\nGrid.ItemMigrate = ItemMigrate;\n\n/**\n * @public\n * @static\n * @see ItemDrag\n */\nGrid.ItemDrag = ItemDrag;\n\n/**\n * @public\n * @static\n * @see ItemDragRelease\n */\nGrid.ItemDragRelease = ItemDragRelease;\n\n/**\n * @public\n * @static\n * @see ItemDragPlaceholder\n */\nGrid.ItemDragPlaceholder = ItemDragPlaceholder;\n\n/**\n * @public\n * @static\n * @see Emitter\n */\nGrid.Emitter = Emitter;\n\n/**\n * @public\n * @static\n * @see Animator\n */\nGrid.Animator = Animator;\n\n/**\n * @public\n * @static\n * @see Dragger\n */\nGrid.Dragger = Dragger;\n\n/**\n * @public\n * @static\n * @see Packer\n */\nGrid.Packer = Packer;\n\n/**\n * @public\n * @static\n * @see AutoScroller\n */\nGrid.AutoScroller = AutoScroller;\n\n/**\n * The default Packer instance used by default for all layouts.\n *\n * @public\n * @static\n * @type {Packer}\n */\nGrid.defaultPacker = new Packer(2);\n\n/**\n * Default options for Grid instance.\n *\n * @public\n * @static\n * @type {Object}\n */\nGrid.defaultOptions = {\n // Initial item elements\n items: '*',\n\n // Default show animation\n showDuration: 300,\n showEasing: 'ease',\n\n // Default hide animation\n hideDuration: 300,\n hideEasing: 'ease',\n\n // Item's visible/hidden state styles\n visibleStyles: {\n opacity: '1',\n transform: 'scale(1)',\n },\n hiddenStyles: {\n opacity: '0',\n transform: 'scale(0.5)',\n },\n\n // Layout\n layout: {\n fillGaps: false,\n horizontal: false,\n alignRight: false,\n alignBottom: false,\n rounding: false,\n },\n layoutOnResize: 150,\n layoutOnInit: true,\n layoutDuration: 300,\n layoutEasing: 'ease',\n\n // Sorting\n sortData: null,\n\n // Drag & Drop\n dragEnabled: false,\n dragContainer: null,\n dragHandle: null,\n dragStartPredicate: {\n distance: 0,\n delay: 0,\n },\n dragAxis: 'xy',\n dragSort: true,\n dragSortHeuristics: {\n sortInterval: 100,\n minDragDistance: 10,\n minBounceBackAngle: 1,\n },\n dragSortPredicate: {\n threshold: 50,\n action: ACTION_MOVE,\n migrateAction: ACTION_MOVE,\n },\n dragRelease: {\n duration: 300,\n easing: 'ease',\n useDragContainer: true,\n },\n dragCssProps: {\n touchAction: 'none',\n userSelect: 'none',\n userDrag: 'none',\n tapHighlightColor: 'rgba(0, 0, 0, 0)',\n touchCallout: 'none',\n contentZooming: 'none',\n },\n dragPlaceholder: {\n enabled: false,\n createElement: null,\n onCreate: null,\n onRemove: null,\n },\n dragAutoScroll: {\n targets: [],\n handle: null,\n threshold: 50,\n safeZone: 0.2,\n speed: AutoScroller.smoothSpeed(1000, 2000, 2500),\n sortDuringScroll: true,\n smoothStop: false,\n onStart: null,\n onStop: null,\n },\n\n // Classnames\n containerClass: 'muuri',\n itemClass: 'muuri-item',\n itemVisibleClass: 'muuri-item-shown',\n itemHiddenClass: 'muuri-item-hidden',\n itemPositioningClass: 'muuri-item-positioning',\n itemDraggingClass: 'muuri-item-dragging',\n itemReleasingClass: 'muuri-item-releasing',\n itemPlaceholderClass: 'muuri-item-placeholder',\n};\n\n/**\n * Public prototype methods\n * ************************\n */\n\n/**\n * Bind an event listener.\n *\n * @public\n * @param {String} event\n * @param {Function} listener\n * @returns {Grid}\n */\nGrid.prototype.on = function (event, listener) {\n this._emitter.on(event, listener);\n return this;\n};\n\n/**\n * Unbind an event listener.\n *\n * @public\n * @param {String} event\n * @param {Function} listener\n * @returns {Grid}\n */\nGrid.prototype.off = function (event, listener) {\n this._emitter.off(event, listener);\n return this;\n};\n\n/**\n * Get the container element.\n *\n * @public\n * @returns {HTMLElement}\n */\nGrid.prototype.getElement = function () {\n return this._element;\n};\n\n/**\n * Get instance's item by element or by index. Target can also be an Item\n * instance in which case the function returns the item if it exists within\n * related Grid instance. If nothing is found with the provided target, null\n * is returned.\n *\n * @private\n * @param {(HtmlElement|Number|Item)} [target]\n * @returns {?Item}\n */\nGrid.prototype.getItem = function (target) {\n // If no target is specified or the instance is destroyed, return null.\n if (this._isDestroyed || (!target && target !== 0)) {\n return null;\n }\n\n // If target is number return the item in that index. If the number is lower\n // than zero look for the item starting from the end of the items array. For\n // example -1 for the last item, -2 for the second last item, etc.\n if (typeof target === NUMBER_TYPE) {\n return this._items[target > -1 ? target : this._items.length + target] || null;\n }\n\n // If the target is an instance of Item return it if it is attached to this\n // Grid instance, otherwise return null.\n if (target instanceof Item) {\n return target._gridId === this._id ? target : null;\n }\n\n // In other cases let's assume that the target is an element, so let's try\n // to find an item that matches the element and return it. If item is not\n // found return null.\n if (ITEM_ELEMENT_MAP) {\n var item = ITEM_ELEMENT_MAP.get(target);\n return item && item._gridId === this._id ? item : null;\n } else {\n for (var i = 0; i < this._items.length; i++) {\n if (this._items[i]._element === target) {\n return this._items[i];\n }\n }\n }\n\n return null;\n};\n\n/**\n * Get all items. Optionally you can provide specific targets (elements,\n * indices and item instances). All items that are not found are omitted from\n * the returned array.\n *\n * @public\n * @param {(HtmlElement|Number|Item|Array)} [targets]\n * @returns {Item[]}\n */\nGrid.prototype.getItems = function (targets) {\n // Return all items immediately if no targets were provided or if the\n // instance is destroyed.\n if (this._isDestroyed || targets === undefined) {\n return this._items.slice(0);\n }\n\n var items = [];\n var i, item;\n\n if (Array.isArray(targets) || isNodeList(targets)) {\n for (i = 0; i < targets.length; i++) {\n item = this.getItem(targets[i]);\n if (item) items.push(item);\n }\n } else {\n item = this.getItem(targets);\n if (item) items.push(item);\n }\n\n return items;\n};\n\n/**\n * Update the cached dimensions of the instance's items. By default all the\n * items are refreshed, but you can also provide an array of target items as the\n * first argument if you want to refresh specific items. Note that all hidden\n * items are not refreshed by default since their \"display\" property is \"none\"\n * and their dimensions are therefore not readable from the DOM. However, if you\n * do want to force update hidden item dimensions too you can provide `true`\n * as the second argument, which makes the elements temporarily visible while\n * their dimensions are being read.\n *\n * @public\n * @param {Item[]} [items]\n * @param {Boolean} [force=false]\n * @returns {Grid}\n */\nGrid.prototype.refreshItems = function (items, force) {\n if (this._isDestroyed) return this;\n\n var targets = items || this._items;\n var i, item, style, hiddenItemStyles;\n\n if (force === true) {\n hiddenItemStyles = [];\n for (i = 0; i < targets.length; i++) {\n item = targets[i];\n if (!item.isVisible() && !item.isHiding()) {\n style = item.getElement().style;\n style.visibility = 'hidden';\n style.display = '';\n hiddenItemStyles.push(style);\n }\n }\n }\n\n for (i = 0; i < targets.length; i++) {\n targets[i]._refreshDimensions(force);\n }\n\n if (force === true) {\n for (i = 0; i < hiddenItemStyles.length; i++) {\n style = hiddenItemStyles[i];\n style.visibility = '';\n style.display = 'none';\n }\n hiddenItemStyles.length = 0;\n }\n\n return this;\n};\n\n/**\n * Update the sort data of the instance's items. By default all the items are\n * refreshed, but you can also provide an array of target items if you want to\n * refresh specific items.\n *\n * @public\n * @param {Item[]} [items]\n * @returns {Grid}\n */\nGrid.prototype.refreshSortData = function (items) {\n if (this._isDestroyed) return this;\n\n var targets = items || this._items;\n for (var i = 0; i < targets.length; i++) {\n targets[i]._refreshSortData();\n }\n\n return this;\n};\n\n/**\n * Synchronize the item elements to match the order of the items in the DOM.\n * This comes handy if you need to keep the DOM structure matched with the\n * order of the items. Note that if an item's element is not currently a child\n * of the container element (if it is dragged for example) it is ignored and\n * left untouched.\n *\n * @public\n * @returns {Grid}\n */\nGrid.prototype.synchronize = function () {\n if (this._isDestroyed) return this;\n\n var items = this._items;\n if (!items.length) return this;\n\n var fragment;\n var element;\n\n for (var i = 0; i < items.length; i++) {\n element = items[i]._element;\n if (element.parentNode === this._element) {\n fragment = fragment || document.createDocumentFragment();\n fragment.appendChild(element);\n }\n }\n\n if (!fragment) return this;\n\n this._element.appendChild(fragment);\n this._emit(EVENT_SYNCHRONIZE);\n\n return this;\n};\n\n/**\n * Calculate and apply item positions.\n *\n * @public\n * @param {Boolean} [instant=false]\n * @param {Function} [onFinish]\n * @returns {Grid}\n */\nGrid.prototype.layout = function (instant, onFinish) {\n if (this._isDestroyed) return this;\n\n // Cancel unfinished layout algorithm if possible.\n var unfinishedLayout = this._nextLayoutData;\n if (unfinishedLayout && isFunction(unfinishedLayout.cancel)) {\n unfinishedLayout.cancel();\n }\n\n // Compute layout id (let's stay in Float32 range).\n layoutId = (layoutId % MAX_SAFE_FLOAT32_INTEGER) + 1;\n var nextLayoutId = layoutId;\n\n // Store data for next layout.\n this._nextLayoutData = {\n id: nextLayoutId,\n instant: instant,\n onFinish: onFinish,\n cancel: null,\n };\n\n // Collect layout items (all active grid items).\n var items = this._items;\n var layoutItems = [];\n for (var i = 0; i < items.length; i++) {\n if (items[i]._isActive) layoutItems.push(items[i]);\n }\n\n // Compute new layout.\n this._refreshDimensions();\n var gridWidth = this._width - this._borderLeft - this._borderRight;\n var gridHeight = this._height - this._borderTop - this._borderBottom;\n var layoutSettings = this._settings.layout;\n var cancelLayout;\n if (isFunction(layoutSettings)) {\n cancelLayout = layoutSettings(\n this,\n nextLayoutId,\n layoutItems,\n gridWidth,\n gridHeight,\n this._onLayoutDataReceived\n );\n } else {\n Grid.defaultPacker.setOptions(layoutSettings);\n cancelLayout = Grid.defaultPacker.createLayout(\n this,\n nextLayoutId,\n layoutItems,\n gridWidth,\n gridHeight,\n this._onLayoutDataReceived\n );\n }\n\n // Store layout cancel method if available.\n if (\n isFunction(cancelLayout) &&\n this._nextLayoutData &&\n this._nextLayoutData.id === nextLayoutId\n ) {\n this._nextLayoutData.cancel = cancelLayout;\n }\n\n return this;\n};\n\n/**\n * Add new items by providing the elements you wish to add to the instance and\n * optionally provide the index where you want the items to be inserted into.\n * All elements that are not already children of the container element will be\n * automatically appended to the container element. If an element has it's CSS\n * display property set to \"none\" it will be marked as inactive during the\n * initiation process. As long as the item is inactive it will not be part of\n * the layout, but it will retain it's index. You can activate items at any\n * point with grid.show() method. This method will automatically call\n * grid.layout() if one or more of the added elements are visible. If only\n * hidden items are added no layout will be called. All the new visible items\n * are positioned without animation during their first layout.\n *\n * @public\n * @param {(HTMLElement|HTMLElement[])} elements\n * @param {Object} [options]\n * @param {Number} [options.index=-1]\n * @param {Boolean} [options.active]\n * @param {(Boolean|Function|String)} [options.layout=true]\n * @returns {Item[]}\n */\nGrid.prototype.add = function (elements, options) {\n if (this._isDestroyed || !elements) return [];\n\n var newItems = toArray(elements);\n if (!newItems.length) return newItems;\n\n var opts = options || {};\n var layout = opts.layout ? opts.layout : opts.layout === undefined;\n var items = this._items;\n var needsLayout = false;\n var fragment;\n var element;\n var item;\n var i;\n\n // Collect all the elements that are not child of the grid element into a\n // document fragment.\n for (i = 0; i < newItems.length; i++) {\n element = newItems[i];\n if (element.parentNode !== this._element) {\n fragment = fragment || document.createDocumentFragment();\n fragment.appendChild(element);\n }\n }\n\n // If we have a fragment, let's append it to the grid element. We could just\n // not do this and the `new Item()` instantiation would handle this for us,\n // but this way we can add the elements into the DOM a bit faster.\n if (fragment) {\n this._element.appendChild(fragment);\n }\n\n // Map provided elements into new grid items.\n for (i = 0; i < newItems.length; i++) {\n element = newItems[i];\n item = newItems[i] = new Item(this, element, opts.active);\n\n // If the item to be added is active, we need to do a layout. Also, we\n // need to mark the item with the skipNextAnimation flag to make it\n // position instantly (without animation) during the next layout. Without\n // the hack the item would animate to it's new position from the northwest\n // corner of the grid, which feels a bit buggy (imho).\n if (item._isActive) {\n needsLayout = true;\n item._layout._skipNextAnimation = true;\n }\n }\n\n // Set up the items' initial dimensions and sort data. This needs to be done\n // in a separate loop to avoid layout thrashing.\n for (i = 0; i < newItems.length; i++) {\n item = newItems[i];\n item._refreshDimensions();\n item._refreshSortData();\n }\n\n // Add the new items to the items collection to correct index.\n arrayInsert(items, newItems, opts.index);\n\n // Emit add event.\n if (this._hasListeners(EVENT_ADD)) {\n this._emit(EVENT_ADD, newItems.slice(0));\n }\n\n // If layout is needed.\n if (needsLayout && layout) {\n this.layout(layout === INSTANT_LAYOUT, isFunction(layout) ? layout : undefined);\n }\n\n return newItems;\n};\n\n/**\n * Remove items from the instance.\n *\n * @public\n * @param {Item[]} items\n * @param {Object} [options]\n * @param {Boolean} [options.removeElements=false]\n * @param {(Boolean|Function|String)} [options.layout=true]\n * @returns {Item[]}\n */\nGrid.prototype.remove = function (items, options) {\n if (this._isDestroyed || !items.length) return [];\n\n var opts = options || {};\n var layout = opts.layout ? opts.layout : opts.layout === undefined;\n var needsLayout = false;\n var allItems = this.getItems();\n var targetItems = [];\n var indices = [];\n var index;\n var item;\n var i;\n\n // Remove the individual items.\n for (i = 0; i < items.length; i++) {\n item = items[i];\n if (item._isDestroyed) continue;\n\n index = this._items.indexOf(item);\n if (index === -1) continue;\n\n if (item._isActive) needsLayout = true;\n\n targetItems.push(item);\n indices.push(allItems.indexOf(item));\n item._destroy(opts.removeElements);\n this._items.splice(index, 1);\n }\n\n // Emit remove event.\n if (this._hasListeners(EVENT_REMOVE)) {\n this._emit(EVENT_REMOVE, targetItems.slice(0), indices);\n }\n\n // If layout is needed.\n if (needsLayout && layout) {\n this.layout(layout === INSTANT_LAYOUT, isFunction(layout) ? layout : undefined);\n }\n\n return targetItems;\n};\n\n/**\n * Show specific instance items.\n *\n * @public\n * @param {Item[]} items\n * @param {Object} [options]\n * @param {Boolean} [options.instant=false]\n * @param {Boolean} [options.syncWithLayout=true]\n * @param {Function} [options.onFinish]\n * @param {(Boolean|Function|String)} [options.layout=true]\n * @returns {Grid}\n */\nGrid.prototype.show = function (items, options) {\n if (!this._isDestroyed && items.length) {\n this._setItemsVisibility(items, true, options);\n }\n return this;\n};\n\n/**\n * Hide specific instance items.\n *\n * @public\n * @param {Item[]} items\n * @param {Object} [options]\n * @param {Boolean} [options.instant=false]\n * @param {Boolean} [options.syncWithLayout=true]\n * @param {Function} [options.onFinish]\n * @param {(Boolean|Function|String)} [options.layout=true]\n * @returns {Grid}\n */\nGrid.prototype.hide = function (items, options) {\n if (!this._isDestroyed && items.length) {\n this._setItemsVisibility(items, false, options);\n }\n return this;\n};\n\n/**\n * Filter items. Expects at least one argument, a predicate, which should be\n * either a function or a string. The predicate callback is executed for every\n * item in the instance. If the return value of the predicate is truthy the\n * item in question will be shown and otherwise hidden. The predicate callback\n * receives the item instance as it's argument. If the predicate is a string\n * it is considered to be a selector and it is checked against every item\n * element in the instance with the native element.matches() method. All the\n * matching items will be shown and others hidden.\n *\n * @public\n * @param {(Function|String)} predicate\n * @param {Object} [options]\n * @param {Boolean} [options.instant=false]\n * @param {Boolean} [options.syncWithLayout=true]\n * @param {FilterCallback} [options.onFinish]\n * @param {(Boolean|Function|String)} [options.layout=true]\n * @returns {Grid}\n */\nGrid.prototype.filter = function (predicate, options) {\n if (this._isDestroyed || !this._items.length) return this;\n\n var itemsToShow = [];\n var itemsToHide = [];\n var isPredicateString = typeof predicate === STRING_TYPE;\n var isPredicateFn = isFunction(predicate);\n var opts = options || {};\n var isInstant = opts.instant === true;\n var syncWithLayout = opts.syncWithLayout;\n var layout = opts.layout ? opts.layout : opts.layout === undefined;\n var onFinish = isFunction(opts.onFinish) ? opts.onFinish : null;\n var tryFinishCounter = -1;\n var tryFinish = noop;\n var item;\n var i;\n\n // If we have onFinish callback, let's create proper tryFinish callback.\n if (onFinish) {\n tryFinish = function () {\n ++tryFinishCounter && onFinish(itemsToShow.slice(0), itemsToHide.slice(0));\n };\n }\n\n // Check which items need to be shown and which hidden.\n if (isPredicateFn || isPredicateString) {\n for (i = 0; i < this._items.length; i++) {\n item = this._items[i];\n if (isPredicateFn ? predicate(item) : elementMatches(item._element, predicate)) {\n itemsToShow.push(item);\n } else {\n itemsToHide.push(item);\n }\n }\n }\n\n // Show items that need to be shown.\n if (itemsToShow.length) {\n this.show(itemsToShow, {\n instant: isInstant,\n syncWithLayout: syncWithLayout,\n onFinish: tryFinish,\n layout: false,\n });\n } else {\n tryFinish();\n }\n\n // Hide items that need to be hidden.\n if (itemsToHide.length) {\n this.hide(itemsToHide, {\n instant: isInstant,\n syncWithLayout: syncWithLayout,\n onFinish: tryFinish,\n layout: false,\n });\n } else {\n tryFinish();\n }\n\n // If there are any items to filter.\n if (itemsToShow.length || itemsToHide.length) {\n // Emit filter event.\n if (this._hasListeners(EVENT_FILTER)) {\n this._emit(EVENT_FILTER, itemsToShow.slice(0), itemsToHide.slice(0));\n }\n\n // If layout is needed.\n if (layout) {\n this.layout(layout === INSTANT_LAYOUT, isFunction(layout) ? layout : undefined);\n }\n }\n\n return this;\n};\n\n/**\n * Sort items. There are three ways to sort the items. The first is simply by\n * providing a function as the comparer which works identically to native\n * array sort. Alternatively you can sort by the sort data you have provided\n * in the instance's options. Just provide the sort data key(s) as a string\n * (separated by space) and the items will be sorted based on the provided\n * sort data keys. Lastly you have the opportunity to provide a presorted\n * array of items which will be used to sync the internal items array in the\n * same order.\n *\n * @public\n * @param {(Function|String|Item[])} comparer\n * @param {Object} [options]\n * @param {Boolean} [options.descending=false]\n * @param {(Boolean|Function|String)} [options.layout=true]\n * @returns {Grid}\n */\nGrid.prototype.sort = (function () {\n var sortComparer;\n var isDescending;\n var origItems;\n var indexMap;\n\n function defaultComparer(a, b) {\n var result = 0;\n var criteriaName;\n var criteriaOrder;\n var valA;\n var valB;\n\n // Loop through the list of sort criteria.\n for (var i = 0; i < sortComparer.length; i++) {\n // Get the criteria name, which should match an item's sort data key.\n criteriaName = sortComparer[i][0];\n criteriaOrder = sortComparer[i][1];\n\n // Get items' cached sort values for the criteria. If the item has no sort\n // data let's update the items sort data (this is a lazy load mechanism).\n valA = (a._sortData ? a : a._refreshSortData())._sortData[criteriaName];\n valB = (b._sortData ? b : b._refreshSortData())._sortData[criteriaName];\n\n // Sort the items in descending order if defined so explicitly. Otherwise\n // sort items in ascending order.\n if (criteriaOrder === 'desc' || (!criteriaOrder && isDescending)) {\n result = valB < valA ? -1 : valB > valA ? 1 : 0;\n } else {\n result = valA < valB ? -1 : valA > valB ? 1 : 0;\n }\n\n // If we have -1 or 1 as the return value, let's return it immediately.\n if (result) return result;\n }\n\n // If values are equal let's compare the item indices to make sure we\n // have a stable sort. Note that this is not necessary in evergreen browsers\n // because Array.sort() is nowadays stable. However, in order to guarantee\n // same results in older browsers we need this.\n if (!result) {\n if (!indexMap) indexMap = createIndexMap(origItems);\n result = isDescending ? compareIndexMap(indexMap, b, a) : compareIndexMap(indexMap, a, b);\n }\n return result;\n }\n\n function customComparer(a, b) {\n var result = isDescending ? -sortComparer(a, b) : sortComparer(a, b);\n if (!result) {\n if (!indexMap) indexMap = createIndexMap(origItems);\n result = isDescending ? compareIndexMap(indexMap, b, a) : compareIndexMap(indexMap, a, b);\n }\n return result;\n }\n\n return function (comparer, options) {\n if (this._isDestroyed || this._items.length < 2) return this;\n\n var items = this._items;\n var opts = options || {};\n var layout = opts.layout ? opts.layout : opts.layout === undefined;\n\n // Setup parent scope data.\n isDescending = !!opts.descending;\n origItems = items.slice(0);\n indexMap = null;\n\n // If function is provided do a native array sort.\n if (isFunction(comparer)) {\n sortComparer = comparer;\n items.sort(customComparer);\n }\n // Otherwise if we got a string, let's sort by the sort data as provided in\n // the instance's options.\n else if (typeof comparer === STRING_TYPE) {\n sortComparer = comparer\n .trim()\n .split(' ')\n .filter(function (val) {\n return val;\n })\n .map(function (val) {\n return val.split(':');\n });\n items.sort(defaultComparer);\n }\n // Otherwise if we got an array, let's assume it's a presorted array of the\n // items and order the items based on it. Here we blindly trust that the\n // presorted array consists of the same item instances as the current\n // `gird._items` array.\n else if (Array.isArray(comparer)) {\n items.length = 0;\n items.push.apply(items, comparer);\n }\n // Otherwise let's throw an error.\n else {\n sortComparer = isDescending = origItems = indexMap = null;\n throw new Error('Invalid comparer argument provided.');\n }\n\n // Emit sort event.\n if (this._hasListeners(EVENT_SORT)) {\n this._emit(EVENT_SORT, items.slice(0), origItems);\n }\n\n // If layout is needed.\n if (layout) {\n this.layout(layout === INSTANT_LAYOUT, isFunction(layout) ? layout : undefined);\n }\n\n // Reset data (to avoid mem leaks).\n sortComparer = isDescending = origItems = indexMap = null;\n\n return this;\n };\n})();\n\n/**\n * Move item to another index or in place of another item.\n *\n * @public\n * @param {(HtmlElement|Number|Item)} item\n * @param {(HtmlElement|Number|Item)} position\n * @param {Object} [options]\n * @param {String} [options.action=\"move\"]\n * - Accepts either \"move\" or \"swap\".\n * - \"move\" moves the item in place of the other item.\n * - \"swap\" swaps the position of the items.\n * @param {(Boolean|Function|String)} [options.layout=true]\n * @returns {Grid}\n */\nGrid.prototype.move = function (item, position, options) {\n if (this._isDestroyed || this._items.length < 2) return this;\n\n var items = this._items;\n var opts = options || {};\n var layout = opts.layout ? opts.layout : opts.layout === undefined;\n var isSwap = opts.action === ACTION_SWAP;\n var action = isSwap ? ACTION_SWAP : ACTION_MOVE;\n var fromItem = this.getItem(item);\n var toItem = this.getItem(position);\n var fromIndex;\n var toIndex;\n\n // Make sure the items exist and are not the same.\n if (fromItem && toItem && fromItem !== toItem) {\n // Get the indices of the items.\n fromIndex = items.indexOf(fromItem);\n toIndex = items.indexOf(toItem);\n\n // Do the move/swap.\n if (isSwap) {\n arraySwap(items, fromIndex, toIndex);\n } else {\n arrayMove(items, fromIndex, toIndex);\n }\n\n // Emit move event.\n if (this._hasListeners(EVENT_MOVE)) {\n this._emit(EVENT_MOVE, {\n item: fromItem,\n fromIndex: fromIndex,\n toIndex: toIndex,\n action: action,\n });\n }\n\n // If layout is needed.\n if (layout) {\n this.layout(layout === INSTANT_LAYOUT, isFunction(layout) ? layout : undefined);\n }\n }\n\n return this;\n};\n\n/**\n * Send item to another Grid instance.\n *\n * @public\n * @param {(HtmlElement|Number|Item)} item\n * @param {Grid} targetGrid\n * @param {(HtmlElement|Number|Item)} position\n * @param {Object} [options]\n * @param {HTMLElement} [options.appendTo=document.body]\n * @param {(Boolean|Function|String)} [options.layoutSender=true]\n * @param {(Boolean|Function|String)} [options.layoutReceiver=true]\n * @returns {Grid}\n */\nGrid.prototype.send = function (item, targetGrid, position, options) {\n if (this._isDestroyed || targetGrid._isDestroyed || this === targetGrid) return this;\n\n // Make sure we have a valid target item.\n item = this.getItem(item);\n if (!item) return this;\n\n var opts = options || {};\n var container = opts.appendTo || document.body;\n var layoutSender = opts.layoutSender ? opts.layoutSender : opts.layoutSender === undefined;\n var layoutReceiver = opts.layoutReceiver\n ? opts.layoutReceiver\n : opts.layoutReceiver === undefined;\n\n // Start the migration process.\n item._migrate.start(targetGrid, position, container);\n\n // If migration was started successfully and the item is active, let's layout\n // the grids.\n if (item._migrate._isActive && item._isActive) {\n if (layoutSender) {\n this.layout(\n layoutSender === INSTANT_LAYOUT,\n isFunction(layoutSender) ? layoutSender : undefined\n );\n }\n if (layoutReceiver) {\n targetGrid.layout(\n layoutReceiver === INSTANT_LAYOUT,\n isFunction(layoutReceiver) ? layoutReceiver : undefined\n );\n }\n }\n\n return this;\n};\n\n/**\n * Destroy the instance.\n *\n * @public\n * @param {Boolean} [removeElements=false]\n * @returns {Grid}\n */\nGrid.prototype.destroy = function (removeElements) {\n if (this._isDestroyed) return this;\n\n var container = this._element;\n var items = this._items.slice(0);\n var layoutStyles = (this._layout && this._layout.styles) || {};\n var i, prop;\n\n // Unbind window resize event listener.\n unbindLayoutOnResize(this);\n\n // Destroy items.\n for (i = 0; i < items.length; i++) items[i]._destroy(removeElements);\n this._items.length = 0;\n\n // Restore container.\n removeClass(container, this._settings.containerClass);\n for (prop in layoutStyles) container.style[prop] = '';\n\n // Emit destroy event and unbind all events.\n this._emit(EVENT_DESTROY);\n this._emitter.destroy();\n\n // Remove reference from the grid instances collection.\n delete GRID_INSTANCES[this._id];\n\n // Flag instance as destroyed.\n this._isDestroyed = true;\n\n return this;\n};\n\n/**\n * Private prototype methods\n * *************************\n */\n\n/**\n * Emit a grid event.\n *\n * @private\n * @param {String} event\n * @param {...*} [arg]\n */\nGrid.prototype._emit = function () {\n if (this._isDestroyed) return;\n this._emitter.emit.apply(this._emitter, arguments);\n};\n\n/**\n * Check if there are any events listeners for an event.\n *\n * @private\n * @param {String} event\n * @returns {Boolean}\n */\nGrid.prototype._hasListeners = function (event) {\n if (this._isDestroyed) return false;\n return this._emitter.countListeners(event) > 0;\n};\n\n/**\n * Update container's width, height and offsets.\n *\n * @private\n */\nGrid.prototype._updateBoundingRect = function () {\n var element = this._element;\n var rect = element.getBoundingClientRect();\n this._width = rect.width;\n this._height = rect.height;\n this._left = rect.left;\n this._top = rect.top;\n this._right = rect.right;\n this._bottom = rect.bottom;\n};\n\n/**\n * Update container's border sizes.\n *\n * @private\n * @param {Boolean} left\n * @param {Boolean} right\n * @param {Boolean} top\n * @param {Boolean} bottom\n */\nGrid.prototype._updateBorders = function (left, right, top, bottom) {\n var element = this._element;\n if (left) this._borderLeft = getStyleAsFloat(element, 'border-left-width');\n if (right) this._borderRight = getStyleAsFloat(element, 'border-right-width');\n if (top) this._borderTop = getStyleAsFloat(element, 'border-top-width');\n if (bottom) this._borderBottom = getStyleAsFloat(element, 'border-bottom-width');\n};\n\n/**\n * Refresh all of container's internal dimensions and offsets.\n *\n * @private\n */\nGrid.prototype._refreshDimensions = function () {\n this._updateBoundingRect();\n this._updateBorders(1, 1, 1, 1);\n this._boxSizing = getStyle(this._element, 'box-sizing');\n};\n\n/**\n * Calculate and apply item positions.\n *\n * @private\n * @param {Object} layout\n */\nGrid.prototype._onLayoutDataReceived = (function () {\n var itemsToLayout = [];\n return function (layout) {\n if (this._isDestroyed || !this._nextLayoutData || this._nextLayoutData.id !== layout.id) return;\n\n var grid = this;\n var instant = this._nextLayoutData.instant;\n var onFinish = this._nextLayoutData.onFinish;\n var numItems = layout.items.length;\n var counter = numItems;\n var item;\n var left;\n var top;\n var i;\n\n // Reset next layout data.\n this._nextLayoutData = null;\n\n if (!this._isLayoutFinished && this._hasListeners(EVENT_LAYOUT_ABORT)) {\n this._emit(EVENT_LAYOUT_ABORT, this._layout.items.slice(0));\n }\n\n // Update the layout reference.\n this._layout = layout;\n\n // Update the item positions and collect all items that need to be laid\n // out. It is critical that we update the item position _before_ the\n // layoutStart event as the new data might be needed in the callback.\n itemsToLayout.length = 0;\n for (i = 0; i < numItems; i++) {\n item = layout.items[i];\n\n // Make sure we have a matching item.\n if (!item) {\n --counter;\n continue;\n }\n\n // Get the item's new left and top values.\n left = layout.slots[i * 2];\n top = layout.slots[i * 2 + 1];\n\n // Let's skip the layout process if we can. Possibly avoids a lot of DOM\n // operations which saves us some CPU cycles.\n if (item._canSkipLayout(left, top)) {\n --counter;\n continue;\n }\n\n // Update the item's position.\n item._left = left;\n item._top = top;\n\n // Only active non-dragged items need to be moved.\n if (item.isActive() && !item.isDragging()) {\n itemsToLayout.push(item);\n } else {\n --counter;\n }\n }\n\n // Set layout styles to the grid element.\n if (layout.styles) {\n setStyles(this._element, layout.styles);\n }\n\n // layoutStart event is intentionally emitted after the container element's\n // dimensions are set, because otherwise there would be no hook for reacting\n // to container dimension changes.\n if (this._hasListeners(EVENT_LAYOUT_START)) {\n this._emit(EVENT_LAYOUT_START, layout.items.slice(0), instant === true);\n // Let's make sure that the current layout process has not been overridden\n // in the layoutStart event, and if so, let's stop processing the aborted\n // layout.\n if (this._layout.id !== layout.id) return;\n }\n\n var tryFinish = function () {\n if (--counter > 0) return;\n\n var hasLayoutChanged = grid._layout.id !== layout.id;\n var callback = isFunction(instant) ? instant : onFinish;\n\n if (!hasLayoutChanged) {\n grid._isLayoutFinished = true;\n }\n\n if (isFunction(callback)) {\n callback(layout.items.slice(0), hasLayoutChanged);\n }\n\n if (!hasLayoutChanged && grid._hasListeners(EVENT_LAYOUT_END)) {\n grid._emit(EVENT_LAYOUT_END, layout.items.slice(0));\n }\n };\n\n if (!itemsToLayout.length) {\n tryFinish();\n return this;\n }\n\n this._isLayoutFinished = false;\n\n for (i = 0; i < itemsToLayout.length; i++) {\n if (this._layout.id !== layout.id) break;\n itemsToLayout[i]._layout.start(instant === true, tryFinish);\n }\n\n if (this._layout.id === layout.id) {\n itemsToLayout.length = 0;\n }\n\n return this;\n };\n})();\n\n/**\n * Show or hide Grid instance's items.\n *\n * @private\n * @param {Item[]} items\n * @param {Boolean} toVisible\n * @param {Object} [options]\n * @param {Boolean} [options.instant=false]\n * @param {Boolean} [options.syncWithLayout=true]\n * @param {Function} [options.onFinish]\n * @param {(Boolean|Function|String)} [options.layout=true]\n */\nGrid.prototype._setItemsVisibility = function (items, toVisible, options) {\n var grid = this;\n var targetItems = items.slice(0);\n var opts = options || {};\n var isInstant = opts.instant === true;\n var callback = opts.onFinish;\n var layout = opts.layout ? opts.layout : opts.layout === undefined;\n var counter = targetItems.length;\n var startEvent = toVisible ? EVENT_SHOW_START : EVENT_HIDE_START;\n var endEvent = toVisible ? EVENT_SHOW_END : EVENT_HIDE_END;\n var method = toVisible ? 'show' : 'hide';\n var needsLayout = false;\n var completedItems = [];\n var hiddenItems = [];\n var item;\n var i;\n\n // If there are no items call the callback, but don't emit any events.\n if (!counter) {\n if (isFunction(callback)) callback(targetItems);\n return;\n }\n\n // Prepare the items.\n for (i = 0; i < targetItems.length; i++) {\n item = targetItems[i];\n\n // If inactive item is shown or active item is hidden we need to do\n // layout.\n if ((toVisible && !item._isActive) || (!toVisible && item._isActive)) {\n needsLayout = true;\n }\n\n // If inactive item is shown we also need to do a little hack to make the\n // item not animate it's next positioning (layout).\n item._layout._skipNextAnimation = !!(toVisible && !item._isActive);\n\n // If a hidden item is being shown we need to refresh the item's\n // dimensions.\n if (toVisible && item._visibility._isHidden) {\n hiddenItems.push(item);\n }\n\n // Add item to layout or remove it from layout.\n if (toVisible) {\n item._addToLayout();\n } else {\n item._removeFromLayout();\n }\n }\n\n // Force refresh the dimensions of all hidden items.\n if (hiddenItems.length) {\n this.refreshItems(hiddenItems, true);\n hiddenItems.length = 0;\n }\n\n // Show the items in sync with the next layout.\n function triggerVisibilityChange() {\n if (needsLayout && opts.syncWithLayout !== false) {\n grid.off(EVENT_LAYOUT_START, triggerVisibilityChange);\n }\n\n if (grid._hasListeners(startEvent)) {\n grid._emit(startEvent, targetItems.slice(0));\n }\n\n for (i = 0; i < targetItems.length; i++) {\n // Make sure the item is still in the original grid. There is a chance\n // that the item starts migrating before tiggerVisibilityChange is called.\n if (targetItems[i]._gridId !== grid._id) {\n if (--counter < 1) {\n if (isFunction(callback)) callback(completedItems.slice(0));\n if (grid._hasListeners(endEvent)) grid._emit(endEvent, completedItems.slice(0));\n }\n continue;\n }\n\n targetItems[i]._visibility[method](isInstant, function (interrupted, item) {\n // If the current item's animation was not interrupted add it to the\n // completedItems array.\n if (!interrupted) completedItems.push(item);\n\n // If all items have finished their animations call the callback\n // and emit showEnd/hideEnd event.\n if (--counter < 1) {\n if (isFunction(callback)) callback(completedItems.slice(0));\n if (grid._hasListeners(endEvent)) grid._emit(endEvent, completedItems.slice(0));\n }\n });\n }\n }\n\n // Trigger the visibility change, either async with layout or instantly.\n if (needsLayout && opts.syncWithLayout !== false) {\n this.on(EVENT_LAYOUT_START, triggerVisibilityChange);\n } else {\n triggerVisibilityChange();\n }\n\n // Trigger layout if needed.\n if (needsLayout && layout) {\n this.layout(layout === INSTANT_LAYOUT, isFunction(layout) ? layout : undefined);\n }\n};\n\n/**\n * Private helpers\n * ***************\n */\n\n/**\n * Merge default settings with user settings. The returned object is a new\n * object with merged values. The merging is a deep merge meaning that all\n * objects and arrays within the provided settings objects will be also merged\n * so that modifying the values of the settings object will have no effect on\n * the returned object.\n *\n * @param {Object} defaultSettings\n * @param {Object} [userSettings]\n * @returns {Object} Returns a new object.\n */\nfunction mergeSettings(defaultSettings, userSettings) {\n // Create a fresh copy of default settings.\n var settings = mergeObjects({}, defaultSettings);\n\n // Merge user settings to default settings.\n if (userSettings) {\n settings = mergeObjects(settings, userSettings);\n }\n\n // Handle visible/hidden styles manually so that the whole object is\n // overridden instead of the props.\n\n if (userSettings && userSettings.visibleStyles) {\n settings.visibleStyles = userSettings.visibleStyles;\n } else if (defaultSettings && defaultSettings.visibleStyles) {\n settings.visibleStyles = defaultSettings.visibleStyles;\n }\n\n if (userSettings && userSettings.hiddenStyles) {\n settings.hiddenStyles = userSettings.hiddenStyles;\n } else if (defaultSettings && defaultSettings.hiddenStyles) {\n settings.hiddenStyles = defaultSettings.hiddenStyles;\n }\n\n return settings;\n}\n\n/**\n * Merge two objects recursively (deep merge). The source object's properties\n * are merged to the target object.\n *\n * @param {Object} target\n * - The target object.\n * @param {Object} source\n * - The source object.\n * @returns {Object} Returns the target object.\n */\nfunction mergeObjects(target, source) {\n var sourceKeys = Object.keys(source);\n var length = sourceKeys.length;\n var isSourceObject;\n var propName;\n var i;\n\n for (i = 0; i < length; i++) {\n propName = sourceKeys[i];\n isSourceObject = isPlainObject(source[propName]);\n\n // If target and source values are both objects, merge the objects and\n // assign the merged value to the target property.\n if (isPlainObject(target[propName]) && isSourceObject) {\n target[propName] = mergeObjects(mergeObjects({}, target[propName]), source[propName]);\n continue;\n }\n\n // If source's value is object and target's is not let's clone the object as\n // the target's value.\n if (isSourceObject) {\n target[propName] = mergeObjects({}, source[propName]);\n continue;\n }\n\n // If source's value is an array let's clone the array as the target's\n // value.\n if (Array.isArray(source[propName])) {\n target[propName] = source[propName].slice(0);\n continue;\n }\n\n // In all other cases let's just directly assign the source's value as the\n // target's value.\n target[propName] = source[propName];\n }\n\n return target;\n}\n\n/**\n * Collect and return initial items for grid.\n *\n * @param {HTMLElement} gridElement\n * @param {?(HTMLElement[]|NodeList|HtmlCollection|String)} elements\n * @returns {(HTMLElement[]|NodeList|HtmlCollection)}\n */\nfunction getInitialGridElements(gridElement, elements) {\n // If we have a wildcard selector let's return all the children.\n if (elements === '*') {\n return gridElement.children;\n }\n\n // If we have some more specific selector, let's filter the elements.\n if (typeof elements === STRING_TYPE) {\n var result = [];\n var children = gridElement.children;\n for (var i = 0; i < children.length; i++) {\n if (elementMatches(children[i], elements)) {\n result.push(children[i]);\n }\n }\n return result;\n }\n\n // If we have an array of elements or a node list.\n if (Array.isArray(elements) || isNodeList(elements)) {\n return elements;\n }\n\n // Otherwise just return an empty array.\n return [];\n}\n\n/**\n * Bind grid's resize handler to window.\n *\n * @param {Grid} grid\n * @param {(Number|Boolean)} delay\n */\nfunction bindLayoutOnResize(grid, delay) {\n if (typeof delay !== NUMBER_TYPE) {\n delay = delay === true ? 0 : -1;\n }\n\n if (delay >= 0) {\n grid._resizeHandler = debounce(function () {\n grid.refreshItems().layout();\n }, delay);\n\n window.addEventListener('resize', grid._resizeHandler);\n }\n}\n\n/**\n * Unbind grid's resize handler from window.\n *\n * @param {Grid} grid\n */\nfunction unbindLayoutOnResize(grid) {\n if (grid._resizeHandler) {\n grid._resizeHandler(true);\n window.removeEventListener('resize', grid._resizeHandler);\n grid._resizeHandler = null;\n }\n}\n\n/**\n * Normalize style declaration object, returns a normalized (new) styles object\n * (prefixed properties and invalid properties removed).\n *\n * @param {Object} styles\n * @returns {Object}\n */\nfunction normalizeStyles(styles) {\n var normalized = {};\n var docElemStyle = document.documentElement.style;\n var prop, prefixedProp;\n\n // Normalize visible styles (prefix and remove invalid).\n for (prop in styles) {\n if (!styles[prop]) continue;\n prefixedProp = getPrefixedPropName(docElemStyle, prop);\n if (!prefixedProp) continue;\n normalized[prefixedProp] = styles[prop];\n }\n\n return normalized;\n}\n\n/**\n * Create index map from items.\n *\n * @param {Item[]} items\n * @returns {Object}\n */\nfunction createIndexMap(items) {\n var result = {};\n for (var i = 0; i < items.length; i++) {\n result[items[i]._id] = i;\n }\n return result;\n}\n\n/**\n * Sort comparer function for items' index map.\n *\n * @param {Object} indexMap\n * @param {Item} itemA\n * @param {Item} itemB\n * @returns {Number}\n */\nfunction compareIndexMap(indexMap, itemA, itemB) {\n var indexA = indexMap[itemA._id];\n var indexB = indexMap[itemB._id];\n return indexA - indexB;\n}\n\nexport default Grid;\n","/**\n * The interfaces in this file are used to make sure our components have the correct properties\n * defined that are needed to pass to Muuri grid constructor.\n *\n * See Muuri's documentation (https://github.com/haltu/muuri#-table-of-contents) for more details.\n *\n * Add this @Props\n */\n\n// @Element() el: HTMLElement;\n\n// /**\n// * Muuri's grid item selector.\n// */\n// @Prop({reflect: true}) gridItemSelector: string = 'sy-grid-item';\n\n// /**\n// * Muuri's grid handle selector.\n// */\n// @Prop() gridHandleSelector: string;\n\n// /**\n// * The element the dragged item should be appended to for the duration of the drag.\n// */\n// @Prop() dragContainerSelector: string;\n\n// /**\n// * Use to create a landscope grid (expand to right).\n// */\n// @Prop() horizontal: boolean = false;\n\n// /**\n// * Muuri's grid constructor options.\n// */\n// @Prop() gridOptions: object;\n\n/**\n * Bellow you can see the standart use (recommended) of Muuri's grid in your component.\n */\n\n// /**\n// * Use to get Muuri grid instance.\n// */\n// @Method()\n// async getGrid() {\n// return this.grid;\n// }\n\n// private grid;\n\n// componentDidRender() {\n// if(this.sortable)\n// this.grid = MuuriHelper.createGrid(this);\n// }\n\n// componentWillUpdate() {\n// MuuriHelper.destroyGrid(this.grid);\n// }\n\nimport Muuri, { GridOptions } from 'muuri';\n\nexport interface MuuriInterface {\n el: HTMLElement;\n gridItemSelector: string;\n gridHandleSelector?: string | undefined;\n dragContainerSelector?: string | undefined;\n horizontal?: boolean | undefined;\n gridOptions?: { [key: string]: any } | undefined;\n dragCursor?: string;\n}\n\nfunction createGrid(component: MuuriInterface): Muuri {\n let overlayEl: HTMLDivElement;\n\n function addOverlay() {\n overlayEl = document.createElement('div');\n overlayEl.style.opacity = '0';\n overlayEl.style.top = '0';\n overlayEl.style.left = '0';\n overlayEl.style.height = '100%';\n overlayEl.style.width = '100%';\n overlayEl.style.position = 'absolute';\n overlayEl.style.zIndex = '999999';\n overlayEl.style.cursor = component.dragCursor ?? '';\n document.body.appendChild(overlayEl);\n }\n\n function removeOverlay() {\n overlayEl?.remove();\n }\n\n const defaultOptions = {\n dragEnabled: true,\n dragHandle: component.gridHandleSelector ? component.gridHandleSelector : null,\n layoutOnResize: true,\n layout: {\n fillGaps: true,\n horizontal: component.horizontal ? component.horizontal : false,\n },\n };\n\n let gridConstructorOptions: GridOptions = { ...defaultOptions, ...component.gridOptions };\n\n if (component.dragContainerSelector) {\n const dragContainer = (component.el.getRootNode() as Element).querySelector(\n component.dragContainerSelector,\n ) as HTMLElement;\n\n gridConstructorOptions = {\n ...gridConstructorOptions,\n dragContainer,\n };\n }\n\n const muuriGrid = new Muuri(component.el, {\n items: component.el.querySelectorAll(component.gridItemSelector),\n ...gridConstructorOptions,\n });\n\n muuriGrid.on('dragStart', () => addOverlay());\n muuriGrid.on('dragEnd', () => removeOverlay());\n\n return muuriGrid;\n}\n\nfunction destroyGrid(grid: Muuri): void {\n grid.destroy();\n}\n\nexport const MuuriHelper = {\n createGrid,\n destroyGrid,\n};\n"]}